aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/Makefile.am25
-rw-r--r--src/bindings/Makefile.am25
-rw-r--r--src/bindings/interface/Makefile.am55
-rw-r--r--src/bindings/interface/Readme.txt4
-rw-r--r--src/bindings/interface/ScriptMgr.cpp4
-rw-r--r--src/bindings/interface/ScriptMgr.h4
-rw-r--r--src/bindings/interface/Scripts/sc_default.cpp4
-rw-r--r--src/bindings/interface/Scripts/sc_defines.cpp4
-rw-r--r--src/bindings/interface/Scripts/sc_defines.h4
-rw-r--r--src/bindings/interface/config.h4
-rw-r--r--src/bindings/interface/system.cpp4
-rw-r--r--src/bindings/scripts/CMakeLists.txt124
-rw-r--r--src/bindings/scripts/Makefile.am448
-rw-r--r--src/bindings/scripts/ScriptMgr.cpp636
-rw-r--r--src/bindings/scripts/ScriptMgr.h16
-rw-r--r--src/bindings/scripts/VC71/71ScriptDev2.vcproj288
-rw-r--r--src/bindings/scripts/VC80/80ScriptDev2.vcproj296
-rw-r--r--src/bindings/scripts/VC90/90ScriptDev2.vcproj3505
-rw-r--r--src/bindings/scripts/docs/EventAI.txt185
-rw-r--r--src/bindings/scripts/docs/Text-tables.txt6
-rw-r--r--src/bindings/scripts/include/precompiled.cpp2
-rw-r--r--src/bindings/scripts/include/precompiled.h3
-rw-r--r--src/bindings/scripts/include/sc_creature.cpp212
-rw-r--r--src/bindings/scripts/include/sc_creature.h45
-rw-r--r--src/bindings/scripts/include/sc_gossip.h53
-rw-r--r--src/bindings/scripts/include/sc_instance.h2
-rw-r--r--src/bindings/scripts/scripts/areatrigger/areatrigger_scripts.cpp14
-rw-r--r--src/bindings/scripts/scripts/boss/boss_emeriss.cpp4
-rw-r--r--src/bindings/scripts/scripts/boss/boss_lethon.cpp2
-rw-r--r--src/bindings/scripts/scripts/boss/boss_taerar.cpp6
-rw-r--r--src/bindings/scripts/scripts/boss/boss_ysondre.cpp6
-rw-r--r--src/bindings/scripts/scripts/creature/mob_generic_creature.cpp6
-rw-r--r--src/bindings/scripts/scripts/creature/simple_ai.cpp57
-rw-r--r--src/bindings/scripts/scripts/creature/simple_ai.h16
-rw-r--r--src/bindings/scripts/scripts/custom/npc_acherus_taxi.cpp39
-rw-r--r--src/bindings/scripts/scripts/custom/npc_wyrmresttempel_taxi.cpp116
-rw-r--r--src/bindings/scripts/scripts/examples/example_creature.cpp258
-rw-r--r--src/bindings/scripts/scripts/examples/example_escort.cpp221
-rw-r--r--src/bindings/scripts/scripts/examples/example_gossip_codebox.cpp88
-rw-r--r--src/bindings/scripts/scripts/examples/example_misc.cpp65
-rw-r--r--src/bindings/scripts/scripts/go/go_scripts.cpp101
-rw-r--r--src/bindings/scripts/scripts/guard/guard_ai.cpp22
-rw-r--r--src/bindings/scripts/scripts/guard/guard_ai.h4
-rw-r--r--src/bindings/scripts/scripts/guard/guards.cpp890
-rw-r--r--src/bindings/scripts/scripts/item/item_scripts.cpp4
-rw-r--r--src/bindings/scripts/scripts/npc/npc_escortAI.cpp150
-rw-r--r--src/bindings/scripts/scripts/npc/npc_escortAI.h16
-rw-r--r--src/bindings/scripts/scripts/npc/npc_innkeeper.cpp6
-rw-r--r--src/bindings/scripts/scripts/npc/npc_professions.cpp4
-rw-r--r--src/bindings/scripts/scripts/npc/npcs_special.cpp638
-rw-r--r--src/bindings/scripts/scripts/zone/alterac_mountains/alterac_mountains.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/arathi_highlands/arathi_highlands.cpp26
-rw-r--r--src/bindings/scripts/scripts/zone/ashenvale_forest/ashenvale.cpp66
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/auchenai_crypts/boss_exarch_maladaar.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/auchenai_crypts/boss_shirrak_the_dead_watcher.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/mana_tombs/boss_nexusprince_shaffar.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/mana_tombs/boss_pandemonius.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/boss_darkweaver_syth.cpp12
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/boss_tailonking_ikiss.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/def_sethekk_halls.h2
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/instance_sethekk_halls.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp20
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp20
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_murmur.cpp44
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/def_shadow_labyrinth.h2
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp22
-rw-r--r--src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_amanitar.cpp79
-rw-r--r--src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_elder_nadox.cpp244
-rw-r--r--src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_herald_volazj.cpp111
-rw-r--r--src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_jedoga_shadowseeker.cpp109
-rw-r--r--src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp109
-rw-r--r--src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/def_ahnkahet.h (renamed from src/shared/Database/QueryResultSqlite.h)39
-rw-r--r--src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/instance_ahnkahet.cpp194
-rw-r--r--src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/boss_anubarak.cpp112
-rw-r--r--src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/boss_hadronox.cpp114
-rw-r--r--src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/boss_krikthir_the_gatewatcher.cpp116
-rw-r--r--src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/def_azjol_nerub.h29
-rw-r--r--src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp180
-rw-r--r--src/bindings/scripts/scripts/zone/azshara/azshara.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/azshara/boss_azuregos.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp277
-rw-r--r--src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp83
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/.boss_teron_gorefiend.cpp-woains536
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/.instance_black_temple.cpp-s8inyu347
-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.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp102
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_mother_shahraz.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp25
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp18
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp227
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_teron_gorefiend.cpp20
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp137
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/def_black_temple.h2
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/illidari_council.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/blackrock_depths.cpp88
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_ambassador_flamelash.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_anubshiah.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_emperor_dagran_thaurissan.cpp20
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_general_angerforge.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_gorosh_the_dervish.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_grizzle.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_high_interrogator_gerstahn.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_magmus.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_moira_bronzebeard.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_tomb_of_seven.cpp14
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_drakkisath.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_gyth.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_halycon.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_highlord_omokk.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_mother_smolderweb.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_overlord_wyrmthalak.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_pyroguard_emberseer.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_quartermaster_zigris.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_rend_blackhand.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_shadow_hunter_voshgajin.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_the_beast.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_warmaster_voone.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_chromaggus.cpp14
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_ebonroc.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_nefarian.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_vaelastrasz.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_victor_nefarius.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/instance_blackwing_lair.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp283
-rw-r--r--src/bindings/scripts/scripts/zone/blasted_lands/blasted_lands.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blasted_lands/boss_kruul.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/borean_tundra/borean_tundra.cpp105
-rw-r--r--src/bindings/scripts/scripts/zone/burning_steppes/burning_steppes.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/boss_epoch.cpp86
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/boss_mal_ganis.cpp123
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/boss_meathook.cpp138
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/boss_salramm.cpp152
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/def_culling_of_stratholme.h4
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp21
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_aeonus.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_temporus.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/dark_portal.cpp31
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/def_dark_portal.h2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/instance_dark_portal.cpp17
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp11
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp392
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp11
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_kazrogal.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/def_hyjal.h2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp19
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.h4
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp30
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.h6
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp53
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp12
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp12
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/def_old_hillsbrad.h2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp215
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp30
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp40
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp57
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/def_serpent_shrine.h2
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_hydromancer_thespia.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_mekgineer_steamrigger.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/def_steam_vault.h2
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/instance_steam_vault.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_hungarfen.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_the_black_stalker.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/darkshore/darkshore.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/draktharon_keep/boss_dred.cpp56
-rw-r--r--src/bindings/scripts/scripts/zone/draktharon_keep/boss_novos.cpp75
-rw-r--r--src/bindings/scripts/scripts/zone/draktharon_keep/boss_tharon_ja.cpp88
-rw-r--r--src/bindings/scripts/scripts/zone/draktharon_keep/boss_trollgore.cpp75
-rw-r--r--src/bindings/scripts/scripts/zone/draktharon_keep/def_drak_tharon_keep.h4
-rw-r--r--src/bindings/scripts/scripts/zone/draktharon_keep/instance_drak_tharon_keep.cpp21
-rw-r--r--src/bindings/scripts/scripts/zone/dun_morogh/dun_morogh.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/dustwallow_marsh/dustwallow_marsh.cpp6
-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.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp64
-rw-r--r--src/bindings/scripts/scripts/zone/felwood/felwood.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/feralas/feralas.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp70
-rw-r--r--src/bindings/scripts/scripts/zone/gruuls_lair/boss_gruul.cpp99
-rw-r--r--src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp61
-rw-r--r--src/bindings/scripts/scripts/zone/gruuls_lair/def_gruuls_lair.h24
-rw-r--r--src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/gundrak/boss_drakkari_colossus.cpp55
-rw-r--r--src/bindings/scripts/scripts/zone/gundrak/boss_eck.cpp65
-rw-r--r--src/bindings/scripts/scripts/zone/gundrak/boss_gal_darah.cpp85
-rw-r--r--src/bindings/scripts/scripts/zone/gundrak/boss_moorabi.cpp88
-rw-r--r--src/bindings/scripts/scripts/zone/gundrak/boss_slad_ran.cpp95
-rw-r--r--src/bindings/scripts/scripts/zone/gundrak/def_gundrak.h4
-rw-r--r--src/bindings/scripts/scripts/zone/gundrak/instance_gundrak.cpp21
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_broggok.cpp56
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp26
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_the_maker.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp18
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_vazruden_the_herald.cpp12
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/def_magtheridons_lair.h2
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp33
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_nethekurse.cpp93
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp21
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp116
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/def_shattered_halls.h2
-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.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp43
-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.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_curator.cpp116
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_maiden_of_virtue.cpp14
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_midnight.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp22
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_netherspite.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_nightbane.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp62
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_shade_of_aran.cpp21
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_terestian_illhoof.cpp47
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp331
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/def_karazhan.h75
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp44
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/karazhan.cpp64
-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.cpp555
-rw-r--r--src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp383
-rw-r--r--src/bindings/scripts/scripts/zone/magisters_terrace/boss_selin_fireheart.cpp155
-rw-r--r--src/bindings/scripts/scripts/zone/magisters_terrace/boss_vexallus.cpp147
-rw-r--r--src/bindings/scripts/scripts/zone/magisters_terrace/def_magisters_terrace.h13
-rw-r--r--src/bindings/scripts/scripts/zone/magisters_terrace/instance_magisters_terrace.cpp86
-rw-r--r--src/bindings/scripts/scripts/zone/maraudon/boss_celebras_the_cursed.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/maraudon/boss_landslide.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/maraudon/boss_noxxion.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/maraudon/boss_princess_theradras.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_baron_geddon.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_garr.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_gehennas.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_golemagg.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_lucifron.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_magmadar.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_majordomo_executus.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_ragnaros.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_shazzrah.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_sulfuron_harbinger.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/def_molten_core.h2
-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.cpp19
-rw-r--r--src/bindings/scripts/scripts/zone/mulgore/mulgore.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/nagrand/nagrand.cpp22
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_anubrekhan.cpp126
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_faerlina.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_four_horsemen.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_gluth.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_grobbulus.cpp92
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_heigan.cpp25
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_kelthuzad.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_loatheb.cpp74
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_maexxna.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp129
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_thaddius.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp26
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/eye_of_eternity/boss_malygos.cpp170
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/eye_of_eternity/def_eye_of_eternity.h4
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/eye_of_eternity/instance_eye_of_eternity.cpp21
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/nexus/boss_anomalus.cpp149
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/nexus/boss_keristrasza.cpp89
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/nexus/boss_magus_telestra.cpp118
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/nexus/boss_ormorok.cpp90
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/nexus/commander_kolurg.cpp57
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/nexus/commander_stoutbeard.cpp63
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/nexus/def_nexus.h35
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/nexus/instance_nexus.cpp158
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/oculus/boss_drakos.cpp82
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/oculus/boss_eregos.cpp104
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/oculus/boss_urom.cpp87
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/oculus/boss_varos.cpp85
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/oculus/def_oculus.h4
-rw-r--r--src/bindings/scripts/scripts/zone/nexus/oculus/instance_oculus.cpp21
-rw-r--r--src/bindings/scripts/scripts/zone/obsidian_sanctum/boss_sartharion.cpp300
-rw-r--r--src/bindings/scripts/scripts/zone/obsidian_sanctum/def_obsidian_sanctum.h4
-rw-r--r--src/bindings/scripts/scripts/zone/obsidian_sanctum/instance_obsidian_sanctum.cpp21
-rw-r--r--src/bindings/scripts/scripts/zone/onyxias_lair/boss_onyxia.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/orgrimmar/orgrimmar.cpp29
-rw-r--r--src/bindings/scripts/scripts/zone/razorfen_downs/boss_amnennar_the_coldbringer.cpp97
-rw-r--r--src/bindings/scripts/scripts/zone/razorfen_downs/razorfen_downs.cpp85
-rw-r--r--src/bindings/scripts/scripts/zone/razorfen_kraul/razorfen_kraul.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_ayamiss.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_buru.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_kurinnaxx.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_moam.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_ossirian.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_rajaxx.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_arcanist_doan.cpp152
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_azshir_the_sleepless.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_bloodmage_thalnos.cpp99
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp20
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_herod.cpp54
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_houndmaster_loksey.cpp25
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_interrogator_vishas.cpp96
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_mograine_and_whitemane.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_scorn.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/def_scarlet_monastery.h8
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp41
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_death_knight_darkreaver.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_doctor_theolen_krastinov.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_illucia_barov.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_instructor_malicia.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_kormok.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_lord_alexei_barov.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_lorekeeper_polkelt.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_ras_frostwhisper.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_the_ravenian.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_vectus.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/def_scholomance.h5
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/instance_scholomance.cpp92
-rw-r--r--src/bindings/scripts/scripts/zone/searing_gorge/searing_gorge.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/shadowfang_keep/def_shadowfang_keep.h2
-rw-r--r--src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp70
-rw-r--r--src/bindings/scripts/scripts/zone/shadowfang_keep/shadowfang_keep.cpp104
-rw-r--r--src/bindings/scripts/scripts/zone/shadowmoon_valley/boss_doomwalker.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/shadowmoon_valley/shadowmoon_valley.cpp36
-rw-r--r--src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp73
-rw-r--r--src/bindings/scripts/scripts/zone/silithus/silithus.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/silvermoon/silvermoon_city.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/silverpine_forest/silverpine_forest.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/stonetalon_mountains/stonetalon_mountains.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp45
-rw-r--r--src/bindings/scripts/scripts/zone/stranglethorn_vale/stranglethorn_vale.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_baron_rivendare.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_baroness_anastari.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_cannon_master_willey.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_magistrate_barthilas.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_maleki_the_pallid.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_nerubenkan.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_order_of_silver_hand.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_postmaster_malown.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_ramstein_the_gorger.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_timmy_the_cruel.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/def_stratholme.h2
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/instance_stratholme.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/stratholme.cpp83
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_brutallus.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_eredar_twins.cpp36
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp14
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp26
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/def_sunwell_plateau.h2
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/tanaris/tanaris.cpp49
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/arcatraz.cpp24
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/def_arcatraz.h2
-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.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_laj.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_warp_splinter.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp12
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp7
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp67
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/def_the_eye.h2
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/the_eye.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/instance_mechanar.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_cthun.cpp44
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_huhuran.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_ouro.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_sartura.cpp38
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_skeram.cpp35
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp30
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_viscidus.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/def_temple_of_ahnqiraj.h2
-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.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp20
-rw-r--r--src/bindings/scripts/scripts/zone/thousand_needles/thousand_needles.cpp25
-rw-r--r--src/bindings/scripts/scripts/zone/thunder_bluff/thunder_bluff.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/uldaman/boss_archaedas.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/uldaman/boss_ironaya.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp26
-rw-r--r--src/bindings/scripts/scripts/zone/uldaman/uldaman.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/boss_bjarngrim.cpp94
-rw-r--r--src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/boss_ionar.cpp114
-rw-r--r--src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/boss_loken.cpp86
-rw-r--r--src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/boss_volkhan.cpp128
-rw-r--r--src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/def_halls_of_lightning.h4
-rw-r--r--src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp21
-rw-r--r--src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/boss_krystallus.cpp73
-rw-r--r--src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/boss_maiden_of_grief.cpp81
-rw-r--r--src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/boss_sjonnir.cpp83
-rw-r--r--src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/def_halls_of_stone.h4
-rw-r--r--src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/instance_halls_of_stone.cpp21
-rw-r--r--src/bindings/scripts/scripts/zone/undercity/undercity.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/ungoro_crater/ungoro_crater.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_dalronn.cpp97
-rw-r--r--src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_ingvar_the_plunderer.cpp449
-rw-r--r--src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_keleseth.cpp338
-rw-r--r--src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_skarvald.cpp96
-rw-r--r--src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_skarvald_dalronn.cpp388
-rw-r--r--src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/def_utgarde_keep.h (renamed from src/shared/Database/DatabaseSqlite.h)35
-rw-r--r--src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp217
-rw-r--r--src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp78
-rw-r--r--src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp89
-rw-r--r--src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/boss_svala.cpp83
-rw-r--r--src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp85
-rw-r--r--src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/def_pinnacle.h4
-rw-r--r--src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp21
-rw-r--r--src/bindings/scripts/scripts/zone/vault_of_archavon/boss_archavon.cpp93
-rw-r--r--src/bindings/scripts/scripts/zone/vault_of_archavon/def_vault_of_archavon.h4
-rw-r--r--src/bindings/scripts/scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp21
-rw-r--r--src/bindings/scripts/scripts/zone/violet_hold/boss_cyanigosa.cpp82
-rw-r--r--src/bindings/scripts/scripts/zone/violet_hold/boss_erekem.cpp82
-rw-r--r--src/bindings/scripts/scripts/zone/violet_hold/boss_ichoron.cpp81
-rw-r--r--src/bindings/scripts/scripts/zone/violet_hold/boss_lavanthor.cpp52
-rw-r--r--src/bindings/scripts/scripts/zone/violet_hold/boss_moragg.cpp50
-rw-r--r--src/bindings/scripts/scripts/zone/violet_hold/boss_xevozz.cpp82
-rw-r--r--src/bindings/scripts/scripts/zone/violet_hold/boss_zuramat.cpp82
-rw-r--r--src/bindings/scripts/scripts/zone/violet_hold/def_violet_hold.h4
-rw-r--r--src/bindings/scripts/scripts/zone/violet_hold/instance_violet_hold.cpp21
-rw-r--r--src/bindings/scripts/scripts/zone/wailing_caverns/instance_wailing_caverns.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/western_plaguelands/western_plaguelands.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/westfall/westfall.cpp78
-rw-r--r--src/bindings/scripts/scripts/zone/winterspring/winterspring.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/zangarmarsh/zangarmarsh.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp17
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_halazzi.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp25
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_janalai.cpp20
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/def_zulaman.h2
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/zulaman.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/zulfarrak/zulfarrak.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_gahzranka.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_hakkar.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_hazzarah.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_jeklik.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp27
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_mandokir.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp30
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_venoxis.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_wushoolay.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/def_zulgurub.h2
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/instance_zulgurub.cpp2
-rw-r--r--src/bindings/scripts/sql/WotLK/npc_taxi.sql10
-rw-r--r--src/bindings/scripts/sql/WotLK/script_texts_wotlk.sql530
-rw-r--r--src/bindings/scripts/sql/WotLK/wotlk_bosses.sql124
-rw-r--r--src/bindings/scripts/system.cpp4
-rw-r--r--src/framework/Dynamic/FactoryHolder.h4
-rw-r--r--src/framework/Dynamic/ObjectRegistry.h4
-rw-r--r--src/framework/GameSystem/Grid.h4
-rw-r--r--src/framework/GameSystem/GridLoader.h4
-rw-r--r--src/framework/GameSystem/GridRefManager.h4
-rw-r--r--src/framework/GameSystem/GridReference.h4
-rw-r--r--src/framework/GameSystem/NGrid.h26
-rw-r--r--src/framework/GameSystem/TypeContainer.h4
-rw-r--r--src/framework/GameSystem/TypeContainerFunctions.h4
-rw-r--r--src/framework/GameSystem/TypeContainerFunctionsPtr.h4
-rw-r--r--src/framework/GameSystem/TypeContainerVisitor.h4
-rw-r--r--src/framework/Makefile.am65
-rw-r--r--src/framework/Network/SocketDefines.h4
-rw-r--r--src/framework/Platform/CompilerDefs.h4
-rw-r--r--src/framework/Platform/Define.h6
-rw-r--r--src/framework/Policies/CreationPolicy.h4
-rw-r--r--src/framework/Policies/ObjectLifeTime.cpp4
-rw-r--r--src/framework/Policies/ObjectLifeTime.h8
-rw-r--r--src/framework/Policies/Singleton.h4
-rw-r--r--src/framework/Policies/SingletonImp.h4
-rw-r--r--src/framework/Policies/ThreadingModel.h4
-rw-r--r--src/framework/Utilities/ByteConverter.h4
-rw-r--r--src/framework/Utilities/Callback.h4
-rw-r--r--src/framework/Utilities/CountedReference/Reference.h4
-rw-r--r--src/framework/Utilities/CountedReference/ReferenceHolder.h4
-rw-r--r--src/framework/Utilities/CountedReference/ReferenceImpl.h4
-rw-r--r--src/framework/Utilities/EventProcessor.cpp4
-rw-r--r--src/framework/Utilities/EventProcessor.h4
-rw-r--r--src/framework/Utilities/LinkedList.h4
-rw-r--r--src/framework/Utilities/LinkedReference/RefManager.h4
-rw-r--r--src/framework/Utilities/LinkedReference/Reference.h18
-rw-r--r--src/framework/Utilities/TypeList.h4
-rw-r--r--src/framework/Utilities/UnorderedMap.h4
-rw-r--r--src/game/AccountMgr.cpp10
-rw-r--r--src/game/AccountMgr.h4
-rw-r--r--src/game/AchievementMgr.cpp1931
-rw-r--r--src/game/AchievementMgr.h265
-rw-r--r--src/game/AddonHandler.cpp69
-rw-r--r--src/game/AddonHandler.h4
-rw-r--r--src/game/AggressorAI.cpp57
-rw-r--r--src/game/AggressorAI.h7
-rw-r--r--src/game/AnimalRandomMovementGenerator.h4
-rw-r--r--src/game/ArenaTeam.cpp78
-rw-r--r--src/game/ArenaTeam.h20
-rw-r--r--src/game/ArenaTeamHandler.cpp9
-rw-r--r--src/game/AuctionHouseBot.cpp54
-rw-r--r--src/game/AuctionHouseHandler.cpp53
-rw-r--r--src/game/AuctionHouseMgr.cpp124
-rw-r--r--src/game/Bag.cpp14
-rw-r--r--src/game/Bag.h7
-rw-r--r--src/game/BattleGround.cpp1019
-rw-r--r--src/game/BattleGround.h230
-rw-r--r--src/game/BattleGroundAA.cpp24
-rw-r--r--src/game/BattleGroundAA.h9
-rw-r--r--src/game/BattleGroundAB.cpp387
-rw-r--r--src/game/BattleGroundAB.h78
-rw-r--r--src/game/BattleGroundAV.cpp50
-rw-r--r--src/game/BattleGroundAV.h8
-rw-r--r--src/game/BattleGroundBE.cpp133
-rw-r--r--src/game/BattleGroundBE.h10
-rw-r--r--src/game/BattleGroundDS.cpp81
-rw-r--r--src/game/BattleGroundDS.h50
-rw-r--r--src/game/BattleGroundEY.cpp369
-rw-r--r--src/game/BattleGroundEY.h81
-rw-r--r--src/game/BattleGroundHandler.cpp511
-rw-r--r--src/game/BattleGroundMgr.cpp1995
-rw-r--r--src/game/BattleGroundMgr.h220
-rw-r--r--src/game/BattleGroundNA.cpp127
-rw-r--r--src/game/BattleGroundNA.h10
-rw-r--r--src/game/BattleGroundRL.cpp128
-rw-r--r--src/game/BattleGroundRL.h12
-rw-r--r--src/game/BattleGroundRV.cpp81
-rw-r--r--src/game/BattleGroundRV.h50
-rw-r--r--src/game/BattleGroundSA.cpp81
-rw-r--r--src/game/BattleGroundSA.h54
-rw-r--r--src/game/BattleGroundWS.cpp344
-rw-r--r--src/game/BattleGroundWS.h31
-rw-r--r--src/game/CMakeLists.txt36
-rw-r--r--src/game/Calendar.cpp17
-rw-r--r--src/game/Calendar.h26
-rw-r--r--src/game/CalendarHandler.cpp159
-rw-r--r--src/game/Cell.h8
-rw-r--r--src/game/CellImpl.h4
-rw-r--r--src/game/Channel.cpp34
-rw-r--r--src/game/Channel.h180
-rw-r--r--src/game/ChannelHandler.cpp4
-rw-r--r--src/game/ChannelMgr.h8
-rw-r--r--src/game/CharacterHandler.cpp405
-rw-r--r--src/game/Chat.cpp1009
-rw-r--r--src/game/Chat.h400
-rw-r--r--src/game/ChatHandler.cpp229
-rw-r--r--src/game/CombatHandler.cpp5
-rw-r--r--src/game/ConfusedMovementGenerator.cpp7
-rw-r--r--src/game/ConfusedMovementGenerator.h4
-rw-r--r--src/game/Corpse.cpp69
-rw-r--r--src/game/Corpse.h11
-rw-r--r--src/game/Creature.cpp234
-rw-r--r--src/game/Creature.h128
-rw-r--r--src/game/CreatureAI.cpp51
-rw-r--r--src/game/CreatureAI.h139
-rw-r--r--src/game/CreatureAIImpl.h4
-rw-r--r--src/game/CreatureAIRegistry.cpp8
-rw-r--r--src/game/CreatureAIRegistry.h4
-rw-r--r--src/game/CreatureAISelector.cpp36
-rw-r--r--src/game/CreatureAISelector.h4
-rw-r--r--src/game/CreatureEventAI.cpp1634
-rw-r--r--src/game/CreatureEventAI.h307
-rw-r--r--src/game/CreatureEventAIMgr.cpp702
-rw-r--r--src/game/CreatureEventAIMgr.h46
-rw-r--r--src/game/DBCEnums.h331
-rw-r--r--src/game/DBCStores.cpp (renamed from src/shared/Database/DBCStores.cpp)184
-rw-r--r--src/game/DBCStores.h (renamed from src/shared/Database/DBCStores.h)117
-rw-r--r--src/game/DBCStructure.h1727
-rw-r--r--src/game/DBCfmt.h109
-rw-r--r--src/game/Debugcmds.cpp385
-rw-r--r--src/game/DestinationHolder.cpp4
-rw-r--r--src/game/DestinationHolder.h4
-rw-r--r--src/game/DestinationHolderImp.h24
-rw-r--r--src/game/DuelHandler.cpp6
-rw-r--r--src/game/DynamicObject.cpp37
-rw-r--r--src/game/DynamicObject.h9
-rw-r--r--src/game/FleeingMovementGenerator.cpp27
-rw-r--r--src/game/FleeingMovementGenerator.h5
-rw-r--r--src/game/FollowerRefManager.h4
-rw-r--r--src/game/FollowerReference.cpp4
-rw-r--r--src/game/FollowerReference.h4
-rw-r--r--src/game/Formulas.h79
-rw-r--r--src/game/GameEventMgr.cpp (renamed from src/game/GameEvent.cpp)301
-rw-r--r--src/game/GameEventMgr.h (renamed from src/game/GameEvent.h)40
-rw-r--r--src/game/GameObject.cpp402
-rw-r--r--src/game/GameObject.h102
-rw-r--r--src/game/GlobalEvents.cpp6
-rw-r--r--src/game/GlobalEvents.h4
-rw-r--r--src/game/GossipDef.cpp154
-rw-r--r--src/game/GossipDef.h43
-rw-r--r--src/game/GridDefines.h8
-rw-r--r--src/game/GridNotifiers.cpp55
-rw-r--r--src/game/GridNotifiers.h258
-rw-r--r--src/game/GridNotifiersImpl.h152
-rw-r--r--src/game/GridStates.h4
-rw-r--r--src/game/Group.cpp160
-rw-r--r--src/game/Group.h22
-rw-r--r--src/game/GroupHandler.cpp119
-rw-r--r--src/game/GroupRefManager.h4
-rw-r--r--src/game/GroupReference.cpp4
-rw-r--r--src/game/GroupReference.h4
-rw-r--r--src/game/GuardAI.cpp70
-rw-r--r--src/game/GuardAI.h7
-rw-r--r--src/game/Guild.cpp95
-rw-r--r--src/game/Guild.h26
-rw-r--r--src/game/GuildHandler.cpp31
-rw-r--r--src/game/HomeMovementGenerator.cpp10
-rw-r--r--src/game/HomeMovementGenerator.h5
-rw-r--r--src/game/HostilRefManager.cpp6
-rw-r--r--src/game/HostilRefManager.h4
-rw-r--r--src/game/IdleMovementGenerator.cpp6
-rw-r--r--src/game/IdleMovementGenerator.h4
-rw-r--r--src/game/InstanceData.cpp12
-rw-r--r--src/game/InstanceData.h8
-rw-r--r--src/game/InstanceSaveMgr.cpp51
-rw-r--r--src/game/InstanceSaveMgr.h4
-rw-r--r--src/game/Item.cpp74
-rw-r--r--src/game/Item.h58
-rw-r--r--src/game/ItemEnchantmentMgr.cpp12
-rw-r--r--src/game/ItemEnchantmentMgr.h4
-rw-r--r--src/game/ItemHandler.cpp238
-rw-r--r--src/game/ItemPrototype.h145
-rw-r--r--src/game/LFGHandler.cpp4
-rw-r--r--src/game/Language.h240
-rw-r--r--src/game/Level0.cpp28
-rw-r--r--src/game/Level1.cpp516
-rw-r--r--src/game/Level2.cpp2487
-rw-r--r--src/game/Level3.cpp1433
-rw-r--r--src/game/LootHandler.cpp56
-rw-r--r--src/game/LootMgr.cpp254
-rw-r--r--src/game/LootMgr.h93
-rw-r--r--src/game/Mail.cpp52
-rw-r--r--src/game/Mail.h8
-rw-r--r--src/game/Makefile.am847
-rw-r--r--src/game/Map.cpp1300
-rw-r--r--src/game/Map.h210
-rw-r--r--src/game/MapInstanced.cpp6
-rw-r--r--src/game/MapInstanced.h6
-rw-r--r--src/game/MapManager.cpp17
-rw-r--r--src/game/MapManager.h35
-rw-r--r--src/game/MapRefManager.h2
-rw-r--r--src/game/MapReference.h2
-rw-r--r--src/game/MiscHandler.cpp247
-rw-r--r--src/game/MotionMaster.cpp99
-rw-r--r--src/game/MotionMaster.h13
-rw-r--r--src/game/MovementGenerator.cpp4
-rw-r--r--src/game/MovementGenerator.h4
-rw-r--r--src/game/MovementGeneratorImpl.h4
-rw-r--r--src/game/MovementHandler.cpp474
-rw-r--r--src/game/NPCHandler.cpp167
-rw-r--r--src/game/NPCHandler.h5
-rw-r--r--src/game/NullCreatureAI.cpp4
-rw-r--r--src/game/NullCreatureAI.h12
-rw-r--r--src/game/Object.cpp546
-rw-r--r--src/game/Object.h66
-rw-r--r--src/game/ObjectAccessor.cpp222
-rw-r--r--src/game/ObjectAccessor.h48
-rw-r--r--src/game/ObjectDefines.h8
-rw-r--r--src/game/ObjectGridLoader.cpp34
-rw-r--r--src/game/ObjectMgr.cpp1354
-rw-r--r--src/game/ObjectMgr.h98
-rw-r--r--src/game/ObjectPosSelector.cpp157
-rw-r--r--src/game/ObjectPosSelector.h155
-rw-r--r--src/game/Opcodes.cpp2261
-rw-r--r--src/game/Opcodes.h407
-rw-r--r--src/game/OutdoorPvP.cpp31
-rw-r--r--src/game/OutdoorPvP.h2
-rw-r--r--src/game/OutdoorPvPEP.cpp2
-rw-r--r--src/game/OutdoorPvPEP.h4
-rw-r--r--src/game/OutdoorPvPHP.cpp2
-rw-r--r--src/game/OutdoorPvPHP.h2
-rw-r--r--src/game/OutdoorPvPMgr.cpp3
-rw-r--r--src/game/OutdoorPvPMgr.h2
-rw-r--r--src/game/OutdoorPvPNA.cpp2
-rw-r--r--src/game/OutdoorPvPNA.h2
-rw-r--r--src/game/OutdoorPvPObjectiveAI.cpp2
-rw-r--r--src/game/OutdoorPvPObjectiveAI.h4
-rw-r--r--src/game/OutdoorPvPSI.cpp14
-rw-r--r--src/game/OutdoorPvPSI.h2
-rw-r--r--src/game/OutdoorPvPTF.cpp2
-rw-r--r--src/game/OutdoorPvPZM.cpp6
-rw-r--r--src/game/OutdoorPvPZM.h2
-rw-r--r--src/game/Path.h4
-rw-r--r--src/game/Pet.cpp1435
-rw-r--r--src/game/Pet.h112
-rw-r--r--src/game/PetAI.cpp92
-rw-r--r--src/game/PetAI.h7
-rw-r--r--src/game/PetHandler.cpp275
-rw-r--r--src/game/PetitionsHandler.cpp41
-rw-r--r--src/game/Player.cpp6761
-rw-r--r--src/game/Player.h782
-rw-r--r--src/game/PlayerDump.cpp103
-rw-r--r--src/game/PlayerDump.h13
-rw-r--r--src/game/PointMovementGenerator.cpp12
-rw-r--r--src/game/PointMovementGenerator.h4
-rw-r--r--src/game/PoolHandler.cpp719
-rw-r--r--src/game/PoolHandler.h104
-rw-r--r--src/game/PossessedAI.cpp4
-rw-r--r--src/game/PossessedAI.h4
-rw-r--r--src/game/QueryHandler.cpp121
-rw-r--r--src/game/QuestDef.cpp121
-rw-r--r--src/game/QuestDef.h54
-rw-r--r--src/game/QuestHandler.cpp26
-rw-r--r--src/game/RandomMovementGenerator.cpp11
-rw-r--r--src/game/RandomMovementGenerator.h4
-rw-r--r--src/game/ReactorAI.cpp56
-rw-r--r--src/game/ReactorAI.h7
-rw-r--r--src/game/ReputationMgr.cpp473
-rw-r--r--src/game/ReputationMgr.h146
-rw-r--r--src/game/ScriptCalls.cpp11
-rw-r--r--src/game/ScriptCalls.h12
-rw-r--r--src/game/SharedDefines.h755
-rw-r--r--src/game/SkillDiscovery.cpp89
-rw-r--r--src/game/SkillDiscovery.h5
-rw-r--r--src/game/SkillExtraItems.cpp4
-rw-r--r--src/game/SkillExtraItems.h4
-rw-r--r--src/game/SkillHandler.cpp112
-rw-r--r--src/game/SocialMgr.cpp32
-rw-r--r--src/game/SocialMgr.h7
-rw-r--r--src/game/Spell.cpp2376
-rw-r--r--src/game/Spell.h195
-rw-r--r--src/game/SpellAuraDefines.h118
-rw-r--r--src/game/SpellAuras.cpp5306
-rw-r--r--src/game/SpellAuras.h326
-rw-r--r--src/game/SpellEffects.cpp3710
-rw-r--r--src/game/SpellHandler.cpp217
-rw-r--r--src/game/SpellMgr.cpp1344
-rw-r--r--src/game/SpellMgr.h486
-rw-r--r--src/game/StatSystem.cpp228
-rw-r--r--src/game/TargetedMovementGenerator.cpp7
-rw-r--r--src/game/TargetedMovementGenerator.h4
-rw-r--r--src/game/TaxiHandler.cpp25
-rw-r--r--src/game/TemporarySummon.cpp170
-rw-r--r--src/game/TemporarySummon.h42
-rw-r--r--src/game/ThreatManager.cpp84
-rw-r--r--src/game/ThreatManager.h53
-rw-r--r--src/game/TicketHandler.cpp4
-rw-r--r--src/game/TicketMgr.cpp4
-rw-r--r--src/game/TicketMgr.h4
-rw-r--r--src/game/Tools.cpp4
-rw-r--r--src/game/Tools.h4
-rw-r--r--src/game/Totem.cpp107
-rw-r--r--src/game/Totem.h18
-rw-r--r--src/game/TotemAI.cpp67
-rw-r--r--src/game/TotemAI.h8
-rw-r--r--src/game/TradeHandler.cpp16
-rw-r--r--src/game/Transports.cpp125
-rw-r--r--src/game/Transports.h26
-rw-r--r--src/game/Traveller.h71
-rw-r--r--src/game/Unit.cpp9419
-rw-r--r--src/game/Unit.h543
-rw-r--r--src/game/UnitEvents.h4
-rw-r--r--src/game/UpdateData.cpp8
-rw-r--r--src/game/UpdateData.h9
-rw-r--r--src/game/UpdateFields.h535
-rw-r--r--src/game/UpdateMask.h36
-rw-r--r--src/game/Vehicle.cpp387
-rw-r--r--src/game/Vehicle.h80
-rw-r--r--src/game/VoiceChatHandler.cpp5
-rw-r--r--src/game/WaypointManager.cpp4
-rw-r--r--src/game/WaypointManager.h4
-rw-r--r--src/game/WaypointMovementGenerator.cpp20
-rw-r--r--src/game/WaypointMovementGenerator.h8
-rw-r--r--src/game/Weather.cpp9
-rw-r--r--src/game/Weather.h6
-rw-r--r--src/game/World.cpp660
-rw-r--r--src/game/World.h88
-rw-r--r--src/game/WorldLog.cpp74
-rw-r--r--src/game/WorldLog.h34
-rw-r--r--src/game/WorldSession.cpp244
-rw-r--r--src/game/WorldSession.h92
-rw-r--r--src/game/WorldSocket.cpp135
-rw-r--r--src/game/WorldSocket.h4
-rw-r--r--src/game/WorldSocketMgr.cpp8
-rw-r--r--src/game/WorldSocketMgr.h4
-rw-r--r--src/shared/Auth/AuthCrypt.cpp9
-rw-r--r--src/shared/Auth/AuthCrypt.h5
-rw-r--r--src/shared/Auth/BigNumber.cpp4
-rw-r--r--src/shared/Auth/BigNumber.h4
-rw-r--r--src/shared/Auth/Hmac.cpp4
-rw-r--r--src/shared/Auth/Hmac.h4
-rw-r--r--src/shared/Auth/Makefile.am41
-rw-r--r--src/shared/Auth/Sha1.cpp4
-rw-r--r--src/shared/Auth/Sha1.h4
-rw-r--r--src/shared/Base.cpp68
-rw-r--r--src/shared/Base.h55
-rw-r--r--src/shared/ByteBuffer.h53
-rw-r--r--src/shared/CMakeLists.txt4
-rw-r--r--src/shared/Common.cpp4
-rw-r--r--src/shared/Common.h10
-rw-r--r--src/shared/Config/Config.cpp118
-rw-r--r--src/shared/Config/Config.h20
-rw-r--r--src/shared/Config/ConfigEnv.h4
-rw-r--r--src/shared/Config/Makefile.am42
-rw-r--r--src/shared/Config/dotconfpp/dotconfpp.cpp24
-rw-r--r--src/shared/Config/dotconfpp/mempool.cpp6
-rw-r--r--src/shared/Database/CMakeLists.txt15
-rw-r--r--src/shared/Database/DBCEnums.h113
-rw-r--r--src/shared/Database/DBCFileLoader.cpp (renamed from src/shared/Database/dbcfile.cpp)53
-rw-r--r--src/shared/Database/DBCFileLoader.h (renamed from src/shared/Database/dbcfile.h)21
-rw-r--r--src/shared/Database/DBCStore.h94
-rw-r--r--src/shared/Database/DBCStructure.h904
-rw-r--r--src/shared/Database/DBCfmt.cpp86
-rw-r--r--src/shared/Database/Database.cpp4
-rw-r--r--src/shared/Database/Database.h6
-rw-r--r--src/shared/Database/DatabaseEnv.h7
-rw-r--r--src/shared/Database/DatabaseImpl.h4
-rw-r--r--src/shared/Database/DatabaseMysql.cpp4
-rw-r--r--src/shared/Database/DatabaseMysql.h4
-rw-r--r--src/shared/Database/DatabasePostgre.cpp13
-rw-r--r--src/shared/Database/DatabasePostgre.h4
-rw-r--r--src/shared/Database/DatabaseSqlite.cpp104
-rw-r--r--src/shared/Database/Field.cpp4
-rw-r--r--src/shared/Database/Field.h4
-rw-r--r--src/shared/Database/Makefile.am59
-rw-r--r--src/shared/Database/MySQLDelayThread.h4
-rw-r--r--src/shared/Database/PGSQLDelayThread.h4
-rw-r--r--src/shared/Database/QueryResult.h4
-rw-r--r--src/shared/Database/QueryResultMysql.cpp4
-rw-r--r--src/shared/Database/QueryResultMysql.h4
-rw-r--r--src/shared/Database/QueryResultPostgre.cpp4
-rw-r--r--src/shared/Database/QueryResultPostgre.h4
-rw-r--r--src/shared/Database/QueryResultSqlite.cpp99
-rw-r--r--src/shared/Database/SQLStorage.cpp22
-rw-r--r--src/shared/Database/SQLStorage.h4
-rw-r--r--src/shared/Database/SQLStorageImpl.h12
-rw-r--r--src/shared/Database/SqlDelayThread.cpp4
-rw-r--r--src/shared/Database/SqlDelayThread.h6
-rw-r--r--src/shared/Database/SqlOperations.cpp6
-rw-r--r--src/shared/Database/SqlOperations.h4
-rw-r--r--src/shared/Errors.h4
-rw-r--r--src/shared/Log.cpp570
-rw-r--r--src/shared/Log.h155
-rw-r--r--src/shared/Makefile.am82
-rw-r--r--src/shared/MemoryLeaks.cpp32
-rw-r--r--src/shared/MemoryLeaks.h48
-rw-r--r--src/shared/Mthread.cpp206
-rw-r--r--src/shared/Mthread.h63
-rw-r--r--src/shared/PacketLog.cpp4
-rw-r--r--src/shared/PacketLog.h4
-rw-r--r--src/shared/ProgressBar.cpp4
-rw-r--r--src/shared/ProgressBar.h4
-rw-r--r--src/shared/ServiceWin32.cpp10
-rw-r--r--src/shared/ServiceWin32.h4
-rw-r--r--src/shared/SystemConfig.h6
-rw-r--r--src/shared/SystemConfig.h.in79
-rw-r--r--src/shared/Timer.h4
-rw-r--r--src/shared/Util.cpp20
-rw-r--r--src/shared/Util.h256
-rw-r--r--src/shared/WorldPacket.h4
-rw-r--r--src/shared/vmap/BaseModel.cpp4
-rw-r--r--src/shared/vmap/BaseModel.h4
-rw-r--r--src/shared/vmap/CoordModelMapping.cpp4
-rw-r--r--src/shared/vmap/CoordModelMapping.h4
-rw-r--r--src/shared/vmap/DebugCmdLogger.cpp4
-rw-r--r--src/shared/vmap/DebugCmdLogger.h4
-rw-r--r--src/shared/vmap/IVMapManager.h4
-rw-r--r--src/shared/vmap/Makefile.am58
-rw-r--r--src/shared/vmap/ManagedModelContainer.cpp4
-rw-r--r--src/shared/vmap/ManagedModelContainer.h4
-rw-r--r--src/shared/vmap/ModelContainer.cpp4
-rw-r--r--src/shared/vmap/ModelContainer.h4
-rw-r--r--src/shared/vmap/NodeValueAccess.h4
-rw-r--r--src/shared/vmap/ShortBox.h4
-rw-r--r--src/shared/vmap/ShortVector.h4
-rw-r--r--src/shared/vmap/SubModel.cpp4
-rw-r--r--src/shared/vmap/SubModel.h4
-rw-r--r--src/shared/vmap/TileAssembler.cpp7
-rw-r--r--src/shared/vmap/TileAssembler.h4
-rw-r--r--src/shared/vmap/TreeNode.cpp4
-rw-r--r--src/shared/vmap/TreeNode.h4
-rw-r--r--src/shared/vmap/VMapDefinitions.h4
-rw-r--r--src/shared/vmap/VMapFactory.cpp4
-rw-r--r--src/shared/vmap/VMapFactory.h4
-rw-r--r--src/shared/vmap/VMapManager.cpp4
-rw-r--r--src/shared/vmap/VMapManager.h4
-rw-r--r--src/shared/vmap/VMapTools.h4
-rw-r--r--src/tools/Makefile.am23
-rw-r--r--src/tools/genrevision/Makefile.am35
-rw-r--r--src/trinitycore/CMakeLists.txt16
-rw-r--r--src/trinitycore/CliRunnable.cpp49
-rw-r--r--src/trinitycore/CliRunnable.h5
-rw-r--r--src/trinitycore/Main.cpp20
-rw-r--r--src/trinitycore/Makefile.am62
-rw-r--r--src/trinitycore/Master.cpp194
-rw-r--r--src/trinitycore/Master.h5
-rw-r--r--src/trinitycore/RASocket.cpp21
-rw-r--r--src/trinitycore/RASocket.h5
-rw-r--r--src/trinitycore/TrinityCore.rc2
-rw-r--r--src/trinitycore/WorldRunnable.cpp27
-rw-r--r--src/trinitycore/WorldRunnable.h5
-rw-r--r--src/trinitycore/resource.h1
-rw-r--r--src/trinitycore/run-mangosd2
-rw-r--r--src/trinitycore/trinitycore.conf.dist421
-rw-r--r--src/trinityrealm/AuthCodes.h9
-rw-r--r--src/trinityrealm/AuthSocket.cpp5
-rw-r--r--src/trinityrealm/AuthSocket.h5
-rw-r--r--src/trinityrealm/CMakeLists.txt17
-rw-r--r--src/trinityrealm/Main.cpp58
-rw-r--r--src/trinityrealm/Makefile.am59
-rw-r--r--src/trinityrealm/RealmList.cpp5
-rw-r--r--src/trinityrealm/RealmList.h7
-rw-r--r--src/trinityrealm/TrinityRealm.rc2
-rw-r--r--src/trinityrealm/resource.h1
-rw-r--r--src/trinityrealm/trinityrealm.conf.dist32
940 files changed, 69445 insertions, 37479 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 8c8b9e0126f..6620f48f933 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,6 +1,6 @@
+add_subdirectory(bindings)
add_subdirectory(framework)
-add_subdirectory(shared)
-add_subdirectory(trinityrealm)
add_subdirectory(game)
-add_subdirectory(bindings)
+add_subdirectory(shared)
add_subdirectory(trinitycore)
+add_subdirectory(trinityrealm)
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 00000000000..7309b10db83
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,25 @@
+# Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
+#
+# Thanks to the original authors: 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
+
+## Process this file with automake to produce Makefile.in
+
+## Sub-directories to parse
+SUBDIRS = tools framework shared realmd game bindings mangosd
+
+## Additional files to include when running 'make dist'
+# Nothing yet.
diff --git a/src/bindings/Makefile.am b/src/bindings/Makefile.am
new file mode 100644
index 00000000000..26914e8fde1
--- /dev/null
+++ b/src/bindings/Makefile.am
@@ -0,0 +1,25 @@
+# Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
+#
+# Thanks to the original authors: 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
+
+# interface folder is disabled for now
+
+#if USE_TSCRIPTS
+SUBDIRS = scripts
+#else
+#SUBDIRS = interface
+#endif
diff --git a/src/bindings/interface/Makefile.am b/src/bindings/interface/Makefile.am
new file mode 100644
index 00000000000..9bb53f98454
--- /dev/null
+++ b/src/bindings/interface/Makefile.am
@@ -0,0 +1,55 @@
+# Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
+#
+# Thanks to the original authors: 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
+
+## Process this file with automake to produce Makefile.in
+
+## Sub-directories to parse
+
+## Build MaNGOS script library as shared library.
+# libmangosscript shared library will later be reused by world server daemon.
+lib_LTLIBRARIES = libtrinityscript.la
+
+libtrinityscript_la_CPPFLAGS = \
+$(MYSQL_INCLUDES) \
+$(POSTGRE_INCLUDES) \
+$(TRINI_INCLUDES) \
+-I$(top_srcdir)/dep/include \
+-I$(top_srcdir)/src/shared \
+-I$(top_srcdir)/src/framework \
+-I$(top_srcdir)/src/game
+
+libtrinityscript_la_SOURCES = \
+$(srcdir)/ScriptMgr.cpp \
+$(srcdir)/ScriptMgr.h \
+$(srcdir)/config.h \
+$(srcdir)/system.cpp \
+$(srcdir)/Scripts/sc_default.cpp \
+$(srcdir)/Scripts/sc_defines.cpp \
+$(srcdir)/Scripts/sc_defines.h
+
+## libtool settings
+# API versioning
+libtrinityscript_la_LIBFLAGS = -version-info 0:0:0
+libtrinityscript_la_LIBADD = $(MYSQL_LIBS) $(POSTGRE_LIBS)
+
+## Additional files to include when running 'make dist'
+# Scripts defaults.
+EXTRA_DIST = \
+ Readme.txt
+
+
diff --git a/src/bindings/interface/Readme.txt b/src/bindings/interface/Readme.txt
index e152162de8e..821f2367be4 100644
--- a/src/bindings/interface/Readme.txt
+++ b/src/bindings/interface/Readme.txt
@@ -2,7 +2,7 @@
** HOW TO SCRIPT IN C++ **
1 - create a file myscript.cpp in scripts folder.
-2 - copy the content of script_default.cpp, it as the structure on how the scripting fuctions are organized.
+2 - copy the content of script_default.cpp, it as the structure on how the scripting fuctions are organized.
dont forget to change the name of fuctions, like GossipHello_default to GossipHello_myscript.
3 - in fuction AddSC_default change to AddSC_myscript.
@@ -14,7 +14,7 @@ add your AddSC_myscript in here
// -- Scripts to be added --
extern void AddSC_default();
-// -------------------
+// -------------------
and here
diff --git a/src/bindings/interface/ScriptMgr.cpp b/src/bindings/interface/ScriptMgr.cpp
index 57e6ea7c224..c5d4652d5e6 100644
--- a/src/bindings/interface/ScriptMgr.cpp
+++ b/src/bindings/interface/ScriptMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/bindings/interface/ScriptMgr.h b/src/bindings/interface/ScriptMgr.h
index 8c6c91ec362..97b75f07db2 100644
--- a/src/bindings/interface/ScriptMgr.h
+++ b/src/bindings/interface/ScriptMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/bindings/interface/Scripts/sc_default.cpp b/src/bindings/interface/Scripts/sc_default.cpp
index 495de39c270..56ec01c4205 100644
--- a/src/bindings/interface/Scripts/sc_default.cpp
+++ b/src/bindings/interface/Scripts/sc_default.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/bindings/interface/Scripts/sc_defines.cpp b/src/bindings/interface/Scripts/sc_defines.cpp
index 5665a299106..922beebfc46 100644
--- a/src/bindings/interface/Scripts/sc_defines.cpp
+++ b/src/bindings/interface/Scripts/sc_defines.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/bindings/interface/Scripts/sc_defines.h b/src/bindings/interface/Scripts/sc_defines.h
index e942e755ae0..f9bac67683c 100644
--- a/src/bindings/interface/Scripts/sc_defines.h
+++ b/src/bindings/interface/Scripts/sc_defines.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/bindings/interface/config.h b/src/bindings/interface/config.h
index eaef18f9aa4..3899d7892a1 100644
--- a/src/bindings/interface/config.h
+++ b/src/bindings/interface/config.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/bindings/interface/system.cpp b/src/bindings/interface/system.cpp
index 3cf3c7acf33..05e932ca3ae 100644
--- a/src/bindings/interface/system.cpp
+++ b/src/bindings/interface/system.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/bindings/scripts/CMakeLists.txt b/src/bindings/scripts/CMakeLists.txt
index dadb2d76985..93fbeaf171a 100644
--- a/src/bindings/scripts/CMakeLists.txt
+++ b/src/bindings/scripts/CMakeLists.txt
@@ -15,20 +15,18 @@ SET(trinityscript_LIB_SRCS
scripts/boss/boss_lethon.cpp
scripts/boss/boss_taerar.cpp
scripts/boss/boss_ysondre.cpp
- scripts/creature/mob_event_ai.cpp
- scripts/creature/mob_event_ai.h
scripts/creature/mob_generic_creature.cpp
scripts/creature/simple_ai.cpp
scripts/creature/simple_ai.h
- scripts/custom/custom_example.cpp
- scripts/custom/custom_gossip_codebox.cpp
- scripts/custom/test.cpp
+ scripts/examples/example_creature.cpp
+ scripts/examples/example_escort.cpp
+ scripts/examples/example_gossip_codebox.cpp
+ scripts/examples/example_misc.cpp
scripts/go/go_scripts.cpp
scripts/guard/guard_ai.cpp
scripts/guard/guard_ai.h
scripts/guard/guards.cpp
scripts/item/item_scripts.cpp
- scripts/item/item_test.cpp
scripts/npc/npc_escortAI.cpp
scripts/npc/npc_escortAI.h
scripts/npc/npc_innkeeper.cpp
@@ -67,19 +65,19 @@ SET(trinityscript_LIB_SRCS
scripts/zone/black_temple/def_black_temple.h
scripts/zone/black_temple/illidari_council.cpp
scripts/zone/black_temple/instance_black_temple.cpp
- scripts/zone/blackrock_depths/blackrock_depths.cpp
- scripts/zone/blackrock_depths/boss_ambassador_flamelash.cpp
- scripts/zone/blackrock_depths/boss_anubshiah.cpp
- scripts/zone/blackrock_depths/boss_emperor_dagran_thaurissan.cpp
- scripts/zone/blackrock_depths/boss_general_angerforge.cpp
+ scripts/zone/blackrock_depths/blackrock_depths.cpp
+ scripts/zone/blackrock_depths/boss_ambassador_flamelash.cpp
+ scripts/zone/blackrock_depths/boss_anubshiah.cpp
+ scripts/zone/blackrock_depths/boss_emperor_dagran_thaurissan.cpp
+ scripts/zone/blackrock_depths/boss_general_angerforge.cpp
scripts/zone/blackrock_depths/boss_gorosh_the_dervish.cpp
- scripts/zone/blackrock_depths/boss_grizzle.cpp
- scripts/zone/blackrock_depths/boss_high_interrogator_gerstahn.cpp
- scripts/zone/blackrock_depths/boss_magmus.cpp
- scripts/zone/blackrock_depths/boss_moira_bronzebeard.cpp
- scripts/zone/blackrock_depths/boss_tomb_of_seven.cpp
- scripts/zone/blackrock_depths/def_blackrock_depths.h
- scripts/zone/blackrock_depths/instance_blackrock_depths.cpp
+ scripts/zone/blackrock_depths/boss_grizzle.cpp
+ scripts/zone/blackrock_depths/boss_high_interrogator_gerstahn.cpp
+ scripts/zone/blackrock_depths/boss_magmus.cpp
+ scripts/zone/blackrock_depths/boss_moira_bronzebeard.cpp
+ scripts/zone/blackrock_depths/boss_tomb_of_seven.cpp
+ scripts/zone/blackrock_depths/def_blackrock_depths.h
+ scripts/zone/blackrock_depths/instance_blackrock_depths.cpp
scripts/zone/blackrock_spire/boss_drakkisath.cpp
scripts/zone/blackrock_spire/boss_gyth.cpp
scripts/zone/blackrock_spire/boss_halycon.cpp
@@ -106,6 +104,7 @@ SET(trinityscript_LIB_SRCS
scripts/zone/blasted_lands/blasted_lands.cpp
scripts/zone/blasted_lands/boss_kruul.cpp
scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp
+ scripts/zone/borean_tundra/borean_tundra.cpp
scripts/zone/burning_steppes/burning_steppes.cpp
scripts/zone/caverns_of_time/dark_portal/def_dark_portal.h
scripts/zone/caverns_of_time/dark_portal/instance_dark_portal.cpp
@@ -227,7 +226,6 @@ SET(trinityscript_LIB_SRCS
scripts/zone/naxxramas/boss_gothik.cpp
scripts/zone/naxxramas/boss_grobbulus.cpp
scripts/zone/naxxramas/boss_heigan.cpp
- scripts/zone/naxxramas/boss_highlord_mograine.cpp
scripts/zone/naxxramas/boss_kelthuzad.cpp
scripts/zone/naxxramas/boss_four_horsemen.cpp
scripts/zone/naxxramas/boss_loatheb.cpp
@@ -242,7 +240,8 @@ SET(trinityscript_LIB_SRCS
scripts/zone/onyxias_lair/boss_onyxia.cpp
scripts/zone/orgrimmar/orgrimmar.cpp
scripts/zone/razorfen_downs/boss_amnennar_the_coldbringer.cpp
- scripts/zone/razorfen_kraul/razorfen_kraul.cpp
+ scripts/zone/razorfen_downs/razorfen_downs.cpp
+ scripts/zone/razorfen_kraul/razorfen_kraul.cpp
scripts/zone/ruins_of_ahnqiraj/boss_ayamiss.cpp
scripts/zone/ruins_of_ahnqiraj/boss_buru.cpp
scripts/zone/ruins_of_ahnqiraj/boss_kurinnaxx.cpp
@@ -385,6 +384,91 @@ SET(trinityscript_LIB_SRCS
scripts/zone/zulgurub/boss_wushoolay.cpp
scripts/zone/zulgurub/def_zulgurub.h
scripts/zone/zulgurub/instance_zulgurub.cpp
+ scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp
+ scripts/zone/utgarde_keep/utgarde_keep/boss_keleseth.cpp
+ scripts/zone/utgarde_keep/utgarde_keep/boss_skarvald_dalronn.cpp
+ scripts/zone/utgarde_keep/utgarde_keep/boss_ingvar_the_plunderer.cpp
+ scripts/zone/utgarde_keep/utgarde_keep/def_utgarde_keep.h
+ scripts/zone/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp
+ scripts/zone/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp
+ scripts/zone/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp
+ scripts/zone/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp
+ scripts/zone/utgarde_keep/utgarde_pinnacle/boss_svala.cpp
+ scripts/zone/utgarde_keep/utgarde_pinnacle/def_pinnacle.h
+ scripts/zone/nexus/nexus/instance_nexus.cpp
+ scripts/zone/nexus/nexus/boss_magus_telestra.cpp
+ scripts/zone/nexus/nexus/boss_anomalus.cpp
+ scripts/zone/nexus/nexus/boss_ormorok.cpp
+ scripts/zone/nexus/nexus/boss_keristrasza.cpp
+ scripts/zone/nexus/nexus/commander_stoutbeard.cpp
+ scripts/zone/nexus/nexus/commander_kolurg.cpp
+ scripts/zone/nexus/nexus/def_nexus.h
+ scripts/zone/nexus/oculus/instance_oculus.cpp
+ scripts/zone/nexus/oculus/boss_drakos.cpp
+ scripts/zone/nexus/oculus/boss_urom.cpp
+ scripts/zone/nexus/oculus/boss_varos.cpp
+ scripts/zone/nexus/oculus/boss_eregos.cpp
+ scripts/zone/nexus/oculus/def_oculus.h
+ scripts/zone/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp
+ scripts/zone/azjol_nerub/azjol_nerub/boss_krikthir_the_gatewatcher.cpp
+ scripts/zone/azjol_nerub/azjol_nerub/boss_hadronox.cpp
+ scripts/zone/azjol_nerub/azjol_nerub/boss_anubarak.cpp
+ scripts/zone/azjol_nerub/azjol_nerub/def_azjol_nerub.h
+ scripts/zone/azjol_nerub/ahnkahet/instance_ahnkahet.cpp
+ scripts/zone/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp
+ scripts/zone/azjol_nerub/ahnkahet/boss_elder_nadox.cpp
+ scripts/zone/azjol_nerub/ahnkahet/boss_jedoga_shadowseeker.cpp
+ scripts/zone/azjol_nerub/ahnkahet/boss_herald_volazj.cpp
+ scripts/zone/azjol_nerub/ahnkahet/boss_amanitar.cpp
+ scripts/zone/azjol_nerub/ahnkahet/def_ahnkahet.h
+ scripts/zone/draktharon_keep/instance_drak_tharon_keep.cpp
+ scripts/zone/draktharon_keep/boss_trollgore.cpp
+ scripts/zone/draktharon_keep/boss_novos.cpp
+ scripts/zone/draktharon_keep/boss_dred.cpp
+ scripts/zone/draktharon_keep/boss_tharon_ja.cpp
+ scripts/zone/draktharon_keep/def_drak_tharon_keep.h
+ scripts/zone/violet_hold/instance_violet_hold.cpp
+ scripts/zone/violet_hold/boss_cyanigosa.cpp
+ scripts/zone/violet_hold/boss_erekem.cpp
+ scripts/zone/violet_hold/boss_ichoron.cpp
+ scripts/zone/violet_hold/boss_lavanthor.cpp
+ scripts/zone/violet_hold/boss_moragg.cpp
+ scripts/zone/violet_hold/boss_xevozz.cpp
+ scripts/zone/violet_hold/boss_zuramat.cpp
+ scripts/zone/violet_hold/def_violet_hold.h
+ scripts/zone/gundrak/instance_gundrak.cpp
+ scripts/zone/gundrak/boss_slad_ran.cpp
+ scripts/zone/gundrak/boss_moorabi.cpp
+ scripts/zone/gundrak/boss_drakkari_colossus.cpp
+ scripts/zone/gundrak/boss_gal_darah.cpp
+ scripts/zone/gundrak/boss_eck.cpp
+ scripts/zone/gundrak/def_gundrak.h
+ scripts/zone/ulduar/halls_of_stone/instance_halls_of_stone.cpp
+ scripts/zone/ulduar/halls_of_stone/boss_maiden_of_grief.cpp
+ scripts/zone/ulduar/halls_of_stone/boss_krystallus.cpp
+ scripts/zone/ulduar/halls_of_stone/boss_sjonnir.cpp
+ scripts/zone/ulduar/halls_of_stone/def_halls_of_stone.h
+ scripts/zone/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp
+ scripts/zone/ulduar/halls_of_lightning/boss_bjarngrim.cpp
+ scripts/zone/ulduar/halls_of_lightning/boss_ionar.cpp
+ scripts/zone/ulduar/halls_of_lightning/boss_volkhan.cpp
+ scripts/zone/ulduar/halls_of_lightning/boss_loken.cpp
+ scripts/zone/ulduar/halls_of_lightning/def_halls_of_lightning.h
+ scripts/zone/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp
+ scripts/zone/caverns_of_time/culling_of_stratholme/boss_meathook.cpp
+ scripts/zone/caverns_of_time/culling_of_stratholme/boss_epoch.cpp
+ scripts/zone/caverns_of_time/culling_of_stratholme/boss_mal_ganis.cpp
+ scripts/zone/caverns_of_time/culling_of_stratholme/boss_salramm.cpp
+ scripts/zone/caverns_of_time/culling_of_stratholme/def_culling_of_stratholme.h
+ scripts/zone/nexus/eye_of_eternity/instance_eye_of_eternity.cpp
+ scripts/zone/nexus/eye_of_eternity/boss_malygos.cpp
+ scripts/zone/nexus/eye_of_eternity/def_eye_of_eternity.h
+ scripts/zone/obsidian_sanctum/instance_obsidian_sanctum.cpp
+ scripts/zone/obsidian_sanctum/boss_sartharion.cpp
+ scripts/zone/obsidian_sanctum/def_obsidian_sanctum.h
+ scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp
+ scripts/zone/vault_of_archavon/boss_archavon.cpp
+ scripts/zone/vault_of_archavon/def_vault_of_archavon.h
system.cpp
)
diff --git a/src/bindings/scripts/Makefile.am b/src/bindings/scripts/Makefile.am
new file mode 100644
index 00000000000..5e98755a8b4
--- /dev/null
+++ b/src/bindings/scripts/Makefile.am
@@ -0,0 +1,448 @@
+# Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
+#
+# Thanks to the original authors: 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
+
+## Process this file with automake to produce Makefile.in
+
+## Sub-directories to parse
+## SUBDIRS = sql
+
+# build shared library
+lib_LTLIBRARIES = libtrinityscript.la
+
+libtrinityscript_la_CPPFLAGS = \
+$(MYSQL_INCLUDES) \
+$(POSTGRE_INCLUDES) \
+-I$(top_srcdir)/dep/include \
+-I$(top_srcdir)/src/shared \
+-I$(top_srcdir)/src/framework \
+-I$(top_srcdir)/src/game \
+-I$(srcdir)/include \
+$(TRINI_INCLUDES) \
+-D_TRINITY_SCRIPT_CONFIG='"$(sysconfdir)/trinitycore.conf"'
+
+libtrinityscript_la_SOURCES = \
+ScriptMgr.cpp \
+ScriptMgr.h \
+include/precompiled.cpp \
+include/precompiled.h \
+include/sc_creature.cpp \
+include/sc_creature.h \
+include/sc_gossip.h \
+include/sc_instance.h \
+scripts/areatrigger/areatrigger_scripts.cpp \
+scripts/boss/boss_emeriss.cpp \
+scripts/boss/boss_lethon.cpp \
+scripts/boss/boss_taerar.cpp \
+scripts/boss/boss_ysondre.cpp \
+scripts/creature/mob_event_ai.cpp \
+scripts/creature/mob_event_ai.h \
+scripts/creature/mob_generic_creature.cpp \
+scripts/creature/simple_ai.cpp \
+scripts/creature/simple_ai.h \
+scripts/examples/example_creature.cpp \
+scripts/examples/example_escort.cpp \
+scripts/examples/example_gossip_codebox.cpp \
+scripts/examples/example_misc.cpp \
+scripts/go/go_scripts.cpp \
+scripts/guard/guard_ai.cpp \
+scripts/guard/guard_ai.h \
+scripts/guard/guards.cpp \
+scripts/item/item_scripts.cpp \
+scripts/npc/npc_escortAI.cpp \
+scripts/npc/npc_escortAI.h \
+scripts/npc/npc_innkeeper.cpp \
+scripts/npc/npc_professions.cpp \
+scripts/npc/npcs_special.cpp \
+scripts/zone/alterac_mountains/alterac_mountains.cpp \
+scripts/zone/arathi_highlands/arathi_highlands.cpp \
+scripts/zone/ashenvale_forest/ashenvale.cpp\
+scripts/zone/aunchindoun/auchenai_crypts/boss_exarch_maladaar.cpp \
+scripts/zone/aunchindoun/auchenai_crypts/boss_shirrak_the_dead_watcher.cpp \
+scripts/zone/aunchindoun/mana_tombs/boss_nexusprince_shaffar.cpp \
+scripts/zone/aunchindoun/mana_tombs/boss_pandemonius.cpp \
+scripts/zone/aunchindoun/sethekk_halls/boss_darkweaver_syth.cpp \
+scripts/zone/aunchindoun/sethekk_halls/boss_tailonking_ikiss.cpp \
+scripts/zone/aunchindoun/sethekk_halls/def_sethekk_halls.h \
+scripts/zone/aunchindoun/sethekk_halls/instance_sethekk_halls.cpp \
+scripts/zone/aunchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp \
+scripts/zone/aunchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp \
+scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp \
+scripts/zone/aunchindoun/shadow_labyrinth/boss_murmur.cpp \
+scripts/zone/aunchindoun/shadow_labyrinth/def_shadow_labyrinth.h \
+scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp \
+scripts/zone/azjol_nerub/ahnkahet/instance_ahnkahet.cpp \
+scripts/zone/azjol_nerub/ahnkahet/boss_elder_nadox.cpp \
+scripts/zone/azjol_nerub/ahnkahet/def_ahnkahet.h \
+scripts/zone/azshara/azshara.cpp \
+scripts/zone/azshara/boss_azuregos.cpp \
+scripts/zone/azuremyst_isle/azuremyst_isle.cpp \
+scripts/zone/barrens/the_barrens.cpp \
+scripts/zone/black_temple/black_temple.cpp \
+scripts/zone/black_temple/boss_bloodboil.cpp \
+scripts/zone/black_temple/boss_illidan.cpp \
+scripts/zone/black_temple/boss_mother_shahraz.cpp \
+scripts/zone/black_temple/boss_reliquary_of_souls.cpp \
+scripts/zone/black_temple/boss_shade_of_akama.cpp \
+scripts/zone/black_temple/boss_supremus.cpp \
+scripts/zone/black_temple/boss_teron_gorefiend.cpp \
+scripts/zone/black_temple/boss_warlord_najentus.cpp \
+scripts/zone/black_temple/def_black_temple.h \
+scripts/zone/black_temple/illidari_council.cpp \
+scripts/zone/black_temple/instance_black_temple.cpp \
+scripts/zone/blackrock_depths/blackrock_depths.cpp \
+scripts/zone/blackrock_depths/boss_ambassador_flamelash.cpp \
+scripts/zone/blackrock_depths/boss_anubshiah.cpp \
+scripts/zone/blackrock_depths/boss_emperor_dagran_thaurissan.cpp \
+scripts/zone/blackrock_depths/boss_general_angerforge.cpp \
+scripts/zone/blackrock_depths/boss_gorosh_the_dervish.cpp \
+scripts/zone/blackrock_depths/boss_grizzle.cpp \
+scripts/zone/blackrock_depths/boss_high_interrogator_gerstahn.cpp \
+scripts/zone/blackrock_depths/boss_magmus.cpp \
+scripts/zone/blackrock_depths/boss_moira_bronzebeard.cpp \
+scripts/zone/blackrock_depths/boss_tomb_of_seven.cpp \
+scripts/zone/blackrock_depths/def_blackrock_depths.h \
+scripts/zone/blackrock_depths/instance_blackrock_depths.cpp \
+scripts/zone/blackrock_spire/boss_drakkisath.cpp \
+scripts/zone/blackrock_spire/boss_gyth.cpp \
+scripts/zone/blackrock_spire/boss_halycon.cpp \
+scripts/zone/blackrock_spire/boss_highlord_omokk.cpp \
+scripts/zone/blackrock_spire/boss_mother_smolderweb.cpp \
+scripts/zone/blackrock_spire/boss_overlord_wyrmthalak.cpp \
+scripts/zone/blackrock_spire/boss_pyroguard_emberseer.cpp \
+scripts/zone/blackrock_spire/boss_quartermaster_zigris.cpp \
+scripts/zone/blackrock_spire/boss_rend_blackhand.cpp \
+scripts/zone/blackrock_spire/boss_shadow_hunter_voshgajin.cpp \
+scripts/zone/blackrock_spire/boss_the_beast.cpp \
+scripts/zone/blackrock_spire/boss_warmaster_voone.cpp \
+scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp \
+scripts/zone/blackwing_lair/boss_chromaggus.cpp \
+scripts/zone/blackwing_lair/boss_ebonroc.cpp \
+scripts/zone/blackwing_lair/boss_firemaw.cpp \
+scripts/zone/blackwing_lair/boss_flamegor.cpp \
+scripts/zone/blackwing_lair/boss_nefarian.cpp \
+scripts/zone/blackwing_lair/boss_razorgore.cpp \
+scripts/zone/blackwing_lair/boss_vaelastrasz.cpp \
+scripts/zone/blackwing_lair/boss_victor_nefarius.cpp \
+scripts/zone/blackwing_lair/instance_blackwing_lair.cpp \
+scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp \
+scripts/zone/blasted_lands/blasted_lands.cpp \
+scripts/zone/blasted_lands/boss_kruul.cpp \
+scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp \
+scripts/zone/borean_tundra/borean_tundra.cpp \
+scripts/zone/burning_steppes/burning_steppes.cpp \
+scripts/zone/caverns_of_time/dark_portal/boss_aeonus.cpp \
+scripts/zone/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp \
+scripts/zone/caverns_of_time/dark_portal/boss_temporus.cpp \
+scripts/zone/caverns_of_time/dark_portal/dark_portal.cpp \
+scripts/zone/caverns_of_time/dark_portal/def_dark_portal.h \
+scripts/zone/caverns_of_time/dark_portal/instance_dark_portal.cpp \
+scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp \
+scripts/zone/caverns_of_time/hyjal/def_hyjal.h \
+scripts/zone/caverns_of_time/hyjal/hyjal.cpp \
+scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp \
+scripts/zone/caverns_of_time/hyjal/hyjalAI.h \
+scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp \
+scripts/zone/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp \
+scripts/zone/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp \
+scripts/zone/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp \
+scripts/zone/caverns_of_time/old_hillsbrad/def_old_hillsbrad.h \
+scripts/zone/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp \
+scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp \
+scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp \
+scripts/zone/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp \
+scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp \
+scripts/zone/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp \
+scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp \
+scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp \
+scripts/zone/coilfang_resevoir/serpent_shrine/def_serpent_shrine.h \
+scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp \
+scripts/zone/coilfang_resevoir/steam_vault/boss_hydromancer_thespia.cpp \
+scripts/zone/coilfang_resevoir/steam_vault/boss_mekgineer_steamrigger.cpp \
+scripts/zone/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp \
+scripts/zone/coilfang_resevoir/steam_vault/def_steam_vault.h \
+scripts/zone/coilfang_resevoir/steam_vault/instance_steam_vault.cpp \
+scripts/zone/coilfang_resevoir/underbog/boss_hungarfen.cpp \
+scripts/zone/darkshore/darkshore.cpp \
+scripts/zone/deadmines/deadmines.cpp \
+scripts/zone/deadmines/def_deadmines.h \
+scripts/zone/dun_morogh/dun_morogh.cpp \
+scripts/zone/dustwallow_marsh/dustwallow_marsh.cpp \
+scripts/zone/eastern_plaguelands/eastern_plaguelands.cpp \
+scripts/zone/elwynn_forest/elwynn_forest.cpp \
+scripts/zone/eversong_woods/eversong_woods.cpp \
+scripts/zone/felwood/felwood.cpp \
+scripts/zone/feralas/feralas.cpp \
+scripts/zone/ghostlands/ghostlands.cpp \
+scripts/zone/gruuls_lair/boss_gruul.cpp \
+scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp \
+scripts/zone/gruuls_lair/def_gruuls_lair.h \
+scripts/zone/gruuls_lair/instance_gruuls_lair.cpp \
+scripts/zone/hellfire_citadel/blood_furnace/boss_broggok.cpp \
+scripts/zone/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp \
+scripts/zone/hellfire_citadel/blood_furnace/boss_the_maker.cpp \
+scripts/zone/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp \
+scripts/zone/hellfire_citadel/blood_furnace/def_blood_furnace.h \
+scripts/zone/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp \
+scripts/zone/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp \
+scripts/zone/hellfire_citadel/hellfire_ramparts/boss_vazruden_the_herald.cpp \
+scripts/zone/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp \
+scripts/zone/hellfire_citadel/magtheridons_lair/def_magtheridons_lair.h \
+scripts/zone/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp \
+scripts/zone/hellfire_citadel/shattered_halls/boss_nethekurse.cpp \
+scripts/zone/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp \
+scripts/zone/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp \
+scripts/zone/hellfire_citadel/shattered_halls/def_shattered_halls.h \
+scripts/zone/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp \
+scripts/zone/hellfire_peninsula/boss_doomlord_kazzak.cpp \
+scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp \
+scripts/zone/ironforge/ironforge.cpp \
+scripts/zone/isle_of_queldanas/isle_of_queldanas.cpp \
+scripts/zone/karazhan/boss_curator.cpp \
+scripts/zone/karazhan/boss_maiden_of_virtue.cpp \
+scripts/zone/karazhan/boss_midnight.cpp \
+scripts/zone/karazhan/boss_moroes.cpp \
+scripts/zone/karazhan/boss_netherspite.cpp \
+scripts/zone/karazhan/boss_nightbane.cpp \
+scripts/zone/karazhan/boss_prince_malchezaar.cpp \
+scripts/zone/karazhan/boss_shade_of_aran.cpp \
+scripts/zone/karazhan/boss_terestian_illhoof.cpp \
+scripts/zone/karazhan/bosses_opera.cpp \
+scripts/zone/karazhan/def_karazhan.h \
+scripts/zone/karazhan/instance_karazhan.cpp \
+scripts/zone/karazhan/karazhan.cpp \
+scripts/zone/loch_modan/loch_modan.cpp \
+scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp \
+scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp \
+scripts/zone/magisters_terrace/boss_selin_fireheart.cpp \
+scripts/zone/magisters_terrace/boss_vexallus.cpp \
+scripts/zone/magisters_terrace/def_magisters_terrace.h \
+scripts/zone/magisters_terrace/instance_magisters_terrace.cpp \
+scripts/zone/maraudon/boss_celebras_the_cursed.cpp \
+scripts/zone/maraudon/boss_landslide.cpp \
+scripts/zone/maraudon/boss_noxxion.cpp \
+scripts/zone/maraudon/boss_princess_theradras.cpp \
+scripts/zone/molten_core/boss_baron_geddon.cpp \
+scripts/zone/molten_core/boss_garr.cpp \
+scripts/zone/molten_core/boss_gehennas.cpp \
+scripts/zone/molten_core/boss_golemagg.cpp \
+scripts/zone/molten_core/boss_lucifron.cpp \
+scripts/zone/molten_core/boss_magmadar.cpp \
+scripts/zone/molten_core/boss_majordomo_executus.cpp \
+scripts/zone/molten_core/boss_ragnaros.cpp \
+scripts/zone/molten_core/boss_shazzrah.cpp \
+scripts/zone/molten_core/boss_sulfuron_harbinger.cpp \
+scripts/zone/molten_core/def_molten_core.h \
+scripts/zone/molten_core/instance_molten_core.cpp \
+scripts/zone/molten_core/molten_core.cpp \
+scripts/zone/moonglade/moonglade.cpp \
+scripts/zone/mulgore/mulgore.cpp \
+scripts/zone/nagrand/nagrand.cpp \
+scripts/zone/naxxramas/boss_anubrekhan.cpp \
+scripts/zone/naxxramas/boss_faerlina.cpp \
+scripts/zone/naxxramas/boss_gluth.cpp \
+scripts/zone/naxxramas/boss_gothik.cpp \
+scripts/zone/naxxramas/boss_grobbulus.cpp \
+scripts/zone/naxxramas/boss_heigan.cpp \
+scripts/zone/naxxramas/boss_kelthuzad.cpp \
+scripts/zone/naxxramas/boss_four_horsemen.cpp \
+scripts/zone/naxxramas/boss_loatheb.cpp \
+scripts/zone/naxxramas/boss_maexxna.cpp \
+scripts/zone/naxxramas/boss_noth.cpp \
+scripts/zone/naxxramas/boss_patchwerk.cpp \
+scripts/zone/naxxramas/boss_razuvious.cpp \
+scripts/zone/naxxramas/boss_sapphiron.cpp \
+scripts/zone/naxxramas/boss_thaddius.cpp \
+scripts/zone/naxxramas/instance_naxxramas.cpp \
+scripts/zone/netherstorm/netherstorm.cpp \
+scripts/zone/onyxias_lair/boss_onyxia.cpp \
+scripts/zone/orgrimmar/orgrimmar.cpp \
+scripts/zone/razorfen_downs/boss_amnennar_the_coldbringer.cpp \
+scripts/zone/razorfen_downs/razorfen_downs.cpp \
+scripts/zone/razorfen_kraul/razorfen_kraul.cpp \
+scripts/zone/ruins_of_ahnqiraj/boss_ayamiss.cpp \
+scripts/zone/ruins_of_ahnqiraj/boss_buru.cpp \
+scripts/zone/ruins_of_ahnqiraj/boss_kurinnaxx.cpp \
+scripts/zone/ruins_of_ahnqiraj/boss_moam.cpp \
+scripts/zone/ruins_of_ahnqiraj/boss_ossirian.cpp \
+scripts/zone/ruins_of_ahnqiraj/boss_rajaxx.cpp \
+scripts/zone/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp \
+scripts/zone/scarlet_monastery/boss_arcanist_doan.cpp \
+scripts/zone/scarlet_monastery/boss_azshir_the_sleepless.cpp \
+scripts/zone/scarlet_monastery/boss_bloodmage_thalnos.cpp \
+scripts/zone/scarlet_monastery/boss_herod.cpp \
+scripts/zone/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp \
+scripts/zone/scarlet_monastery/boss_houndmaster_loksey.cpp \
+scripts/zone/scarlet_monastery/boss_interrogator_vishas.cpp \
+scripts/zone/scarlet_monastery/boss_scorn.cpp \
+scripts/zone/scarlet_monastery/boss_headless_horseman.cpp \
+scripts/zone/scarlet_monastery/boss_mograine_and_whitemane.cpp \
+scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp \
+scripts/zone/scarlet_monastery/def_scarlet_monastery.h \
+scripts/zone/scholomance/boss_darkmaster_gandling.cpp \
+scripts/zone/scholomance/boss_death_knight_darkreaver.cpp \
+scripts/zone/scholomance/boss_doctor_theolen_krastinov.cpp \
+scripts/zone/scholomance/boss_illucia_barov.cpp \
+scripts/zone/scholomance/boss_instructor_malicia.cpp \
+scripts/zone/scholomance/boss_jandice_barov.cpp \
+scripts/zone/scholomance/boss_kormok.cpp \
+scripts/zone/scholomance/boss_lord_alexei_barov.cpp \
+scripts/zone/scholomance/boss_lorekeeper_polkelt.cpp \
+scripts/zone/scholomance/boss_ras_frostwhisper.cpp \
+scripts/zone/scholomance/boss_the_ravenian.cpp \
+scripts/zone/scholomance/boss_vectus.cpp \
+scripts/zone/scholomance/def_scholomance.h \
+scripts/zone/scholomance/instance_scholomance.cpp \
+scripts/zone/searing_gorge/searing_gorge.cpp \
+scripts/zone/shadowfang_keep/def_shadowfang_keep.h \
+scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp \
+scripts/zone/shadowfang_keep/shadowfang_keep.cpp \
+scripts/zone/shadowmoon_valley/boss_doomwalker.cpp \
+scripts/zone/shadowmoon_valley/shadowmoon_valley.cpp \
+scripts/zone/shattrath/shattrath_city.cpp \
+scripts/zone/silithus/silithus.cpp \
+scripts/zone/silvermoon/silvermoon_city.cpp \
+scripts/zone/silverpine_forest/silverpine_forest.cpp \
+scripts/zone/stonetalon_mountains/stonetalon_mountains.cpp \
+scripts/zone/stormwind/stormwind_city.cpp \
+scripts/zone/stranglethorn_vale/stranglethorn_vale.cpp \
+scripts/zone/stratholme/boss_baron_rivendare.cpp \
+scripts/zone/stratholme/boss_baroness_anastari.cpp \
+scripts/zone/stratholme/boss_cannon_master_willey.cpp \
+scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp \
+scripts/zone/stratholme/boss_magistrate_barthilas.cpp \
+scripts/zone/stratholme/boss_maleki_the_pallid.cpp \
+scripts/zone/stratholme/boss_nerubenkan.cpp \
+scripts/zone/stratholme/boss_order_of_silver_hand.cpp \
+scripts/zone/stratholme/boss_postmaster_malown.cpp \
+scripts/zone/stratholme/boss_ramstein_the_gorger.cpp \
+scripts/zone/stratholme/boss_timmy_the_cruel.cpp \
+scripts/zone/stratholme/def_stratholme.h \
+scripts/zone/stratholme/instance_stratholme.cpp \
+scripts/zone/stratholme/stratholme.cpp \
+scripts/zone/sunwell_plateau/boss_eredar_twins.cpp \
+scripts/zone/sunwell_plateau/boss_felmyst.cpp \
+scripts/zone/sunwell_plateau/boss_brutallus.cpp \
+scripts/zone/sunwell_plateau/boss_kalecgos.cpp \
+scripts/zone/sunwell_plateau/def_sunwell_plateau.h \
+scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp \
+scripts/zone/tanaris/tanaris.cpp \
+scripts/zone/tempest_keep/arcatraz/arcatraz.cpp \
+scripts/zone/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp \
+scripts/zone/tempest_keep/arcatraz/def_arcatraz.h \
+scripts/zone/tempest_keep/arcatraz/instance_arcatraz.cpp \
+scripts/zone/tempest_keep/botanica/boss_high_botanist_freywinn.cpp \
+scripts/zone/tempest_keep/botanica/boss_laj.cpp \
+scripts/zone/tempest_keep/botanica/boss_warp_splinter.cpp \
+scripts/zone/tempest_keep/the_eye/boss_alar.cpp \
+scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp \
+scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp \
+scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp \
+scripts/zone/tempest_keep/the_eye/def_the_eye.h \
+scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp \
+scripts/zone/tempest_keep/the_eye/the_eye.cpp \
+scripts/zone/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp \
+scripts/zone/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp \
+scripts/zone/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp \
+scripts/zone/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp \
+scripts/zone/tempest_keep/the_mechanar/def_mechanar.h \
+scripts/zone/tempest_keep/the_mechanar/instance_mechanar.cpp \
+scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp \
+scripts/zone/temple_of_ahnqiraj/boss_cthun.cpp \
+scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp \
+scripts/zone/temple_of_ahnqiraj/boss_huhuran.cpp \
+scripts/zone/temple_of_ahnqiraj/boss_ouro.cpp \
+scripts/zone/temple_of_ahnqiraj/boss_sartura.cpp \
+scripts/zone/temple_of_ahnqiraj/boss_skeram.cpp \
+scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp \
+scripts/zone/temple_of_ahnqiraj/boss_viscidus.cpp \
+scripts/zone/temple_of_ahnqiraj/def_temple_of_ahnqiraj.h \
+scripts/zone/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp \
+scripts/zone/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp \
+scripts/zone/terokkar_forest/terokkar_forest.cpp \
+scripts/zone/thunder_bluff/thunder_bluff.cpp \
+scripts/zone/tirisfal_glades/tirisfal_glades.cpp \
+scripts/zone/thousand_needles/thousand_needles.cpp \
+scripts/zone/uldaman/boss_archaedas.cpp \
+scripts/zone/uldaman/instance_uldaman.cpp \
+scripts/zone/uldaman/boss_ironaya.cpp \
+scripts/zone/uldaman/uldaman.cpp \
+scripts/zone/undercity/undercity.cpp \
+scripts/zone/ungoro_crater/ungoro_crater.cpp \
+scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp \
+scripts/zone/utgarde_keep/utgarde_keep/boss_keleseth.cpp \
+scripts/zone/utgarde_keep/utgarde_keep/boss_skarvald_dalronn.cpp \
+scripts/zone/utgarde_keep/utgarde_keep/boss_ingvar_the_plunderer.cpp \
+scripts/zone/wailing_caverns/instance_wailing_caverns.cpp \
+scripts/zone/western_plaguelands/western_plaguelands.cpp \
+scripts/zone/westfall/westfall.cpp \
+scripts/zone/winterspring/winterspring.cpp \
+scripts/zone/zangarmarsh/zangarmarsh.cpp \
+scripts/zone/zulaman/boss_akilzon.cpp \
+scripts/zone/zulaman/boss_halazzi.cpp \
+scripts/zone/zulaman/boss_hexlord.cpp \
+scripts/zone/zulaman/boss_janalai.cpp \
+scripts/zone/zulaman/boss_nalorakk.cpp \
+scripts/zone/zulaman/boss_zuljin.cpp \
+scripts/zone/zulaman/def_zulaman.h \
+scripts/zone/zulaman/instance_zulaman.cpp \
+scripts/zone/zulaman/zulaman.cpp \
+scripts/zone/zulfarrak/zulfarrak.cpp \
+scripts/zone/zulgurub/boss_arlokk.cpp \
+scripts/zone/zulgurub/boss_gahzranka.cpp \
+scripts/zone/zulgurub/boss_grilek.cpp \
+scripts/zone/zulgurub/boss_hakkar.cpp \
+scripts/zone/zulgurub/boss_hazzarah.cpp \
+scripts/zone/zulgurub/boss_jeklik.cpp \
+scripts/zone/zulgurub/boss_jindo.cpp \
+scripts/zone/zulgurub/boss_mandokir.cpp \
+scripts/zone/zulgurub/boss_marli.cpp \
+scripts/zone/zulgurub/boss_renataki.cpp \
+scripts/zone/zulgurub/boss_thekal.cpp \
+scripts/zone/zulgurub/boss_venoxis.cpp \
+scripts/zone/zulgurub/boss_wushoolay.cpp \
+scripts/zone/zulgurub/def_zulgurub.h \
+scripts/zone/zulgurub/instance_zulgurub.cpp \
+system.cpp
+
+## libtool settings
+# API versioning
+# Increase the last number, if you do bug fixes only, no interface change.
+# Increase the middle number when you augmented the interface ( aka add new exported functions ).
+# Increase the first number when you break old interface. ( aka remove/change previously exported functions ).
+libtrinityscript_la_LIBFLAGS = -version-info 0:0:1
+libtrinityscript_la_LIBADD = $(MYSQL_LIBS) $(POSTGRE_LIBS)
+
+## Additional files to install
+## sysconf_DATA =
+
+## EXTRA_DIST =
+
+## Prevend overwrite of the config file, if its already installed
+install-data-hook:
+ @list='$(sysconf_DATA)'; for p in $$list; do \
+ dest=`echo $$p | sed -e s/.dist//`; \
+ if test -f $(DESTDIR)$(sysconfdir)/$$dest; then \
+ echo "$@ will not overwrite existing $(DESTDIR)$(sysconfdir)/$$dest"; \
+ else \
+ echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(sysconfdir)/$$dest"; \
+ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(sysconfdir)/$$dest; \
+ fi; \
+ done
+
+
+
diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp
index 6b19bba23a9..bf80865f0bc 100644
--- a/src/bindings/scripts/ScriptMgr.cpp
+++ b/src/bindings/scripts/ScriptMgr.cpp
@@ -5,10 +5,9 @@
#include "precompiled.h"
#include "Config/Config.h"
#include "Database/DatabaseEnv.h"
-#include "Database/DBCStores.h"
+#include "DBCStores.h"
#include "ObjectMgr.h"
#include "ProgressBar.h"
-#include "scripts/creature/mob_event_ai.h"
#define _FULLVERSION "TrinityScript"
@@ -16,7 +15,6 @@
# define _TRINITY_SCRIPT_CONFIG "trinitycore.conf"
#endif _TRINITY_SCRIPT_CONFIG
-//*** Global data ***
int num_sc_scripts;
Script *m_scripts[MAX_SCRIPTS];
@@ -32,36 +30,13 @@ struct StringTextData
uint32 Emote;
};
-// Enums used by StringTextData::Type
-enum ChatType
-{
- CHAT_TYPE_SAY = 0,
- CHAT_TYPE_YELL = 1,
- CHAT_TYPE_TEXT_EMOTE = 2,
- CHAT_TYPE_BOSS_EMOTE = 3,
- CHAT_TYPE_WHISPER = 4,
- CHAT_TYPE_BOSS_WHISPER = 5,
-};
-
#define TEXT_SOURCE_RANGE -1000000 //the amount of entries each text source has available
// Text Maps
UNORDERED_MAP<int32, StringTextData> TextMap;
-//*** End Global data ***
-
-//*** EventAI data ***
-//Event AI structure. Used exclusivly by mob_event_ai.cpp (60 bytes each)
-UNORDERED_MAP<uint32, std::vector<EventAI_Event> > EventAI_Event_Map;
-
-//Event AI summon structure. Used exclusivly by mob_event_ai.cpp.
-UNORDERED_MAP<uint32, EventAI_Summon> EventAI_Summon_Map;
-
-//Event AI error prevention structure. Used at runtime to prevent error log spam of same creature id.
-//UNORDERED_MAP<uint32, EventAI_CreatureError> EventAI_CreatureErrorPreventionList;
-
-uint32 EAI_ErrorLevel;
-//*** End EventAI data ***
+// Waypoint map (escorts)
+UNORDERED_MAP<uint32, std::vector<PointMovement> > PointMovementMap;
void FillSpellSummary();
void LoadOverridenSQLData();
@@ -78,13 +53,15 @@ extern void AddSC_boss_taerar();
extern void AddSC_boss_ysondre();
// -- Creature --
-extern void AddSC_mob_event();
extern void AddSC_generic_creature();
// -- Custom --
-extern void AddSC_custom_example();
-extern void AddSC_custom_gossip_codebox();
-extern void AddSC_test();
+
+// -- Examples --
+extern void AddSC_example_creature();
+extern void AddSC_example_escort();
+extern void AddSC_example_gossip_codebox();
+extern void AddSC_example_misc();
// -- GO --
extern void AddSC_go_scripts();
@@ -96,7 +73,6 @@ extern void AddSC_guards();
// -- Item --
extern void AddSC_item_scripts();
-extern void AddSC_item_test();
// -- NPC --
extern void AddSC_npc_professions();
@@ -137,6 +113,11 @@ extern void AddSC_boss_grandmaster_vorpil();
extern void AddSC_boss_murmur();
extern void AddSC_instance_shadow_labyrinth();
+//Azjol-Nerub
+//--Ahn'kahet
+extern void AddSC_instance_ahnkahet();
+extern void AddSC_boss_elder_nadox();
+
//Azshara
extern void AddSC_boss_azuregos();
extern void AddSC_azshara();
@@ -211,6 +192,9 @@ extern void AddSC_blasted_lands();
//Bloodmyst Isle
extern void AddSC_bloodmyst_isle();
+//Borean Tundra
+extern void AddSC_borean_tundra();
+
//Burning steppes
extern void AddSC_burning_steppes();
@@ -394,15 +378,15 @@ extern void AddSC_nagrand();
extern void AddSC_boss_anubrekhan();
extern void AddSC_boss_maexxna();
extern void AddSC_boss_patchwerk();
+extern void AddSC_boss_grobbulus();
extern void AddSC_boss_razuvious();
-extern void AddSC_boss_highlord_mograine();
extern void AddSC_boss_kelthuzad();
-extern void AddSC_boss_faerlina();
extern void AddSC_boss_loatheb();
extern void AddSC_boss_noth();
extern void AddSC_boss_gluth();
extern void AddSC_boss_sapphiron();
extern void AddSC_boss_four_horsemen();
+extern void AddSC_boss_faerlina();
//Netherstorm
extern void AddSC_netherstorm();
@@ -416,6 +400,7 @@ extern void AddSC_orgrimmar();
//Ragefire Chasm
//Razorfen Downs
extern void AddSC_boss_amnennar_the_coldbringer();
+extern void AddSC_razorfen_downs();
//Razorfen Kraul
extern void AddSC_razorfen_kraul();
@@ -574,6 +559,13 @@ extern void AddSC_undercity();
extern void AddSC_ungoro_crater();
//Upper blackrock spire
+
+//Utgarde Keep
+extern void AddSC_boss_keleseth();
+extern void AddSC_boss_skarvald_dalronn();
+extern void AddSC_boss_ingvar_the_plunderer();
+extern void AddSC_instance_utgarde_keep();
+
//Wailing caverns
//Western plaguelands
@@ -622,17 +614,17 @@ extern void AddSC_zulaman();
void LoadDatabase()
{
//Get db string from file
- char const* dbstring = NULL;
+ std::string dbstring = TScriptConfig.GetStringDefault("WorldDatabaseInfo", "");
- if (!TScriptConfig.GetString("WorldDatabaseInfo", &dbstring) )
+ if (dbstring.empty() )
{
error_log("TSCR: Missing world database info from configuration file. Load database aborted.");
return;
}
//Initialize connection to DB
- if (dbstring && TScriptDB.Initialize(dbstring) )
- outstring_log("TSCR: TrinityScript database: %s",dbstring);
+ if (!dbstring.empty() && TScriptDB.Initialize(dbstring.c_str()) )
+ outstring_log("TSCR: TrinityScript database: %s",dbstring.c_str());
else
{
error_log("TSCR: Unable to connect to Database. Load database aborted.");
@@ -663,11 +655,10 @@ void LoadDatabase()
// Load EventAI Text
outstring_log("TSCR: Loading EventAI Texts...");
- LoadTrinityStrings(TScriptDB,"eventai_texts",-1,1+(TEXT_SOURCE_RANGE));
+ LoadTrinityStrings(TScriptDB,"creature_ai_texts",-1,1+(TEXT_SOURCE_RANGE));
// Gather Additional data from EventAI Texts
- //result = TScriptDB.PQuery("SELECT entry, sound, type, language, emote FROM eventai_texts");
- result = TScriptDB.PQuery("SELECT entry, sound, type, language FROM eventai_texts");
+ result = TScriptDB.PQuery("SELECT entry, sound, type, language, emote FROM creature_ai_texts");
outstring_log("TSCR: Loading EventAI Texts additional data...");
if (result)
@@ -685,31 +676,31 @@ void LoadDatabase()
temp.SoundId = fields[1].GetInt32();
temp.Type = fields[2].GetInt32();
temp.Language = fields[3].GetInt32();
- temp.Emote = 0;//fields[4].GetInt32();
+ temp.Emote = fields[4].GetInt32();
if (i >= 0)
{
- error_db_log("TSCR: Entry %i in table `eventai_texts` is not a negative value.",i);
+ error_db_log("TSCR: Entry %i in table `creature_ai_texts` is not a negative value.",i);
continue;
}
if (i <= TEXT_SOURCE_RANGE)
{
- error_db_log("TSCR: Entry %i in table `eventai_texts` is out of accepted entry range for table.",i);
+ error_db_log("TSCR: Entry %i in table `creature_ai_texts` is out of accepted entry range for table.",i);
continue;
}
if (temp.SoundId)
{
if (!GetSoundEntriesStore()->LookupEntry(temp.SoundId))
- error_db_log("TSCR: Entry %i in table `eventai_texts` has soundId %u but sound does not exist.",i,temp.SoundId);
+ error_db_log("TSCR: Entry %i in table `creature_ai_texts` has soundId %u but sound does not exist.",i,temp.SoundId);
}
if (!GetLanguageDescByID(temp.Language))
- error_db_log("TSCR: Entry %i in table `eventai_texts` using Language %u but Language does not exist.",i,temp.Language);
+ error_db_log("TSCR: Entry %i in table `creature_ai_texts` using Language %u but Language does not exist.",i,temp.Language);
- if (temp.Type > CHAT_TYPE_BOSS_WHISPER)
- error_db_log("TSCR: Entry %i in table `eventai_texts` has Type %u but this Chat Type does not exist.",i,temp.Type);
+ if (temp.Type > CHAT_TYPE_ZONE_YELL)
+ error_db_log("TSCR: Entry %i in table `creature_ai_texts` has Type %u but this Chat Type does not exist.",i,temp.Type);
TextMap[i] = temp;
++count;
@@ -724,7 +715,7 @@ void LoadDatabase()
barGoLink bar(1);
bar.step();
outstring_log("");
- outstring_log(">> Loaded 0 additional EventAI Texts data. DB table `eventai_texts` is empty.");
+ outstring_log(">> Loaded 0 additional EventAI Texts data. DB table `creature_ai_texts` is empty.");
}
// Load Script Text
@@ -773,7 +764,7 @@ void LoadDatabase()
if (!GetLanguageDescByID(temp.Language))
error_db_log("TSCR: Entry %i in table `script_texts` using Language %u but Language does not exist.",i,temp.Language);
- if (temp.Type > CHAT_TYPE_BOSS_WHISPER)
+ if (temp.Type > CHAT_TYPE_ZONE_YELL)
error_db_log("TSCR: Entry %i in table `script_texts` has Type %u but this Chat Type does not exist.",i,temp.Type);
TextMap[i] = temp;
@@ -838,7 +829,7 @@ void LoadDatabase()
if (!GetLanguageDescByID(temp.Language))
error_db_log("TSCR: Entry %i in table `custom_texts` using Language %u but Language does not exist.",i,temp.Language);
- if (temp.Type > CHAT_TYPE_BOSS_WHISPER)
+ if (temp.Type > CHAT_TYPE_ZONE_YELL)
error_db_log("TSCR: Entry %i in table `custom_texts` has Type %u but this Chat Type does not exist.",i,temp.Type);
TextMap[i] = temp;
@@ -857,455 +848,66 @@ void LoadDatabase()
outstring_log(">> Loaded 0 additional Custom Texts data. DB table `custom_texts` is empty.");
}
- //Gather additional data for EventAI
- result = TScriptDB.PQuery("SELECT id, position_x, position_y, position_z, orientation, spawntimesecs FROM eventai_summons");
+ // Drop Existing Waypoint list
+ PointMovementMap.clear();
+ uint64 uiCreatureCount = 0;
- //Drop Existing EventSummon Map
- EventAI_Summon_Map.clear();
-
- outstring_log("TSCR: Loading EventAI Summons...");
+ // Load Waypoints
+ result = TScriptDB.PQuery("SELECT COUNT(entry) FROM script_waypoint GROUP BY entry");
if (result)
{
- barGoLink bar(result->GetRowCount());
- uint32 Count = 0;
-
- do
- {
- bar.step();
- Field *fields = result->Fetch();
-
- EventAI_Summon temp;
-
- uint32 i = fields[0].GetUInt32();
- temp.position_x = fields[1].GetFloat();
- temp.position_y = fields[2].GetFloat();
- temp.position_z = fields[3].GetFloat();
- temp.orientation = fields[4].GetFloat();
- temp.SpawnTimeSecs = fields[5].GetUInt32();
-
- //Add to map
- EventAI_Summon_Map[i] = temp;
- ++Count;
- }while (result->NextRow());
-
+ uiCreatureCount = result->GetRowCount();
delete result;
-
- outstring_log("");
- outstring_log(">> Loaded %u EventAI summon definitions", Count);
- }else
- {
- barGoLink bar(1);
- bar.step();
- outstring_log("");
- outstring_log(">> Loaded 0 EventAI Summon definitions. DB table `eventai_summons` is empty.");
}
- //Gather event data
- result = TScriptDB.PQuery("SELECT id, creature_id, event_type, event_inverse_phase_mask, event_chance, event_flags, "
- "event_param1, event_param2, event_param3, event_param4, "
- "action1_type, action1_param1, action1_param2, action1_param3, "
- "action2_type, action2_param1, action2_param2, action2_param3, "
- "action3_type, action3_param1, action3_param2, action3_param3 "
- "FROM eventai_scripts");
+ outstring_log("TSCR: Loading Script Waypoints for %u creature(s)...", uiCreatureCount);
- //Drop Existing EventAI List
- EventAI_Event_Map.clear();
+ result = TScriptDB.PQuery("SELECT entry, pointid, location_x, location_y, location_z, waittime FROM script_waypoint ORDER BY pointid");
- outstring_log("TSCR: Loading EventAI scripts...");
if (result)
{
barGoLink bar(result->GetRowCount());
- uint32 Count = 0;
+ uint32 uiNodeCount = 0;
do
{
bar.step();
- Field *fields = result->Fetch();
-
- EventAI_Event temp;
-
- temp.event_id = fields[0].GetUInt32();
- uint32 i = temp.event_id;
- temp.creature_id = fields[1].GetUInt32();
- uint32 creature_id = temp.creature_id;
- temp.event_type = fields[2].GetUInt16();
- temp.event_inverse_phase_mask = fields[3].GetUInt32();
- temp.event_chance = fields[4].GetUInt8();
- temp.event_flags = fields[5].GetUInt8();
- temp.event_param1 = fields[6].GetUInt32();
- temp.event_param2 = fields[7].GetUInt32();
- temp.event_param3 = fields[8].GetUInt32();
- temp.event_param4 = fields[9].GetUInt32();
-
- //Creature does not exist in database
- if (!GetCreatureTemplateStore(temp.creature_id))
- error_db_log("TSCR: Event %u has script for non-existing creature.", i);
-
- //Report any errors in event
- if (temp.event_type >= EVENT_T_END)
- error_db_log("TSCR: Event %u has incorrect event type. Maybe DB requires updated version of SD2.", i);
-
- //No chance of this event occuring
- if (temp.event_chance == 0)
- error_db_log("TSCR: Event %u has 0 percent chance. Event will never trigger!", i);
-
- //Chance above 100, force it to be 100
- if (temp.event_chance > 100)
- {
- error_db_log("TSCR: Creature %u are using event %u with more than 100 percent chance. Adjusting to 100 percent.", temp.creature_id, i);
- temp.event_chance = 100;
- }
-
- //Individual event checks
- switch (temp.event_type)
- {
- case EVENT_T_HP:
- case EVENT_T_MANA:
- case EVENT_T_TARGET_HP:
- {
- if (temp.event_param2 > 100)
- error_db_log("TSCR: Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i);
-
- if (temp.event_param1 <= temp.event_param2)
- error_db_log("TSCR: Creature %u are using percentage event(%u) with param1 <= param2 (MaxPercent <= MinPercent). Event will never trigger! ", temp.creature_id, i);
-
- if (temp.event_flags & EFLAG_REPEATABLE && !temp.event_param3 && !temp.event_param4)
- {
- error_db_log("TSCR: Creature %u has param3 and param4=0 (RepeatMin/RepeatMax) but cannot be repeatable without timers. Removing EFLAG_REPEATABLE for event %u.", temp.creature_id, i);
- temp.event_flags &= ~EFLAG_REPEATABLE;
- }
- }
- break;
-
- case EVENT_T_SPELLHIT:
- {
- if (temp.event_param1)
- {
- SpellEntry const* pSpell = GetSpellStore()->LookupEntry(temp.event_param1);
- if (!pSpell)
- {
- error_db_log("TSCR: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.event_param1, i);
- continue;
- }
-
- if (temp.event_param2_s != -1 && temp.event_param2 != pSpell->SchoolMask)
- error_db_log("TSCR: Creature %u has param1(spellId %u) but param2 is not -1 and not equal to spell's school mask. Event %u can never trigger.", temp.creature_id, temp.event_param1, i);
- }
-
- //TODO: fix this system with SPELL_SCHOOL_MASK. Current complicate things, using int32(-1) instead of just 0
- //SPELL_SCHOOL_MASK_NONE = 0 and does not exist, thus it can not ever trigger or be used in SpellHit()
- if (temp.event_param2_s != -1 && temp.event_param2_s > SPELL_SCHOOL_MASK_ALL)
- error_db_log("TSCR: Creature %u is using invalid SpellSchoolMask(%u) defined in event %u.", temp.creature_id, temp.event_param2, i);
-
- if (temp.event_param4 < temp.event_param3)
- error_db_log("TSCR: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
- }
- break;
-
- case EVENT_T_RANGE:
- case EVENT_T_OOC_LOS:
- case EVENT_T_FRIENDLY_HP:
- case EVENT_T_FRIENDLY_IS_CC:
- case EVENT_T_FRIENDLY_MISSING_BUFF:
- {
- if (temp.event_param4 < temp.event_param3)
- error_db_log("TSCR: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
- }
- break;
-
- case EVENT_T_TIMER:
- case EVENT_T_TIMER_OOC:
- {
- if (temp.event_param2 < temp.event_param1)
- error_db_log("TSCR: Creature %u are using timed event(%u) with param2 < param1 (InitialMax < InitialMin). Event will never repeat.", temp.creature_id, i);
-
- if (temp.event_param4 < temp.event_param3)
- error_db_log("TSCR: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
- }
- break;
-
- case EVENT_T_KILL:
- case EVENT_T_TARGET_CASTING:
- {
- if (temp.event_param2 < temp.event_param1)
- error_db_log("TSCR: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
- }
- break;
-
- case EVENT_T_AGGRO:
- case EVENT_T_DEATH:
- case EVENT_T_EVADE:
- case EVENT_T_SPAWNED:
- case EVENT_T_REACHED_HOME:
- {
- if (temp.event_flags & EFLAG_REPEATABLE)
- {
- error_db_log("TSCR: Creature %u has EFLAG_REPEATABLE set. Event can never be repeatable. Removing flag for event %u.", temp.creature_id, i);
- temp.event_flags &= ~EFLAG_REPEATABLE;
- }
- }
- break;
- }
-
- for (uint32 j = 0; j < MAX_ACTIONS; j++)
+ Field* pFields = result->Fetch();
+ PointMovement pTemp;
+
+ pTemp.m_uiCreatureEntry = pFields[0].GetUInt32();
+ uint32 uiCreatureEntry = pTemp.m_uiCreatureEntry;
+ pTemp.m_uiPointId = pFields[1].GetUInt32();
+ pTemp.m_fX = pFields[2].GetFloat();
+ pTemp.m_fY = pFields[3].GetFloat();
+ pTemp.m_fZ = pFields[4].GetFloat();
+ pTemp.m_uiWaitTime = pFields[5].GetUInt32();
+
+ CreatureInfo const* pCInfo = GetCreatureTemplateStore(pTemp.m_uiCreatureEntry);
+ if (!pCInfo)
{
- temp.action[j].type = fields[10+(j*4)].GetUInt16();
- temp.action[j].param1 = fields[11+(j*4)].GetUInt32();
- temp.action[j].param2 = fields[12+(j*4)].GetUInt32();
- temp.action[j].param3 = fields[13+(j*4)].GetUInt32();
-
- //Report any errors in actions
- switch (temp.action[j].type)
- {
- case ACTION_T_TEXT:
- {
- if (temp.action[j].param1_s < 0)
- {
- if (TextMap.find(temp.action[j].param1_s) == TextMap.end())
- error_db_log("TSCR: Event %u Action %u param1 refrences non-existing entry in texts table.", i, j+1);
- }
- if (temp.action[j].param2_s < 0)
- {
- if (TextMap.find(temp.action[j].param2_s) == TextMap.end())
- error_db_log("TSCR: Event %u Action %u param2 refrences non-existing entry in texts table.", i, j+1);
-
- if (!temp.action[j].param1_s)
- error_db_log("TSCR: Event %u Action %u has param2, but param1 is not set. Required for randomized text.", i, j+1);
- }
- if (temp.action[j].param3_s < 0)
- {
- if (TextMap.find(temp.action[j].param3_s) == TextMap.end())
- error_db_log("TSCR: Event %u Action %u param3 refrences non-existing entry in texts table.", i, j+1);
-
- if (!temp.action[j].param1_s || !temp.action[j].param2_s)
- error_db_log("TSCR: Event %u Action %u has param3, but param1 and/or param2 is not set. Required for randomized text.", i, j+1);
- }
- }
- break;
- case ACTION_T_SET_FACTION:
- /*if (temp.action[j].param1 !=0 && !GetFactionStore()->LookupEntry(temp.action[j].param1))
- {
- error_db_log("TSCR: Event %u Action %u uses non-existant FactionId %u.", i, j+1, temp.action[j].param1);
- temp.action[j].param1 = 0;
- }*/
- break;
- case ACTION_T_MORPH_TO_ENTRY_OR_MODEL:
- if (temp.action[j].param1 !=0 || temp.action[j].param2 !=0)
- {
- if (temp.action[j].param1 && !GetCreatureTemplateStore(temp.action[j].param1))
- {
- error_db_log("TSCR: Event %u Action %u uses non-existant Creature entry %u.", i, j+1, temp.action[j].param1);
- temp.action[j].param1 = 0;
- }
-
- /*if (temp.action[j].param2 && !GetCreatureDisplayStore()->LookupEntry(temp.action[j].param2))
- {
- error_db_log("TSCR: Event %u Action %u uses non-existant ModelId %u.", i, j+1, temp.action[j].param2);
- temp.action[j].param2 = 0;
- }*/
- }
- break;
- case ACTION_T_SOUND:
- if (!GetSoundEntriesStore()->LookupEntry(temp.action[j].param1))
- error_db_log("TSCR: Event %u Action %u uses non-existant SoundID %u.", i, j+1, temp.action[j].param1);
- break;
-
- /*case ACTION_T_RANDOM_SOUND:
- {
- if(!GetSoundEntriesStore()->LookupEntry(temp.action[j].param1))
- error_db_log("TSCR: Event %u Action %u param1 uses non-existant SoundID %u.", i, j+1, temp.action[j].param1);
- if(!GetSoundEntriesStore()->LookupEntry(temp.action[j].param2))
- error_db_log("TSCR: Event %u Action %u param2 uses non-existant SoundID %u.", i, j+1, temp.action[j].param2);
- if(!GetSoundEntriesStore()->LookupEntry(temp.action[j].param3))
- error_db_log("TSCR: Event %u Action %u param3 uses non-existant SoundID %u.", i, j+1, temp.action[j].param3);
- }
- break;*/
-
- case ACTION_T_CAST:
- {
- const SpellEntry *spell = GetSpellStore()->LookupEntry(temp.action[j].param1);
- if (!spell)
- error_db_log("TSCR: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param1);
- else
- {
- if (spell->RecoveryTime > 0 && temp.event_flags & EFLAG_REPEATABLE)
- {
- //output as debug for now, also because there's no general rule all spells have RecoveryTime
- if (temp.event_param3 < spell->RecoveryTime)
- debug_log("TSCR: Event %u Action %u uses SpellID %u but cooldown is longer(%u) than minumum defined in event param3(%u).", i, j+1,temp.action[j].param1, spell->RecoveryTime, temp.event_param3);
- }
- }
-
- if (temp.action[j].param2 >= TARGET_T_END)
- error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
- }
- break;
-
- case ACTION_T_REMOVEAURASFROMSPELL:
- {
- if (!GetSpellStore()->LookupEntry(temp.action[j].param2))
- error_db_log("TSCR: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2);
-
- if (temp.action[j].param1 >= TARGET_T_END)
- error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
- }
- break;
- case ACTION_T_QUEST_EVENT:
- {
- if (Quest const* qid = GetQuestTemplateStore(temp.action[j].param1))
- {
- if (!qid->HasFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT))
- error_db_log("TSCR: Event %u Action %u. SpecialFlags for quest entry %u does not include |2, Action will not have any effect.", i, j+1, temp.action[j].param1);
- }
- else
- error_db_log("TSCR: Event %u Action %u uses non-existant Quest entry %u.", i, j+1, temp.action[j].param1);
-
- if (temp.action[j].param2 >= TARGET_T_END)
- error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
- }
- break;
- case ACTION_T_QUEST_EVENT_ALL:
- {
- if (Quest const* qid = GetQuestTemplateStore(temp.action[j].param1))
- {
- if (!qid->HasFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT))
- error_db_log("TSCR: Event %u Action %u. SpecialFlags for quest entry %u does not include |2, Action will not have any effect.", i, j+1, temp.action[j].param1);
- }
- else
- error_db_log("TSCR: Event %u Action %u uses non-existant Quest entry %u.", i, j+1, temp.action[j].param1);
- }
- break;
- case ACTION_T_CASTCREATUREGO:
- {
- if (!GetCreatureTemplateStore(temp.action[j].param1))
- error_db_log("TSCR: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
-
- if (!GetSpellStore()->LookupEntry(temp.action[j].param2))
- error_db_log("TSCR: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2);
-
- if (temp.action[j].param3 >= TARGET_T_END)
- error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
- }
- break;
- case ACTION_T_CASTCREATUREGO_ALL:
- {
- if (!GetQuestTemplateStore(temp.action[j].param1))
- error_db_log("TSCR: Event %u Action %u uses non-existant Quest entry %u.", i, j+1, temp.action[j].param1);
-
- if (!GetSpellStore()->LookupEntry(temp.action[j].param2))
- error_db_log("TSCR: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2);
- }
- break;
-
- //2nd param target
- case ACTION_T_SUMMON_ID:
- {
- if (!GetCreatureTemplateStore(temp.action[j].param1))
- error_db_log("TSCR: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
-
- if (EventAI_Summon_Map.find(temp.action[j].param3) == EventAI_Summon_Map.end())
- error_db_log("TSCR: Event %u Action %u summons missing EventAI_Summon %u", i, j+1, temp.action[j].param3);
-
- if (temp.action[j].param2 >= TARGET_T_END)
- error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
- }
- break;
- case ACTION_T_KILLED_MONSTER:
- {
- if (!GetCreatureTemplateStore(temp.action[j].param1))
- error_db_log("TSCR: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
-
- if (temp.action[j].param2 >= TARGET_T_END)
- error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
- }
- break;
- case ACTION_T_SUMMON:
- {
- if (!GetCreatureTemplateStore(temp.action[j].param1))
- error_db_log("TSCR: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
-
- if (temp.action[j].param2 >= TARGET_T_END)
- error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
- }
- break;
- case ACTION_T_THREAT_SINGLE_PCT:
- case ACTION_T_SET_UNIT_FLAG:
- case ACTION_T_REMOVE_UNIT_FLAG:
- if (temp.action[j].param2 >= TARGET_T_END)
- error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
- break;
-
- //3rd param target
- case ACTION_T_SET_UNIT_FIELD:
- if (temp.action[j].param1 < OBJECT_END || temp.action[j].param1 >= UNIT_END)
- error_db_log("TSCR: Event %u Action %u param1 (UNIT_FIELD*). Index out of range for intended use.", i, j+1);
- if (temp.action[j].param3 >= TARGET_T_END)
- error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
- break;
-
- case ACTION_T_SET_PHASE:
- if (temp.action[j].param1 > 31)
- error_db_log("TSCR: Event %u Action %u attempts to set phase > 31. Phase mask cannot be used past phase 31.", i, j+1);
- break;
-
- case ACTION_T_INC_PHASE:
- if (!temp.action[j].param1)
- error_db_log("TSCR: Event %u Action %u is incrementing phase by 0. Was this intended?", i, j+1);
- break;
-
- case ACTION_T_SET_INST_DATA:
- {
- if (!(temp.event_flags & EFLAG_NORMAL) && !(temp.event_flags & EFLAG_HEROIC))
- error_db_log("TSCR: Event %u Action %u. Cannot set instance data without event flags (normal/heroic).", i, j+1);
-
- if (temp.action[j].param2 > SPECIAL)
- error_db_log("TSCR: Event %u Action %u attempts to set instance data above encounter state 4. Custom case?", i, j+1);
- }
- break;
- case ACTION_T_SET_INST_DATA64:
- {
- if (!(temp.event_flags & EFLAG_NORMAL) && !(temp.event_flags & EFLAG_HEROIC))
- error_db_log("TSCR: Event %u Action %u. Cannot set instance data without event flags (normal/heroic).", i, j+1);
-
- if (temp.action[j].param2 >= TARGET_T_END)
- error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
- }
- break;
- case ACTION_T_UPDATE_TEMPLATE:
- {
- if (!GetCreatureTemplateStore(temp.action[j].param1))
- error_db_log("TSCR: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
- }
- break;
- case ACTION_T_RANDOM_SAY:
- case ACTION_T_RANDOM_YELL:
- case ACTION_T_RANDOM_TEXTEMOTE:
- error_db_log("TSCR: Event %u Action %u currently unused ACTION type. Did you forget to update database?", i, j+1);
- break;
-
- default:
- if (temp.action[j].type >= ACTION_T_END)
- error_db_log("TSCR: Event %u Action %u has incorrect action type. Maybe DB requires updated version of SD2.", i, j+1);
- break;
- }
+ error_db_log("TSCR: DB table script_waypoint has waypoint for non-existant creature entry %u", pTemp.m_uiCreatureEntry);
+ continue;
}
- //Add to list
- EventAI_Event_Map[creature_id].push_back(temp);
+ if (!pCInfo->ScriptID)
+ error_db_log("TSCR: DB table script_waypoint has waypoint for creature entry %u, but creature does not have ScriptName defined and then useless.", pTemp.m_uiCreatureEntry);
- ++Count;
+ PointMovementMap[uiCreatureEntry].push_back(pTemp);
+ ++uiNodeCount;
} while (result->NextRow());
delete result;
outstring_log("");
- outstring_log(">> Loaded %u EventAI scripts", Count);
- }else
+ outstring_log(">> Loaded %u Script Waypoint nodes.", uiNodeCount);
+ }
+ else
{
barGoLink bar(1);
bar.step();
outstring_log("");
- outstring_log(">> Loaded 0 EventAI scripts. DB table `eventai_scripts` is empty.");
+ outstring_log(">> Loaded 0 Script Waypoints. DB table `script_waypoint` is empty.");
}
//Free database thread and resources
@@ -1325,7 +927,7 @@ void ScriptsFree()
delete []SpellSummary;
// Free resources before library unload
- for(int i=0;i<num_sc_scripts;i++)
+ for(int i=0;i<MAX_SCRIPTS;i++)
delete m_scripts[i];
num_sc_scripts = 0;
@@ -1354,25 +956,6 @@ void ScriptsInit(char const* cfg_file = "trinitycore.conf")
}
else outstring_log("TSCR: Using configuration file %s",cfg_file);
- EAI_ErrorLevel = TScriptConfig.GetIntDefault("EAIErrorLevel", 1);
-
- switch (EAI_ErrorLevel)
- {
- case 0:
- outstring_log("TSCR: EventAI Error Reporting level set to 0 (Startup Errors only)");
- break;
- case 1:
- outstring_log("TSCR: EventAI Error Reporting level set to 1 (Startup errors and Runtime event errors)");
- break;
- case 2:
- outstring_log("TSCR: EventAI Error Reporting level set to 2 (Startup errors, Runtime event errors, and Creation errors)");
- break;
- default:
- outstring_log("TSCR: Unknown EventAI Error Reporting level. Defaulting to 1 (Startup errors and Runtime event errors)");
- EAI_ErrorLevel = 1;
- break;
- }
-
outstring_log("");
//Load database (must be called after TScriptConfig.SetSource). In case it failed, no need to even try load.
@@ -1400,13 +983,15 @@ void ScriptsInit(char const* cfg_file = "trinitycore.conf")
AddSC_boss_ysondre();
// -- Creature --
- AddSC_mob_event();
AddSC_generic_creature();
// -- Custom --
- AddSC_custom_example();
- AddSC_custom_gossip_codebox();
- AddSC_test();
+
+ // -- Examples --
+ AddSC_example_creature();
+ AddSC_example_escort();
+ AddSC_example_gossip_codebox();
+ AddSC_example_misc();
// -- GO --
AddSC_go_scripts();
@@ -1418,7 +1003,6 @@ void ScriptsInit(char const* cfg_file = "trinitycore.conf")
// -- Item --
AddSC_item_scripts();
- AddSC_item_test();
// -- NPC --
AddSC_npc_professions();
@@ -1459,6 +1043,11 @@ void ScriptsInit(char const* cfg_file = "trinitycore.conf")
AddSC_boss_murmur();
AddSC_instance_shadow_labyrinth();
+ //Azjol-Nerub
+ //--Ahn'kahet
+ AddSC_instance_ahnkahet();
+ AddSC_boss_elder_nadox();
+
//Azshara
AddSC_boss_azuregos();
AddSC_azshara();
@@ -1532,6 +1121,9 @@ void ScriptsInit(char const* cfg_file = "trinitycore.conf")
//Bloodmyst Isle
AddSC_bloodmyst_isle();
+
+ //Borean Tundra
+ AddSC_borean_tundra();
//Burning steppes
AddSC_burning_steppes();
@@ -1713,12 +1305,12 @@ void ScriptsInit(char const* cfg_file = "trinitycore.conf")
//Naxxramas
AddSC_boss_anubrekhan();
+ AddSC_boss_faerlina();
AddSC_boss_maexxna();
AddSC_boss_patchwerk();
+ AddSC_boss_grobbulus();
AddSC_boss_razuvious();
- AddSC_boss_highlord_mograine();
AddSC_boss_kelthuzad();
- AddSC_boss_faerlina();
AddSC_boss_loatheb();
AddSC_boss_noth();
AddSC_boss_gluth();
@@ -1737,6 +1329,7 @@ void ScriptsInit(char const* cfg_file = "trinitycore.conf")
//Ragefire Chasm
//Razorfen Downs
AddSC_boss_amnennar_the_coldbringer();
+ AddSC_razorfen_downs();
//Razorfen Kraul
AddSC_razorfen_kraul();
@@ -1895,6 +1488,13 @@ void ScriptsInit(char const* cfg_file = "trinitycore.conf")
AddSC_ungoro_crater();
//Upper blackrock spire
+
+ //Utgarde Keep
+ AddSC_boss_keleseth();
+ AddSC_boss_skarvald_dalronn();
+ AddSC_boss_ingvar_the_plunderer();
+ AddSC_instance_utgarde_keep();
+
//Wailing caverns
//Western plaguelands
@@ -2022,6 +1622,9 @@ void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target)
pSource->MonsterWhisper(textEntry, target->GetGUID(), true);
else error_log("TSCR: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", textEntry);
}break;
+ case CHAT_TYPE_ZONE_YELL:
+ pSource->MonsterYellToZone(textEntry, (*i).second.Language, target ? target->GetGUID() : 0);
+ break;
}
}
@@ -2037,7 +1640,10 @@ void Script::RegisterSelf()
++num_sc_scripts;
}
else
+ {
error_db_log("CRASH ALERT! TrinityScript: RegisterSelf, but script named %s does not have ScriptName assigned in database.",(this)->Name.c_str());
+ delete this;
+ }
}
//********************************
@@ -2248,12 +1854,34 @@ bool ItemUse( Player *player, Item* _Item, SpellCastTargets const& targets)
}
TRINITY_DLL_EXPORT
-bool ReceiveEmote( Player *player, Creature *_Creature, uint32 emote )
+bool EffectDummyCreature(Unit *caster, uint32 spellId, uint32 effIndex, Creature *crTarget )
{
- Script *tmpscript = m_scripts[_Creature->GetScriptId()];
- if (!tmpscript || !tmpscript->pReceiveEmote) return false;
+ Script *tmpscript = m_scripts[crTarget->GetScriptId()];
+
+ if (!tmpscript || !tmpscript->pEffectDummyCreature) return false;
+
+ return tmpscript->pEffectDummyCreature(caster, spellId,effIndex,crTarget);
+}
+
+TRINITY_DLL_EXPORT
+bool EffectDummyGameObj(Unit *caster, uint32 spellId, uint32 effIndex, GameObject *gameObjTarget )
+{
+ Script *tmpscript = m_scripts[gameObjTarget->GetGOInfo()->ScriptId];
+
+ if (!tmpscript || !tmpscript->pEffectDummyGameObj) return false;
+
+ return tmpscript->pEffectDummyGameObj(caster, spellId,effIndex,gameObjTarget);
+}
+
+
+TRINITY_DLL_EXPORT
+bool EffectDummyItem(Unit *caster, uint32 spellId, uint32 effIndex, Item *itemTarget )
+{
+ Script *tmpscript = m_scripts[itemTarget->GetProto()->ScriptId];
+
+ if (!tmpscript || !tmpscript->pEffectDummyItem) return false;
- return tmpscript->pReceiveEmote(player, _Creature, emote);
+ return tmpscript->pEffectDummyItem(caster, spellId,effIndex,itemTarget);
}
TRINITY_DLL_EXPORT
diff --git a/src/bindings/scripts/ScriptMgr.h b/src/bindings/scripts/ScriptMgr.h
index 87a557779a2..719cf7932e9 100644
--- a/src/bindings/scripts/ScriptMgr.h
+++ b/src/bindings/scripts/ScriptMgr.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+/* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* Thanks to the original authors: ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
@@ -10,7 +10,7 @@
#include "Common.h"
#include "Platform/CompilerDefs.h"
-#include "Database/DBCStructure.h"
+#include "DBCStructure.h"
class Player;
class Creature;
@@ -32,9 +32,11 @@ 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)
+ pQuestSelect(NULL), pQuestComplete(NULL), pNPCDialogStatus(NULL), pGODialogStatus(NULL),
+ pChooseReward(NULL), pItemHello(NULL), pGOHello(NULL), pAreaTrigger(NULL), pItemQuestAccept(NULL),
+ pGOQuestAccept(NULL), pGOChooseReward(NULL),pItemUse(NULL),
+ pEffectDummyCreature(NULL), pEffectDummyGameObj(NULL), pEffectDummyItem(NULL),
+ GetAI(NULL), GetInstanceData(NULL)
{}
std::string Name;
@@ -57,8 +59,10 @@ struct Script
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& );
+ bool (*pEffectDummyCreature )(Unit*, uint32, uint32, Creature* );
+ bool (*pEffectDummyGameObj )(Unit*, uint32, uint32, GameObject* );
+ bool (*pEffectDummyItem )(Unit*, uint32, uint32, Item* );
CreatureAI* (*GetAI)(Creature*);
InstanceData* (*GetInstanceData)(Map*);
diff --git a/src/bindings/scripts/VC71/71ScriptDev2.vcproj b/src/bindings/scripts/VC71/71ScriptDev2.vcproj
index e92d43e61c2..f241121295a 100644
--- a/src/bindings/scripts/VC71/71ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC71/71ScriptDev2.vcproj
@@ -43,7 +43,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\dep\include\;..\..\..\shared\;..\..\..\framework\;..\..\..\game\;..\include\;..\..\..\..\dep\ACE_wrappers"
- PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_WINDOWS;_USRDLL;SCRIPT"
+ PreprocessorDefinitions="WIN32;_DEBUG;TRINITY_DEBUG;_WINDOWS;_USRDLL;SCRIPT"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@@ -51,7 +51,7 @@
PrecompiledHeaderThrough="precompiled.h"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
+ DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@@ -69,7 +69,7 @@
LinkIncremental="2"
AdditionalLibraryDirectories="..\..\..\..\win\VC71\zthread__$(PlatformName)_$(ConfigurationName);..\..\..\..\win\VC71\trinitycore__$(PlatformName)_$(ConfigurationName)"
GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/MaNGOSScript.pdb"
+ ProgramDatabaseFile="$(OutDir)/TrinityScript.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
@@ -231,6 +231,26 @@
</File>
</Filter>
<Filter
+ Name="examples"
+ >
+ <File
+ RelativePath="..\scripts\examples\example_creature.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\examples\example_escort.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\examples\example_gossip_codebox.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\examples\example_misc.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
Name="guard"
>
<File
@@ -281,18 +301,6 @@
<Filter
Name="custom"
>
- <File
- RelativePath="..\scripts\custom\custom_example.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\custom\custom_gossip_codebox.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\custom\test.cpp"
- >
- </File>
</Filter>
<Filter
Name="areatrigger"
@@ -317,10 +325,6 @@
RelativePath="..\scripts\item\item_scripts.cpp"
>
</File>
- <File
- RelativePath="..\scripts\item\item_test.cpp"
- >
- </File>
</Filter>
<Filter
Name="zone"
@@ -578,6 +582,190 @@
>
</Filter>
<Filter
+ Name="Borean Tundra"
+ >
+ <File
+ RelativePath="..\scripts\zone\borean_tundra\borean_tundra.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Howling Fjord"
+ >
+ </Filter>
+ <Filter
+ Name="Crystalsong Forest"
+ >
+ </Filter>
+ <Filter
+ Name="Dalaran"
+ >
+ </Filter>
+ <Filter
+ Name="Dragonblight"
+ >
+ </Filter>
+ <Filter
+ Name="Grizzly Hills"
+ >
+ </Filter>
+ <Filter
+ Name="Icecrown"
+ >
+ </Filter>
+ <Filter
+ Name="Sholazar Basin"
+ >
+ </Filter>
+ <Filter
+ Name="The Storm Peaks"
+ >
+ </Filter>
+ <Filter
+ Name="Zul&apos;Drak"
+ >
+ </Filter>
+ <Filter
+ Name="Azjol-Nerub"
+ >
+ <Filter
+ Name="Ahn&apos;kahet"
+ >
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\boss_amanitar.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\boss_elder_nadox.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\boss_herald_volazj.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\boss_jedoga_shadowseeker.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\boss_prince_taldaram.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\def_ahnkahet.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\instance_ahnkahet.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Azjol-Nerub"
+ >
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\azjol_nerub\boss_anubarak.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\azjol_nerub\boss_hadronox.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\azjol_nerub\boss_krikthir_the_gatewatcher.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\azjol_nerub\def_azjol_nerub.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\azjol_nerub\instance_azjol_nerub.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Drak&apos;Tharon Keep"
+ >
+ </Filter>
+ <Filter
+ Name="Gundrak"
+ >
+ </Filter>
+ <Filter
+ Name="Nexus"
+ >
+ <Filter
+ Name="Nexus"
+ >
+ </Filter>
+ <Filter
+ Name="Oculus"
+ >
+ </Filter>
+ <Filter
+ Name="Eye of Eternity"
+ >
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Violet Hold"
+ >
+ </Filter>
+ <Filter
+ Name="Ulduar"
+ >
+ <Filter
+ Name="Halls of Stone"
+ >
+ </Filter>
+ <Filter
+ Name="Halls of Lightning"
+ >
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Utgarde Keep"
+ >
+ <Filter
+ Name="Utgarde Keep"
+ >
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\boss_ingvar_the_plunderer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\boss_keleseth.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\boss_skarvald_dalronn.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\def_utgarde_keep.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\instance_utgarde_keep.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Utgarde Pinnacle"
+ >
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Obsidian Sanctum"
+ >
+ </Filter>
+ <Filter
+ Name="Vault of Archavon"
+ >
+ </Filter>
+ <Filter
Name="Scarlet Monastery"
>
<File
@@ -849,10 +1037,6 @@
>
</File>
<File
- RelativePath="..\scripts\zone\naxxramas\boss_highlord_mograine.cpp"
- >
- </File>
- <File
RelativePath="..\scripts\zone\naxxramas\boss_kelthuzad.cpp"
>
</File>
@@ -908,6 +1092,10 @@
RelativePath="..\scripts\zone\razorfen_downs\boss_amnennar_the_coldbringer.cpp"
>
</File>
+ <File
+ RelativePath="..\scripts\zone\razorfen_downs\razorfen_downs.cpp"
+ >
+ </File>
</Filter>
<Filter
Name="Shadowfang Keep"
@@ -1073,9 +1261,9 @@
Name="Thousand Needles"
>
<File
- RelativePath="..\scripts\zone\thousand_needles\thousand_needles.cpp"
- >
- </File>
+ RelativePath="..\scripts\zone\thousand_needles\thousand_needles.cpp"
+ >
+ </File>
</Filter>
<Filter
Name="Silithus"
@@ -1237,9 +1425,9 @@
Name="Un&apos;Goro Crater"
>
<File
- RelativePath="..\scripts\zone\ungoro_crater\ungoro_crater.cpp"
- >
- </File>
+ RelativePath="..\scripts\zone\ungoro_crater\ungoro_crater.cpp"
+ >
+ </File>
</Filter>
<Filter
Name="Aunchindoun"
@@ -1464,11 +1652,11 @@
>
</File>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\hellfire_ramparts\boss_watchkeeper_gargolmar.cpp"
+ RelativePath="..\scripts\zone\hellfire_citadel\hellfire_ramparts\boss_vazruden_the_herald.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\hellfire_ramparts\boss_vazruden_the_herald.cpp"
+ RelativePath="..\scripts\zone\hellfire_citadel\hellfire_ramparts\boss_watchkeeper_gargolmar.cpp"
>
</File>
</Filter>
@@ -1934,6 +2122,10 @@
</Filter>
<Filter
+ Name="Culling of Stratholme"
+ >
+ </Filter>
+ <Filter
Name="Old Hillsbrad"
>
<File
@@ -2142,21 +2334,13 @@
>
</File>
<File
- RelativePath="..\scripts\zone\blackrock_depths\def_blackrock_depths.h"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_depths\instance_blackrock_depths.cpp"
- >
- </File>
- <File
RelativePath="..\scripts\zone\blackrock_depths\boss_ambassador_flamelash.cpp"
>
- </File>
+ </File>
<File
RelativePath="..\scripts\zone\blackrock_depths\boss_anubshiah.cpp"
>
- </File>
+ </File>
<File
RelativePath="..\scripts\zone\blackrock_depths\boss_emperor_dagran_thaurissan.cpp"
>
@@ -2164,7 +2348,7 @@
<File
RelativePath="..\scripts\zone\blackrock_depths\boss_general_angerforge.cpp"
>
- </File>
+ </File>
<File
RelativePath="..\scripts\zone\blackrock_depths\boss_gorosh_the_dervish.cpp"
>
@@ -2172,7 +2356,7 @@
<File
RelativePath="..\scripts\zone\blackrock_depths\boss_grizzle.cpp"
>
- </File>
+ </File>
<File
RelativePath="..\scripts\zone\blackrock_depths\boss_high_interrogator_gerstahn.cpp"
>
@@ -2184,11 +2368,19 @@
<File
RelativePath="..\scripts\zone\blackrock_depths\boss_moira_bronzebeard.cpp"
>
- </File>
+ </File>
<File
RelativePath="..\scripts\zone\blackrock_depths\boss_tomb_of_seven.cpp"
>
</File>
+ <File
+ RelativePath="..\scripts\zone\blackrock_depths\def_blackrock_depths.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackrock_depths\instance_blackrock_depths.cpp"
+ >
+ </File>
</Filter>
<Filter
Name="Loch Modan"
@@ -2249,10 +2441,6 @@
</File>
</Filter>
<File
- RelativePath="..\config.h"
- >
- </File>
- <File
RelativePath="..\ScriptMgr.cpp"
>
</File>
@@ -2261,10 +2449,6 @@
>
</File>
<File
- RelativePath="..\svn_revision.h"
- >
- </File>
- <File
RelativePath="..\system.cpp"
>
</File>
diff --git a/src/bindings/scripts/VC80/80ScriptDev2.vcproj b/src/bindings/scripts/VC80/80ScriptDev2.vcproj
index fcec093ee91..b10552f9f57 100644
--- a/src/bindings/scripts/VC80/80ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC80/80ScriptDev2.vcproj
@@ -47,15 +47,15 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\dep\include\;..\..\..\shared\;..\..\..\framework\;..\..\..\game\;..\include\;..\..\..\..\dep\ACE_wrappers"
- PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_WINDOWS;_USRDLL;SCRIPT"
+ PreprocessorDefinitions="WIN32;_DEBUG;TRINITY_DEBUG;_WINDOWS;_USRDLL;SCRIPT"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="precompiled.h"
WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@@ -73,7 +73,7 @@
LinkIncremental="2"
AdditionalLibraryDirectories="..\..\..\..\win\VC80\zthread__$(PlatformName)_$(ConfigurationName);..\..\..\..\win\VC80\trinitycore__$(PlatformName)_$(ConfigurationName)"
GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/MaNGOSScript.pdb"
+ ProgramDatabaseFile="$(OutDir)/TrinityScript.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
@@ -215,7 +215,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\dep\include\;..\..\..\shared\;..\..\..\framework\;..\..\..\game\;..\include\;..\..\..\..\dep\ACE_wrappers"
- PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_WINDOWS;_USRDLL;SCRIPT"
+ PreprocessorDefinitions="WIN32;_DEBUG;TRINITY_DEBUG;_WINDOWS;_USRDLL;SCRIPT"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@@ -241,7 +241,7 @@
LinkIncremental="2"
AdditionalLibraryDirectories="..\..\..\..\win\VC80\zthread__$(PlatformName)_$(ConfigurationName);..\..\..\..\win\VC80\trinitycore__$(PlatformName)_$(ConfigurationName)"
GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/MaNGOSScript.pdb"
+ ProgramDatabaseFile="$(OutDir)/TrinityScript.pdb"
SubSystem="2"
ImportLibrary="$(OutDir)/TrinityScript.lib"
TargetMachine="17"
@@ -387,23 +387,35 @@
Name="creature"
>
<File
- RelativePath="..\scripts\creature\mob_event_ai.cpp"
+ RelativePath="..\scripts\creature\mob_generic_creature.cpp"
>
</File>
<File
- RelativePath="..\scripts\creature\mob_event_ai.h"
+ RelativePath="..\scripts\creature\simple_ai.cpp"
>
</File>
<File
- RelativePath="..\scripts\creature\mob_generic_creature.cpp"
+ RelativePath="..\scripts\creature\simple_ai.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="examples"
+ >
+ <File
+ RelativePath="..\scripts\examples\example_creature.cpp"
>
</File>
<File
- RelativePath="..\scripts\creature\simple_ai.cpp"
+ RelativePath="..\scripts\examples\example_escort.cpp"
>
</File>
<File
- RelativePath="..\scripts\creature\simple_ai.h"
+ RelativePath="..\scripts\examples\example_gossip_codebox.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\examples\example_misc.cpp"
>
</File>
</Filter>
@@ -458,18 +470,6 @@
<Filter
Name="custom"
>
- <File
- RelativePath="..\scripts\custom\custom_example.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\custom\custom_gossip_codebox.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\custom\test.cpp"
- >
- </File>
</Filter>
<Filter
Name="areatrigger"
@@ -494,10 +494,6 @@
RelativePath="..\scripts\item\item_scripts.cpp"
>
</File>
- <File
- RelativePath="..\scripts\item\item_test.cpp"
- >
- </File>
</Filter>
<Filter
Name="zone"
@@ -755,6 +751,190 @@
>
</Filter>
<Filter
+ Name="Borean Tundra"
+ >
+ <File
+ RelativePath="..\scripts\zone\borean_tundra\borean_tundra.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Howling Fjord"
+ >
+ </Filter>
+ <Filter
+ Name="Crystalsong Forest"
+ >
+ </Filter>
+ <Filter
+ Name="Dalaran"
+ >
+ </Filter>
+ <Filter
+ Name="Dragonblight"
+ >
+ </Filter>
+ <Filter
+ Name="Grizzly Hills"
+ >
+ </Filter>
+ <Filter
+ Name="Icecrown"
+ >
+ </Filter>
+ <Filter
+ Name="Sholazar Basin"
+ >
+ </Filter>
+ <Filter
+ Name="The Storm Peaks"
+ >
+ </Filter>
+ <Filter
+ Name="Zul&apos;Drak"
+ >
+ </Filter>
+ <Filter
+ Name="Azjol-Nerub"
+ >
+ <Filter
+ Name="Ahn&apos;kahet"
+ >
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\boss_amanitar.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\boss_elder_nadox.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\boss_herald_volazj.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\boss_jedoga_shadowseeker.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\boss_prince_taldaram.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\def_ahnkahet.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\instance_ahnkahet.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Azjol-Nerub"
+ >
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\azjol_nerub\boss_anubarak.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\azjol_nerub\boss_hadronox.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\azjol_nerub\boss_krikthir_the_gatewatcher.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\azjol_nerub\def_azjol_nerub.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\azjol_nerub\instance_azjol_nerub.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Drak&apos;Tharon Keep"
+ >
+ </Filter>
+ <Filter
+ Name="Gundrak"
+ >
+ </Filter>
+ <Filter
+ Name="Nexus"
+ >
+ <Filter
+ Name="Nexus"
+ >
+ </Filter>
+ <Filter
+ Name="Oculus"
+ >
+ </Filter>
+ <Filter
+ Name="Eye of Eternity"
+ >
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Violet Hold"
+ >
+ </Filter>
+ <Filter
+ Name="Ulduar"
+ >
+ <Filter
+ Name="Halls of Stone"
+ >
+ </Filter>
+ <Filter
+ Name="Halls of Lightning"
+ >
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Utgarde Keep"
+ >
+ <Filter
+ Name="Utgarde Keep"
+ >
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\boss_ingvar_the_plunderer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\boss_keleseth.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\boss_skarvald_dalronn.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\def_utgarde_keep.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\instance_utgarde_keep.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Utgarde Pinnacle"
+ >
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Obsidian Sanctum"
+ >
+ </Filter>
+ <Filter
+ Name="Vault of Archavon"
+ >
+ </Filter>
+ <Filter
Name="Scarlet Monastery"
>
<File
@@ -1026,10 +1206,6 @@
>
</File>
<File
- RelativePath="..\scripts\zone\naxxramas\boss_highlord_mograine.cpp"
- >
- </File>
- <File
RelativePath="..\scripts\zone\naxxramas\boss_kelthuzad.cpp"
>
</File>
@@ -1085,6 +1261,10 @@
RelativePath="..\scripts\zone\razorfen_downs\boss_amnennar_the_coldbringer.cpp"
>
</File>
+ <File
+ RelativePath="..\scripts\zone\razorfen_downs\razorfen_downs.cpp"
+ >
+ </File>
</Filter>
<Filter
Name="Shadowfang Keep"
@@ -1250,9 +1430,9 @@
Name="Thousand Needles"
>
<File
- RelativePath="..\scripts\zone\thousand_needles\thousand_needles.cpp"
- >
- </File>
+ RelativePath="..\scripts\zone\thousand_needles\thousand_needles.cpp"
+ >
+ </File>
</Filter>
<Filter
Name="Silithus"
@@ -1414,9 +1594,9 @@
Name="Un&apos;Goro Crater"
>
<File
- RelativePath="..\scripts\zone\ungoro_crater\ungoro_crater.cpp"
- >
- </File>
+ RelativePath="..\scripts\zone\ungoro_crater\ungoro_crater.cpp"
+ >
+ </File>
</Filter>
<Filter
Name="Aunchindoun"
@@ -1641,11 +1821,11 @@
>
</File>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\hellfire_ramparts\boss_watchkeeper_gargolmar.cpp"
+ RelativePath="..\scripts\zone\hellfire_citadel\hellfire_ramparts\boss_vazruden_the_herald.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\hellfire_ramparts\boss_vazruden_the_herald.cpp"
+ RelativePath="..\scripts\zone\hellfire_citadel\hellfire_ramparts\boss_watchkeeper_gargolmar.cpp"
>
</File>
</Filter>
@@ -2111,6 +2291,10 @@
</Filter>
<Filter
+ Name="Culling of Stratholme"
+ >
+ </Filter>
+ <Filter
Name="Old Hillsbrad"
>
<File
@@ -2319,21 +2503,13 @@
>
</File>
<File
- RelativePath="..\scripts\zone\blackrock_depths\def_blackrock_depths.h"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_depths\instance_blackrock_depths.cpp"
- >
- </File>
- <File
RelativePath="..\scripts\zone\blackrock_depths\boss_ambassador_flamelash.cpp"
>
- </File>
+ </File>
<File
RelativePath="..\scripts\zone\blackrock_depths\boss_anubshiah.cpp"
>
- </File>
+ </File>
<File
RelativePath="..\scripts\zone\blackrock_depths\boss_emperor_dagran_thaurissan.cpp"
>
@@ -2341,7 +2517,7 @@
<File
RelativePath="..\scripts\zone\blackrock_depths\boss_general_angerforge.cpp"
>
- </File>
+ </File>
<File
RelativePath="..\scripts\zone\blackrock_depths\boss_gorosh_the_dervish.cpp"
>
@@ -2349,7 +2525,7 @@
<File
RelativePath="..\scripts\zone\blackrock_depths\boss_grizzle.cpp"
>
- </File>
+ </File>
<File
RelativePath="..\scripts\zone\blackrock_depths\boss_high_interrogator_gerstahn.cpp"
>
@@ -2361,11 +2537,19 @@
<File
RelativePath="..\scripts\zone\blackrock_depths\boss_moira_bronzebeard.cpp"
>
- </File>
+ </File>
<File
RelativePath="..\scripts\zone\blackrock_depths\boss_tomb_of_seven.cpp"
>
</File>
+ <File
+ RelativePath="..\scripts\zone\blackrock_depths\def_blackrock_depths.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackrock_depths\instance_blackrock_depths.cpp"
+ >
+ </File>
</Filter>
<Filter
Name="Loch Modan"
@@ -2442,10 +2626,6 @@
</File>
</Filter>
<File
- RelativePath="..\config.h"
- >
- </File>
- <File
RelativePath="..\ScriptMgr.cpp"
>
</File>
@@ -2454,10 +2634,6 @@
>
</File>
<File
- RelativePath="..\svn_revision.h"
- >
- </File>
- <File
RelativePath="..\system.cpp"
>
</File>
diff --git a/src/bindings/scripts/VC90/90ScriptDev2.vcproj b/src/bindings/scripts/VC90/90ScriptDev2.vcproj
index 7cf04d191ed..12331bbf34f 100644
--- a/src/bindings/scripts/VC90/90ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC90/90ScriptDev2.vcproj
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="windows-1250"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="9,00"
+ Version="9.00"
Name="TrinityScript"
ProjectGUID="{4295C8A9-79B7-4354-8064-F05FB9CA0C96}"
RootNamespace="ScriptDev2"
@@ -47,7 +47,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\dep\include\;..\..\..\shared\;..\..\..\framework\;..\..\..\game\;..\include\;..\..\..\..\dep\ACE_wrappers"
- PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_WINDOWS;_USRDLL;SCRIPT"
+ PreprocessorDefinitions="WIN32;_DEBUG;TRINITY_DEBUG;_WINDOWS;_USRDLL;SCRIPT"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@@ -55,7 +55,7 @@
PrecompiledHeaderThrough="precompiled.h"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
- DebugInformationFormat="4"
+ DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@@ -73,7 +73,7 @@
LinkIncremental="2"
AdditionalLibraryDirectories="..\..\..\..\win\VC90\zthread__$(PlatformName)_$(ConfigurationName);..\..\..\..\win\VC90\trinitycore__$(PlatformName)_$(ConfigurationName)"
GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/MaNGOSScript.pdb"
+ ProgramDatabaseFile="$(OutDir)/TrinityScript.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
@@ -216,7 +216,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\dep\include\;..\..\..\shared\;..\..\..\framework\;..\..\..\game\;..\include\;..\..\..\..\dep\ACE_wrappers"
- PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_WINDOWS;_USRDLL;SCRIPT"
+ PreprocessorDefinitions="WIN32;_DEBUG;TRINITY_DEBUG;_WINDOWS;_USRDLL;SCRIPT"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@@ -242,7 +242,7 @@
LinkIncremental="2"
AdditionalLibraryDirectories="..\..\..\..\win\VC90\zthread__$(PlatformName)_$(ConfigurationName);..\..\..\..\win\VC90\trinitycore__$(PlatformName)_$(ConfigurationName)"
GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/MaNGOSScript.pdb"
+ ProgramDatabaseFile="$(OutDir)/TrinityScript.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
@@ -267,6 +267,9 @@
<Tool
Name="VCAppVerifierTool"
/>
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
</Configuration>
<Configuration
Name="Release|x64"
@@ -348,6 +351,9 @@
<Tool
Name="VCAppVerifierTool"
/>
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
</Configuration>
</Configurations>
<References>
@@ -380,23 +386,35 @@
Name="creature"
>
<File
- RelativePath="..\scripts\creature\mob_event_ai.cpp"
+ RelativePath="..\scripts\creature\mob_generic_creature.cpp"
>
</File>
<File
- RelativePath="..\scripts\creature\mob_event_ai.h"
+ RelativePath="..\scripts\creature\simple_ai.cpp"
>
</File>
<File
- RelativePath="..\scripts\creature\mob_generic_creature.cpp"
+ RelativePath="..\scripts\creature\simple_ai.h"
>
</File>
+ </Filter>
+ <Filter
+ Name="examples"
+ >
<File
- RelativePath="..\scripts\creature\simple_ai.cpp"
+ RelativePath="..\scripts\examples\example_creature.cpp"
>
</File>
<File
- RelativePath="..\scripts\creature\simple_ai.h"
+ RelativePath="..\scripts\examples\example_escort.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\examples\example_gossip_codebox.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\examples\example_misc.cpp"
>
</File>
</Filter>
@@ -452,15 +470,11 @@
Name="custom"
>
<File
- RelativePath="..\scripts\custom\custom_example.cpp"
+ RelativePath="..\scripts\custom\npc_acherus_taxi.cpp"
>
</File>
<File
- RelativePath="..\scripts\custom\custom_gossip_codebox.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\custom\test.cpp"
+ RelativePath="..\scripts\custom\npc_wyrmresttempel_taxi.cpp"
>
</File>
</Filter>
@@ -487,1886 +501,2369 @@
RelativePath="..\scripts\item\item_scripts.cpp"
>
</File>
- <File
- RelativePath="..\scripts\item\item_test.cpp"
- >
- </File>
</Filter>
<Filter
Name="zone"
>
<Filter
- Name="Alterac Mountains"
- >
- <File
- RelativePath="..\scripts\zone\alterac_mountains\alterac_mountains.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Ashenvale Forest"
- >
- <File
- RelativePath="..\scripts\zone\ashenvale_forest\ashenvale.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Azshara"
- >
- <File
- RelativePath="..\scripts\zone\azshara\azshara.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\azshara\boss_azuregos.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Badlands"
- >
- </Filter>
- <Filter
- Name="Barrens"
- >
- <File
- RelativePath="..\scripts\zone\barrens\the_barrens.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Blackfathom Depths"
- >
- </Filter>
- <Filter
- Name="Arathi Highlands"
- >
- <File
- RelativePath="..\scripts\zone\arathi_highlands\arathi_highlands.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Deadmines"
- >
- <File
- RelativePath="..\scripts\zone\deadmines\deadmines.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\deadmines\def_deadmines.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Deadwind Pass"
- >
- </Filter>
- <Filter
- Name="Desolace"
- >
- </Filter>
- <Filter
- Name="Dire Maul"
- >
- </Filter>
- <Filter
- Name="Dun Morogh"
- >
- <File
- RelativePath="..\scripts\zone\dun_morogh\dun_morogh.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Durotar"
- >
- </Filter>
- <Filter
- Name="Duskwood"
- >
- </Filter>
- <Filter
- Name="Dustwallow Marsh"
- >
- <File
- RelativePath="..\scripts\zone\dustwallow_marsh\dustwallow_marsh.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Blackwing Lair"
- >
- <File
- RelativePath="..\scripts\zone\blackwing_lair\boss_broodlord_lashlayer.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackwing_lair\boss_chromaggus.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackwing_lair\boss_ebonroc.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackwing_lair\boss_firemaw.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackwing_lair\boss_flamegor.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackwing_lair\boss_nefarian.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackwing_lair\boss_razorgore.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackwing_lair\boss_vaelastrasz.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackwing_lair\boss_victor_nefarius.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackwing_lair\instance_blackwing_lair.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Bloodmyst Isle"
- >
- <File
- RelativePath="..\scripts\zone\bloodmyst_isle\bloodmyst_isle.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Gruul&apos;s Lair"
- >
- <File
- RelativePath="..\scripts\zone\gruuls_lair\boss_gruul.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\gruuls_lair\boss_high_king_maulgar.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\gruuls_lair\def_gruuls_lair.h"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\gruuls_lair\instance_gruuls_lair.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Burning Steppes"
- >
- <File
- RelativePath="..\scripts\zone\burning_steppes\burning_steppes.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Darkshore"
+ Name="Kalimdor"
>
- <File
- RelativePath="..\scripts\zone\darkshore\darkshore.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Eastern Plaguelands"
- >
- <File
- RelativePath="..\scripts\zone\eastern_plaguelands\eastern_plaguelands.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Moonglade"
- >
- <File
- RelativePath="..\scripts\zone\moonglade\moonglade.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Razorfen Kraul"
- >
- <File
- RelativePath="..\scripts\zone\razorfen_kraul\razorfen_kraul.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Redridge Mountains"
- >
- </Filter>
- <Filter
- Name="Ruins of Ahn&apos;Qiraj"
- >
- <File
- RelativePath="..\scripts\zone\ruins_of_ahnqiraj\boss_ayamiss.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\ruins_of_ahnqiraj\boss_buru.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\ruins_of_ahnqiraj\boss_kurinnaxx.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\ruins_of_ahnqiraj\boss_moam.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\ruins_of_ahnqiraj\boss_ossirian.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\ruins_of_ahnqiraj\boss_rajaxx.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\ruins_of_ahnqiraj\instance_ruins_of_ahnqiraj.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Swamp of Sorrows"
- >
- </Filter>
- <Filter
- Name="Scarlet Monastery"
- >
- <File
- RelativePath="..\scripts\zone\scarlet_monastery\boss_arcanist_doan.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scarlet_monastery\boss_azshir_the_sleepless.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scarlet_monastery\boss_bloodmage_thalnos.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scarlet_monastery\boss_headless_horseman.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scarlet_monastery\boss_herod.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scarlet_monastery\boss_high_inquisitor_fairbanks.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scarlet_monastery\boss_houndmaster_loksey.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scarlet_monastery\boss_interrogator_vishas.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scarlet_monastery\boss_mograine_and_whitemane.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scarlet_monastery\boss_scorn.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scarlet_monastery\def_scarlet_monastery.h"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scarlet_monastery\instance_scarlet_monastery.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Scholomance"
- >
- <File
- RelativePath="..\scripts\zone\scholomance\boss_darkmaster_gandling.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scholomance\boss_death_knight_darkreaver.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scholomance\boss_doctor_theolen_krastinov.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scholomance\boss_illucia_barov.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scholomance\boss_instructor_malicia.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scholomance\boss_jandice_barov.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scholomance\boss_kormok.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scholomance\boss_lord_alexei_barov.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scholomance\boss_lorekeeper_polkelt.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scholomance\boss_ras_frostwhisper.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scholomance\boss_the_ravenian.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scholomance\boss_vectus.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scholomance\def_scholomance.h"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\scholomance\instance_scholomance.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Searing Gorge"
- >
- <File
- RelativePath="..\scripts\zone\searing_gorge\searing_gorge.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Elwynn Forest"
- >
- <File
- RelativePath="..\scripts\zone\elwynn_forest\elwynn_forest.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Felwood"
- >
- <File
- RelativePath="..\scripts\zone\felwood\felwood.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Feralas"
- >
- <File
- RelativePath="..\scripts\zone\feralas\feralas.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Gnomeregan"
- >
- </Filter>
- <Filter
- Name="Hillsbrad Foothills"
- >
- </Filter>
- <Filter
- Name="Hinterlands"
- >
- </Filter>
- <Filter
- Name="Maraudon"
- >
- <File
- RelativePath="..\scripts\zone\maraudon\boss_celebras_the_cursed.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\maraudon\boss_landslide.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\maraudon\boss_noxxion.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\maraudon\boss_princess_theradras.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Molten Core"
- >
- <File
- RelativePath="..\scripts\zone\molten_core\boss_baron_geddon.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\molten_core\boss_garr.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\molten_core\boss_gehennas.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\molten_core\boss_golemagg.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\molten_core\boss_lucifron.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\molten_core\boss_magmadar.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\molten_core\boss_majordomo_executus.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\molten_core\boss_ragnaros.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\molten_core\boss_shazzrah.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\molten_core\boss_sulfuron_harbinger.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\molten_core\def_molten_core.h"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\molten_core\instance_molten_core.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\molten_core\molten_core.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Mulgore"
- >
- <File
- RelativePath="..\scripts\zone\mulgore\mulgore.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Naxxramas"
- >
- <File
- RelativePath="..\scripts\zone\naxxramas\boss_anubrekhan.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\naxxramas\boss_faerlina.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\naxxramas\boss_four_horsemen.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\naxxramas\boss_gluth.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\naxxramas\boss_gothik.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\naxxramas\boss_grobbulus.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\naxxramas\boss_heigan.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\naxxramas\boss_highlord_mograine.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\naxxramas\boss_kelthuzad.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\naxxramas\boss_loatheb.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\naxxramas\boss_maexxna.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\naxxramas\boss_noth.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\naxxramas\boss_patchwerk.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\naxxramas\boss_razuvious.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\naxxramas\boss_sapphiron.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\naxxramas\boss_thaddius.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\naxxramas\instance_naxxramas.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Onyxia&apos;s Lair"
- >
- <File
- RelativePath="..\scripts\zone\onyxias_lair\boss_onyxia.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Ragefire Chasm"
- >
- </Filter>
- <Filter
- Name="Razorfen Downs"
- >
- <File
- RelativePath="..\scripts\zone\razorfen_downs\boss_amnennar_the_coldbringer.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Shadowfang Keep"
- >
- <File
- RelativePath="..\scripts\zone\shadowfang_keep\def_shadowfang_keep.h"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\shadowfang_keep\instance_shadowfang_keep.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\shadowfang_keep\shadowfang_keep.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Stonetalon Mountains"
- >
- <File
- RelativePath="..\scripts\zone\stonetalon_mountains\stonetalon_mountains.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Stranglethorn Vale"
- >
- <File
- RelativePath="..\scripts\zone\stranglethorn_vale\stranglethorn_vale.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Stratholme"
- >
- <File
- RelativePath="..\scripts\zone\stratholme\boss_baron_rivendare.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\stratholme\boss_baroness_anastari.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\stratholme\boss_cannon_master_willey.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\stratholme\boss_dathrohan_balnazzar.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\stratholme\boss_magistrate_barthilas.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\stratholme\boss_maleki_the_pallid.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\stratholme\boss_nerubenkan.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\stratholme\boss_order_of_silver_hand.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\stratholme\boss_postmaster_malown.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\stratholme\boss_ramstein_the_gorger.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\stratholme\boss_timmy_the_cruel.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\stratholme\def_stratholme.h"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\stratholme\instance_stratholme.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\stratholme\stratholme.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Sunken Temple"
- >
- </Filter>
- <Filter
- Name="Tanaris"
- >
- <File
- RelativePath="..\scripts\zone\tanaris\tanaris.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Teldrassil"
- >
- </Filter>
- <Filter
- Name="Temple of Ahn&apos;Qiraj"
- >
- <File
- RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_bug_trio.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_cthun.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_fankriss.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_huhuran.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_ouro.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_sartura.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_skeram.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_twinemperors.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_viscidus.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\temple_of_ahnqiraj\def_temple_of_ahnqiraj.h"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\temple_of_ahnqiraj\instance_temple_of_ahnqiraj.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\temple_of_ahnqiraj\mob_anubisath_sentinel.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Thousand Needles"
- >
- <File
- RelativePath="..\scripts\zone\thousand_needles\thousand_needles.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Silithus"
- >
- <File
- RelativePath="..\scripts\zone\silithus\silithus.cpp"
+ <Filter
+ Name="Ashenvale Forest"
>
- </File>
- </Filter>
- <Filter
- Name="Silverpine Forest"
- >
- <File
- RelativePath="..\scripts\zone\silverpine_forest\silverpine_forest.cpp"
+ <File
+ RelativePath="..\scripts\zone\ashenvale_forest\ashenvale.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Azshara"
>
- </File>
- </Filter>
- <Filter
- Name="Stockade"
- >
- </Filter>
- <Filter
- Name="Tirisfal Glades"
- >
- <File
- RelativePath="..\scripts\zone\tirisfal_glades\tirisfal_glades.cpp"
+ <File
+ RelativePath="..\scripts\zone\azshara\azshara.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azshara\boss_azuregos.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Azuremyst Isle"
>
- </File>
- </Filter>
- <Filter
- Name="Wailing Caverns"
- >
- <File
- RelativePath="..\scripts\zone\wailing_caverns\instance_wailing_caverns.cpp"
+ <File
+ RelativePath="..\scripts\zone\azuremyst_isle\azuremyst_isle.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Badlands"
>
- </File>
- </Filter>
- <Filter
- Name="Western Plaguelands"
- >
- <File
- RelativePath="..\scripts\zone\western_plaguelands\western_plaguelands.cpp"
+ </Filter>
+ <Filter
+ Name="Barrens"
>
- </File>
- </Filter>
- <Filter
- Name="Westfall"
- >
- <File
- RelativePath="..\scripts\zone\westfall\westfall.cpp"
+ <File
+ RelativePath="..\scripts\zone\barrens\the_barrens.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Blackfathom Depths"
>
- </File>
- </Filter>
- <Filter
- Name="Wetlands"
- >
- </Filter>
- <Filter
- Name="Winterspring"
- >
- <File
- RelativePath="..\scripts\zone\winterspring\winterspring.cpp"
+ </Filter>
+ <Filter
+ Name="Bloodmyst Isle"
>
- </File>
- </Filter>
- <Filter
- Name="Zul&apos;Farrak"
- >
- <File
- RelativePath="..\scripts\zone\zulfarrak\zulfarrak.cpp"
+ <File
+ RelativePath="..\scripts\zone\bloodmyst_isle\bloodmyst_isle.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Caverns of Time"
+ >
+ <Filter
+ Name="The Dark Portal"
+ >
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\dark_portal\boss_aeonus.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\dark_portal\boss_chrono_lord_deja.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\dark_portal\boss_temporus.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\dark_portal\dark_portal.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\dark_portal\def_dark_portal.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\dark_portal\instance_dark_portal.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Battle for Mt. Hyjal"
+ >
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\hyjal\boss_anetheron.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\hyjal\boss_archimonde.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\hyjal\boss_azgalor.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\hyjal\boss_kazrogal.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\hyjal\boss_rage_winterchill.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\hyjal\def_hyjal.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\hyjal\hyjal.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\hyjal\hyjal_trash.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\hyjal\hyjal_trash.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\hyjal\hyjalAI.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\hyjal\hyjalAI.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\hyjal\instance_hyjal.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Culling of Stratholme"
+ >
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\culling_of_stratholme\boss_epoch.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\culling_of_stratholme\boss_mal_ganis.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\culling_of_stratholme\boss_meathook.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\culling_of_stratholme\boss_salramm.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\culling_of_stratholme\def_culling_of_stratholme.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\culling_of_stratholme\instance_culling_of_stratholme.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Old Hillsbrad"
+ >
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\old_hillsbrad\boss_captain_skarloc.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\old_hillsbrad\boss_epoch_hunter.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\old_hillsbrad\boss_leutenant_drake.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\old_hillsbrad\def_old_hillsbrad.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\old_hillsbrad\instance_old_hillsbrad.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\caverns_of_time\old_hillsbrad\old_hillsbrad.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Darkshore"
>
- </File>
- </Filter>
- <Filter
- Name="Zul&apos;Gurub"
- >
- <File
- RelativePath="..\scripts\zone\zulgurub\boss_arlokk.cpp"
+ <File
+ RelativePath="..\scripts\zone\darkshore\darkshore.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Darnassus"
>
- </File>
- <File
- RelativePath="..\scripts\zone\zulgurub\boss_gahzranka.cpp"
+ </Filter>
+ <Filter
+ Name="Desolace"
>
- </File>
- <File
- RelativePath="..\scripts\zone\zulgurub\boss_grilek.cpp"
+ </Filter>
+ <Filter
+ Name="Dire Maul"
>
- </File>
- <File
- RelativePath="..\scripts\zone\zulgurub\boss_hakkar.cpp"
+ </Filter>
+ <Filter
+ Name="Durotar"
>
- </File>
- <File
- RelativePath="..\scripts\zone\zulgurub\boss_hazzarah.cpp"
+ </Filter>
+ <Filter
+ Name="Dustwallow Marsh"
>
- </File>
- <File
- RelativePath="..\scripts\zone\zulgurub\boss_jeklik.cpp"
+ <File
+ RelativePath="..\scripts\zone\dustwallow_marsh\dustwallow_marsh.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Exodar"
>
- </File>
- <File
- RelativePath="..\scripts\zone\zulgurub\boss_jindo.cpp"
+ </Filter>
+ <Filter
+ Name="Felwood"
>
- </File>
- <File
- RelativePath="..\scripts\zone\zulgurub\boss_mandokir.cpp"
+ <File
+ RelativePath="..\scripts\zone\felwood\felwood.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Feralas"
>
- </File>
- <File
- RelativePath="..\scripts\zone\zulgurub\boss_marli.cpp"
+ <File
+ RelativePath="..\scripts\zone\feralas\feralas.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Maraudon"
>
- </File>
- <File
- RelativePath="..\scripts\zone\zulgurub\boss_renataki.cpp"
+ <File
+ RelativePath="..\scripts\zone\maraudon\boss_celebras_the_cursed.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\maraudon\boss_landslide.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\maraudon\boss_noxxion.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\maraudon\boss_princess_theradras.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Moonglade"
>
- </File>
- <File
- RelativePath="..\scripts\zone\zulgurub\boss_thekal.cpp"
+ <File
+ RelativePath="..\scripts\zone\moonglade\moonglade.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Mulgore"
>
- </File>
- <File
- RelativePath="..\scripts\zone\zulgurub\boss_venoxis.cpp"
+ <File
+ RelativePath="..\scripts\zone\mulgore\mulgore.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Onyxia&apos;s Lair"
>
- </File>
- <File
- RelativePath="..\scripts\zone\zulgurub\boss_wushoolay.cpp"
+ <File
+ RelativePath="..\scripts\zone\onyxias_lair\boss_onyxia.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Orgrimmar"
>
- </File>
- <File
- RelativePath="..\scripts\zone\zulgurub\def_zulgurub.h"
+ <File
+ RelativePath="..\scripts\zone\orgrimmar\orgrimmar.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Ragefire Chasm"
>
- </File>
- <File
- RelativePath="..\scripts\zone\zulgurub\instance_zulgurub.cpp"
+ </Filter>
+ <Filter
+ Name="Razorfen Downs"
>
- </File>
- </Filter>
- <Filter
- Name="Uldaman"
- >
- <File
- RelativePath="..\scripts\zone\uldaman\boss_archaedas.cpp"
+ <File
+ RelativePath="..\scripts\zone\razorfen_downs\boss_amnennar_the_coldbringer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\razorfen_downs\razorfen_downs.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Razorfen Kraul"
>
- </File>
- <File
- RelativePath="..\scripts\zone\uldaman\boss_ironaya.cpp"
+ <File
+ RelativePath="..\scripts\zone\razorfen_kraul\razorfen_kraul.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Ruins of Ahn&apos;Qiraj"
>
- </File>
- <File
- RelativePath="..\scripts\zone\uldaman\instance_uldaman.cpp"
+ <File
+ RelativePath="..\scripts\zone\ruins_of_ahnqiraj\boss_ayamiss.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\ruins_of_ahnqiraj\boss_buru.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\ruins_of_ahnqiraj\boss_kurinnaxx.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\ruins_of_ahnqiraj\boss_moam.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\ruins_of_ahnqiraj\boss_ossirian.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\ruins_of_ahnqiraj\boss_rajaxx.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\ruins_of_ahnqiraj\instance_ruins_of_ahnqiraj.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Silithus"
>
- </File>
- <File
- RelativePath="..\scripts\zone\uldaman\uldaman.cpp"
+ <File
+ RelativePath="..\scripts\zone\silithus\silithus.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Zul&apos;Farrak"
>
- </File>
- </Filter>
- <Filter
- Name="Un&apos;Goro Crater"
- >
- <File
- RelativePath="..\scripts\zone\ungoro_crater\ungoro_crater.cpp"
+ <File
+ RelativePath="..\scripts\zone\zulfarrak\zulfarrak.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Winterspring"
>
- </File>
- </Filter>
- <Filter
- Name="Aunchindoun"
- >
+ <File
+ RelativePath="..\scripts\zone\winterspring\winterspring.cpp"
+ >
+ </File>
+ </Filter>
<Filter
- Name="Auchenai Crypts"
+ Name="Wailing Caverns"
>
<File
- RelativePath="..\scripts\zone\aunchindoun\auchenai_crypts\boss_exarch_maladaar.cpp"
+ RelativePath="..\scripts\zone\wailing_caverns\instance_wailing_caverns.cpp"
>
</File>
+ </Filter>
+ <Filter
+ Name="Un&apos;Goro Crater"
+ >
<File
- RelativePath="..\scripts\zone\aunchindoun\auchenai_crypts\boss_shirrak_the_dead_watcher.cpp"
+ RelativePath="..\scripts\zone\ungoro_crater\ungoro_crater.cpp"
>
</File>
</Filter>
<Filter
- Name="Mana Tombs"
+ Name="Thunder Bluff"
>
<File
- RelativePath="..\scripts\zone\aunchindoun\mana_tombs\boss_nexusprince_shaffar.cpp"
+ RelativePath="..\scripts\zone\thunder_bluff\thunder_bluff.cpp"
>
</File>
+ </Filter>
+ <Filter
+ Name="Thousand Needles"
+ >
<File
- RelativePath="..\scripts\zone\aunchindoun\mana_tombs\boss_pandemonius.cpp"
+ RelativePath="..\scripts\zone\thousand_needles\thousand_needles.cpp"
>
</File>
</Filter>
<Filter
- Name="Sethekk Halls"
+ Name="Temple of Ahn&apos;Qiraj"
>
<File
- RelativePath="..\scripts\zone\aunchindoun\sethekk_halls\boss_darkweaver_syth.cpp"
+ RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_bug_trio.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\aunchindoun\sethekk_halls\boss_tailonking_ikiss.cpp"
+ RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_cthun.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\aunchindoun\sethekk_halls\def_sethekk_halls.h"
+ RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_fankriss.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\aunchindoun\sethekk_halls\instance_sethekk_halls.cpp"
+ RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_huhuran.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_ouro.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_sartura.cpp"
>
</File>
- </Filter>
- <Filter
- Name="Shadow Labyrinth"
- >
<File
- RelativePath="..\scripts\zone\aunchindoun\shadow_labyrinth\boss_ambassador_hellmaw.cpp"
+ RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_skeram.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\aunchindoun\shadow_labyrinth\boss_blackheart_the_inciter.cpp"
+ RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_twinemperors.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\aunchindoun\shadow_labyrinth\boss_grandmaster_vorpil.cpp"
+ RelativePath="..\scripts\zone\temple_of_ahnqiraj\boss_viscidus.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\aunchindoun\shadow_labyrinth\boss_murmur.cpp"
+ RelativePath="..\scripts\zone\temple_of_ahnqiraj\def_temple_of_ahnqiraj.h"
>
</File>
<File
- RelativePath="..\scripts\zone\aunchindoun\shadow_labyrinth\def_shadow_labyrinth.h"
+ RelativePath="..\scripts\zone\temple_of_ahnqiraj\instance_temple_of_ahnqiraj.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\aunchindoun\shadow_labyrinth\instance_shadow_labyrinth.cpp"
+ RelativePath="..\scripts\zone\temple_of_ahnqiraj\mob_anubisath_sentinel.cpp"
>
</File>
</Filter>
- </Filter>
- <Filter
- Name="Azuremyst Isle"
- >
- <File
- RelativePath="..\scripts\zone\azuremyst_isle\azuremyst_isle.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Black Temple"
- >
- <File
- RelativePath="..\scripts\zone\black_temple\black_temple.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\black_temple\boss_bloodboil.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\black_temple\boss_illidan.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\black_temple\boss_mother_shahraz.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\black_temple\boss_reliquary_of_souls.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\black_temple\boss_shade_of_akama.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\black_temple\boss_supremus.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\black_temple\boss_teron_gorefiend.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\black_temple\boss_warlord_najentus.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\black_temple\def_black_temple.h"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\black_temple\illidari_council.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\black_temple\instance_black_temple.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Eversong Woods"
- >
- <File
- RelativePath="..\scripts\zone\eversong_woods\eversong_woods.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Ghostlands"
- >
- <File
- RelativePath="..\scripts\zone\ghostlands\ghostlands.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Blade&apos;s Edge Mountains"
- >
- <File
- RelativePath="..\scripts\zone\blades_edge_mountains\blades_edge_mountains.cpp"
+ <Filter
+ Name="Teldrassil"
>
- </File>
- </Filter>
- <Filter
- Name="Blasted Lands"
- >
- <File
- RelativePath="..\scripts\zone\blasted_lands\blasted_lands.cpp"
+ </Filter>
+ <Filter
+ Name="Tanaris"
>
- </File>
- <File
- RelativePath="..\scripts\zone\blasted_lands\boss_kruul.cpp"
+ <File
+ RelativePath="..\scripts\zone\tanaris\tanaris.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Stonetalon Mountains"
>
- </File>
+ <File
+ RelativePath="..\scripts\zone\stonetalon_mountains\stonetalon_mountains.cpp"
+ >
+ </File>
+ </Filter>
</Filter>
<Filter
- Name="Hellfire Citadel"
+ Name="Azeroth"
>
<Filter
- Name="Blood Furnace"
+ Name="Molten Core"
>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\blood_furnace\boss_broggok.cpp"
+ RelativePath="..\scripts\zone\molten_core\boss_baron_geddon.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\blood_furnace\boss_kelidan_the_breaker.cpp"
+ RelativePath="..\scripts\zone\molten_core\boss_garr.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\blood_furnace\boss_the_maker.cpp"
+ RelativePath="..\scripts\zone\molten_core\boss_gehennas.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\blood_furnace\def_blood_furnace.h"
+ RelativePath="..\scripts\zone\molten_core\boss_golemagg.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\blood_furnace\instance_blood_furnace.cpp"
+ RelativePath="..\scripts\zone\molten_core\boss_lucifron.cpp"
>
</File>
- </Filter>
- <Filter
- Name="Magtheridon&apos;s lair"
- >
<File
- RelativePath="..\scripts\zone\hellfire_citadel\magtheridons_lair\boss_magtheridon.cpp"
+ RelativePath="..\scripts\zone\molten_core\boss_magmadar.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\magtheridons_lair\def_magtheridons_lair.h"
+ RelativePath="..\scripts\zone\molten_core\boss_majordomo_executus.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\magtheridons_lair\instance_magtheridons_lair.cpp"
+ RelativePath="..\scripts\zone\molten_core\boss_ragnaros.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\molten_core\boss_shazzrah.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\molten_core\boss_sulfuron_harbinger.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\molten_core\def_molten_core.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\molten_core\instance_molten_core.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\molten_core\molten_core.cpp"
>
</File>
</Filter>
<Filter
- Name="Hellfire Ramparts"
+ Name="Magister&apos;s Terrace"
>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\hellfire_ramparts\boss_omor_the_unscarred.cpp"
+ RelativePath="..\scripts\zone\magisters_terrace\boss_felblood_kaelthas.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\magisters_terrace\boss_priestess_delrissa.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\hellfire_ramparts\boss_vazruden_the_herald.cpp"
+ RelativePath="..\scripts\zone\magisters_terrace\boss_selin_fireheart.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\hellfire_ramparts\boss_watchkeeper_gargolmar.cpp"
+ RelativePath="..\scripts\zone\magisters_terrace\boss_vexallus.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\magisters_terrace\def_magisters_terrace.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\magisters_terrace\instance_magisters_terrace.cpp"
>
</File>
</Filter>
<Filter
- Name="Shattered Halls"
+ Name="Loch Modan"
>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\shattered_halls\boss_nethekurse.cpp"
+ RelativePath="..\scripts\zone\loch_modan\loch_modan.cpp"
>
</File>
+ </Filter>
+ <Filter
+ Name="Karazhan"
+ >
<File
- RelativePath="..\scripts\zone\hellfire_citadel\shattered_halls\boss_warbringer_omrogg.cpp"
+ RelativePath="..\scripts\zone\karazhan\boss_curator.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\shattered_halls\boss_warchief_kargath_bladefist.cpp"
+ RelativePath="..\scripts\zone\karazhan\boss_maiden_of_virtue.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\shattered_halls\def_shattered_halls.h"
+ RelativePath="..\scripts\zone\karazhan\boss_midnight.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\hellfire_citadel\shattered_halls\instance_shattered_halls.cpp"
+ RelativePath="..\scripts\zone\karazhan\boss_moroes.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\karazhan\boss_netherspite.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\karazhan\boss_nightbane.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\karazhan\boss_prince_malchezaar.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\karazhan\boss_shade_of_aran.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\karazhan\boss_terestian_illhoof.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\karazhan\bosses_opera.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\karazhan\def_karazhan.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\karazhan\instance_karazhan.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\karazhan\karazhan.cpp"
>
</File>
</Filter>
- </Filter>
- <Filter
- Name="Hellfire Peninsula"
- >
- <File
- RelativePath="..\scripts\zone\hellfire_peninsula\boss_doomlord_kazzak.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\hellfire_peninsula\hellfire_peninsula.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Karazhan"
- >
- <File
- RelativePath="..\scripts\zone\karazhan\boss_curator.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\karazhan\boss_maiden_of_virtue.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\karazhan\boss_midnight.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\karazhan\boss_moroes.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\karazhan\boss_netherspite.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\karazhan\boss_nightbane.cpp"
+ <Filter
+ Name="Isle of Quel&apos;Danas"
>
- </File>
- <File
- RelativePath="..\scripts\zone\karazhan\boss_prince_malchezaar.cpp"
+ <File
+ RelativePath="..\scripts\zone\isle_of_queldanas\isle_of_queldanas.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Hinterlands"
>
- </File>
- <File
- RelativePath="..\scripts\zone\karazhan\boss_shade_of_aran.cpp"
+ </Filter>
+ <Filter
+ Name="Iron Forge"
>
- </File>
- <File
- RelativePath="..\scripts\zone\karazhan\boss_terestian_illhoof.cpp"
+ <File
+ RelativePath="..\scripts\zone\ironforge\ironforge.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Hillsbrad Foothills"
>
- </File>
- <File
- RelativePath="..\scripts\zone\karazhan\bosses_opera.cpp"
+ </Filter>
+ <Filter
+ Name="Gnomeregan"
>
- </File>
- <File
- RelativePath="..\scripts\zone\karazhan\def_karazhan.h"
+ </Filter>
+ <Filter
+ Name="Ghostlands"
>
- </File>
- <File
- RelativePath="..\scripts\zone\karazhan\instance_karazhan.cpp"
+ <File
+ RelativePath="..\scripts\zone\ghostlands\ghostlands.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Elwynn Forest"
>
- </File>
- <File
- RelativePath="..\scripts\zone\karazhan\karazhan.cpp"
+ <File
+ RelativePath="..\scripts\zone\elwynn_forest\elwynn_forest.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Deadmines"
>
- </File>
- </Filter>
- <Filter
- Name="Nagrand"
- >
- <File
- RelativePath="..\scripts\zone\nagrand\nagrand.cpp"
+ <File
+ RelativePath="..\scripts\zone\deadmines\deadmines.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\deadmines\def_deadmines.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Deadwind Pass"
>
- </File>
- </Filter>
- <Filter
- Name="Netherstorm"
- >
- <File
- RelativePath="..\scripts\zone\netherstorm\netherstorm.cpp"
+ </Filter>
+ <Filter
+ Name="Dun Morogh"
>
- </File>
- </Filter>
- <Filter
- Name="Shadowmoon Valley"
- >
- <File
- RelativePath="..\scripts\zone\shadowmoon_valley\boss_doomwalker.cpp"
+ <File
+ RelativePath="..\scripts\zone\dun_morogh\dun_morogh.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Alterac Mountains"
>
- </File>
- <File
- RelativePath="..\scripts\zone\shadowmoon_valley\shadowmoon_valley.cpp"
+ <File
+ RelativePath="..\scripts\zone\alterac_mountains\alterac_mountains.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Arathi Highlands"
>
- </File>
- </Filter>
- <Filter
- Name="Tempest Keep"
- >
+ <File
+ RelativePath="..\scripts\zone\arathi_highlands\arathi_highlands.cpp"
+ >
+ </File>
+ </Filter>
<Filter
- Name="Arcatraz"
+ Name="Blackrock Depths"
>
<File
- RelativePath="..\scripts\zone\tempest_keep\arcatraz\arcatraz.cpp"
+ RelativePath="..\scripts\zone\blackrock_depths\blackrock_depths.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\tempest_keep\arcatraz\boss_harbinger_skyriss.cpp"
+ RelativePath="..\scripts\zone\blackrock_depths\boss_ambassador_flamelash.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\tempest_keep\arcatraz\def_arcatraz.h"
+ RelativePath="..\scripts\zone\blackrock_depths\boss_anubshiah.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\tempest_keep\arcatraz\instance_arcatraz.cpp"
+ RelativePath="..\scripts\zone\blackrock_depths\boss_emperor_dagran_thaurissan.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackrock_depths\boss_general_angerforge.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackrock_depths\boss_gorosh_the_dervish.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackrock_depths\boss_grizzle.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackrock_depths\boss_high_interrogator_gerstahn.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackrock_depths\boss_magmus.cpp"
>
</File>
- </Filter>
- <Filter
- Name="Botanica"
- >
<File
- RelativePath="..\scripts\zone\tempest_keep\botanica\boss_high_botanist_freywinn.cpp"
+ RelativePath="..\scripts\zone\blackrock_depths\boss_moira_bronzebeard.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\tempest_keep\botanica\boss_laj.cpp"
+ RelativePath="..\scripts\zone\blackrock_depths\boss_tomb_of_seven.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\tempest_keep\botanica\boss_warp_splinter.cpp"
+ RelativePath="..\scripts\zone\blackrock_depths\def_blackrock_depths.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackrock_depths\instance_blackrock_depths.cpp"
>
</File>
</Filter>
<Filter
- Name="The Eye"
+ Name="Blackrock Spire"
>
<File
- RelativePath="..\scripts\zone\tempest_keep\the_eye\boss_alar.cpp"
+ RelativePath="..\scripts\zone\blackrock_spire\boss_drakkisath.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackrock_spire\boss_gyth.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackrock_spire\boss_halycon.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackrock_spire\boss_highlord_omokk.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackrock_spire\boss_mother_smolderweb.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackrock_spire\boss_overlord_wyrmthalak.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\tempest_keep\the_eye\boss_astromancer.cpp"
+ RelativePath="..\scripts\zone\blackrock_spire\boss_pyroguard_emberseer.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\tempest_keep\the_eye\boss_kaelthas.cpp"
+ RelativePath="..\scripts\zone\blackrock_spire\boss_quartermaster_zigris.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\tempest_keep\the_eye\boss_void_reaver.cpp"
+ RelativePath="..\scripts\zone\blackrock_spire\boss_rend_blackhand.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\tempest_keep\the_eye\def_the_eye.h"
+ RelativePath="..\scripts\zone\blackrock_spire\boss_shadow_hunter_voshgajin.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\tempest_keep\the_eye\instance_the_eye.cpp"
+ RelativePath="..\scripts\zone\blackrock_spire\boss_the_beast.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\tempest_keep\the_eye\the_eye.cpp"
+ RelativePath="..\scripts\zone\blackrock_spire\boss_warmaster_voone.cpp"
>
</File>
</Filter>
<Filter
- Name="The Mechanar"
+ Name="Blackwing Lair"
>
<File
- RelativePath="..\scripts\zone\tempest_keep\the_mechanar\boss_gatewatcher_gyrokill.cpp"
+ RelativePath="..\scripts\zone\blackwing_lair\boss_broodlord_lashlayer.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\tempest_keep\the_mechanar\boss_gatewatcher_ironhand.cpp"
+ RelativePath="..\scripts\zone\blackwing_lair\boss_chromaggus.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\tempest_keep\the_mechanar\boss_nethermancer_sepethrea.cpp"
+ RelativePath="..\scripts\zone\blackwing_lair\boss_ebonroc.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\tempest_keep\the_mechanar\boss_pathaleon_the_calculator.cpp"
+ RelativePath="..\scripts\zone\blackwing_lair\boss_firemaw.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\tempest_keep\the_mechanar\def_mechanar.h"
+ RelativePath="..\scripts\zone\blackwing_lair\boss_flamegor.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\tempest_keep\the_mechanar\instance_mechanar.cpp"
+ RelativePath="..\scripts\zone\blackwing_lair\boss_nefarian.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackwing_lair\boss_razorgore.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackwing_lair\boss_vaelastrasz.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackwing_lair\boss_victor_nefarius.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blackwing_lair\instance_blackwing_lair.cpp"
>
</File>
</Filter>
- </Filter>
- <Filter
- Name="Terokkar Forest"
- >
- <File
- RelativePath="..\scripts\zone\terokkar_forest\terokkar_forest.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Zangarmarsh"
- >
- <File
- RelativePath="..\scripts\zone\zangarmarsh\zangarmarsh.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Blackrock Spire"
- >
- <File
- RelativePath="..\scripts\zone\blackrock_spire\boss_drakkisath.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_spire\boss_gyth.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_spire\boss_halycon.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_spire\boss_highlord_omokk.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_spire\boss_mother_smolderweb.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_spire\boss_overlord_wyrmthalak.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_spire\boss_pyroguard_emberseer.cpp"
+ <Filter
+ Name="Blasted Lands"
>
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_spire\boss_quartermaster_zigris.cpp"
+ <File
+ RelativePath="..\scripts\zone\blasted_lands\blasted_lands.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\blasted_lands\boss_kruul.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Burning Steppes"
>
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_spire\boss_rend_blackhand.cpp"
+ <File
+ RelativePath="..\scripts\zone\burning_steppes\burning_steppes.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Duskwood"
>
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_spire\boss_shadow_hunter_voshgajin.cpp"
+ </Filter>
+ <Filter
+ Name="Eastern Plaguelands"
>
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_spire\boss_the_beast.cpp"
+ <File
+ RelativePath="..\scripts\zone\eastern_plaguelands\eastern_plaguelands.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Eversong Woods"
>
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_spire\boss_warmaster_voone.cpp"
+ <File
+ RelativePath="..\scripts\zone\eversong_woods\eversong_woods.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Redridge Mountains"
>
- </File>
- </Filter>
- <Filter
- Name="Stormwind City"
- >
- <File
- RelativePath="..\scripts\zone\stormwind\stormwind_city.cpp"
+ </Filter>
+ <Filter
+ Name="Scarlet Monastery"
>
- </File>
- </Filter>
- <Filter
- Name="Coilfang Resevoir"
- >
+ <File
+ RelativePath="..\scripts\zone\scarlet_monastery\boss_arcanist_doan.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scarlet_monastery\boss_azshir_the_sleepless.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scarlet_monastery\boss_bloodmage_thalnos.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scarlet_monastery\boss_headless_horseman.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scarlet_monastery\boss_herod.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scarlet_monastery\boss_high_inquisitor_fairbanks.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scarlet_monastery\boss_houndmaster_loksey.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scarlet_monastery\boss_interrogator_vishas.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scarlet_monastery\boss_mograine_and_whitemane.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scarlet_monastery\boss_scorn.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scarlet_monastery\def_scarlet_monastery.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scarlet_monastery\instance_scarlet_monastery.cpp"
+ >
+ </File>
+ </Filter>
<Filter
- Name="Serpent Shrine Cavern"
+ Name="Scholomance"
>
<File
- RelativePath="..\scripts\zone\coilfang_resevoir\serpent_shrine\boss_fathomlord_karathress.cpp"
+ RelativePath="..\scripts\zone\scholomance\boss_darkmaster_gandling.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scholomance\boss_death_knight_darkreaver.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\coilfang_resevoir\serpent_shrine\boss_hydross_the_unstable.cpp"
+ RelativePath="..\scripts\zone\scholomance\boss_doctor_theolen_krastinov.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\coilfang_resevoir\serpent_shrine\boss_lady_vashj.cpp"
+ RelativePath="..\scripts\zone\scholomance\boss_illucia_barov.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\coilfang_resevoir\serpent_shrine\boss_leotheras_the_blind.cpp"
+ RelativePath="..\scripts\zone\scholomance\boss_instructor_malicia.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\coilfang_resevoir\serpent_shrine\boss_lurker_below.cpp"
+ RelativePath="..\scripts\zone\scholomance\boss_jandice_barov.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\coilfang_resevoir\serpent_shrine\boss_morogrim_tidewalker.cpp"
+ RelativePath="..\scripts\zone\scholomance\boss_kormok.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\coilfang_resevoir\serpent_shrine\def_serpent_shrine.h"
+ RelativePath="..\scripts\zone\scholomance\boss_lord_alexei_barov.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\coilfang_resevoir\serpent_shrine\instance_serpent_shrine.cpp"
+ RelativePath="..\scripts\zone\scholomance\boss_lorekeeper_polkelt.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scholomance\boss_ras_frostwhisper.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scholomance\boss_the_ravenian.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scholomance\boss_vectus.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scholomance\def_scholomance.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\scholomance\instance_scholomance.cpp"
>
</File>
</Filter>
<Filter
- Name="Slave Pens"
+ Name="Searing Gorge"
>
+ <File
+ RelativePath="..\scripts\zone\searing_gorge\searing_gorge.cpp"
+ >
+ </File>
</Filter>
<Filter
- Name="Steam Vault"
+ Name="Shadowfang Keep"
>
<File
- RelativePath="..\scripts\zone\coilfang_resevoir\steam_vault\boss_hydromancer_thespia.cpp"
+ RelativePath="..\scripts\zone\shadowfang_keep\def_shadowfang_keep.h"
>
</File>
<File
- RelativePath="..\scripts\zone\coilfang_resevoir\steam_vault\boss_mekgineer_steamrigger.cpp"
+ RelativePath="..\scripts\zone\shadowfang_keep\instance_shadowfang_keep.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\coilfang_resevoir\steam_vault\boss_warlord_kalithresh.cpp"
+ RelativePath="..\scripts\zone\shadowfang_keep\shadowfang_keep.cpp"
>
</File>
+ </Filter>
+ <Filter
+ Name="Silvermoon City"
+ >
<File
- RelativePath="..\scripts\zone\coilfang_resevoir\steam_vault\def_steam_vault.h"
+ RelativePath="..\scripts\zone\silvermoon\silvermoon_city.cpp"
>
</File>
+ </Filter>
+ <Filter
+ Name="Silverpine Forest"
+ >
<File
- RelativePath="..\scripts\zone\coilfang_resevoir\steam_vault\instance_steam_vault.cpp"
+ RelativePath="..\scripts\zone\silverpine_forest\silverpine_forest.cpp"
>
</File>
</Filter>
<Filter
- Name="Underbog"
+ Name="Stockade"
+ >
+ </Filter>
+ <Filter
+ Name="Stormwind City"
>
<File
- RelativePath="..\scripts\zone\coilfang_resevoir\underbog\boss_hungarfen.cpp"
+ RelativePath="..\scripts\zone\stormwind\stormwind_city.cpp"
>
</File>
+ </Filter>
+ <Filter
+ Name="Stranglethorn Vale"
+ >
<File
- RelativePath="..\scripts\zone\coilfang_resevoir\underbog\boss_the_black_stalker.cpp"
+ RelativePath="..\scripts\zone\stranglethorn_vale\stranglethorn_vale.cpp"
>
</File>
</Filter>
- </Filter>
- <Filter
- Name="Caverns of Time"
- >
<Filter
- Name="The Dark Portal"
+ Name="Stratholme"
>
<File
- RelativePath="..\scripts\zone\caverns_of_time\dark_portal\boss_aeonus.cpp"
+ RelativePath="..\scripts\zone\stratholme\boss_baron_rivendare.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\stratholme\boss_baroness_anastari.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\dark_portal\boss_chrono_lord_deja.cpp"
+ RelativePath="..\scripts\zone\stratholme\boss_cannon_master_willey.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\dark_portal\boss_temporus.cpp"
+ RelativePath="..\scripts\zone\stratholme\boss_dathrohan_balnazzar.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\dark_portal\dark_portal.cpp"
+ RelativePath="..\scripts\zone\stratholme\boss_magistrate_barthilas.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\dark_portal\def_dark_portal.h"
+ RelativePath="..\scripts\zone\stratholme\boss_maleki_the_pallid.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\dark_portal\instance_dark_portal.cpp"
+ RelativePath="..\scripts\zone\stratholme\boss_nerubenkan.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\stratholme\boss_order_of_silver_hand.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\stratholme\boss_postmaster_malown.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\stratholme\boss_ramstein_the_gorger.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\stratholme\boss_timmy_the_cruel.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\stratholme\def_stratholme.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\stratholme\instance_stratholme.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\stratholme\stratholme.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Sunken Temple"
+ >
+ </Filter>
+ <Filter
+ Name="Sunwell Plateau"
+ >
+ <File
+ RelativePath="..\scripts\zone\sunwell_plateau\boss_brutallus.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\sunwell_plateau\boss_eredar_twins.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\sunwell_plateau\boss_felmyst.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\sunwell_plateau\boss_kalecgos.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\sunwell_plateau\boss_kiljaeden.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\sunwell_plateau\boss_muru.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\sunwell_plateau\def_sunwell_plateau.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\sunwell_plateau\instance_sunwell_plateau.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\sunwell_plateau\sunwell_plateau.cpp"
>
</File>
</Filter>
<Filter
- Name="Battle for Mt. Hyjal"
+ Name="Swamp of Sorrows"
>
+ </Filter>
+ <Filter
+ Name="Zul&apos;Gurub"
+ >
+ <File
+ RelativePath="..\scripts\zone\zulgurub\boss_arlokk.cpp"
+ >
+ </File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\hyjal\boss_anetheron.cpp"
+ RelativePath="..\scripts\zone\zulgurub\boss_gahzranka.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\hyjal\boss_archimonde.cpp"
+ RelativePath="..\scripts\zone\zulgurub\boss_grilek.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\hyjal\boss_azgalor.cpp"
+ RelativePath="..\scripts\zone\zulgurub\boss_hakkar.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\hyjal\boss_kazrogal.cpp"
+ RelativePath="..\scripts\zone\zulgurub\boss_hazzarah.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\hyjal\boss_rage_winterchill.cpp"
+ RelativePath="..\scripts\zone\zulgurub\boss_jeklik.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\hyjal\def_hyjal.h"
+ RelativePath="..\scripts\zone\zulgurub\boss_jindo.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\hyjal\hyjal.cpp"
+ RelativePath="..\scripts\zone\zulgurub\boss_mandokir.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\hyjal\hyjal_trash.cpp"
+ RelativePath="..\scripts\zone\zulgurub\boss_marli.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\hyjal\hyjal_trash.h"
+ RelativePath="..\scripts\zone\zulgurub\boss_renataki.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\hyjal\hyjalAI.cpp"
+ RelativePath="..\scripts\zone\zulgurub\boss_thekal.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\hyjal\hyjalAI.h"
+ RelativePath="..\scripts\zone\zulgurub\boss_venoxis.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\hyjal\instance_hyjal.cpp"
+ RelativePath="..\scripts\zone\zulgurub\boss_wushoolay.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\zulgurub\def_zulgurub.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\zulgurub\instance_zulgurub.cpp"
>
</File>
</Filter>
-
<Filter
- Name="Old Hillsbrad"
+ Name="Zul&apos;Aman"
>
<File
- RelativePath="..\scripts\zone\caverns_of_time\old_hillsbrad\boss_captain_skarloc.cpp"
+ RelativePath="..\scripts\zone\zulaman\boss_akilzon.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\zulaman\boss_halazzi.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\zulaman\boss_hexlord.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\zulaman\boss_janalai.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\old_hillsbrad\boss_epoch_hunter.cpp"
+ RelativePath="..\scripts\zone\zulaman\boss_nalorakk.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\old_hillsbrad\boss_leutenant_drake.cpp"
+ RelativePath="..\scripts\zone\zulaman\boss_zuljin.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\old_hillsbrad\def_old_hillsbrad.h"
+ RelativePath="..\scripts\zone\zulaman\def_zulaman.h"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\old_hillsbrad\instance_old_hillsbrad.cpp"
+ RelativePath="..\scripts\zone\zulaman\instance_zulaman.cpp"
>
</File>
<File
- RelativePath="..\scripts\zone\caverns_of_time\old_hillsbrad\old_hillsbrad.cpp"
+ RelativePath="..\scripts\zone\zulaman\zulaman.cpp"
>
</File>
</Filter>
- </Filter>
- <Filter
- Name="Silvermoon City"
- >
- <File
- RelativePath="..\scripts\zone\silvermoon\silvermoon_city.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Darnassus"
- >
- </Filter>
- <Filter
- Name="Exodar"
- >
- </Filter>
- <Filter
- Name="Iron Forge"
- >
- <File
- RelativePath="..\scripts\zone\ironforge\ironforge.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Orgrimmar"
- >
- <File
- RelativePath="..\scripts\zone\orgrimmar\orgrimmar.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Shattrath City"
- >
- <File
- RelativePath="..\scripts\zone\shattrath\shattrath_city.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Thunder Bluff"
- >
- <File
- RelativePath="..\scripts\zone\thunder_bluff\thunder_bluff.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Undercity"
- >
- <File
- RelativePath="..\scripts\zone\undercity\undercity.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Zul&apos;Aman"
- >
- <File
- RelativePath="..\scripts\zone\zulaman\boss_akilzon.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\zulaman\boss_halazzi.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\zulaman\boss_hexlord.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\zulaman\boss_janalai.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\zulaman\boss_nalorakk.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\zulaman\boss_zuljin.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\zulaman\def_zulaman.h"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\zulaman\instance_zulaman.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\zulaman\zulaman.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Isle of Quel&apos;Danas"
- >
- <File
- RelativePath="..\scripts\zone\isle_of_queldanas\isle_of_queldanas.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Magister&apos;s Terrace"
- >
- <File
- RelativePath="..\scripts\zone\magisters_terrace\boss_felblood_kaelthas.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\magisters_terrace\boss_priestess_delrissa.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\magisters_terrace\boss_selin_fireheart.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\magisters_terrace\boss_vexallus.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\magisters_terrace\def_magisters_terrace.h"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\magisters_terrace\instance_magisters_terrace.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Sunwell Plateau"
- >
- <File
- RelativePath="..\scripts\zone\sunwell_plateau\boss_brutallus.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\sunwell_plateau\boss_eredar_twins.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\sunwell_plateau\boss_felmyst.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\sunwell_plateau\boss_kalecgos.cpp"
+ <Filter
+ Name="Wetlands"
>
- </File>
- <File
- RelativePath="..\scripts\zone\sunwell_plateau\boss_muru.cpp"
+ </Filter>
+ <Filter
+ Name="Westfall"
>
- </File>
- <File
- RelativePath="..\scripts\zone\sunwell_plateau\boss_kiljaeden.cpp"
+ <File
+ RelativePath="..\scripts\zone\westfall\westfall.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Western Plaguelands"
>
- </File>
- <File
- RelativePath="..\scripts\zone\sunwell_plateau\sunwell_plateau.cpp"
+ <File
+ RelativePath="..\scripts\zone\western_plaguelands\western_plaguelands.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Undercity"
>
- </File>
- <File
- RelativePath="..\scripts\zone\sunwell_plateau\def_sunwell_plateau.h"
+ <File
+ RelativePath="..\scripts\zone\undercity\undercity.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Uldaman"
>
- </File>
- <File
- RelativePath="..\scripts\zone\sunwell_plateau\instance_sunwell_plateau.cpp"
+ <File
+ RelativePath="..\scripts\zone\uldaman\boss_archaedas.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\uldaman\boss_ironaya.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\uldaman\instance_uldaman.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\uldaman\uldaman.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Tirisfal Glades"
>
- </File>
+ <File
+ RelativePath="..\scripts\zone\tirisfal_glades\tirisfal_glades.cpp"
+ >
+ </File>
+ </Filter>
</Filter>
<Filter
- Name="Blackrock Depths"
+ Name="Outland"
>
- <File
- RelativePath="..\scripts\zone\blackrock_depths\blackrock_depths.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_depths\boss_ambassador_flamelash.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_depths\boss_anubshiah.cpp"
- >
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_depths\boss_emperor_dagran_thaurissan.cpp"
+ <Filter
+ Name="Netherstorm"
>
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_depths\boss_general_angerforge.cpp"
+ <File
+ RelativePath="..\scripts\zone\netherstorm\netherstorm.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Nagrand"
>
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_depths\boss_gorosh_the_dervish.cpp"
+ <File
+ RelativePath="..\scripts\zone\nagrand\nagrand.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Gruul&apos;s Lair"
>
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_depths\boss_grizzle.cpp"
+ <File
+ RelativePath="..\scripts\zone\gruuls_lair\boss_gruul.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\gruuls_lair\boss_high_king_maulgar.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\gruuls_lair\def_gruuls_lair.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\gruuls_lair\instance_gruuls_lair.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Hellfire Citadel"
+ >
+ <Filter
+ Name="Blood Furnace"
+ >
+ <File
+ RelativePath="..\scripts\zone\hellfire_citadel\blood_furnace\boss_broggok.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\hellfire_citadel\blood_furnace\boss_kelidan_the_breaker.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\hellfire_citadel\blood_furnace\boss_the_maker.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\hellfire_citadel\blood_furnace\def_blood_furnace.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\hellfire_citadel\blood_furnace\instance_blood_furnace.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Magtheridon&apos;s lair"
+ >
+ <File
+ RelativePath="..\scripts\zone\hellfire_citadel\magtheridons_lair\boss_magtheridon.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\hellfire_citadel\magtheridons_lair\def_magtheridons_lair.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\hellfire_citadel\magtheridons_lair\instance_magtheridons_lair.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Hellfire Ramparts"
+ >
+ <File
+ RelativePath="..\scripts\zone\hellfire_citadel\hellfire_ramparts\boss_omor_the_unscarred.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\hellfire_citadel\hellfire_ramparts\boss_vazruden_the_herald.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\hellfire_citadel\hellfire_ramparts\boss_watchkeeper_gargolmar.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Shattered Halls"
+ >
+ <File
+ RelativePath="..\scripts\zone\hellfire_citadel\shattered_halls\boss_nethekurse.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\hellfire_citadel\shattered_halls\boss_warbringer_omrogg.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\hellfire_citadel\shattered_halls\boss_warchief_kargath_bladefist.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\hellfire_citadel\shattered_halls\def_shattered_halls.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\hellfire_citadel\shattered_halls\instance_shattered_halls.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Hellfire Peninsula"
>
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_depths\boss_high_interrogator_gerstahn.cpp"
+ <File
+ RelativePath="..\scripts\zone\hellfire_peninsula\boss_doomlord_kazzak.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\hellfire_peninsula\hellfire_peninsula.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Shadowmoon Valley"
>
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_depths\boss_magmus.cpp"
+ <File
+ RelativePath="..\scripts\zone\shadowmoon_valley\boss_doomwalker.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\shadowmoon_valley\shadowmoon_valley.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Tempest Keep"
+ >
+ <Filter
+ Name="Arcatraz"
+ >
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\arcatraz\arcatraz.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\arcatraz\boss_harbinger_skyriss.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\arcatraz\def_arcatraz.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\arcatraz\instance_arcatraz.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Botanica"
+ >
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\botanica\boss_high_botanist_freywinn.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\botanica\boss_laj.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\botanica\boss_warp_splinter.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="The Eye"
+ >
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\the_eye\boss_alar.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\the_eye\boss_astromancer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\the_eye\boss_kaelthas.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\the_eye\boss_void_reaver.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\the_eye\def_the_eye.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\the_eye\instance_the_eye.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\the_eye\the_eye.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="The Mechanar"
+ >
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\the_mechanar\boss_gatewatcher_gyrokill.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\the_mechanar\boss_gatewatcher_ironhand.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\the_mechanar\boss_nethermancer_sepethrea.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\the_mechanar\boss_pathaleon_the_calculator.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\the_mechanar\def_mechanar.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\tempest_keep\the_mechanar\instance_mechanar.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Terokkar Forest"
>
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_depths\boss_moira_bronzebeard.cpp"
+ <File
+ RelativePath="..\scripts\zone\terokkar_forest\terokkar_forest.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Coilfang Resevoir"
+ >
+ <Filter
+ Name="Serpent Shrine Cavern"
+ >
+ <File
+ RelativePath="..\scripts\zone\coilfang_resevoir\serpent_shrine\boss_fathomlord_karathress.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\coilfang_resevoir\serpent_shrine\boss_hydross_the_unstable.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\coilfang_resevoir\serpent_shrine\boss_lady_vashj.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\coilfang_resevoir\serpent_shrine\boss_leotheras_the_blind.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\coilfang_resevoir\serpent_shrine\boss_lurker_below.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\coilfang_resevoir\serpent_shrine\boss_morogrim_tidewalker.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\coilfang_resevoir\serpent_shrine\def_serpent_shrine.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\coilfang_resevoir\serpent_shrine\instance_serpent_shrine.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Slave Pens"
+ >
+ </Filter>
+ <Filter
+ Name="Steam Vault"
+ >
+ <File
+ RelativePath="..\scripts\zone\coilfang_resevoir\steam_vault\boss_hydromancer_thespia.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\coilfang_resevoir\steam_vault\boss_mekgineer_steamrigger.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\coilfang_resevoir\steam_vault\boss_warlord_kalithresh.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\coilfang_resevoir\steam_vault\def_steam_vault.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\coilfang_resevoir\steam_vault\instance_steam_vault.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Underbog"
+ >
+ <File
+ RelativePath="..\scripts\zone\coilfang_resevoir\underbog\boss_hungarfen.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\coilfang_resevoir\underbog\boss_the_black_stalker.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Aunchindoun"
+ >
+ <Filter
+ Name="Auchenai Crypts"
+ >
+ <File
+ RelativePath="..\scripts\zone\aunchindoun\auchenai_crypts\boss_exarch_maladaar.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\aunchindoun\auchenai_crypts\boss_shirrak_the_dead_watcher.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Mana Tombs"
+ >
+ <File
+ RelativePath="..\scripts\zone\aunchindoun\mana_tombs\boss_nexusprince_shaffar.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\aunchindoun\mana_tombs\boss_pandemonius.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Sethekk Halls"
+ >
+ <File
+ RelativePath="..\scripts\zone\aunchindoun\sethekk_halls\boss_darkweaver_syth.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\aunchindoun\sethekk_halls\boss_tailonking_ikiss.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\aunchindoun\sethekk_halls\def_sethekk_halls.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\aunchindoun\sethekk_halls\instance_sethekk_halls.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Shadow Labyrinth"
+ >
+ <File
+ RelativePath="..\scripts\zone\aunchindoun\shadow_labyrinth\boss_ambassador_hellmaw.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\aunchindoun\shadow_labyrinth\boss_blackheart_the_inciter.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\aunchindoun\shadow_labyrinth\boss_grandmaster_vorpil.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\aunchindoun\shadow_labyrinth\boss_murmur.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\aunchindoun\shadow_labyrinth\def_shadow_labyrinth.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\aunchindoun\shadow_labyrinth\instance_shadow_labyrinth.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Black Temple"
>
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_depths\boss_tomb_of_seven.cpp"
+ <File
+ RelativePath="..\scripts\zone\black_temple\black_temple.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\black_temple\boss_bloodboil.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\black_temple\boss_illidan.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\black_temple\boss_mother_shahraz.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\black_temple\boss_reliquary_of_souls.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\black_temple\boss_shade_of_akama.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\black_temple\boss_supremus.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\black_temple\boss_teron_gorefiend.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\black_temple\boss_warlord_najentus.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\black_temple\def_black_temple.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\black_temple\illidari_council.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\black_temple\instance_black_temple.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Blade&apos;s Edge Mountains"
>
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_depths\def_blackrock_depths.h"
+ <File
+ RelativePath="..\scripts\zone\blades_edge_mountains\blades_edge_mountains.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Zangarmarsh"
>
- </File>
- <File
- RelativePath="..\scripts\zone\blackrock_depths\instance_blackrock_depths.cpp"
+ <File
+ RelativePath="..\scripts\zone\zangarmarsh\zangarmarsh.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Shattrath City"
>
- </File>
+ <File
+ RelativePath="..\scripts\zone\shattrath\shattrath_city.cpp"
+ >
+ </File>
+ </Filter>
</Filter>
<Filter
- Name="Loch Modan"
+ Name="Northrend"
>
- <File
- RelativePath="..\scripts\zone\loch_modan\loch_modan.cpp"
+ <Filter
+ Name="Region"
>
- </File>
+ <Filter
+ Name="Howling Fjord"
+ >
+ </Filter>
+ <Filter
+ Name="Grizzly Hills"
+ >
+ </Filter>
+ <Filter
+ Name="Zul&apos;Drak"
+ >
+ </Filter>
+ <Filter
+ Name="The Storm Peaks"
+ >
+ </Filter>
+ <Filter
+ Name="Crystalsong Forest"
+ >
+ </Filter>
+ <Filter
+ Name="Dragonblight"
+ >
+ </Filter>
+ <Filter
+ Name="Borean Tundra"
+ >
+ <File
+ RelativePath="..\scripts\zone\borean_tundra\borean_tundra.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Wintergrasp"
+ >
+ </Filter>
+ <Filter
+ Name="Icecrown"
+ >
+ </Filter>
+ <Filter
+ Name="Sholazar Basin"
+ >
+ </Filter>
+ <Filter
+ Name="Dalaran"
+ >
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Dungeon"
+ >
+ <Filter
+ Name="Naxxramas"
+ >
+ <File
+ RelativePath="..\scripts\zone\naxxramas\boss_anubrekhan.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\naxxramas\boss_faerlina.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\naxxramas\boss_four_horsemen.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\naxxramas\boss_gluth.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\naxxramas\boss_gothik.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\naxxramas\boss_grobbulus.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\naxxramas\boss_heigan.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\naxxramas\boss_kelthuzad.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\naxxramas\boss_loatheb.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\naxxramas\boss_maexxna.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\naxxramas\boss_noth.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\naxxramas\boss_patchwerk.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\naxxramas\boss_razuvious.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\naxxramas\boss_sapphiron.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\naxxramas\boss_thaddius.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\naxxramas\instance_naxxramas.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Nexus"
+ >
+ <Filter
+ Name="Nexus"
+ >
+ <File
+ RelativePath="..\scripts\zone\nexus\nexus\boss_anomalus.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\nexus\nexus\boss_keristrasza.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\nexus\nexus\boss_magus_telestra.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\nexus\nexus\boss_ormorok.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\nexus\nexus\commander_kolurg.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\nexus\nexus\commander_stoutbeard.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\nexus\nexus\def_nexus.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\nexus\nexus\instance_nexus.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Oculus"
+ >
+ <File
+ RelativePath="..\scripts\zone\nexus\oculus\boss_drakos.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\nexus\oculus\boss_eregos.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\nexus\oculus\boss_urom.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\nexus\oculus\boss_varos.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\nexus\oculus\def_oculus.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\nexus\oculus\instance_oculus.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Eye of Eternity"
+ >
+ <File
+ RelativePath="..\scripts\zone\nexus\eye_of_eternity\boss_malygos.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\nexus\eye_of_eternity\def_eye_of_eternity.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\nexus\eye_of_eternity\instance_eye_of_eternity.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Obsidian Sanctum"
+ >
+ <File
+ RelativePath="..\scripts\zone\obsidian_sanctum\boss_sartharion.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\obsidian_sanctum\def_obsidian_sanctum.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\obsidian_sanctum\instance_obsidian_sanctum.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Ulduar"
+ >
+ <Filter
+ Name="Halls of Stone"
+ >
+ <File
+ RelativePath="..\scripts\zone\ulduar\halls_of_stone\boss_krystallus.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\ulduar\halls_of_stone\boss_maiden_of_grief.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\ulduar\halls_of_stone\boss_sjonnir.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\ulduar\halls_of_stone\def_halls_of_stone.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\ulduar\halls_of_stone\instance_halls_of_stone.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Halls of Lightning"
+ >
+ <File
+ RelativePath="..\scripts\zone\ulduar\halls_of_lightning\boss_bjarngrim.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\ulduar\halls_of_lightning\boss_ionar.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\ulduar\halls_of_lightning\boss_loken.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\ulduar\halls_of_lightning\boss_volkhan.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\ulduar\halls_of_lightning\def_halls_of_lightning.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\ulduar\halls_of_lightning\instance_halls_of_lightning.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Utgarde Keep"
+ >
+ <Filter
+ Name="Utgarde Keep"
+ >
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\boss_ingvar_the_plunderer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\boss_keleseth.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\boss_skarvald_dalronn.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\def_utgarde_keep.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\instance_utgarde_keep.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Utgarde Pinnacle"
+ >
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_pinnacle\boss_palehoof.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_pinnacle\boss_skadi.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_pinnacle\boss_svala.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_pinnacle\boss_ymiron.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_pinnacle\def_pinnacle.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_pinnacle\instance_pinnacle.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Vault of Archavon"
+ >
+ <File
+ RelativePath="..\scripts\zone\vault_of_archavon\boss_archavon.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\vault_of_archavon\def_vault_of_archavon.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\vault_of_archavon\instance_vault_of_archavon.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Violet Hold"
+ >
+ <File
+ RelativePath="..\scripts\zone\violet_hold\boss_cyanigosa.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\violet_hold\boss_erekem.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\violet_hold\boss_ichoron.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\violet_hold\boss_lavanthor.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\violet_hold\boss_moragg.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\violet_hold\boss_xevozz.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\violet_hold\boss_zuramat.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\violet_hold\def_violet_hold.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\violet_hold\instance_violet_hold.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Gundrak"
+ >
+ <File
+ RelativePath="..\scripts\zone\gundrak\boss_drakkari_colossus.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\gundrak\boss_eck.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\gundrak\boss_gal_darah.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\gundrak\boss_moorabi.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\gundrak\boss_slad_ran.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\gundrak\def_gundrak.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\gundrak\instance_gundrak.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Drak&apos;Tharon Keep"
+ >
+ <File
+ RelativePath="..\scripts\zone\draktharon_keep\boss_dred.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\draktharon_keep\boss_novos.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\draktharon_keep\boss_tharon_ja.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\draktharon_keep\boss_trollgore.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\draktharon_keep\def_drak_tharon_keep.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\draktharon_keep\instance_drak_tharon_keep.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Azjol-Nerub"
+ >
+ <Filter
+ Name="Ahn&apos;kahet"
+ >
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\boss_amanitar.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\boss_elder_nadox.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\boss_herald_volazj.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\boss_jedoga_shadowseeker.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\boss_prince_taldaram.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\def_ahnkahet.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\ahnkahet\instance_ahnkahet.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Azjol-Nerub"
+ >
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\azjol_nerub\boss_anubarak.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\azjol_nerub\boss_hadronox.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\azjol_nerub\boss_krikthir_the_gatewatcher.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\azjol_nerub\def_azjol_nerub.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\azjol_nerub\azjol_nerub\instance_azjol_nerub.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Filter>
</Filter>
</Filter>
</Filter>
@@ -2435,10 +2932,6 @@
</File>
</Filter>
<File
- RelativePath="..\config.h"
- >
- </File>
- <File
RelativePath="..\ScriptMgr.cpp"
>
</File>
@@ -2447,10 +2940,6 @@
>
</File>
<File
- RelativePath="..\svn_revision.h"
- >
- </File>
- <File
RelativePath="..\system.cpp"
>
</File>
diff --git a/src/bindings/scripts/docs/EventAI.txt b/src/bindings/scripts/docs/EventAI.txt
index 37064b63e8b..3dac5c271e8 100644
--- a/src/bindings/scripts/docs/EventAI.txt
+++ b/src/bindings/scripts/docs/EventAI.txt
@@ -42,7 +42,7 @@ action3_param3
All params are signed 32 bit values (+/- 2147483647). If param specifies time then time is in milliseconds. If param specifies percentage then percentages are value/100 (ex: if param = 500 then that means 500%, -50 = -50%)
-*Phase mask is a bit mask of which phases this event should not trigger in. Example: Phase mask value of 12 (1100) would mean that this event would trigger 0, 1 and all other phases except for 2 and 3 (0 counts as the first phase).
+*Phase mask is a bit mask of which phases this event should not trigger in. Example: Phase mask value of 12 (1100) would mean that this event would trigger 0, 1 and all other phases except for 2 and 3 (0 counts as the first phase).
=========================================
Event Types
@@ -56,22 +56,24 @@ Events will not repeat until the creature exits combat unless EFLAG_REPEATABLE i
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0 EVENT_T_TIMER InitialMin, InitialMax, RepeatMin, RepeatMax Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4). but only in combat.
1 EVENT_T_TIMER_OOC InitialMin, InitialMax, RepeatMin, RepeatMax Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4). but only out of combat.
-2 EVENT_T_HP HPMax%, HPMin%, RepeatMin, RepeatMax Expires when HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
-3 EVENT_T_MANA ManaMax%,ManaMin% RepeatMin, RepeatMax Expires once Mana% is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
-4 EVENT_T_AGGRO NONE Expires upon initial aggro (does not repeat).
+2 EVENT_T_HP HPMax%, HPMin%, RepeatMin, RepeatMax Expires when HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
+3 EVENT_T_MANA ManaMax%,ManaMin% RepeatMin, RepeatMax Expires once Mana% is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
+4 EVENT_T_AGGRO NONE Expires upon initial aggro (does not repeat).
5 EVENT_T_KILL RepeatMin, RepeatMax Expires upon killing a player. Will repeat between every (Param1) and (Param2).
-6 EVENT_T_DEATH NONE Expires upon Death of the Creature.
+6 EVENT_T_DEATH NONE Expires upon Death of the Creature.
7 EVENT_T_EVADE NONE Expires upon creature EnterEvadeMode().
8 EVENT_T_SPELLHIT SpellID, School, RepeatMin, RepeatMax Expires upon Spell hit. If (param1) is set will only expire on that spell. If (param2) will only expire on spells of that school (-1 for all). Will repeat every (Param3) and (Param4) .
9 EVENT_T_RANGE MinDist, MaxDist, RepeatMin, RepeatMax Expires when the highest threat target distance is greater than (Param1) and less than (Param2). Will repeat every (Param3) and (Param4) .
-10 EVENT_T_OOC_LOS NoHostile, NoFriendly, RepeatMin, RepeatMax Expires when a Player moves within visible distance to creature. Does not expire for Hostile Players if (Param1) is not 0. Does not expire for Friendly Players if (Param2) is not 0. Will repeat every (Param3) and (Param4) . Does not expire for creatures or pet or when the creature is in combat.
+10 EVENT_T_OOC_LOS Hostile-or-Not, MaxAllowedRange, RepeatMin, RepeatMax Expires when a Unit moves within distance(MaxAllowedRange) to creature. If Param1=0 it will expire if Unit are Hostile. If Param1=1 it will only expire if Unit are not Hostile(generally determined by faction). Will repeat every (Param3) and (Param4). Does not expire when the creature is in combat.
11 EVENT_T_SPAWNED NONE Expires at initial spawn and at creature respawn (useful for setting ranged movement type)
-12 EVENT_T_TARGET_HP HPMax%, HPMin%, RepeatMin, RepeatMax Expires when Current Target's HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4) .
+12 EVENT_T_TARGET_HP HPMax%, HPMin%, RepeatMin, RepeatMax Expires when Current Target's HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4) .
13 EVENT_T_TARGET_CASTING RepeatMin, RepeatatMax Expires when the current target is casting a spell. Will repeat every (Param1) and (Param2) .
14 EVENT_T_FRIENDLY_HP HPDeficit, Radius, RepeatMin, RepeatMax Expires when a friendly unit in radius has at least (param1) hp missing. Will repeat every (Param3) and (Param4) .
15 EVENT_T_FRIENDLY_IS_CC DispelType, Radius, RepeatMin, RepeatMax Expires when a friendly unit is Crowd controlled within the given radius (param2). Will repeat every (Param3) and (Param4) .
16 EVENT_T_MISSING_BUFF SpellId, Radius, RepeatMin, RepeatMax Expires when a friendly unit is missing aura's given by spell (param1) within radius (param2). Will repeat every (Param3) and (Param4) .
-17 EVENT_T_SUMMONED_UNIT CreatureId, RepeatMin, RepeatMax Expires after creature with entry = (param1) is spawned or for all spawns if param1 = 0. Will repeat every (Param2) and (Param3) .
+17 EVENT_T_SUMMONED_UNIT CreatureId, RepeatMin, RepeatMax Expires after creature with entry = (param1) is spawned or for all spawns if param1 = 0. Will repeat every (Param2) and (Param3).
+18 EVENT_T_TARGET_MANA ManaMax%, ManaMin%, RepeatMin, RepeatMax
+21 EVENT_T_REACHED_HOME NONE Expires when creature reach it's home(spawn) location after Evade.
=========================================
Action Types
@@ -83,8 +85,8 @@ Params are always read from Param1, then Param2, then Param3.
(# Internal Name Param usage Discription)
0 ACTION_T_NONE No Action Does Nothing
1 ACTION_T_TEXT -TextId1, -TextId2, -TextId3 Displays the -TextId as defined. In case -TextId2 and optionally -TextId3, the output will be randomized. Type text are defined in the text table itself(say, yell, whisper, etc) along with other options for the text. All values are required to be negative.
-2 ACTION_T_YELL UNUSED
-3 ACTION_T_TEXTEMOTE UNUSED
+2 ACTION_T_SET_FACTION FactionId Change faction for creature. If param1==0, creature will revert to default faction.
+3 ACTION_T_MORPH_TO_ENTRY_OR_MODEL CreatureEntry, ModelId Set model from creature_template.entry(param1) OR set explicit modelId(param2). If param1 AND param2 both 0, demorph and revert to default model for creature.
4 ACTION_T_SOUND SoundId Plays Sound
5 ACTION_T_EMOTE EmoteId Does emote
6 ACTION_T_RANDOM_SAY UNUSED
@@ -93,7 +95,7 @@ Params are always read from Param1, then Param2, then Param3.
9 ACTION_T_RANDOM_SOUND SoundId1, SoundId2, SoundId3 Plays random sound between 3 params*
10 ACTION_T_RANDOM_EMOTE EmoteId1, EmoteId2, EmoteId3 Emotes random emote between 3 params
11 ACTION_T_CAST SpellId, Target, CastFlags Casts spell (param1) on target type (param2). Uses Cast Flags (specified below target types)
-12 ACTION_T_SUMMON CreatureID, Target, Duration Summons creature (param1) to attack target (param2) for (param3) duration. Spawns on top of current creature.
+12 ACTION_T_SUMMON CreatureID, Target, Duration Summons creature (param1) to attack target (param2) for (param3) duration. Spawns on top of current creature.
13 ACTION_T_THREAT_SINGLE_PCT Threat%, Target Modifies threat by (param1) on target type (param2)
14 ACTION_T_THREAT_ALL_PCT Threat% Modifies threat by (param1) on all targets (using -100% on all will result in full aggro dump)
15 ACTION_T_QUEST_EVENT QuestID, Target Calls AreaExploredOrEventHappens with (param1) for target type (Param2)
@@ -113,7 +115,7 @@ Params are always read from Param1, then Param2, then Param3.
29 ACTION_T_RANGED_MOVEMENT Distance, Angle Changes the movement generator type to a ranged type. Note: Default melee type can still be done with this. Specify 0 angle and 0 distance.
30 ACTION_T_RANDOM_PHASE PhaseId1, PhaseId2, PhaseId3 Sets the phase to the id between 3 params*
31 ACTION_T_RANDOM_PHASE_RANGE PhaseMin, PhaseMax Sets the phase to a random id (Phase = PhaseMin + rnd % PhaseMin-PhaseMax). PhaseMax must be greater than PhaseMin.
-32 ACTION_T_SUMMON CreatureID, Target, SummonID Summons creature (param1) to attack target (param2) at location specified by EventAI_Summons (param3).
+32 ACTION_T_SUMMON CreatureID, Target, SummonID Summons creature (param1) to attack target (param2) at location specified by EventAI_Summons (param3).
33 ACTION_T_KILLED_MONSTER CreatureID, Target Calls KilledMonster (param1) for target of type (param2)
34 ACTION_T_SET_INST_DATA Field, Data Calls ScriptedInstance::SetData with field (param1) and data (param2)
35 ACTION_T_SET_INST_DATA64 Field, Target Calls ScriptedInstance::SetData64 with field (param1) and data (param2) target's GUID.
@@ -135,7 +137,7 @@ BOTH - This event can trigger both in and out of combat.
Events that do not have lables on them are events that are directly involved with the in and out of combat state.
------------------
-0 = EVENT_T_TIMER:
+0 = EVENT_T_TIMER:
------------------
Parameter 1: InitialMin - Minumum Time used to calculate Random Initial Expire
Parameter 2: InitialMax - Maximum Time used to calculate Random Initial Expire
@@ -153,7 +155,7 @@ Parameter 2: InitialMax - Maximum Time used to calculate Random Initial Expire
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-OUT OF COMBAT ONLY! - Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4) from then on.
+OUT OF COMBAT ONLY! - Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4) from then on.
This is commonly used for events that occur and repeat outside of combat.
---------------
@@ -164,7 +166,7 @@ Parameter 2: HPMin% - Minimum HP% That this Event will Expire
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-BOTH - Expires when HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
+BOTH - Expires when HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
This is commonly used for events that trigger at a specific HP% (Such as Heal/Enrage Spells or NPC's that Flee).
-----------------
@@ -175,7 +177,7 @@ Parameter 2: ManaMin% - Minimum Mana% That this Event will Expire
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-BOTH - Expires once Mana% is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
+BOTH - Expires once Mana% is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
This is commonly used for events where an NPC low on Mana will do something (Such as stop casting spells and switch to melee).
------------------
@@ -189,7 +191,7 @@ This Event Expires upon initial aggro (does not repeat).
Parameter 1: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 2: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-COMBAT ONLY! - Expires upon killing a player. Will repeat every (Param1) and (Param2).
+COMBAT ONLY! - Expires upon killing a player. Will repeat every (Param1) and (Param2).
This Event Expires upon killing a player. It is commonly used for NPC's who yell or do something after killing a player.
------------------
@@ -201,7 +203,7 @@ This is commonly used for NPC's who have a yell on death or cast some kind if su
------------------
7 = EVENT_T_EVADE:
------------------
-This Event Expires upon the creature EnterEvadeMode().
+This Event Expires upon the creature EnterEvadeMode().
This is commonly used for NPC's who use phases, allows you to reset their phase to 0 upon evade to prevent possible strange behavior.
---------------------
@@ -224,7 +226,7 @@ Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
COMBAT ONLY! - Expires when the highest threat target distance is greater than (Param1) and less than (Param2). Will repeat every (Param3) and (Param4).
-This Event is commonly used for NPC's who have Ranged Combat and will Throw/Shoot between a certian distance.
+This Event is commonly used for NPC's who have Ranged Combat and will Throw/Shoot between a certian distance.
---------------------
10 = EVENT_T_OOC_LOS:
@@ -234,7 +236,7 @@ Parameter 2: NoFriendly - This Value is to Prevent this Action from Expiring Whe
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-OUT OF COMBAT ONLY! - Expires when a Player moves within visible distance to the NPC. Does not expire for Hostile Players if (Param1) is not 0. Does not expire for Friendly Players if (Param2) is not 0. Will repeat every (Param3) and (Param4). Does not expire for creatures or pets when they are in combat.
+OUT OF COMBAT ONLY! - Expires when a Player moves within visible distance to the NPC. Does not expire for Hostile Players if (Param1) is not 0. Does not expire for Friendly Players if (Param2) is not 0. Will repeat every (Param3) and (Param4). Does not expire for creatures or pets when they are in combat.
This Event is commonly used for NPC's who Do Something or Say Something when you walk past them Out of Combat.
---------------------
@@ -251,7 +253,7 @@ Parameter 2: HPMin% - Minimum HP% That this Event will Expire
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-COMBAT ONLY! - Expires when Current NPC's Target's HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
+COMBAT ONLY! - Expires when Current NPC's Target's HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
This Event is commonly used for NPC's who have a special ability (Like Execute) that only casts when a Player HP is low.
----------------------------
@@ -260,7 +262,7 @@ This Event is commonly used for NPC's who have a special ability (Like Execute)
Parameter 1: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 2: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-COMBAT ONLY! - Expires when the current target is casting a spell. Will repeat every (Param1) and (Param2).
+COMBAT ONLY! - Expires when the current target is casting a spell. Will repeat every (Param1) and (Param2).
This event is commonly used for NPC's who will cast a counter spell when their target starts to cast a spell.
-------------------------
@@ -282,7 +284,7 @@ Parameter 2: Radius - This is the Range in Yards the NPC will scan for nearby Fr
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-COMBAT ONLY! - Expires when a friendly unit is Crowd controlled within the given radius (param2). Will repeat every (Param3) and (Param4).
+COMBAT ONLY! - Expires when a friendly unit is Crowd controlled within the given radius (param2). Will repeat every (Param3) and (Param4).
This is commonly used for NPC's who can come to the resule of other Friendly NPC's if being Crowd Controlled
--------------------------
@@ -303,9 +305,15 @@ Parameter 1: CreatureId - The CreatureID that the NPC is watching to spawn to tr
Parameter 2: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 3: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-BOTH - Expires after creature with entry(Param1) is spawned or for all spawns if param1 = 0. Will repeat every (Param2) and (Param3) .
+BOTH - Expires after creature with entry(Param1) is spawned or for all spawns if param1 = 0. Will repeat every (Param2) and (Param3) .
This is commonly used for NPC's who will do something special once another NPC is summoned. Usually used is Complex Scripts or Special Events.
+---------------------------
+21 = EVENT_T_REACHED_HOME:
+---------------------------
+Expires only when creature has returned to it's home location after Evade. Out of combat event.
+Most commonly used to cast spells that can not be casted in EVENT_T_EVADE and other effects that does not fit in while still running back to spawn/home location.
+
=========================================
Action Types
@@ -322,15 +330,20 @@ Parameter 1: The entry of the text that the NPC should use from eventai_texts ta
Parameter 2: Optional. TextId can be defined in addition. The same apply to this as explained above, however eventAI will randomize between the two.
Parameter 3: Optional, if Parameter 2 exist. In this case, eventAI will randomize between three.
+See Text-tables.txt for documentation of eventai_texts-table.
+
------------------
-2 = ACTION_T_YELL:
+2 = ACTION_T_SET_FACTION:
------------------
-UNUSED Can be reused to create new action type
+Parameter 1: FactionId from Faction.dbc OR 0. Changes faction for creature. If 0, creature will revert to it's default faction if previously changed.
-----------------------
-3 = ACTION_T_TEXTEMOTE:
+3 = ACTION_T_MORPH_TO_ENTRY_OR_MODEL:
-----------------------
-UNUSED Can be reused to create new action type
+Parameter 1: Creature entry from creature_template. Action will then change to the model this creature are using.
+Parameter 2: If parameter 1 is 0, then this modelId will be used (in case parameter 1 exist, parameter 2 will not be used)
+
+If both parameter 1 and 2 is 0, the creature will DeMorph, and use it's default model.
-------------------
4 = ACTION_T_SOUND:
@@ -368,16 +381,16 @@ UNUSED Can be reused to create new action type
--------------------------
Parameter 1: The Sound ID to be played as Random Choice #1.
Parameter 2: The Sound ID to be played as Random Choice #2.
-Parameter 3: The Sound ID to be played as Random Choice #3.
+Parameter 3: The Sound ID to be played as Random Choice #3.
-Similar to the ACTION_T_SOUND action, it will choose at random a sound to play.
+Similar to the ACTION_T_SOUND action, it will choose at random a sound to play.
---------------------------
10 = ACTION_T_RANDOM_EMOTE:
---------------------------
Parameter 1: The Emote ID to be played as Random Choice #1.
Parameter 2: The Emote ID to be played as Random Choice #2.
-Parameter 3: The Emote ID to be played as Random Choice #3.
+Parameter 3: The Emote ID to be played as Random Choice #3.
Similar to the ACTION_T_EMOTE action, it will choose at random an Emote to Visually Perform.
@@ -388,26 +401,26 @@ Parameter 1: SpellId - The Spell ID to use for the NPC to cast. The value used i
Parameter 2: Target - The Target Type defining who the creature should cast the spell at. The value in this field needs to be a valid Target Type as specified in the reference tables below.
Parameter 3: CastFlags - See Table Below for Cast Flag Bitmask Values. If you are unsure what to set this value at leave it at 0.
-The creature will cast a spell specified by a spell ID on a target specified by the target type.
+The creature will cast a spell specified by a spell ID on a target specified by the target type.
This is commonly used for NPC's who cast spells.
---------------------
12 = ACTION_T_SUMMON:
---------------------
Parameter 1: CreatureID - The Creature Template ID to be Summoned. The value here needs to be a valid Creature Template ID.
-Parameter 2: Target - The Target Type defining who the Summoned creature will attack once spawned. The value in this field needs to be a valid Target Type as specified in the reference tables below.
-Parameter 3: Duration - The duration until the summoned creature should be unsummoned AFTER Combat ends. The value in this field is in milliseconds or 0.
+Parameter 2: Target - The Target Type defining who the Summoned creature will attack once spawned. The value in this field needs to be a valid Target Type as specified in the reference tables below.
+Parameter 3: Duration - The duration until the summoned creature should be unsummoned AFTER Combat ends. The value in this field is in milliseconds or 0.
-The NPC will Summon another creature at the same spot as itself that will attack the specified target.
+The NPC will Summon another creature at the same spot as itself that will attack the specified target.
NOTE: Almost all Creature Summons have proper Summon Spells that should be used when possible. This Action is a powerful last resort option only to be used if nothing else works.
NOTE: Using Target Type 0 will cause the Summoned creature to not attack anyone.
-NOTE: If Duration is set at 0, then the summoned creature will not despawn until it has died.
+NOTE: If Duration is set at 0, then the summoned creature will not despawn until it has died.
This is used as a manual way to force an NPC to Summon.
--------------------------------
13 = ACTION_T_THREAT_SINGLE_PCT:
--------------------------------
Parameter 1: Threat% - Threat percent that should be modified. The value in this field can range from -100 to +100. If it is negative, threat will be taken away and if positive, threat will be added.
-Parameter 2: Target - The Target Type defining on whom the threat change should occur. The value in this field needs to be a valid target type as specified in the reference tables below.
+Parameter 2: Target - The Target Type defining on whom the threat change should occur. The value in this field needs to be a valid target type as specified in the reference tables below.
This action will modify the threat of a target in the creature's threat list by the specified percent.
This is commonly used to allow an NPC to adjust the Threat to a single player.
@@ -415,7 +428,7 @@ This is commonly used to allow an NPC to adjust the Threat to a single player.
-----------------------------
14 = ACTION_T_THREAT_ALL_PCT:
-----------------------------
-Parameter 1: Threat% - The percent that should be used in modifying everyone's threat in the creature's threat list. The value here can range from -100 to +100.
+Parameter 1: Threat% - The percent that should be used in modifying everyone's threat in the creature's threat list. The value here can range from -100 to +100.
This action will modify the threat for everyone in the creature's threat list by the specified percent.
NOTE: Using -100 will cause the creature to reset everyone's threat to 0 so that everyone has the same amount of threat. It will NOT remove anyone from the threat list.
@@ -425,10 +438,10 @@ This is commonly used to allow an NPC to drop threat for all players to zero.
15 = ACTION_T_QUEST_EVENT:
--------------------------
Parameter 1: QuestID - The Quest Template ID. The value here must be a valid quest template ID. Furthermore, the quest should have SpecialFlags | 2 as it would need to be completed by an external event which is the activation of this action.
-Parameter 2: Target - The Target Type defining whom the quest should be completed for. The value in this field needs to be a valid target type as specified in the reference tables below.
+Parameter 2: Target - The Target Type defining whom the quest should be completed for. The value in this field needs to be a valid target type as specified in the reference tables below.
-This action will satisfy the external completion requirement for the quest for the specified target defined by the target type.
-NOTE: This action can only be used with player targets so it must be ensured that the target type will point to a player.
+This action will satisfy the external completion requirement for the quest for the specified target defined by the target type.
+NOTE: This action can only be used with player targets so it must be ensured that the target type will point to a player.
This is commonly used for Quests where only ONE player will gain credit for the quest.
-----------------------------
@@ -436,9 +449,9 @@ This is commonly used for Quests where only ONE player will gain credit for the
-----------------------------
Parameter 1: CreatureID - The Creature Template ID to be Summoned. The value here needs to be a valid Creature Template ID.
Parameter 2: SpellId - The Spell ID to use to simulate the cast. The value used in this field needs to be a valid Spell ID.
-Parameter 3: Target - The Target Type defining whom the quest credit should be given to. The value in this field needs to be a valid target type as specified in the reference tables below.
+Parameter 3: Target - The Target Type defining whom the quest credit should be given to. The value in this field needs to be a valid target type as specified in the reference tables below.
-This action will call CastedCreatureOrGO() function for the player. It can be used to give quest credit for casting a spell on the creature.
+This action will call CastedCreatureOrGO() function for the player. It can be used to give quest credit for casting a spell on the creature.
This is commonly used for NPC's who have a special requirement to have a Spell cast on them to complete a quest.
-----------------------------
@@ -446,7 +459,7 @@ This is commonly used for NPC's who have a special requirement to have a Spell c
-----------------------------
Parameter 1: Field_Number - The index of the Field Number to be changed. Use (http://wiki.udbforums.org/index.php/Character_data) for a list of indeces and what they control. Creatures only contain the OBJECT_FIELD_* and UNIT_FIELD_* fields. They do not contain the PLAYER_FIELD_* fields.
Parameter 2: Value - The new value to be put in the field.
-Parameter 3: Target - The Target Type defining for whom the unit field should be changed. The value in this field needs to be a valid target type as specified in the reference tables below.
+Parameter 3: Target - The Target Type defining for whom the unit field should be changed. The value in this field needs to be a valid target type as specified in the reference tables below.
When activated, this action can change the target's unit field values. More information on the field value indeces can be found at (http://wiki.udbforums.org/index.php/Character_data)
@@ -454,31 +467,31 @@ When activated, this action can change the target's unit field values. More info
18 = ACTION_T_SET_UNIT_FLAG:
----------------------------
Parameter 1: Flags - The flag(s) to be set. Multiple flags can be set by using bitwise-OR on them (adding them together).
-Parameter 2: Target - The Target Type defining for whom the flags should be changed. The value in this field needs to be a valid Target Type as specified in the reference tables below.
+Parameter 2: Target - The Target Type defining for whom the flags should be changed. The value in this field needs to be a valid Target Type as specified in the reference tables below.
-When activated, this action changes the target's flags by adding (turning on) more flags. For example, this action can make the creature unattackable/unselectable if the right flags are used.
+When activated, this action changes the target's flags by adding (turning on) more flags. For example, this action can make the creature unattackable/unselectable if the right flags are used.
-------------------------------
19 = ACTION_T_REMOVE_UNIT_FLAG:
-------------------------------
Parameter 1: Flags - The flag(s) to be removed. Multiple flags can be set by using bitwise-OR on them (adding them together).
-Parameter 2: Target - The target type defining for whom the flags should be changed. The value in this field needs to be a valid Target Type as specified in the reference tables below.
+Parameter 2: Target - The target type defining for whom the flags should be changed. The value in this field needs to be a valid Target Type as specified in the reference tables below.
-When activated, this action changes the target's flags by removing (turning off) flags. For example, this action can make the creature normal after it was unattackable/unselectable if the right flags are used.
+When activated, this action changes the target's flags by removing (turning off) flags. For example, this action can make the creature normal after it was unattackable/unselectable if the right flags are used.
--------------------------
20 = ACTION_T_AUTO_ATTACK:
--------------------------
-Parameter 1: AllowAutoAttack - If zero, then the creature will stop its melee attacks. If non-zero, then the creature will either continue its melee attacks (the action would then have no effect) or it will start its melee attacks on the target with the top threat if its melee attacks were previously stopped.
+Parameter 1: AllowAutoAttack - If zero, then the creature will stop its melee attacks. If non-zero, then the creature will either continue its melee attacks (the action would then have no effect) or it will start its melee attacks on the target with the top threat if its melee attacks were previously stopped.
-This action controls whether or not the creature should stop or start the auto melee attack.
+This action controls whether or not the creature should stop or start the auto melee attack.
NOTE: The ACID Dev Team has conformed to using either 0 or 1 for the Param values (0 = Stop Melee, 1 = Start Melee).
This is commonly used in combination with EVENT_T_RANGE and ACTION_T_COMBAT_MOVEMENT for Ranged Combat for Mages and Spell Casters.
------------------------------
21 = ACTION_T_COMBAT_MOVEMENT:
------------------------------
-Parameter 1: If zero, then the creature will stop moving towards its victim (if its victim gets out of melee range) and will be stationary. If non-zero, then the creature will either continue to follow its victim (the action would have no effect) or it will start to follow the target with the top threat if its movement was disabled before.
+Parameter 1: If zero, then the creature will stop moving towards its victim (if its victim gets out of melee range) and will be stationary. If non-zero, then the creature will either continue to follow its victim (the action would have no effect) or it will start to follow the target with the top threat if its movement was disabled before.
This action controls whether or not the creature will always move towards its target.
NOTE: The ACID Dev Team has conformed to using either 0 or 1 for the Param values. (0 = Stop Movement, 1 = Start Movement)
@@ -487,7 +500,7 @@ This is commonly used with EVENT_T_RANGE and ACTION_T_AUTO_ATTACK for NPC's who
------------------------
22 = ACTION_T_SET_PHASE:
------------------------
-Parameter 1: The new phase to set the creature in. This number must be an integer between 0 and 31. Numbers outside of that range will result in an error.
+Parameter 1: The new phase to set the creature in. This number must be an integer between 0 and 31. Numbers outside of that range will result in an error.
When activated, this action sets the creature's event to the specified value.
NOTE: The creature's current Phase is NOT reset at creature evade. You must manually set the phase back to 0 at EVENT_T_RESET.
@@ -497,20 +510,20 @@ This is commonly used for complex scripts with several phases and you need to sw
------------------------
23 = ACTION_T_INC_PHASE:
------------------------
-Parameter 1: Value - The number of phases to increase or decrease. Use negative values to decrease the current phase.
+Parameter 1: Value - The number of phases to increase or decrease. Use negative values to decrease the current phase.
-When activated, this action will increase (or decrease) the current creature's phase.
-NOTE: After increasing or decreasing the phase by this action, the current phase must NOT be lower than 0 or exceed 31.
+When activated, this action will increase (or decrease) the current creature's phase.
+NOTE: After increasing or decreasing the phase by this action, the current phase must NOT be lower than 0 or exceed 31.
This can be used instead of ACTION_T_SET_PHASE to change phases in scripts. Just a user friendly option for changing phases.
--------------------
24 = ACTION_T_EVADE:
--------------------
-When activated, the creature will immediately exit out of combat, clear its threat list, and move back to its spawn point. Basically, this action will reset the whole encounter.
+When activated, the creature will immediately exit out of combat, clear its threat list, and move back to its spawn point. Basically, this action will reset the whole encounter.
NOTE: All Param Values Are 0 for this Action.
-------------------
-25 = ACTION_T_FLEE:
+25 = ACTION_T_FLEE:
-------------------
When activated, the creature will try to flee from combat. Currently this is done by it casting a fear-like spell on itself called "Run Away". A Better Flee system is in Development but will take time before it is implimented.
NOTE: All Param Values Are 0 for this Action.
@@ -518,47 +531,47 @@ NOTE: All Param Values Are 0 for this Action.
------------------------------
26 = ACTION_T_QUEST_EVENT_ALL:
------------------------------
-Parameter 1: QuestId - The quest ID to finish for everyone.
+Parameter 1: QuestId - The quest ID to finish for everyone.
-This action does the same thing as the ACTION_T_QUEST_EVENT does but it does it for all players in the creature's threat list.
-NOTE: If a player is not in the NPC's threat list for whatever reason, he/she won't get the quest completed.
+This action does the same thing as the ACTION_T_QUEST_EVENT does but it does it for all players in the creature's threat list.
+NOTE: If a player is not in the NPC's threat list for whatever reason, he/she won't get the quest completed.
---------------------------------
27 = ACTION_T_CASTCREATUREGO_ALL:
---------------------------------
Parameter 1: QuestId - The quest template ID.
-Parameter 2: SpellId - The spell ID used to simulate the cast.
+Parameter 2: SpellId - The spell ID used to simulate the cast.
-This action does the same thing as the ACTION_T_CASTCREATUREGO does but it does it for all players in the creature's threat list.
-NOTE: If a player is not in its threat list for whatever reason, he/she won't receive the cast emulation.
+This action does the same thing as the ACTION_T_CASTCREATUREGO does but it does it for all players in the creature's threat list.
+NOTE: If a player is not in its threat list for whatever reason, he/she won't receive the cast emulation.
-----------------------------------
28 = ACTION_T_REMOVEAURASFROMSPELL:
-----------------------------------
Parameter 1: Target - The target type defining for whom the unit field should be changed. The value in this field needs to be a valid target type as specified in the reference tables below.
-Parameter 2: SpellId - The spell ID whose auras will be removed.
+Parameter 2: SpellId - The spell ID whose auras will be removed.
-This action will remove all auras from a specific spell from the target.
+This action will remove all auras from a specific spell from the target.
This is commonly used for NPC's who have an OOC Aura that is removed at combat start or a similar idea (Like Stealth or Shape Shift)
------------------------------
29 = ACTION_T_RANGED_MOVEMENT:
------------------------------
Parameter 1: Distance - The distance the mob should keep between it and its target.
-Parameter 2: Angle - The angle the mob should use.
+Parameter 2: Angle - The angle the mob should use.
-This action changes the movement type generator to ranged type using the specified values for angle and distance.
-NOTE: Specifying zero angle and distance will make it just melee instead.
-This is commonly used for NPC's who always attack at range and you can specify the distance they will maintain from the target.
+This action changes the movement type generator to ranged type using the specified values for angle and distance.
+NOTE: Specifying zero angle and distance will make it just melee instead.
+This is commonly used for NPC's who always attack at range and you can specify the distance they will maintain from the target.
---------------------------
30 = ACTION_T_RANDOM_PHASE:
---------------------------
Parameter 1: PhaseId1 - A possible random phase choice.
Parameter 2: PhaseId2 - A possible random phase choice.
-Parameter 3: PhaseId3 - A possible random phase choice.
+Parameter 3: PhaseId3 - A possible random phase choice.
-Randomly sets the phase to one from the three parameter choices.
+Randomly sets the phase to one from the three parameter choices.
NOTE: Use -1 to specify that if this param is picked to do nothing. Random is constant between actions within an event. So if you have a random Yell and a random Sound they will match up (ex: param2 with param2)
NOTE 2: PLEASE NOTE THAT EACH OF THE PARAM VALUES ARE ACTUAL PHASE NUMBERS NOT THE INVERSE PHASE MASK VALUE.
This is commonly used for Spellcasting NPC's who on Aggro may select at random a school of spells to use for the fight. Use this if you have up to 3 phases used, otherwise use Action 31 for more then 3 phases.
@@ -567,9 +580,9 @@ This is commonly used for Spellcasting NPC's who on Aggro may select at random a
31 = ACTION_T_RANDOM_PHASE_RANGE:
---------------------------------
Parameter 1: PhaseMin - The minimum of the phase range.
-Parameter 2: PhaseMax - The maximum of the phase range. The number here must be greater than PhaseMin.
+Parameter 2: PhaseMax - The maximum of the phase range. The number here must be greater than PhaseMin.
-Randomly sets the phase between a range of phases controlled by the parameters. Sets the phase to a random id (Phase = PhaseMin + rnd % PhaseMin-PhaseMax).
+Randomly sets the phase between a range of phases controlled by the parameters. Sets the phase to a random id (Phase = PhaseMin + rnd % PhaseMin-PhaseMax).
NOTE: PhaseMax must be greater than PhaseMin.
NOTE 2: PLEASE NOTE THAT EACH OF THE PARAM VALUES ARE ACTUAL PHASE NUMBERS NOT THE INVERSE PHASE MASK VALUE.
This is commonly used for Spellcasting NPC's who on Aggro may select at random a school of spells to use for the fight. Use this if you have MORE then 3 phases used, otherwise use Action 30.
@@ -579,9 +592,9 @@ This is commonly used for Spellcasting NPC's who on Aggro may select at random a
---------------------
Parameter 1: CreatureID - The creature template ID to be summoned. The value here needs to be a valid creature template ID.
Parameter 2: Target - The target type defining who the summoned creature will attack. The value in this field needs to be a valid target type as specified in the reference tables below. NOTE: Using target type 0 will cause the summoned creature to not attack anyone.
-Parameter 3: SummonID - The summon ID from the eventai_summons table controlling the position (and spawntime) where the summoned mob should be spawned at.
+Parameter 3: SummonID - The summon ID from the eventai_summons table controlling the position (and spawntime) where the summoned mob should be spawned at.
-Summons creature (param1) to attack target (param2) at location specified by EventAI_Summons (param3).
+Summons creature (param1) to attack target (param2) at location specified by EventAI_Summons (param3).
NOTE: Param3 Value is the ID Value used for the entry used in EventAI_Summons for this action. You MUST have an EventAI_Summons entry to use this action.
This is commonly used for NPC's who need to Summon a creature at a specific location. (Normally used for complex events)
@@ -589,9 +602,9 @@ This is commonly used for NPC's who need to Summon a creature at a specific loca
33 = ACTION_T_KILLED_MONSTER:
-----------------------------
Parameter 1: CreatureID - The creature template ID. The value here must be a valid creature template ID.
-Parameter 2: Target - The target type defining whom the quest kill count should be given to. The value in this field needs to be a valid target type as specified in the reference tables below.
+Parameter 2: Target - The target type defining whom the quest kill count should be given to. The value in this field needs to be a valid target type as specified in the reference tables below.
-When activated, this action will call KilledMonster() function for the player. It can be used to give creature credit for killing a creature. In general if the quest is set to be accompished on different creatures (e.g. "Credit" templates).
+When activated, this action will call KilledMonster() function for the player. It can be used to give creature credit for killing a creature. In general if the quest is set to be accompished on different creatures (e.g. "Credit" templates).
NOTE: It can be ANY creature including certain quest specific triggers
This is commonly used for giving the player Quest Credits for NPC kills (Many NPC's may use the same CreatureID for the Kill Credit)
@@ -601,7 +614,7 @@ This is commonly used for giving the player Quest Credits for NPC kills (Many NP
Parameter 1: Field - The field to change in the instance script. Again, this field needs to be a valid field that has been already defined in the instance's script.
Parameter 2: Data - The value to put at that field index.
-Sets data for the instance. Note that this will only work when the creature is inside an instantiable zone that has a valid script (ScriptedInstance) assigned.
+Sets data for the instance. Note that this will only work when the creature is inside an instantiable zone that has a valid script (ScriptedInstance) assigned.
NOTE: Param1 Value is located in "def_<instance name>.h" SD2 File and Param2 value is generally found in the "sc_instance.h" file in SD2
This is commonly used to link an ACID script with a SD2 C++ Script. You make make things happen like opening doors on specific events that happen. ACID Just triggers the C++ Script to function.
@@ -609,30 +622,30 @@ This is commonly used to link an ACID script with a SD2 C++ Script. You make mak
35 = ACTION_T_SET_INST_DATA64:
------------------------------
Parameter 1: Field - The field to change in the instance script. Again, this field needs to be a valid field that has been already defined in the instance's script.
-Parameter 2: Target - The target type to use to get the GUID that will be stored at the field index. The value in this field needs to be a valid target type as specified in the reference tables below.
+Parameter 2: Target - The target type to use to get the GUID that will be stored at the field index. The value in this field needs to be a valid target type as specified in the reference tables below.
-Sets GUID (64 bits) data for the instance based on the target. Note that this will only work when the creature is inside an instantiable zone that has a valid script (ScriptedInstance) assigned.
+Sets GUID (64 bits) data for the instance based on the target. Note that this will only work when the creature is inside an instantiable zone that has a valid script (ScriptedInstance) assigned.
Calls ScriptedInstance::SetData64 with field (param1) and data (param2) target's GUID.
------------------------------
36 = ACTION_T_UPDATE_TEMPLATE:
------------------------------
Parameter 1: TemplateId - The creature template ID. The value here must be a valid creature template ID.
-Parameter 2: Team - Use model_id from team : Alliance(0) or Horde (1).
+Parameter 2: Team - Use model_id from team : Alliance(0) or Horde (1).
-This function temporarily changes creature entry to new entry, display is changed, loot is changed, but AI is not changed. At respawn creature will be reverted to original entry.
+This function temporarily changes creature entry to new entry, display is changed, loot is changed, but AI is not changed. At respawn creature will be reverted to original entry.
Changes the creature to a new creature template of (param1) with team = Alliance if (param2) = false or Horde if (param2) = true
------------------
37 = ACTION_T_DIE:
------------------
Kills the creature
-This is commonly used if you need to Instakill the creature for one reason or another.
+This is commonly used if you need to Instakill the creature for one reason or another.
--------------------------------
38 = ACTION_T_ZONE_COMBAT_PULSE:
--------------------------------
-Places all players within the instance into combat with the creature. Only works in combat and only works inside of instances.
+Places all players within the instance into combat with the creature. Only works in combat and only works inside of instances.
=========================================
@@ -666,7 +679,7 @@ Another example: the number "5" (101 in Binary, selecting first and third option
4 16 CAST_FORCE_TARGET_SELF Forces the target to cast this spell on itself
5 32 CAST_AURA_NOT_PRESENT Only casts the spell on the target if the target does not have the aura from that spell on itself already.
-NOTE: You can add the numbers in the decimal column to combine flags.
+NOTE: You can add the numbers in the decimal column to combine flags.
For example if you wanted to use CAST_NO_MELEE_IF_OOM(8) and CAST_TRIGGERED(2) you would simply use 10 in the cast flags field (8 + 2 = 10).
=========================================
@@ -684,4 +697,4 @@ Below is the list of current Event Flags that EventAI can handle. Event flags ar
6 64
7 128 EFLAG_DEBUG_ONLY Prevents events from occuring on Release builds of ScriptDev2. Useful for testing new features.
-NOTE: You can add the numbers in the decimal column to combine flags.
+NOTE: You can add the numbers in the decimal column to combine flags. \ No newline at end of file
diff --git a/src/bindings/scripts/docs/Text-tables.txt b/src/bindings/scripts/docs/Text-tables.txt
index 6db1ce9d852..2a539a72874 100644
--- a/src/bindings/scripts/docs/Text-tables.txt
+++ b/src/bindings/scripts/docs/Text-tables.txt
@@ -52,8 +52,8 @@ Below is the list of current Text types that texts tables can handle. These were
-----------------------------------------------------------
0 CHAT_TYPE_SAY This type sets the text to be displayed as a Say (Speech Bubble).
1 CHAT_TYPE_YELL This type sets the text to be displayed as a Yell (Red Speech Bubble) and usually has a matching Sound ID.
-2 CHAT_TYPE_TEXT_EMOTE This type sets the text to be displayed as a text emote in orange in the chat log.
-3 CHAT_TYPE_BOSS_EMOTE This type sets the text to be displayed as a text emote in orange in the chat log (Used only for specific Bosses).
+2 CHAT_TYPE_TEXT_EMOTE This type sets the text to be displayed as a text emote in orange in the chat log.
+3 CHAT_TYPE_BOSS_EMOTE This type sets the text to be displayed as a text emote in orange in the chat log (Used only for specific Bosses).
4 CHAT_TYPE_WHISPER This type sets the text to be displayed as a whisper to the player in the chat log.
5 CHAT_TYPE_BOSS_WHISPER This type sets the text to be displayed as a whisper to the player in the chat log (Used only for specific Bosses).
@@ -65,7 +65,7 @@ Below is the list of current Language types that are allowed.
This is the Race Language that the text is native to (So it will display properly)
# Internal Name Description
------------------------------------------------------------
+-----------------------------------------------------------
0 UNIVERSAL Text in this language is understood by ALL Races.
1 ORCISH Text in this language is understood ONLY by Horde Races.
2 DARNASSIAN Text in this language is understood ONLY by the Night Elf Race.
diff --git a/src/bindings/scripts/include/precompiled.cpp b/src/bindings/scripts/include/precompiled.cpp
index 9753d023374..75bfae9e1c4 100644
--- a/src/bindings/scripts/include/precompiled.cpp
+++ b/src/bindings/scripts/include/precompiled.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
diff --git a/src/bindings/scripts/include/precompiled.h b/src/bindings/scripts/include/precompiled.h
index cd6d68f9f31..2c36cc924e0 100644
--- a/src/bindings/scripts/include/precompiled.h
+++ b/src/bindings/scripts/include/precompiled.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
@@ -12,6 +12,7 @@
#include "GridNotifiersImpl.h"
#include "Unit.h"
#include "GameObject.h"
+#include "TemporarySummon.h"
#include "sc_creature.h"
#include "sc_gossip.h"
#include "sc_instance.h"
diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp
index 0615d865f9f..fed04c5303c 100644
--- a/src/bindings/scripts/include/sc_creature.cpp
+++ b/src/bindings/scripts/include/sc_creature.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+/* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* Thanks to the original authors: ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
@@ -16,52 +16,54 @@ struct TSpellSummary {
uint8 Effects; // set of enum SelectEffect
} *SpellSummary;
-void SummonList::Despawn(Creature *summon)
+void SummonList::DoAction(uint32 entry, uint32 info)
{
- uint64 guid = summon->GetGUID();
- for(iterator i = begin(); i != end(); ++i)
+ for(iterator i = begin(); i != end();)
{
- if(*i == guid)
- {
- erase(i);
- return;
- }
+ Creature *summon = Unit::GetCreature(*m_creature, *i);
+ ++i;
+ if(summon && summon->IsAIEnabled)
+ summon->AI()->DoAction(info);
}
}
void SummonList::DespawnEntry(uint32 entry)
{
- for(iterator i = begin(); i != end(); ++i)
+ for(iterator i = begin(); i != end();)
{
- if(Creature *summon = Unit::GetCreature(*m_creature, *i))
+ Creature *summon = Unit::GetCreature(*m_creature, *i);
+ if(!summon)
+ erase(i++);
+ else if(summon->GetEntry() == entry)
{
- if(summon->GetEntry() == entry)
- {
- summon->setDeathState(JUST_DIED);
- summon->RemoveCorpse();
- i = erase(i);
- --i;
- }
+ erase(i++);
+ summon->setDeathState(JUST_DIED);
+ summon->RemoveCorpse();
}
else
- {
- i = erase(i);
- --i;
- }
+ ++i;
}
}
void SummonList::DespawnAll()
{
- for(iterator i = begin(); i != end(); ++i)
+ while(!empty())
{
- if(Creature *summon = Unit::GetCreature(*m_creature, *i))
+ Creature *summon = Unit::GetCreature(*m_creature, *begin());
+ if(!summon)
+ erase(begin());
+ else
{
+ erase(begin());
summon->setDeathState(JUST_DIED);
summon->RemoveCorpse();
}
}
- clear();
+}
+
+ScriptedAI::ScriptedAI(Creature* creature) : CreatureAI(creature), m_creature(creature), IsFleeing(false)
+{
+ HeroicMode = m_creature->GetMap()->IsHeroic();
}
void ScriptedAI::AttackStart(Unit* who, bool melee)
@@ -71,14 +73,6 @@ void ScriptedAI::AttackStart(Unit* who, bool melee)
if (m_creature->Attack(who, melee))
{
- m_creature->AddThreat(who, 0.0f);
-
- if (!InCombat)
- {
- InCombat = true;
- Aggro(who);
- }
-
if(melee)
DoStartMovement(who);
else
@@ -93,14 +87,6 @@ void ScriptedAI::AttackStart(Unit* who)
if (m_creature->Attack(who, true))
{
- m_creature->AddThreat(who, 0.0f);
-
- if (!InCombat)
- {
- InCombat = true;
- Aggro(who);
- }
-
DoStartMovement(who);
}
}
@@ -108,9 +94,9 @@ void ScriptedAI::AttackStart(Unit* who)
void ScriptedAI::UpdateAI(const uint32 diff)
{
//Check if we have a current target
- if (m_creature->isAlive() && UpdateVictim())
+ if (UpdateVictim())
{
- if (m_creature->isAttackReady() )
+ if (m_creature->isAttackReady())
{
//If we are within range melee the target
if (m_creature->IsWithinMeleeRange(m_creature->getVictim()))
@@ -142,13 +128,11 @@ void ScriptedAI::EnterEvadeMode()
m_creature->GetMotionMaster()->MoveTargetedHome();
}
- InCombat = false;
Reset();
}
void ScriptedAI::JustRespawned()
{
- InCombat = false;
Reset();
}
@@ -206,23 +190,23 @@ void ScriptedAI::DoSay(const char* text, uint32 language, Unit* target, bool Say
{
if (target)
{
- m_creature->Say(text, language, target->GetGUID());
+ m_creature->MonsterSay(text, language, target->GetGUID());
if(SayEmote)
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
}
- else m_creature->Say(text, language, 0);
+ else m_creature->MonsterSay(text, language, 0);
}
void ScriptedAI::DoYell(const char* text, uint32 language, Unit* target)
{
- if (target) m_creature->Yell(text, language, target->GetGUID());
- else m_creature->Yell(text, language, 0);
+ if (target) m_creature->MonsterYell(text, language, target->GetGUID());
+ else m_creature->MonsterYell(text, language, 0);
}
void ScriptedAI::DoTextEmote(const char* text, Unit* target, bool IsBossEmote)
{
- if (target) m_creature->TextEmote(text, target->GetGUID(), IsBossEmote);
- else m_creature->TextEmote(text, 0, IsBossEmote);
+ if (target) m_creature->MonsterTextEmote(text, target->GetGUID(), IsBossEmote);
+ else m_creature->MonsterTextEmote(text, 0, IsBossEmote);
}
void ScriptedAI::DoWhisper(const char* text, Unit* reciever, bool IsBossWhisper)
@@ -230,24 +214,21 @@ void ScriptedAI::DoWhisper(const char* text, Unit* reciever, bool IsBossWhisper)
if (!reciever || reciever->GetTypeId() != TYPEID_PLAYER)
return;
- m_creature->Whisper(text, reciever->GetGUID(), IsBossWhisper);
+ m_creature->MonsterWhisper(text, reciever->GetGUID(), IsBossWhisper);
}
-void ScriptedAI::DoPlaySoundToSet(Unit* unit, uint32 sound)
+void ScriptedAI::DoPlaySoundToSet(Unit* pSource, uint32 uiSoundId)
{
- if (!unit)
+ if (!pSource)
return;
- if (!GetSoundEntriesStore()->LookupEntry(sound))
+ if (!GetSoundEntriesStore()->LookupEntry(uiSoundId))
{
- error_log("TSCR: Invalid soundId %u used in DoPlaySoundToSet (by unit TypeId %u, guid %u)", sound, unit->GetTypeId(), unit->GetGUID());
+ error_log("TSCR: Invalid soundId %u used in DoPlaySoundToSet (by unit TypeId %u, guid %u)", uiSoundId, pSource->GetTypeId(), pSource->GetGUID());
return;
}
- WorldPacket data(4);
- data.SetOpcode(SMSG_PLAY_SOUND);
- data << uint32(sound);
- unit->SendMessageToSet(&data,false);
+ pSource->PlayDirectSound(uiSoundId);
}
Creature* ScriptedAI::DoSpawnCreature(uint32 id, float x, float y, float z, float angle, uint32 type, uint32 despawntime)
@@ -437,11 +418,9 @@ SpellEntry const* ScriptedAI::SelectSpell(Unit* Target, int32 School, int32 Mech
return false;
//Using the extended script system we first create a list of viable spells
- SpellEntry const* Spell[4];
- Spell[0] = 0;
- Spell[1] = 0;
- Spell[2] = 0;
- Spell[3] = 0;
+ SpellEntry const* Spell[CREATURE_MAX_SPELLS];
+ for (uint8 i=0;i<CREATURE_MAX_SPELLS;i++)
+ Spell[i] = 0;
uint32 SpellCount = 0;
@@ -449,7 +428,7 @@ SpellEntry const* ScriptedAI::SelectSpell(Unit* Target, int32 School, int32 Mech
SpellRangeEntry const* TempRange;
//Check if each spell is viable(set it to null if not)
- for (uint32 i = 0; i < 4; i++)
+ for (uint32 i = 0; i < CREATURE_MAX_SPELLS; i++)
{
TempSpell = GetSpellStore()->LookupEntry(m_creature->m_spells[i]);
@@ -493,13 +472,13 @@ SpellEntry const* ScriptedAI::SelectSpell(Unit* Target, int32 School, int32 Mech
continue;
//Check if the spell meets our range requirements
- if (RangeMin && TempRange->maxRange < RangeMin)
+ if (RangeMin && m_creature->GetSpellMinRangeForTarget(Target, TempRange) < RangeMin)
continue;
- if (RangeMax && TempRange->maxRange > RangeMax)
+ if (RangeMax && m_creature->GetSpellMaxRangeForTarget(Target, TempRange) > RangeMax)
continue;
//Check if our target is in range
- if (m_creature->IsWithinDistInMap(Target, TempRange->minRange) || !m_creature->IsWithinDistInMap(Target, TempRange->maxRange))
+ if (m_creature->IsWithinDistInMap(Target, m_creature->GetSpellMinRangeForTarget(Target, TempRange)) || !m_creature->IsWithinDistInMap(Target, m_creature->GetSpellMaxRangeForTarget(Target, TempRange)))
continue;
//All good so lets add it to the spell list
@@ -521,11 +500,11 @@ bool ScriptedAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered)
return false;
//Silenced so we can't cast
- if (!Triggered && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
+ if (!Triggered && me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
return false;
//Check for power
- if (!Triggered && m_creature->GetPower((Powers)Spell->powerType) < Spell->manaCost)
+ if (!Triggered && me->GetPower((Powers)Spell->powerType) < Spell->manaCost)
return false;
SpellRangeEntry const *TempRange = NULL;
@@ -537,20 +516,21 @@ bool ScriptedAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered)
return false;
//Unit is out of range of this spell
- if (m_creature->GetDistance(Target) > TempRange->maxRange || m_creature->GetDistance(Target) < TempRange->minRange)
+ if (me->GetDistance(Target) > me->GetSpellMaxRangeForTarget(Target, TempRange)
+ || me->GetDistance(Target) < me->GetSpellMinRangeForTarget(Target, TempRange))
return false;
return true;
}
-float GetSpellMaxRange(uint32 id)
+float GetSpellMaxRangeForHostile(uint32 id)
{
SpellEntry const *spellInfo = GetSpellStore()->LookupEntry(id);
if(!spellInfo) return 0;
SpellRangeEntry const *range = GetSpellRangeStore()->LookupEntry(spellInfo->rangeIndex);
if(!range) return 0;
- return range->maxRange;
+ return range->maxRangeHostile;
}
void FillSpellSummary()
@@ -583,7 +563,7 @@ void FillSpellSummary()
//Spell targets AoE at enemy
if ( TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_AROUND_CASTER ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_DEST_CASTER ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED )
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_ENEMY-1);
@@ -592,7 +572,7 @@ void FillSpellSummary()
TempSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_ENEMY_COORDINATES ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_AROUND_CASTER ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_DEST_CASTER ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED )
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_ENEMY-1);
@@ -605,7 +585,7 @@ void FillSpellSummary()
//Spell targets aoe friends
if ( TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||
TempSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_AROUND_CASTER)
+ TempSpell->EffectImplicitTargetA[j] == TARGET_DEST_CASTER)
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_FRIEND-1);
//Spell targets any friend(or self)
@@ -614,7 +594,7 @@ void FillSpellSummary()
TempSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||
TempSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_AROUND_CASTER)
+ TempSpell->EffectImplicitTargetA[j] == TARGET_DEST_CASTER)
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_FRIEND-1);
//Make sure that this spell includes a damage effect
@@ -638,39 +618,6 @@ void FillSpellSummary()
}
}
-void ScriptedAI::DoZoneInCombat(Unit* pUnit)
-{
- if (!pUnit)
- pUnit = m_creature;
-
- Map *map = pUnit->GetMap();
-
- if (!map->IsDungeon()) //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated
- {
- error_log("TSCR: DoZoneInCombat call for map that isn't an instance (pUnit entry = %d)", pUnit->GetTypeId() == TYPEID_UNIT ? ((Creature*)pUnit)->GetEntry() : 0);
- return;
- }
-
- if (!pUnit->CanHaveThreatList() || pUnit->getThreatManager().isThreatListEmpty())
- {
- error_log("TSCR: DoZoneInCombat called for creature that either cannot have threat list or has empty threat list (pUnit entry = %d)", pUnit->GetTypeId() == TYPEID_UNIT ? ((Creature*)pUnit)->GetEntry() : 0);
-
- return;
- }
-
- Map::PlayerList const &PlayerList = map->GetPlayers();
- for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- {
- if (Player* i_pl = i->getSource())
- if (i_pl->isAlive())
- {
- pUnit->SetInCombatWith(i_pl);
- i_pl->SetInCombatWith(pUnit);
- pUnit->AddThreat(i_pl, 0.0f);
- }
- }
-}
-
void ScriptedAI::DoResetThreat()
{
if (!m_creature->CanHaveThreatList() || m_creature->getThreatManager().isThreatListEmpty())
@@ -741,7 +688,7 @@ Unit* FindCreature(uint32 entry, float range, Unit* Finder)
return NULL;
Creature* target = NULL;
Trinity::AllCreaturesOfEntryInRange check(Finder, entry, range);
- Trinity::CreatureSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(target, check);
+ Trinity::CreatureSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(Finder, target, check);
Finder->VisitNearbyObject(range, searcher);
return target;
}
@@ -752,7 +699,7 @@ GameObject* FindGameObject(uint32 entry, float range, Unit* Finder)
return NULL;
GameObject* target = NULL;
Trinity::AllGameObjectsWithEntryInGrid go_check(entry);
- Trinity::GameObjectSearcher<Trinity::AllGameObjectsWithEntryInGrid> searcher(target, go_check);
+ Trinity::GameObjectSearcher<Trinity::AllGameObjectsWithEntryInGrid> searcher(Finder, target, go_check);
Finder->VisitNearbyGridObject(range, searcher);
return target;
}
@@ -761,7 +708,7 @@ Unit* ScriptedAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
{
Unit* pUnit = NULL;
Trinity::MostHPMissingInRange u_check(m_creature, range, MinHPDiff);
- Trinity::UnitLastSearcher<Trinity::MostHPMissingInRange> searcher(pUnit, u_check);
+ Trinity::UnitLastSearcher<Trinity::MostHPMissingInRange> searcher(m_creature, pUnit, u_check);
m_creature->VisitNearbyObject(range, searcher);
return pUnit;
}
@@ -770,7 +717,7 @@ std::list<Creature*> ScriptedAI::DoFindFriendlyCC(float range)
{
std::list<Creature*> pList;
Trinity::FriendlyCCedInRange u_check(m_creature, range);
- Trinity::CreatureListSearcher<Trinity::FriendlyCCedInRange> searcher(pList, u_check);
+ Trinity::CreatureListSearcher<Trinity::FriendlyCCedInRange> searcher(m_creature, pList, u_check);
m_creature->VisitNearbyObject(range, searcher);
return pList;
}
@@ -779,11 +726,36 @@ std::list<Creature*> ScriptedAI::DoFindFriendlyMissingBuff(float range, uint32 s
{
std::list<Creature*> pList;
Trinity::FriendlyMissingBuffInRange u_check(m_creature, range, spellid);
- Trinity::CreatureListSearcher<Trinity::FriendlyMissingBuffInRange> searcher(pList, u_check);
+ Trinity::CreatureListSearcher<Trinity::FriendlyMissingBuffInRange> searcher(m_creature, pList, u_check);
m_creature->VisitNearbyObject(range, searcher);
return pList;
}
+void ScriptedAI::SetEquipmentSlots(bool bLoadDefault, int32 uiMainHand, int32 uiOffHand, int32 uiRanged)
+{
+ if (bLoadDefault)
+ {
+ if (CreatureInfo const* pInfo = GetCreatureTemplateStore(m_creature->GetEntry()))
+ m_creature->LoadEquipment(pInfo->equipmentId,true);
+
+ return;
+ }
+
+ if (uiMainHand >= 0)
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(uiMainHand));
+
+ if (uiOffHand >= 0)
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(uiOffHand));
+
+ if (uiRanged >= 0)
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, uint32(uiRanged));
+}
+
+void ScriptedAI::SetSheathState(SheathState newState)
+{
+ m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, newState);
+}
+
/*void Scripted_NoMovementAI::MoveInLineOfSight(Unit *who)
{
if( !m_creature->getVictim() && m_creature->canAttack(who) && ( m_creature->IsHostileTo( who )) && who->isInAccessiblePlaceFor(m_creature) )
@@ -807,14 +779,6 @@ void Scripted_NoMovementAI::AttackStart(Unit* who)
if (m_creature->Attack(who, true))
{
- m_creature->AddThreat(who, 0.0f);
-
- if (!InCombat)
- {
- InCombat = true;
- Aggro(who);
- }
-
DoStartNoMovement(who);
}
}
diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h
index 40a331b7d6b..dfdb23eeb14 100644
--- a/src/bindings/scripts/include/sc_creature.h
+++ b/src/bindings/scripts/include/sc_creature.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+/* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* Thanks to the original authors: ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
@@ -11,16 +11,19 @@
#include "CreatureAI.h"
#include "Creature.h"
-float GetSpellMaxRange(uint32 id);
+#define HEROIC(n,h) (HeroicMode ? h : n)
-class SummonList : std::list<uint64>
+float GetSpellMaxRangeForHostile(uint32 id);
+
+class SummonList : private std::list<uint64>
{
public:
- SummonList(Creature* creature) : m_creature(creature) {}
- void Summon(Creature *summon) {push_back(summon->GetGUID());}
- void Despawn(Creature *summon);
+ explicit SummonList(Creature* creature) : m_creature(creature) {}
+ void Summon(Creature *summon) { push_back(summon->GetGUID()); }
+ void Despawn(Creature *summon) { remove(summon->GetGUID()); }
void DespawnEntry(uint32 entry);
void DespawnAll();
+ void DoAction(uint32 entry, uint32 info);
private:
Creature *m_creature;
};
@@ -31,9 +34,19 @@ Unit* FindCreature(uint32 entry, float range, Unit* Finder);
//Get a single gameobject of given entry
GameObject* FindGameObject(uint32 entry, float range, Unit* Finder);
+struct PointMovement
+{
+ uint32 m_uiCreatureEntry;
+ uint32 m_uiPointId;
+ float m_fX;
+ float m_fY;
+ float m_fZ;
+ uint32 m_uiWaitTime;
+};
+
struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI
{
- ScriptedAI(Creature* creature) : CreatureAI(creature), m_creature(creature), InCombat(false), IsFleeing(false) {}
+ explicit ScriptedAI(Creature* creature);
~ScriptedAI() {}
//*************
@@ -87,12 +100,11 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI
//Pointer to creature we are manipulating
Creature* m_creature;
- //Bool for if we are in combat or not
- bool InCombat;
-
//For fleeing
bool IsFleeing;
+ bool HeroicMode;
+
//*************
//Pure virtual functions
//*************
@@ -101,7 +113,7 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI
void Reset() {}
//Called at creature aggro either by MoveInLOS or Attack Start
- virtual void Aggro(Unit*) = 0;
+ void EnterCombat(Unit*) {}
//*************
//AI Helper Functions
@@ -138,9 +150,6 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI
//Plays a sound to all nearby players
void DoPlaySoundToSet(Unit* unit, uint32 sound);
- //Places the entire map into combat with creature
- void DoZoneInCombat(Unit* pUnit = 0);
-
//Drops all threat to 0%. Does not remove players from the threat list
void DoResetThreat();
@@ -172,11 +181,17 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI
Unit* SelectUnit(SelectAggroTarget target, uint32 position, float dist, bool playerOnly);
void SelectUnitList(std::list<Unit*> &targetList, uint32 num, SelectAggroTarget target, float dist, bool playerOnly);
+ bool HealthBelowPct(uint32 pct) const { return me->GetHealth() * 100 < m_creature->GetMaxHealth() * pct; }
+
//Returns spells that meet the specified criteria from the creatures spell list
SpellEntry const* SelectSpell(Unit* Target, int32 School, int32 Mechanic, SelectTarget Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effect);
//Checks if you can cast the specified spell
bool CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered = false);
+
+ void SetEquipmentSlots(bool bLoadDefault, int32 uiMainHand = EQUIP_NO_CHANGE, int32 uiOffHand = EQUIP_NO_CHANGE, int32 uiRanged = EQUIP_NO_CHANGE);
+
+ void SetSheathState(SheathState newState);
};
struct TRINITY_DLL_DECL Scripted_NoMovementAI : public ScriptedAI
@@ -196,7 +211,7 @@ struct TRINITY_DLL_DECL NullCreatureAI : public ScriptedAI
~NullCreatureAI() {}
void Reset() {}
- void Aggro(Unit*) {}
+ void EnterCombat(Unit*) {}
void MoveInLineOfSight(Unit *) {}
void AttackStart(Unit *) {}
void EnterEvadeMode() {}
diff --git a/src/bindings/scripts/include/sc_gossip.h b/src/bindings/scripts/include/sc_gossip.h
index 74bc93694af..9665a7e1123 100644
--- a/src/bindings/scripts/include/sc_gossip.h
+++ b/src/bindings/scripts/include/sc_gossip.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+/* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* Thanks to the original authors: ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
@@ -16,29 +16,38 @@
#define GOSSIP_TEXT_BROWSE_GOODS "I'd like to browse your goods."
#define GOSSIP_TEXT_TRAIN "Train me!"
-#define GOSSIP_TEXT_BANK "The Bank"
-#define GOSSIP_TEXT_WINDRIDER "Wind rider master"
-#define GOSSIP_TEXT_GRYPHON "Gryphon Master"
-#define GOSSIP_TEXT_BATHANDLER "Bat Handler"
-#define GOSSIP_TEXT_HIPPOGRYPH "Hippogryph Master"
-#define GOSSIP_TEXT_FLIGHTMASTER "Flight Master"
-#define GOSSIP_TEXT_AUCTIONHOUSE "Auction House"
-#define GOSSIP_TEXT_GUILDMASTER "Guild Master"
-#define GOSSIP_TEXT_INN "The Inn"
-#define GOSSIP_TEXT_MAILBOX "Mailbox"
-#define GOSSIP_TEXT_STABLEMASTER "Stable Master"
-#define GOSSIP_TEXT_WEAPONMASTER "Weapons Trainer"
-#define GOSSIP_TEXT_BATTLEMASTER "Battlemaster"
-#define GOSSIP_TEXT_CLASSTRAINER "Class Trainer"
-#define GOSSIP_TEXT_PROFTRAINER "Profession Trainer"
-#define GOSSIP_TEXT_OFFICERS "The officers` lounge"
+#define GOSSIP_TEXT_BANK "The bank"
+#define GOSSIP_TEXT_IRONFORGE_BANK "The bank of Ironforge"
+#define GOSSIP_TEXT_STORMWIND_BANK "The bank of Stormwind"
+#define GOSSIP_TEXT_WINDRIDER "The wind rider master"
+#define GOSSIP_TEXT_GRYPHON "The gryphon master"
+#define GOSSIP_TEXT_BATHANDLER "The bat handler"
+#define GOSSIP_TEXT_HIPPOGRYPH "The hippogryph master"
+#define GOSSIP_TEXT_ZEPPLINMASTER "The zeppelin master"
+#define GOSSIP_TEXT_DEEPRUNTRAM "The Deeprun Tram"
+#define GOSSIP_TEXT_FERRY "The Rut'theran Ferry"
+#define GOSSIP_TEXT_FLIGHTMASTER "The flight master"
+#define GOSSIP_TEXT_AUCTIONHOUSE "The auction house"
+#define GOSSIP_TEXT_GUILDMASTER "The guild master"
+#define GOSSIP_TEXT_INN "The inn"
+#define GOSSIP_TEXT_MAILBOX "The mailbox"
+#define GOSSIP_TEXT_STABLEMASTER "The stable master"
+#define GOSSIP_TEXT_WEAPONMASTER "The weapon master"
+#define GOSSIP_TEXT_OFFICERS "The officers' lounge"
+#define GOSSIP_TEXT_BATTLEMASTER "The battlemaster"
+#define GOSSIP_TEXT_BARBER "Barber"
+#define GOSSIP_TEXT_CLASSTRAINER "A class trainer"
+#define GOSSIP_TEXT_PROFTRAINER "A profession trainer"
+#define GOSSIP_TEXT_LEXICON "Lexicon of Power"
#define GOSSIP_TEXT_ALTERACVALLEY "Alterac Valley"
#define GOSSIP_TEXT_ARATHIBASIN "Arathi Basin"
#define GOSSIP_TEXT_WARSONGULCH "Warsong Gulch"
#define GOSSIP_TEXT_ARENA "Arena"
#define GOSSIP_TEXT_EYEOFTHESTORM "Eye of The Storm"
+#define GOSSIP_TEXT_STRANDOFANCIENT "Strand of the Ancients"
+#define GOSSIP_TEXT_DEATH_KNIGHT "Death Knight"
#define GOSSIP_TEXT_DRUID "Druid"
#define GOSSIP_TEXT_HUNTER "Hunter"
#define GOSSIP_TEXT_PRIEST "Priest"
@@ -57,18 +66,12 @@
#define GOSSIP_TEXT_FIRSTAID "First Aid"
#define GOSSIP_TEXT_HERBALISM "Herbalism"
#define GOSSIP_TEXT_LEATHERWORKING "Leatherworking"
-#define GOSSIP_TEXT_POISONS "Poisons"
#define GOSSIP_TEXT_TAILORING "Tailoring"
#define GOSSIP_TEXT_MINING "Mining"
#define GOSSIP_TEXT_FISHING "Fishing"
#define GOSSIP_TEXT_SKINNING "Skinning"
#define GOSSIP_TEXT_JEWELCRAFTING "Jewelcrafting"
-
-#define GOSSIP_TEXT_IRONFORGE_BANK "Bank of Ironforge"
-#define GOSSIP_TEXT_STORMWIND_BANK "Bank of Stormwind"
-#define GOSSIP_TEXT_DEEPRUNTRAM "Deeprun Tram"
-#define GOSSIP_TEXT_ZEPPLINMASTER "Zeppelin master"
-#define GOSSIP_TEXT_FERRY "Rut'theran Ferry"
+#define GOSSIP_TEXT_INSCRIPTION "Inscription"
// Skill defines
@@ -86,6 +89,7 @@
#define TRADESKILL_FISHING 12
#define TRADESKILL_SKINNING 13
#define TRADESKILL_JEWLCRAFTING 14
+#define TRADESKILL_INSCRIPTION 15
#define TRADESKILL_LEVEL_NONE 0
#define TRADESKILL_LEVEL_APPRENTICE 1
@@ -93,6 +97,7 @@
#define TRADESKILL_LEVEL_EXPERT 3
#define TRADESKILL_LEVEL_ARTISAN 4
#define TRADESKILL_LEVEL_MASTER 5
+#define TRADESKILL_LEVEL_GRAND_MASTER 6
// Gossip defines
diff --git a/src/bindings/scripts/include/sc_instance.h b/src/bindings/scripts/include/sc_instance.h
index 4443c510110..42205f1ec34 100644
--- a/src/bindings/scripts/include/sc_instance.h
+++ b/src/bindings/scripts/include/sc_instance.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
diff --git a/src/bindings/scripts/scripts/areatrigger/areatrigger_scripts.cpp b/src/bindings/scripts/scripts/areatrigger/areatrigger_scripts.cpp
index 6767a8fe88b..1c1b7312cb3 100644
--- a/src/bindings/scripts/scripts/areatrigger/areatrigger_scripts.cpp
+++ b/src/bindings/scripts/scripts/areatrigger/areatrigger_scripts.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -23,7 +23,6 @@ EndScriptData */
/* ContentData
at_legion_teleporter 4560 Teleporter TO Invasion Point: Cataclysm
-at_test script test only
EndContentData */
#include "precompiled.h"
@@ -56,12 +55,6 @@ bool AreaTrigger_at_legion_teleporter(Player *player, AreaTriggerEntry *at)
return false;
}
-bool ATtest(Player *player, AreaTriggerEntry *at)
-{
- player->Say("Hi!",LANG_UNIVERSAL);
- return true;
-}
-
void AddSC_areatrigger_scripts()
{
Script *newscript;
@@ -70,10 +63,5 @@ void AddSC_areatrigger_scripts()
newscript->Name = "at_legion_teleporter";
newscript->pAreaTrigger = &AreaTrigger_at_legion_teleporter;
newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name="at_test";
- newscript->pAreaTrigger = &ATtest;
- newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/boss/boss_emeriss.cpp b/src/bindings/scripts/scripts/boss/boss_emeriss.cpp
index eecd2595a68..f2fc1ab8515 100644
--- a/src/bindings/scripts/scripts/boss/boss_emeriss.cpp
+++ b/src/bindings/scripts/scripts/boss/boss_emeriss.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -55,7 +55,7 @@ struct TRINITY_DLL_DECL boss_emerissAI : public ScriptedAI
CorruptionofEarth3_Timer = 0;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void UpdateAI(const uint32 diff)
{
diff --git a/src/bindings/scripts/scripts/boss/boss_lethon.cpp b/src/bindings/scripts/scripts/boss/boss_lethon.cpp
index 721009ac68c..e387891efed 100644
--- a/src/bindings/scripts/scripts/boss/boss_lethon.cpp
+++ b/src/bindings/scripts/scripts/boss/boss_lethon.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
diff --git a/src/bindings/scripts/scripts/boss/boss_taerar.cpp b/src/bindings/scripts/scripts/boss/boss_taerar.cpp
index 57184aa4b98..47586a1e98c 100644
--- a/src/bindings/scripts/scripts/boss/boss_taerar.cpp
+++ b/src/bindings/scripts/scripts/boss/boss_taerar.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -73,7 +73,7 @@ struct TRINITY_DLL_DECL boss_taerarAI : public ScriptedAI
Shades = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -253,7 +253,7 @@ struct TRINITY_DLL_DECL boss_shadeoftaerarAI : public ScriptedAI
PosionBreath_Timer = 12000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/boss/boss_ysondre.cpp b/src/bindings/scripts/scripts/boss/boss_ysondre.cpp
index fca9bc4b15b..e6199a4b6fd 100644
--- a/src/bindings/scripts/scripts/boss/boss_ysondre.cpp
+++ b/src/bindings/scripts/scripts/boss/boss_ysondre.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -63,7 +63,7 @@ struct TRINITY_DLL_DECL boss_ysondreAI : public ScriptedAI
SummonDruids3_Timer = 0;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -200,7 +200,7 @@ struct TRINITY_DLL_DECL mob_dementeddruidsAI : public ScriptedAI
MoonFire_Timer = 3000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp b/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp
index d3395327aa7..2f2d5349f2a 100644
--- a/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp
+++ b/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -40,7 +40,7 @@ struct TRINITY_DLL_DECL generic_creatureAI : public ScriptedAI
IsSelfRooted = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if (!m_creature->IsWithinMeleeRange(who))
{
@@ -56,7 +56,7 @@ struct TRINITY_DLL_DECL generic_creatureAI : public ScriptedAI
else GlobalCooldown = 0;
//Buff timer (only buff when we are alive and not in combat
- if (!InCombat && m_creature->isAlive())
+ if (!m_creature->isInCombat() && m_creature->isAlive())
if (BuffTimer < diff )
{
//Find a spell that targets friendly and applies an aura (these are generally buffs)
diff --git a/src/bindings/scripts/scripts/creature/simple_ai.cpp b/src/bindings/scripts/scripts/creature/simple_ai.cpp
index 96583c4ee39..a33f66fcef0 100644
--- a/src/bindings/scripts/scripts/creature/simple_ai.cpp
+++ b/src/bindings/scripts/scripts/creature/simple_ai.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -27,34 +27,25 @@ EndScriptData */
SimpleAI::SimpleAI(Creature *c) : ScriptedAI(c)
{
//Clear all data
- Aggro_Text[0] = NULL;
- Aggro_Text[1] = NULL;
- Aggro_Text[2] = NULL;
- Aggro_Say[0] = false;
- Aggro_Say[1] = false;
- Aggro_Say[2] = false;
+ Aggro_TextId[0] = 0;
+ Aggro_TextId[1] = 0;
+ Aggro_TextId[2] = 0;
Aggro_Sound[0] = 0;
Aggro_Sound[1] = 0;
Aggro_Sound[2] = 0;
- Death_Text[0] = NULL;
- Death_Text[1] = NULL;
- Death_Text[2] = NULL;
- Death_Say[0] = false;
- Death_Say[1] = false;
- Death_Say[2] = false;
+ Death_TextId[0] = 0;
+ Death_TextId[1] = 0;
+ Death_TextId[2] = 0;
Death_Sound[0] = 0;
Death_Sound[1] = 0;
Death_Sound[2] = 0;
Death_Spell = 0;
Death_Target_Type = 0;
- Kill_Text[0] = NULL;
- Kill_Text[1] = NULL;
- Kill_Text[2] = NULL;
- Kill_Say[0] = false;
- Kill_Say[1] = false;
- Kill_Say[2] = false;
+ Kill_TextId[0] = 0;
+ Kill_TextId[1] = 0;
+ Kill_TextId[2] = 0;
Kill_Sound[0] = 0;
Kill_Sound[1] = 0;
Kill_Sound[2] = 0;
@@ -70,7 +61,7 @@ void SimpleAI::Reset()
{
}
-void SimpleAI::Aggro(Unit *who)
+void SimpleAI::EnterCombat(Unit *who)
{
//Reset cast timers
if (Spell[0].First_Cast >= 0)
@@ -106,11 +97,9 @@ void SimpleAI::Aggro(Unit *who)
uint32 random_text = rand()%3;
- //Random yell
- if (Aggro_Text[random_text])
- if (Aggro_Say[random_text])
- DoSay(Aggro_Text[random_text], LANG_UNIVERSAL, who);
- else DoYell(Aggro_Text[random_text], LANG_UNIVERSAL, who);
+ //Random text
+ if (Aggro_TextId[random_text])
+ DoScriptText(Aggro_TextId[random_text], m_creature, who);
//Random sound
if (Aggro_Sound[random_text])
@@ -122,10 +111,8 @@ void SimpleAI::KilledUnit(Unit *victim)
uint32 random_text = rand()%3;
//Random yell
- if (Kill_Text[random_text])
- if (Kill_Say[random_text])
- DoSay(Kill_Text[random_text], LANG_UNIVERSAL, victim);
- else DoYell(Kill_Text[random_text], LANG_UNIVERSAL, victim);
+ if (Kill_TextId[random_text])
+ DoScriptText(Kill_TextId[random_text], m_creature, victim);
//Random sound
if (Kill_Sound[random_text])
@@ -172,10 +159,8 @@ void SimpleAI::DamageTaken(Unit *killer, uint32 &damage)
uint32 random_text = rand()%3;
//Random yell
- if (Death_Text[random_text])
- if (Death_Say[random_text])
- DoSay(Death_Text[random_text], LANG_UNIVERSAL, killer);
- else DoYell(Death_Text[random_text], LANG_UNIVERSAL, killer);
+ if (Death_TextId[random_text])
+ DoScriptText(Death_TextId[random_text], m_creature, killer);
//Random sound
if (Death_Sound[random_text])
@@ -269,10 +254,8 @@ void SimpleAI::UpdateAI(const uint32 diff)
uint32 random_text = rand()%3;
//Random yell
- if (Spell[i].Text[random_text])
- if (Spell[i].Say[random_text])
- DoSay(Spell[i].Text[random_text], LANG_UNIVERSAL, target);
- else DoYell(Spell[i].Text[random_text], LANG_UNIVERSAL, target);
+ if (Spell[i].TextId[random_text])
+ DoScriptText(Spell[i].TextId[random_text], m_creature, target);
//Random sound
if (Spell[i].Text_Sound[random_text])
diff --git a/src/bindings/scripts/scripts/creature/simple_ai.h b/src/bindings/scripts/scripts/creature/simple_ai.h
index 8745d78ad41..3a2e8a9341a 100644
--- a/src/bindings/scripts/scripts/creature/simple_ai.h
+++ b/src/bindings/scripts/scripts/creature/simple_ai.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
@@ -25,7 +25,7 @@ struct TRINITY_DLL_DECL SimpleAI : public ScriptedAI
void Reset();
- void Aggro(Unit *who);
+ void EnterCombat(Unit *who);
void KilledUnit(Unit *victim);
@@ -35,18 +35,15 @@ struct TRINITY_DLL_DECL SimpleAI : public ScriptedAI
public:
- char* Aggro_Text[3];
- bool Aggro_Say[3];
+ int32 Aggro_TextId[3];
uint32 Aggro_Sound[3];
- char* Death_Text[3];
- bool Death_Say[3];
+ int32 Death_TextId[3];
uint32 Death_Sound[3];
uint32 Death_Spell;
uint32 Death_Target_Type;
- char* Kill_Text[3];
- bool Kill_Say[3];
+ int32 Kill_TextId[3];
uint32 Kill_Sound[3];
uint32 Kill_Spell;
uint32 Kill_Target_Type;
@@ -62,8 +59,7 @@ public:
bool Enabled; //Spell enabled or disabled (default: false)
//3 texts to many?
- char* Text[3];
- bool Say[3];
+ int32 TextId[3];
uint32 Text_Sound[3];
}Spell[10];
diff --git a/src/bindings/scripts/scripts/custom/npc_acherus_taxi.cpp b/src/bindings/scripts/scripts/custom/npc_acherus_taxi.cpp
new file mode 100644
index 00000000000..3e58efa345b
--- /dev/null
+++ b/src/bindings/scripts/scripts/custom/npc_acherus_taxi.cpp
@@ -0,0 +1,39 @@
+#include "precompiled.h"
+#include "WorldPacket.h"
+
+#define GOSSIP_FLIGHT "I need a ride"
+
+bool GossipHello_npc_acherus_taxi(Player *player, Creature *_Creature)
+{
+player->SetTaxiCheater(true);
+
+player->ADD_GOSSIP_ITEM(0, GOSSIP_FLIGHT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ player->SEND_GOSSIP_MENU(9978,_Creature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_acherus_taxi(Player *player, Creature *_Creature, uint32 sender, uint32 action )
+{
+ if (action == GOSSIP_ACTION_INFO_DEF + 1)
+ {
+ if (player->GetPositionZ() >=316)
+ {
+ player->GetSession()->SendDoFlight(24446, 1053);
+ }else{
+ player->GetSession()->SendDoFlight(24446, 1054);
+ }
+
+ }
+ return true;
+}
+
+void AddSC_npc_acherus_taxi()
+{
+ Script *newscript;
+
+newscript = new Script;
+newscript->Name="npc_acherus_taxi";
+newscript->pGossipHello = &GossipHello_npc_acherus_taxi;
+newscript->pGossipSelect = &GossipSelect_npc_acherus_taxi;
+newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/custom/npc_wyrmresttempel_taxi.cpp b/src/bindings/scripts/scripts/custom/npc_wyrmresttempel_taxi.cpp
new file mode 100644
index 00000000000..2e9ab3f412d
--- /dev/null
+++ b/src/bindings/scripts/scripts/custom/npc_wyrmresttempel_taxi.cpp
@@ -0,0 +1,116 @@
+#include "precompiled.h"
+#include "WorldPacket.h"
+
+#define GOSSIP_UP "My Lord, I must go to the upper floor of the temple."
+#define GOSSIP_DOWN "I would like to take a flight to the ground, Lord Afrasastrasz."
+#define GOSSIP_MIDDLE "Can you spare a drake to travel to Lord Afrasastrasz, in the middle of the temple?"
+#define GOSSIP_TOP "Please, Let me take one of these dragons to the top floor of the temple."
+#define GOSSIP_BOTTOM "Yes, Please. I would like to return to the ground floor of the temple."
+#define GOSSIP_ONEDOWN "I would like to see Lord Afrasastrasz, in the middle of the temple."
+
+bool GossipHello_npc_wyrmresttempel_middle_taxi(Player *player, Creature *_Creature)
+{
+player->SetTaxiCheater(true);
+
+player->ADD_GOSSIP_ITEM(0, GOSSIP_UP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+player->ADD_GOSSIP_ITEM(0, GOSSIP_DOWN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ player->SEND_GOSSIP_MENU(12887,_Creature->GetGUID());
+
+ return true;
+}
+
+bool GossipSelect_npc_wyrmresttempel_middle_taxi(Player *player, Creature *_Creature, uint32 sender, uint32 action )
+{
+ if (action == GOSSIP_ACTION_INFO_DEF + 1)
+ {
+ player->GetSession()->SendDoFlight(6376, 881);
+ }
+
+
+ if (action == GOSSIP_ACTION_INFO_DEF + 2)
+ {
+ player->GetSession()->SendDoFlight(6376, 882);
+
+ }
+return true;
+}
+
+bool GossipHello_npc_wyrmresttempel_bottom_taxi(Player *player, Creature *_Creature)
+{
+player->SetTaxiCheater(true);
+
+player->ADD_GOSSIP_ITEM(0, GOSSIP_TOP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
+player->ADD_GOSSIP_ITEM(0, GOSSIP_MIDDLE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ player->SEND_GOSSIP_MENU(12713,_Creature->GetGUID());
+
+ return true;
+}
+
+
+
+bool GossipSelect_npc_wyrmresttempel_bottom_taxi(Player *player, Creature *_Creature, uint32 sender, uint32 action )
+{
+ if (action == GOSSIP_ACTION_INFO_DEF + 4)
+ {
+ player->GetSession()->SendDoFlight(6376, 878);
+ }
+
+
+ if (action == GOSSIP_ACTION_INFO_DEF + 3)
+ {
+ player->GetSession()->SendDoFlight(6376, 883);
+
+ }
+return true;
+}
+
+bool GossipHello_npc_wyrmresttempel_top_taxi(Player *player, Creature *_Creature)
+{
+player->SetTaxiCheater(true);
+
+player->ADD_GOSSIP_ITEM(0, GOSSIP_BOTTOM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
+player->ADD_GOSSIP_ITEM(0, GOSSIP_ONEDOWN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6);
+ player->SEND_GOSSIP_MENU(12714,_Creature->GetGUID());
+
+ return true;
+}
+
+bool GossipSelect_npc_wyrmresttempel_top_taxi(Player *player, Creature *_Creature, uint32 sender, uint32 action )
+{
+ if (action == GOSSIP_ACTION_INFO_DEF + 5)
+ {
+ player->GetSession()->SendDoFlight(6376, 879);
+ }
+
+ if (action == GOSSIP_ACTION_INFO_DEF + 6)
+
+ {
+ player->GetSession()->SendDoFlight(6376, 880);
+
+ }
+return true;
+}
+
+void AddSC_npc_wyrmresttempel_taxi()
+{
+ Script *newscript;
+
+newscript = new Script;
+newscript->Name="npc_wyrmresttempelmiddle_taxi";
+newscript->pGossipHello = &GossipHello_npc_wyrmresttempel_middle_taxi;
+newscript->pGossipSelect = &GossipSelect_npc_wyrmresttempel_middle_taxi;
+newscript->RegisterSelf();
+
+newscript = new Script;
+newscript->Name="npc_wyrmresttempelbottom_taxi";
+newscript->pGossipHello = &GossipHello_npc_wyrmresttempel_bottom_taxi;
+newscript->pGossipSelect = &GossipSelect_npc_wyrmresttempel_bottom_taxi;
+newscript->RegisterSelf();
+
+newscript = new Script;
+newscript->Name="npc_wyrmresttempeltop_taxi";
+newscript->pGossipHello = &GossipHello_npc_wyrmresttempel_top_taxi;
+newscript->pGossipSelect = &GossipSelect_npc_wyrmresttempel_top_taxi;
+newscript->RegisterSelf();
+
+}
diff --git a/src/bindings/scripts/scripts/examples/example_creature.cpp b/src/bindings/scripts/scripts/examples/example_creature.cpp
new file mode 100644
index 00000000000..cba35d173ca
--- /dev/null
+++ b/src/bindings/scripts/scripts/examples/example_creature.cpp
@@ -0,0 +1,258 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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
+ */
+
+/* ScriptData
+SDName: Example_Creature
+SD%Complete: 100
+SDComment: Short custom scripting example
+SDCategory: Script Examples
+EndScriptData */
+
+#include "precompiled.h"
+
+// **** This script is designed as an example for others to build on ****
+// **** Please modify whatever you'd like to as this script is only for developement ****
+
+// **** Script Info ****
+// This script is written in a way that it can be used for both friendly and hostile monsters
+// Its primary purpose is to show just how much you can really do with scripts
+// I recommend trying it out on both an agressive NPC and on friendly npc
+
+// **** Quick Info ****
+// Functions with Handled Function marked above them are functions that are called automatically by the core
+// Functions that are marked Custom Function are functions I've created to simplify code
+
+//List of text id's. The text is stored in database, also in a localized version
+//(if translation not exist for the textId, default english text will be used)
+//Not required to define in this way, but simplify if changes are needed.
+#define SAY_AGGRO -1999900
+#define SAY_RANDOM_0 -1999901
+#define SAY_RANDOM_1 -1999902
+#define SAY_RANDOM_2 -1999903
+#define SAY_RANDOM_3 -1999904
+#define SAY_RANDOM_4 -1999905
+#define SAY_BESERK -1999906
+#define SAY_PHASE -1999907
+#define SAY_DANCE -1999908
+#define SAY_SALUTE -1999909
+
+//List of gossip item texts. Items will appear in the gossip window.
+#define GOSSIP_ITEM "I'm looking for a fight"
+
+//List of spells. Not required to define them in this way, but will make it easier to maintain in case spellId change
+#define SPELL_BUFF 25661
+#define SPELL_ONE 12555
+#define SPELL_ONE_ALT 24099
+#define SPELL_TWO 10017
+#define SPELL_THREE 26027
+#define SPELL_ENRAGE 23537
+#define SPELL_BESERK 32309
+
+struct TRINITY_DLL_DECL example_creatureAI : public ScriptedAI
+{
+ //*** HANDLED FUNCTION ***
+ //This is the constructor, called only once when the creature is first created
+ example_creatureAI(Creature *c) : ScriptedAI(c) {Reset();}
+
+ //*** CUSTOM VARIABLES ****
+ //These variables are for use only by this individual script.
+ //Nothing else will ever call them but us.
+
+ uint32 Say_Timer; //Timer for random chat
+ uint32 Rebuff_Timer; //Timer for rebuffing
+ uint32 Spell_1_Timer; //Timer for spell 1 when in combat
+ uint32 Spell_2_Timer; //Timer for spell 1 when in combat
+ uint32 Spell_3_Timer; //Timer for spell 1 when in combat
+ uint32 Beserk_Timer; //Timer until we go into Beserk (enraged) mode
+ uint32 Phase; //The current battle phase we are in
+ uint32 Phase_Timer; //Timer until phase transition
+
+ //*** HANDLED FUNCTION ***
+ //This is called whenever the core decides we need to evade
+ void Reset()
+ {
+ Phase = 1; //Start in phase 1
+ Phase_Timer = 60000; //60 seconds
+ Spell_1_Timer = 5000; //5 seconds
+ Spell_2_Timer = 37000; //37 seconds
+ Spell_3_Timer = 19000; //19 seconds
+ Beserk_Timer = 120000; //2 minutes
+ }
+
+ //*** HANDLED FUNCTION ***
+ //Attack Start is called whenever someone hits us.
+ void EnterCombat(Unit *who)
+ {
+ //Say some stuff
+ DoScriptText(SAY_AGGRO, m_creature, who);
+ }
+
+ //*** HANDLED FUNCTION ***
+ //Update AI is called Every single map update (roughly once every 100ms if a player is within the grid)
+ void UpdateAI(const uint32 diff)
+ {
+ //Out of combat timers
+ if (!m_creature->getVictim())
+ {
+ //Random Say timer
+ if (Say_Timer < diff)
+ {
+ //Random switch between 5 outcomes
+ switch (rand()%5)
+ {
+ case 0: DoScriptText(SAY_RANDOM_0, m_creature); break;
+ case 1: DoScriptText(SAY_RANDOM_1, m_creature); break;
+ case 2: DoScriptText(SAY_RANDOM_2, m_creature); break;
+ case 3: DoScriptText(SAY_RANDOM_3, m_creature); break;
+ case 4: DoScriptText(SAY_RANDOM_4, m_creature); break;
+ }
+
+ Say_Timer = 45000; //Say something agian in 45 seconds
+ }else Say_Timer -= diff;
+
+ //Rebuff timer
+ if (Rebuff_Timer < diff)
+ {
+ DoCast(m_creature,SPELL_BUFF);
+ Rebuff_Timer = 900000; //Rebuff agian in 15 minutes
+ }else Rebuff_Timer -= diff;
+ }
+
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ //Spell 1 timer
+ if (Spell_1_Timer < diff)
+ {
+ //Cast spell one on our current target.
+ if (rand()%50 > 10)
+ DoCast(m_creature->getVictim(),SPELL_ONE_ALT);
+ else if (m_creature->GetDistance(m_creature->getVictim()) < 25)
+ DoCast(m_creature->getVictim(),SPELL_ONE);
+
+ Spell_1_Timer = 5000;
+ }else Spell_1_Timer -= diff;
+
+ //Spell 2 timer
+ if (Spell_2_Timer < diff)
+ {
+ //Cast spell one on our current target.
+ DoCast(m_creature->getVictim(),SPELL_TWO);
+
+ Spell_2_Timer = 37000;
+ }else Spell_2_Timer -= diff;
+
+ //Spell 3 timer
+ if (Phase > 1)
+ if (Spell_3_Timer < diff)
+ {
+ //Cast spell one on our current target.
+ DoCast(m_creature->getVictim(),SPELL_THREE);
+
+ Spell_3_Timer = 19000;
+ }else Spell_3_Timer -= diff;
+
+ //Beserk timer
+ if (Phase > 1)
+ if (Beserk_Timer < diff)
+ {
+ //Say our line then cast uber death spell
+ DoScriptText(SAY_BESERK, m_creature, m_creature->getVictim());
+ DoCast(m_creature->getVictim(),SPELL_BESERK);
+
+ //Cast our beserk spell agian in 12 seconds if we didn't kill everyone
+ Beserk_Timer = 12000;
+ }else Beserk_Timer -= diff;
+
+ //Phase timer
+ if (Phase == 1)
+ if (Phase_Timer < diff)
+ {
+ //Go to next phase
+ Phase++;
+ DoScriptText(SAY_PHASE, m_creature);
+ DoCast(m_creature,SPELL_ENRAGE);
+ }else Phase_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ //Our Recive emote function
+ void ReceiveEmote(Player *player, uint32 emote)
+ {
+ m_creature->HandleEmoteCommand(emote);
+
+ if (emote == TEXTEMOTE_DANCE)
+ DoScriptText(SAY_DANCE, m_creature);
+
+ if (emote == TEXTEMOTE_SALUTE)
+ DoScriptText(SAY_SALUTE, m_creature);
+ }
+};
+
+//This is the GetAI method used by all scripts that involve AI
+//It is called every time a new creature using this script is created
+CreatureAI* GetAI_example_creature(Creature *_Creature)
+{
+ return new example_creatureAI (_Creature);
+}
+
+//This function is called when the player clicks an option on the gossip menu
+void SendDefaultMenu_example_creature(Player *player, Creature *_Creature, uint32 action)
+{
+ if (action == GOSSIP_ACTION_INFO_DEF + 1) //Fight time
+ {
+ //Set our faction to hostile twoards all
+ _Creature->setFaction(24);
+ _Creature->Attack(player, true);
+ player->PlayerTalkClass->CloseGossip();
+ }
+}
+
+//This function is called when the player clicks an option on the gossip menu
+bool GossipSelect_example_creature(Player *player, Creature *_Creature, uint32 sender, uint32 action )
+{
+ if (sender == GOSSIP_SENDER_MAIN)
+ SendDefaultMenu_example_creature(player, _Creature, action);
+
+ return true;
+}
+
+//This function is called when the player opens the gossip menu
+bool GossipHello_example_creature(Player *player, Creature *_Creature)
+{
+ player->ADD_GOSSIP_ITEM( 0, GOSSIP_ITEM , GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ player->PlayerTalkClass->SendGossipMenu(907,_Creature->GetGUID());
+
+ return true;
+}
+
+//This is the actual function called only once durring InitScripts()
+//It must define all handled functions that are to be run in this script
+//For example if you want this Script to handle Emotes you must include
+//newscript->ReciveEmote = My_Emote_Function;
+void AddSC_example_creature()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "example_creature";
+ newscript->GetAI = &GetAI_example_creature;
+ newscript->pGossipHello = &GossipHello_example_creature;
+ newscript->pGossipSelect = &GossipSelect_example_creature;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/examples/example_escort.cpp b/src/bindings/scripts/scripts/examples/example_escort.cpp
new file mode 100644
index 00000000000..4d701ed0fdf
--- /dev/null
+++ b/src/bindings/scripts/scripts/examples/example_escort.cpp
@@ -0,0 +1,221 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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
+ */
+
+/* ScriptData
+SDName: Example_Escort
+SD%Complete: 100
+SDComment: Script used for testing escortAI
+SDCategory: Script Examples
+EndScriptData */
+
+#include "precompiled.h"
+#include "../npc/npc_escortAI.h"
+
+#define SAY_AGGRO1 -1999910
+#define SAY_AGGRO2 -1999911
+#define SAY_WP_1 -1999912
+#define SAY_WP_2 -1999913
+#define SAY_WP_3 -1999914
+#define SAY_WP_4 -1999915
+#define SAY_DEATH_1 -1999916
+#define SAY_DEATH_2 -1999917
+#define SAY_DEATH_3 -1999918
+#define SAY_SPELL -1999919
+#define SAY_RAND_1 -1999920
+#define SAY_RAND_2 -1999921
+
+#define GOSSIP_ITEM_1 "Click to Test Escort(Attack, Defend, Run)"
+#define GOSSIP_ITEM_2 "Click to Test Escort(NoAttack, NoDefend, Walk)"
+#define GOSSIP_ITEM_3 "Click to Test Escort(NoAttack, Defend, Walk)"
+
+struct TRINITY_DLL_DECL example_escortAI : public npc_escortAI
+{
+ public:
+
+ // CreatureAI functions
+ example_escortAI(Creature *c) : npc_escortAI(c) {Reset();}
+
+ uint32 DeathCoilTimer;
+ uint32 ChatTimer;
+
+ // Pure Virtual Functions
+ void WaypointReached(uint32 i)
+ {
+ switch (i)
+ {
+ case 1:
+ DoScriptText(SAY_WP_1, m_creature);
+ break;
+
+ case 3:
+ {
+ DoScriptText(SAY_WP_2, m_creature);
+ Creature* temp = m_creature->SummonCreature(21878, m_creature->GetPositionX()+5, m_creature->GetPositionY()+7, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 3000);
+ if(temp)
+ temp->AI()->AttackStart(m_creature);
+ }
+ break;
+
+ case 4:
+ {
+ Unit* temp = Unit::GetUnit(*m_creature, PlayerGUID);
+ if (temp)
+ {
+ //temp is the target of the text
+ DoScriptText(SAY_WP_3, m_creature, temp);
+ //temp is the source of the text
+ DoScriptText(SAY_WP_4, temp);
+ }
+ }
+ break;
+ }
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ if (IsBeingEscorted)
+ {
+ if (Unit* temp = Unit::GetUnit(*m_creature, PlayerGUID))
+ DoScriptText(SAY_AGGRO1, m_creature, temp);
+ }
+ else DoScriptText(SAY_AGGRO2, m_creature);
+ }
+
+ void Reset()
+ {
+ DeathCoilTimer = 4000;
+ ChatTimer = 4000;
+ }
+
+ void JustDied(Unit* killer)
+ {
+ if (IsBeingEscorted)
+ {
+ Unit *pTemp = Unit::GetUnit(*m_creature,PlayerGUID);
+ //killer = m_creature when player got to far from creature
+ if (killer == m_creature)
+ {
+ //This is actually a whisper. You control the text type in database
+ if (pTemp)
+ DoScriptText(SAY_DEATH_1, m_creature, pTemp);
+ }
+ else if (pTemp) DoScriptText(SAY_DEATH_2, m_creature, pTemp);
+ }
+ else DoScriptText(SAY_DEATH_3, m_creature);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Must update npc_escortAI
+ npc_escortAI::UpdateAI(diff);
+
+ //Combat check
+ if (m_creature->getVictim())
+ {
+ if (DeathCoilTimer < diff)
+ {
+ DoScriptText(SAY_SPELL, m_creature);
+ m_creature->CastSpell(m_creature->getVictim(), 33130, false);
+
+ DeathCoilTimer = 4000;
+ }else DeathCoilTimer -= diff;
+ }
+ else if(!m_creature->isInCombat())
+ {
+ //Out of combat but being escorted
+ if (IsBeingEscorted)
+ if (ChatTimer < diff)
+ {
+ if (m_creature->HasAura(3593))
+ {
+ DoScriptText(SAY_RAND_1, m_creature);
+ m_creature->CastSpell(m_creature, 11540, false);
+ }else
+ {
+ DoScriptText(SAY_RAND_2, m_creature);
+ m_creature->CastSpell(m_creature, 3593, false);
+ }
+
+ ChatTimer = 12000;
+ }else ChatTimer -= diff;
+ }
+ }
+};
+
+CreatureAI* GetAI_example_escort(Creature *_Creature)
+{
+ example_escortAI* testAI = new example_escortAI(_Creature);
+
+ testAI->AddWaypoint(0, 1231, -4419, 23);
+ testAI->AddWaypoint(1, 1198, -4440, 23, 0);
+ testAI->AddWaypoint(2, 1208, -4392, 23);
+ testAI->AddWaypoint(3, 1231, -4419, 23, 5000);
+ testAI->AddWaypoint(4, 1208, -4392, 23, 5000);
+
+ return (CreatureAI*)testAI;
+}
+
+bool GossipHello_example_escort(Player *player, Creature *_Creature)
+{
+ player->TalkedToCreature(_Creature->GetEntry(),_Creature->GetGUID());
+ _Creature->prepareGossipMenu(player,0);
+
+ player->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ player->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ player->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
+
+ _Creature->sendPreparedGossip( player );
+ return true;
+}
+
+bool GossipSelect_example_escort(Player *player, Creature *_Creature, uint32 sender, uint32 action )
+{
+ if (action == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ player->CLOSE_GOSSIP_MENU();
+ ((npc_escortAI*)(_Creature->AI()))->Start(true, true, true, player->GetGUID());
+
+ return true; // prevent mangos core handling
+ }
+
+ if (action == GOSSIP_ACTION_INFO_DEF+2)
+ {
+ player->CLOSE_GOSSIP_MENU();
+ ((npc_escortAI*)(_Creature->AI()))->Start(false, false, false, player->GetGUID());
+
+ return true; // prevent mangos core handling
+ }
+
+ if (action == GOSSIP_ACTION_INFO_DEF+3)
+ {
+ player->CLOSE_GOSSIP_MENU();
+ ((npc_escortAI*)(_Creature->AI()))->Start(false, true, false, player->GetGUID());
+
+ return true; // prevent mangos core handling
+ }
+ return false;
+}
+
+void AddSC_example_escort()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "example_escort";
+ newscript->GetAI = &GetAI_example_escort;
+ newscript->pGossipHello = &GossipHello_example_escort;
+ newscript->pGossipSelect = &GossipSelect_example_escort;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/examples/example_gossip_codebox.cpp b/src/bindings/scripts/scripts/examples/example_gossip_codebox.cpp
new file mode 100644
index 00000000000..5d05197fd7a
--- /dev/null
+++ b/src/bindings/scripts/scripts/examples/example_gossip_codebox.cpp
@@ -0,0 +1,88 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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
+ */
+
+/* ScriptData
+SDName: Example_Gossip_Codebox
+SD%Complete: 100
+SDComment: Show a codebox in gossip option
+SDCategory: Script Examples
+EndScriptData */
+
+#include "precompiled.h"
+#include <cstring>
+
+#define SAY_NOT_INTERESTED -1999922
+#define SAY_WRONG -1999923
+#define SAY_CORRECT -1999924
+
+#define GOSSIP_ITEM_1 "A quiz: what's your name?"
+#define GOSSIP_ITEM_2 "I'm not interested"
+
+//This function is called when the player opens the gossip menubool
+bool GossipHello_example_gossip_codebox(Player *player, Creature *_Creature)
+{
+ player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1, "", 0, true);
+ player->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+
+ player->PlayerTalkClass->SendGossipMenu(907,_Creature->GetGUID());
+ return true;
+}
+
+//This function is called when the player clicks an option on the gossip menubool
+bool GossipSelect_example_gossip_codebox(Player *player, Creature *_Creature, uint32 sender, uint32 action )
+{
+ if(action == GOSSIP_ACTION_INFO_DEF+2)
+ {
+ DoScriptText(SAY_NOT_INTERESTED, _Creature);
+ player->CLOSE_GOSSIP_MENU();
+ }
+ return true;
+}
+
+bool GossipSelectWithCode_example_gossip_codebox( Player *player, Creature *_Creature, uint32 sender, uint32 action, const char* sCode )
+{
+ if(sender == GOSSIP_SENDER_MAIN)
+ {
+ if(action == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ if(std::strcmp(sCode, player->GetName())!=0)
+ {
+ DoScriptText(SAY_WRONG, _Creature);
+ _Creature->CastSpell(player, 12826, true);
+ }
+ else
+ {
+ DoScriptText(SAY_CORRECT, _Creature);
+ _Creature->CastSpell(player, 26990, true);
+ }
+ player->CLOSE_GOSSIP_MENU();
+ return true;
+ }
+ }
+ return false;
+}
+
+void AddSC_example_gossip_codebox()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "example_gossip_codebox";
+ newscript->pGossipHello = &GossipHello_example_gossip_codebox;
+ newscript->pGossipSelect = &GossipSelect_example_gossip_codebox;
+ newscript->pGossipSelectWithCode = &GossipSelectWithCode_example_gossip_codebox;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/examples/example_misc.cpp b/src/bindings/scripts/scripts/examples/example_misc.cpp
new file mode 100644
index 00000000000..63136c6bc5d
--- /dev/null
+++ b/src/bindings/scripts/scripts/examples/example_misc.cpp
@@ -0,0 +1,65 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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
+ */
+
+/* ScriptData
+SDName: Example_Misc
+SD%Complete: 100
+SDComment: Item, Areatrigger and other small code examples
+SDCategory: Script Examples
+EndScriptData */
+
+#include "precompiled.h"
+
+#define SAY_HI -1999925
+
+bool AT_example_areatrigger(Player *player, AreaTriggerEntry *at)
+{
+ DoScriptText(SAY_HI, player);
+ return true;
+}
+
+extern void LoadDatabase();
+bool ItemUse_example_item(Player *player, Item* _Item, SpellCastTargets const& targets)
+{
+ LoadDatabase();
+ return true;
+}
+
+bool GOHello_example_go_teleporter(Player *player, GameObject* _GO)
+{
+ player->TeleportTo(0, 1807.07f,336.105f,70.3975f,0.0f);
+ return false;
+}
+
+void AddSC_example_misc()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "example_areatrigger";
+ newscript->pAreaTrigger = &AT_example_areatrigger;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "example_item";
+ newscript->pItemUse = &ItemUse_example_item;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "example_go_teleporter";
+ newscript->pGOHello = &GOHello_example_go_teleporter;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/go/go_scripts.cpp b/src/bindings/scripts/scripts/go/go_scripts.cpp
index cc64074b6bc..4a58a0d4010 100644
--- a/src/bindings/scripts/scripts/go/go_scripts.cpp
+++ b/src/bindings/scripts/scripts/go/go_scripts.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -22,6 +22,7 @@ SDCategory: Game Objects
EndScriptData */
/* ContentData
+go_cat_figurine (the "trap" version of GO, two different exist)
go_northern_crystal_pylon
go_eastern_crystal_pylon
go_western_crystal_pylon
@@ -30,12 +31,26 @@ go_field_repair_bot_74A
go_orb_of_command
go_tablet_of_madness
go_tablet_of_the_seven
-go_teleporter
EndContentData */
#include "precompiled.h"
/*######
+## go_cat_figurine
+######*/
+
+enum
+{
+ SPELL_SUMMON_GHOST_SABER = 5968,
+};
+
+bool GOHello_go_cat_figurine(Player *player, GameObject* _GO)
+{
+ player->CastSpell(player,SPELL_SUMMON_GHOST_SABER,true);
+ return false;
+}
+
+/*######
## go_crystal_pylons (3x)
######*/
@@ -108,6 +123,26 @@ bool GOHello_go_field_repair_bot_74A(Player *player, GameObject* _GO)
}
/*######
+## go_gilded_brazier
+######*/
+
+enum
+{
+ NPC_STILLBLADE = 17716,
+};
+
+bool GOHello_go_gilded_brazier(Player* pPlayer, GameObject* pGO)
+{
+ if (pGO->GetGoType() == GAMEOBJECT_TYPE_GOOBER)
+ {
+ if (Creature* pCreature = pPlayer->SummonCreature(NPC_STILLBLADE, 8087.632, -7542.740, 151.568, 0.122, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000))
+ pCreature->AI()->AttackStart(pPlayer);
+ }
+
+ return true;
+}
+
+/*######
## go_orb_of_command
######*/
@@ -148,16 +183,6 @@ bool GOHello_go_tablet_of_the_seven(Player *player, GameObject* _GO)
return true;
}
-/*######
-## go_teleporter
-######*/
-
-bool GOHello_go_teleporter(Player *player, GameObject* _GO)
-{
- player->TeleportTo(0, 1807.07f,336.105f,70.3975f,0.0f);
- return false;
-}
-
/*#####
## go_jump_a_tron
######*/
@@ -173,7 +198,7 @@ bool GOHello_go_jump_a_tron(Player *player, GameObject* _GO)
/*######
## go_ethereum_prison
######*/
-
+
float ethereum_NPC[2][7] =
{
{20785,20790,20789,20784,20786,20783,20788}, // hostile npc
@@ -182,9 +207,9 @@ float ethereum_NPC[2][7] =
bool GOHello_go_ethereum_prison(Player *player, GameObject* _GO)
{
- _GO->SetGoState(0);
+ _GO->SetGoState(GO_STATE_ACTIVE);
switch(rand()%2){
- case 0:
+ case 0:
_GO->SummonCreature(ethereum_NPC[0][rand()%6],_GO->GetPositionX(),_GO->GetPositionY(),_GO->GetPositionZ()+0.3, 0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,10000);
break;
case 1:
@@ -208,11 +233,47 @@ bool GOHello_go_sacred_fire_of_life(Player* pPlayer, GameObject* pGO)
return true;
}
+/*######
+## go_tele_to_dalaran_crystal
+######*/
+
+enum
+{
+ QUEST_LEARN_LEAVE_RETURN = 12790,
+ QUEST_TELE_CRYSTAL_FLAG = 12845
+};
+
+bool GOHello_go_tele_to_dalaran_crystal(Player* pPlayer, GameObject* pGo)
+{
+ if (pPlayer->GetQuestRewardStatus(QUEST_TELE_CRYSTAL_FLAG))
+ return false;
+
+ //TODO: must send error message (what kind of message? On-screen?)
+ return true;
+}
+
+/*######
+## go_tele_to_violet_stand
+######*/
+
+bool GOHello_go_tele_to_violet_stand(Player* pPlayer, GameObject* pGo)
+{
+ if (pPlayer->GetQuestRewardStatus(QUEST_LEARN_LEAVE_RETURN) || pPlayer->GetQuestStatus(QUEST_LEARN_LEAVE_RETURN) == QUEST_STATUS_INCOMPLETE)
+ return false;
+
+ return true;
+}
+
void AddSC_go_scripts()
{
Script *newscript;
newscript = new Script;
+ newscript->Name = "go_cat_figurine";
+ newscript->pGOHello = &GOHello_go_cat_figurine;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
newscript->Name="go_northern_crystal_pylon";
newscript->pGOHello = &GOHello_go_northern_crystal_pylon;
newscript->RegisterSelf();
@@ -238,6 +299,11 @@ void AddSC_go_scripts()
newscript->RegisterSelf();
newscript = new Script;
+ newscript->Name = "go_gilded_brazier";
+ newscript->pGOHello = &GOHello_go_gilded_brazier;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
newscript->Name="go_orb_of_command";
newscript->pGOHello = &GOHello_go_orb_of_command;
newscript->RegisterSelf();
@@ -253,11 +319,6 @@ void AddSC_go_scripts()
newscript->RegisterSelf();
newscript = new Script;
- newscript->Name="go_teleporter";
- newscript->pGOHello = &GOHello_go_teleporter;
- newscript->RegisterSelf();
-
- newscript = new Script;
newscript->Name="go_jump_a_tron";
newscript->pGOHello = &GOHello_go_jump_a_tron;
newscript->RegisterSelf();
diff --git a/src/bindings/scripts/scripts/guard/guard_ai.cpp b/src/bindings/scripts/scripts/guard/guard_ai.cpp
index f28820eb7ee..3d7c3f5ba4c 100644
--- a/src/bindings/scripts/scripts/guard/guard_ai.cpp
+++ b/src/bindings/scripts/scripts/guard/guard_ai.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -28,27 +28,25 @@ EndScriptData */
#define GENERIC_CREATURE_COOLDOWN 5000
+#define SAY_GUARD_SIL_AGGRO1 -1070001
+#define SAY_GUARD_SIL_AGGRO2 -1070002
+#define SAY_GUARD_SIL_AGGRO3 -1070003
+
void guardAI::Reset()
{
GlobalCooldown = 0;
BuffTimer = 0; //Rebuff as soon as we can
}
-void guardAI::Aggro(Unit *who)
+void guardAI::EnterCombat(Unit *who)
{
if (m_creature->GetEntry() == 15184)
{
switch(rand()%3)
{
- case 0:
- DoSay("Taste blade, mongrel!", LANG_UNIVERSAL,NULL);
- break;
- case 1:
- DoSay("Please tell me that you didn't just do what I think you just did. Please tell me that I'm not going to have to hurt you...", LANG_UNIVERSAL,NULL);
- break;
- case 2:
- DoSay("As if we don't have enough problems, you go and create more!", LANG_UNIVERSAL,NULL);
- break;
+ case 0: DoScriptText(SAY_GUARD_SIL_AGGRO1, m_creature, who); break;
+ case 1: DoScriptText(SAY_GUARD_SIL_AGGRO1, m_creature, who); break;
+ case 2: DoScriptText(SAY_GUARD_SIL_AGGRO1, m_creature, who); break;
}
}
@@ -71,7 +69,7 @@ void guardAI::UpdateAI(const uint32 diff)
else GlobalCooldown = 0;
//Buff timer (only buff when we are alive and not in combat
- if (m_creature->isAlive() && !InCombat)
+ if (m_creature->isAlive() && !m_creature->isInCombat())
if (BuffTimer < diff )
{
//Find a spell that targets friendly and applies an aura (these are generally buffs)
diff --git a/src/bindings/scripts/scripts/guard/guard_ai.h b/src/bindings/scripts/scripts/guard/guard_ai.h
index 7952040b5e2..71ded211f6f 100644
--- a/src/bindings/scripts/scripts/guard/guard_ai.h
+++ b/src/bindings/scripts/scripts/guard/guard_ai.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
@@ -16,7 +16,7 @@ struct TRINITY_DLL_DECL guardAI : public ScriptedAI
void Reset();
- void Aggro(Unit *who);
+ void EnterCombat(Unit *who);
void JustDied(Unit *Killer);
diff --git a/src/bindings/scripts/scripts/guard/guards.cpp b/src/bindings/scripts/scripts/guard/guards.cpp
index ff6ec258b22..fb27c64135d 100644
--- a/src/bindings/scripts/scripts/guard/guards.cpp
+++ b/src/bindings/scripts/scripts/guard/guards.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -115,23 +115,23 @@ void SendDefaultMenu_guard_azuremyst(Player *player, Creature *_Creature, uint32
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Bank
- player->SEND_POI(-3918.95, -11544.7, 6, 6, 0, "Bank");
+ player->SEND_POI(-3918.95, -11544.7, 7, 6, 0, "Bank");
player->SEND_GOSSIP_MENU(10067,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Hippogryph Master
- player->SEND_POI(-4057.15, -11788.6, 6, 6, 0, "Stephanos");
+ player->SEND_POI(-4057.15, -11788.6, 7, 6, 0, "Stephanos");
player->SEND_GOSSIP_MENU(10071,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Guild master
- player->SEND_POI(-4092.43, -11626.6, 6, 6, 0, "Funaam");
+ player->SEND_POI(-4092.43, -11626.6, 7, 6, 0, "Funaam");
player->SEND_GOSSIP_MENU(10073,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Inn
- player->SEND_POI(-4129.43, -12469, 6, 6, 0, "Caregiver Chellan");
+ player->SEND_POI(-4129.43, -12469, 7, 6, 0, "Caregiver Chellan");
player->SEND_GOSSIP_MENU(10074,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Stable Master
- player->SEND_POI(-4146.42, -12492.7, 6, 6, 0, "Esbina");
+ player->SEND_POI(-4146.42, -12492.7, 7, 6, 0, "Esbina");
player->SEND_GOSSIP_MENU(10075,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Class trainer
@@ -168,31 +168,31 @@ void SendClassTrainerMenu_guard_azuremyst(Player *player, Creature *_Creature, u
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Druid
- player->SEND_POI(-4274.81, -11495.3, 6, 6, 0, "Shalannius");
+ player->SEND_POI(-4274.81, -11495.3, 7, 6, 0, "Shalannius");
player->SEND_GOSSIP_MENU(10077,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Hunter
- player->SEND_POI(-4203.65, -12526.5, 6, 6, 0, "Acteon");
+ player->SEND_POI(-4203.65, -12526.5, 7, 6, 0, "Acteon");
player->SEND_GOSSIP_MENU(10078,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Mage
- player->SEND_POI(-4149.62, -12530.1, 6, 6, 0, "Semid");
+ player->SEND_POI(-4149.62, -12530.1, 7, 6, 0, "Semid");
player->SEND_GOSSIP_MENU(10081,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Paladin
- player->SEND_POI(-4138.98, -12468.5, 6, 6, 0, "Tullas");
+ player->SEND_POI(-4138.98, -12468.5, 7, 6, 0, "Tullas");
player->SEND_GOSSIP_MENU(10083,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Priest
- player->SEND_POI(-4131.66, -12478.6, 6, 6, 0, "Guvan");
+ player->SEND_POI(-4131.66, -12478.6, 7, 6, 0, "Guvan");
player->SEND_GOSSIP_MENU(10084,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Shaman
- player->SEND_POI(-4162.33, -12456.1, 6, 6, 0, "Tuluun");
+ player->SEND_POI(-4162.33, -12456.1, 7, 6, 0, "Tuluun");
player->SEND_GOSSIP_MENU(10085,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Warrior
- player->SEND_POI(-4165.05, -12536.4, 6, 6, 0, "Ruada");
+ player->SEND_POI(-4165.05, -12536.4, 7, 6, 0, "Ruada");
player->SEND_GOSSIP_MENU(10086,_Creature->GetGUID());
break;
}
@@ -203,54 +203,54 @@ void SendProfTrainerMenu_guard_azuremyst(Player *player, Creature *_Creature, ui
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(-4191.15, -12470, 6, 6, 0, "Daedal");
+ player->SEND_POI(-4191.15, -12470, 7, 6, 0, "Daedal");
player->SEND_GOSSIP_MENU(10088,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Blacksmithing
- player->SEND_POI(-4726.29, -12387, 6, 6, 0, "Blacksmith Calypso");
+ player->SEND_POI(-4726.29, -12387, 7, 6, 0, "Blacksmith Calypso");
player->SEND_GOSSIP_MENU(10089,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Cooking
- player->SEND_POI(-4710.87, -12400.6, 6, 6, 0, "'Cookie' McWeaksauce");
+ player->SEND_POI(-4710.87, -12400.6, 7, 6, 0, "'Cookie' McWeaksauce");
player->SEND_GOSSIP_MENU(10090,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Enchanting
- player->SEND_POI(-3882.85, -11496.7, 6, 6, 0, "Nahogg");
+ player->SEND_POI(-3882.85, -11496.7, 7, 6, 0, "Nahogg");
player->SEND_GOSSIP_MENU(10091,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Engineering
- player->SEND_POI(-4157.57, -12470.2, 6, 6, 0, "Artificer Daelo");
+ player->SEND_POI(-4157.57, -12470.2, 7, 6, 0, "Artificer Daelo");
player->SEND_GOSSIP_MENU(10092,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //First Aid
- player->SEND_POI(-4199.11, -12469.9, 6, 6, 0, "Anchorite Fateema");
+ player->SEND_POI(-4199.11, -12469.9, 7, 6, 0, "Anchorite Fateema");
player->SEND_GOSSIP_MENU(10093,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Fishing
- player->SEND_POI(-4266.38, -12985.1, 6, 6, 0, "Diktynna");
+ player->SEND_POI(-4266.38, -12985.1, 7, 6, 0, "Diktynna");
player->SEND_GOSSIP_MENU(10094,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Herbalism
player->SEND_GOSSIP_MENU(10095,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Jewelcrafting
- player->SEND_POI(-3781.55, -11541.8, 6, 6, 0, "Farii");
+ player->SEND_POI(-3781.55, -11541.8, 7, 6, 0, "Farii");
player->SEND_GOSSIP_MENU(10096,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Leatherworking
- player->SEND_POI(-3442.68, -12322.2, 6, 6, 0, "Moordo");
+ player->SEND_POI(-3442.68, -12322.2, 7, 6, 0, "Moordo");
player->SEND_GOSSIP_MENU(10098,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Mining
- player->SEND_POI(-4179.89, -12493.1, 6, 6, 0, "Dulvi");
+ player->SEND_POI(-4179.89, -12493.1, 7, 6, 0, "Dulvi");
player->SEND_GOSSIP_MENU(10097,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 12: //Skinning
- player->SEND_POI(-3431.17, -12316.5, 6, 6, 0, "Gurf");
+ player->SEND_POI(-3431.17, -12316.5, 7, 6, 0, "Gurf");
player->SEND_GOSSIP_MENU(10098,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 13: //Tailoring
- player->SEND_POI(-4711.54, -12386.7, 6, 6, 0, "Erin Kelly");
+ player->SEND_POI(-4711.54, -12386.7, 7, 6, 0, "Erin Kelly");
player->SEND_GOSSIP_MENU(10099,_Creature->GetGUID());
break;
}
@@ -302,35 +302,35 @@ void SendDefaultMenu_guard_bluffwatcher(Player *player, Creature *_Creature, uin
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Bank
- player->SEND_POI(-1257.8, 24.14, 6, 6, 0, "Thunder Bluff Bank");
+ player->SEND_POI(-1257.8, 24.14, 7, 6, 0, "Thunder Bluff Bank");
player->SEND_GOSSIP_MENU(1292,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Wind master
- player->SEND_POI(-1196.43, 28.26, 6, 6, 0, "Wind Rider Roost");
+ player->SEND_POI(-1196.43, 28.26, 7, 6, 0, "Wind Rider Roost");
player->SEND_GOSSIP_MENU(1293,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Guild master
- player->SEND_POI(-1296.5, 127.57, 6, 6, 0, "Thunder Bluff Civic Information");
+ player->SEND_POI(-1296.5, 127.57, 7, 6, 0, "Thunder Bluff Civic Information");
player->SEND_GOSSIP_MENU(1291,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Inn
- player->SEND_POI(-1296, 39.7, 6, 6, 0, "Thunder Bluff Inn");
+ player->SEND_POI(-1296, 39.7, 7, 6, 0, "Thunder Bluff Inn");
player->SEND_GOSSIP_MENU(3153,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Mailbox
- player->SEND_POI(-1263.59, 44.36, 6, 6, 0, "Thunder Bluff Mailbox");
+ player->SEND_POI(-1263.59, 44.36, 7, 6, 0, "Thunder Bluff Mailbox");
player->SEND_GOSSIP_MENU(3154,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Auction House
- player->SEND_POI(1381.77, -4371.16, 6, 6, 0, GOSSIP_TEXT_AUCTIONHOUSE);
+ player->SEND_POI(1381.77, -4371.16, 7, 6, 0, GOSSIP_TEXT_AUCTIONHOUSE);
player->SEND_GOSSIP_MENU(3155,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Weapon master
- player->SEND_POI(-1282.31, 89.56, 6, 6, 0, "Ansekhwa");
+ player->SEND_POI(-1282.31, 89.56, 7, 6, 0, "Ansekhwa");
player->SEND_GOSSIP_MENU(4520,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Stable master
- player->SEND_POI(-1270.19, 48.84, 6, 6, 0, "Bulrug");
+ player->SEND_POI(-1270.19, 48.84, 7, 6, 0, "Bulrug");
player->SEND_GOSSIP_MENU(5977,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //battlemaster
@@ -370,15 +370,15 @@ void SendBattleMasterMenu_guard_bluffwatcher(Player *player, Creature *_Creature
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //AV
- player->SEND_POI(-1387.82, -97.55, 6, 6, 0, "Taim Ragetotem");
+ player->SEND_POI(-1387.82, -97.55, 7, 6, 0, "Taim Ragetotem");
player->SEND_GOSSIP_MENU(7522,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //AB
- player->SEND_POI(-997, 214.12, 6, 6, 0, "Martin Lindsey");
+ player->SEND_POI(-997, 214.12, 7, 6, 0, "Martin Lindsey");
player->SEND_GOSSIP_MENU(7648,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //WSG
- player->SEND_POI(-1384.94, -75.91, 6, 6, 0, "Kergul Bloodaxe");
+ player->SEND_POI(-1384.94, -75.91, 7, 6, 0, "Kergul Bloodaxe");
player->SEND_GOSSIP_MENU(7523,_Creature->GetGUID());
break;
}
@@ -389,27 +389,27 @@ void SendClassTrainerMenu_guard_bluffwatcher(Player *player, Creature *_Creature
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Druid
- player->SEND_POI(-1054.47, -285, 6, 6, 0, "Hall of Elders");
+ player->SEND_POI(-1054.47, -285, 7, 6, 0, "Hall of Elders");
player->SEND_GOSSIP_MENU(1294,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Hunter
- player->SEND_POI(-1416.32, -114.28, 6, 6, 0, "Hunter's Hall");
+ player->SEND_POI(-1416.32, -114.28, 7, 6, 0, "Hunter's Hall");
player->SEND_GOSSIP_MENU(1295,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Mage
- player->SEND_POI(-1061.2, 195.5, 6, 6, 0, "Pools of Vision");
+ player->SEND_POI(-1061.2, 195.5, 7, 6, 0, "Pools of Vision");
player->SEND_GOSSIP_MENU(1296,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Priest
- player->SEND_POI(-1061.2, 195.5, 6, 6, 0, "Pools of Vision");
+ player->SEND_POI(-1061.2, 195.5, 7, 6, 0, "Pools of Vision");
player->SEND_GOSSIP_MENU(1297,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Shaman
- player->SEND_POI(-989.54, 278.25, 6, 6, 0, "Hall of Spirits");
+ player->SEND_POI(-989.54, 278.25, 7, 6, 0, "Hall of Spirits");
player->SEND_GOSSIP_MENU(1298,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Warrior
- player->SEND_POI(-1416.32, -114.28, 6, 6, 0, "Hunter's Hall");
+ player->SEND_POI(-1416.32, -114.28, 7, 6, 0, "Hunter's Hall");
player->SEND_GOSSIP_MENU(1299,_Creature->GetGUID());
break;
}
@@ -420,47 +420,47 @@ void SendProfTrainerMenu_guard_bluffwatcher(Player *player, Creature *_Creature,
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(-1085.56, 27.29, 6, 6, 0, "Bena's Alchemy");
+ player->SEND_POI(-1085.56, 27.29, 7, 6, 0, "Bena's Alchemy");
player->SEND_GOSSIP_MENU(1332,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Blacksmithing
- player->SEND_POI(-1239.75, 104.88, 6, 6, 0, "Karn's Smithy");
+ player->SEND_POI(-1239.75, 104.88, 7, 6, 0, "Karn's Smithy");
player->SEND_GOSSIP_MENU(1333,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Cooking
- player->SEND_POI(-1214.5, -21.23, 6, 6, 0, "Aska's Kitchen");
+ player->SEND_POI(-1214.5, -21.23, 7, 6, 0, "Aska's Kitchen");
player->SEND_GOSSIP_MENU(1334,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Enchanting
- player->SEND_POI(-1112.65, 48.26, 6, 6, 0, "Dawnstrider Enchanters");
+ player->SEND_POI(-1112.65, 48.26, 7, 6, 0, "Dawnstrider Enchanters");
player->SEND_GOSSIP_MENU(1335,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //First Aid
- player->SEND_POI(-996.58, 200.5, 6, 6, 0, "Spiritual Healing");
+ player->SEND_POI(-996.58, 200.5, 7, 6, 0, "Spiritual Healing");
player->SEND_GOSSIP_MENU(1336,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Fishing
- player->SEND_POI(-1169.35, -68.87, 6, 6, 0, "Mountaintop Bait & Tackle");
+ player->SEND_POI(-1169.35, -68.87, 7, 6, 0, "Mountaintop Bait & Tackle");
player->SEND_GOSSIP_MENU(1337,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Herbalism
- player->SEND_POI(-1137.7, -1.51, 6, 6, 0, "Holistic Herbalism");
+ player->SEND_POI(-1137.7, -1.51, 7, 6, 0, "Holistic Herbalism");
player->SEND_GOSSIP_MENU(1338,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Leatherworking
- player->SEND_POI(-1156.22, 66.86, 6, 6, 0, "Thunder Bluff Armorers");
+ player->SEND_POI(-1156.22, 66.86, 7, 6, 0, "Thunder Bluff Armorers");
player->SEND_GOSSIP_MENU(1339,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Mining
- player->SEND_POI(-1249.17, 155, 6, 6, 0, "Stonehoof Geology");
+ player->SEND_POI(-1249.17, 155, 7, 6, 0, "Stonehoof Geology");
player->SEND_GOSSIP_MENU(1340,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Skinning
- player->SEND_POI(-1148.56, 51.18, 6, 6, 0, "Mooranta");
+ player->SEND_POI(-1148.56, 51.18, 7, 6, 0, "Mooranta");
player->SEND_GOSSIP_MENU(1343,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Tailoring
- player->SEND_POI(-1156.22, 66.86, 6, 6, 0, "Thunder Bluff Armorers");
+ player->SEND_POI(-1156.22, 66.86, 7, 6, 0, "Thunder Bluff Armorers");
player->SEND_GOSSIP_MENU(1341,_Creature->GetGUID());
break;
}
@@ -525,35 +525,35 @@ void SendDefaultMenu_guard_darnassus(Player *player, Creature *_Creature, uint32
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Auction house
- player->SEND_POI(9861.23, 2334.55, 6, 6, 0, "Darnassus Auction House");
+ player->SEND_POI(9861.23, 2334.55, 7, 6, 0, "Darnassus Auction House");
player->SEND_GOSSIP_MENU(3833, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Bank
- player->SEND_POI(9938.45, 2512.35, 6, 6, 0, "Darnassus Bank");
+ player->SEND_POI(9938.45, 2512.35, 7, 6, 0, "Darnassus Bank");
player->SEND_GOSSIP_MENU(3017, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Wind master
- player->SEND_POI(9945.65, 2618.94, 6, 6, 0, "Rut'theran Village");
+ player->SEND_POI(9945.65, 2618.94, 7, 6, 0, "Rut'theran Village");
player->SEND_GOSSIP_MENU(3018, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Guild master
- player->SEND_POI(10076.40, 2199.59, 6, 6, 0, "Darnassus Guild Master");
+ player->SEND_POI(10076.40, 2199.59, 7, 6, 0, "Darnassus Guild Master");
player->SEND_GOSSIP_MENU(3019, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Inn
- player->SEND_POI(10133.29, 2222.52, 6, 6, 0, "Darnassus Inn");
+ player->SEND_POI(10133.29, 2222.52, 7, 6, 0, "Darnassus Inn");
player->SEND_GOSSIP_MENU(3020, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Mailbox
- player->SEND_POI(9942.17, 2495.48, 6, 6, 0, "Darnassus Mailbox");
+ player->SEND_POI(9942.17, 2495.48, 7, 6, 0, "Darnassus Mailbox");
player->SEND_GOSSIP_MENU(3021, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Stable master
- player->SEND_POI(10167.20, 2522.66, 6, 6, 0, "Alassin");
+ player->SEND_POI(10167.20, 2522.66, 7, 6, 0, "Alassin");
player->SEND_GOSSIP_MENU(5980, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Weapon trainer
- player->SEND_POI(9907.11, 2329.70, 6, 6, 0, "Ilyenia Moonfire");
+ player->SEND_POI(9907.11, 2329.70, 7, 6, 0, "Ilyenia Moonfire");
player->SEND_GOSSIP_MENU(4517, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Battlemaster
@@ -590,15 +590,15 @@ void SendBattleMasterMenu_guard_darnassus(Player *player, Creature *_Creature, u
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //AV
- player->SEND_POI(9923.61, 2327.43, 6, 6, 0, "Brogun Stoneshield");
+ player->SEND_POI(9923.61, 2327.43, 7, 6, 0, "Brogun Stoneshield");
player->SEND_GOSSIP_MENU(7518, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //AB
- player->SEND_POI(9977.37, 2324.39, 6, 6, 0, "Keras Wolfheart");
+ player->SEND_POI(9977.37, 2324.39, 7, 6, 0, "Keras Wolfheart");
player->SEND_GOSSIP_MENU(7651, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //WSG
- player->SEND_POI(9979.84, 2315.79, 6, 6, 0, "Aethalas");
+ player->SEND_POI(9979.84, 2315.79, 7, 6, 0, "Aethalas");
player->SEND_GOSSIP_MENU(7482, _Creature->GetGUID());
break;
}
@@ -609,23 +609,23 @@ void SendClassTrainerMenu_guard_darnassus(Player *player, Creature *_Creature, u
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Druid
- player->SEND_POI(10186, 2570.46, 6, 6, 0, "Darnassus Druid Trainer");
+ player->SEND_POI(10186, 2570.46, 7, 6, 0, "Darnassus Druid Trainer");
player->SEND_GOSSIP_MENU(3024, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Hunter
- player->SEND_POI(10177.29, 2511.10, 6, 6, 0, "Darnassus Hunter Trainer");
+ player->SEND_POI(10177.29, 2511.10, 7, 6, 0, "Darnassus Hunter Trainer");
player->SEND_GOSSIP_MENU(3023, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Priest
- player->SEND_POI(9659.12, 2524.88, 6, 6, 0, "Temple of the Moon");
+ player->SEND_POI(9659.12, 2524.88, 7, 6, 0, "Temple of the Moon");
player->SEND_GOSSIP_MENU(3025, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Rogue
- player->SEND_POI(10122, 2599.12, 6, 6, 0, "Darnassus Rogue Trainer");
+ player->SEND_POI(10122, 2599.12, 7, 6, 0, "Darnassus Rogue Trainer");
player->SEND_GOSSIP_MENU(3026, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Warrior
- player->SEND_POI(9951.91, 2280.38, 6, 6, 0, "Warrior's Terrace");
+ player->SEND_POI(9951.91, 2280.38, 7, 6, 0, "Warrior's Terrace");
player->SEND_GOSSIP_MENU(3033, _Creature->GetGUID());
break;
}
@@ -636,39 +636,39 @@ void SendProfTrainerMenu_guard_darnassus(Player *player, Creature *_Creature, ui
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(10075.90, 2356.76, 6, 6, 0, "Darnassus Alchemy Trainer");
+ player->SEND_POI(10075.90, 2356.76, 7, 6, 0, "Darnassus Alchemy Trainer");
player->SEND_GOSSIP_MENU(3035, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Cooking
- player->SEND_POI(10088.59, 2419.21, 6, 6, 0, "Darnassus Cooking Trainer");
+ player->SEND_POI(10088.59, 2419.21, 7, 6, 0, "Darnassus Cooking Trainer");
player->SEND_GOSSIP_MENU(3036, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Enchanting
- player->SEND_POI(10146.09, 2313.42, 6, 6, 0, "Darnassus Enchanting Trainer");
+ player->SEND_POI(10146.09, 2313.42, 7, 6, 0, "Darnassus Enchanting Trainer");
player->SEND_GOSSIP_MENU(3337, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //First Aid
- player->SEND_POI(10150.09, 2390.43, 6, 6, 0, "Darnassus First Aid Trainer");
+ player->SEND_POI(10150.09, 2390.43, 7, 6, 0, "Darnassus First Aid Trainer");
player->SEND_GOSSIP_MENU(3037, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Fishing
- player->SEND_POI(9836.20, 2432.17, 6, 6, 0, "Darnassus Fishing Trainer");
+ player->SEND_POI(9836.20, 2432.17, 7, 6, 0, "Darnassus Fishing Trainer");
player->SEND_GOSSIP_MENU(3038, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Herbalism
- player->SEND_POI(9757.17, 2430.16, 6, 6, 0, "Darnassus Herbalism Trainer");
+ player->SEND_POI(9757.17, 2430.16, 7, 6, 0, "Darnassus Herbalism Trainer");
player->SEND_GOSSIP_MENU(3039, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Leatherworking
- player->SEND_POI(10086.59, 2255.77, 6, 6, 0, "Darnassus Leatherworking Trainer");
+ player->SEND_POI(10086.59, 2255.77, 7, 6, 0, "Darnassus Leatherworking Trainer");
player->SEND_GOSSIP_MENU(3040, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Skinning
- player->SEND_POI(10081.40, 2257.18, 6, 6, 0, "Darnassus Skinning Trainer");
+ player->SEND_POI(10081.40, 2257.18, 7, 6, 0, "Darnassus Skinning Trainer");
player->SEND_GOSSIP_MENU(3042, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Tailoring
- player->SEND_POI(10079.70, 2268.19, 6, 6, 0, "Darnassus Tailor");
+ player->SEND_POI(10079.70, 2268.19, 7, 6, 0, "Darnassus Tailor");
player->SEND_GOSSIP_MENU(3044, _Creature->GetGUID());
break;
}
@@ -727,11 +727,11 @@ void SendDefaultMenu_guard_dunmorogh(Player *player, Creature *_Creature, uint32
player->SEND_GOSSIP_MENU(4290,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Inn
- player->SEND_POI(-5582.66, -525.89, 6, 6, 0, "Thunderbrew Distillery");
+ player->SEND_POI(-5582.66, -525.89, 7, 6, 0, "Thunderbrew Distillery");
player->SEND_GOSSIP_MENU(4291,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Stable Master
- player->SEND_POI(-5604, -509.58, 6, 6, 0, "Shelby Stoneflint");
+ player->SEND_POI(-5604, -509.58, 7, 6, 0, "Shelby Stoneflint");
player->SEND_GOSSIP_MENU(5985,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Class trainer
@@ -767,31 +767,31 @@ void SendClassTrainerMenu_guard_dunmorogh(Player *player, Creature *_Creature, u
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Hunter
- player->SEND_POI(-5618.29, -454.25, 6, 6, 0, "Grif Wildheart");
+ player->SEND_POI(-5618.29, -454.25, 7, 6, 0, "Grif Wildheart");
player->SEND_GOSSIP_MENU(4293,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Mage
- player->SEND_POI(-5585.6, -539.99, 6, 6, 0, "Magis Sparkmantle");
+ player->SEND_POI(-5585.6, -539.99, 7, 6, 0, "Magis Sparkmantle");
player->SEND_GOSSIP_MENU(4294,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Paladin
- player->SEND_POI(-5585.6, -539.99, 6, 6, 0, "Azar Stronghammer");
+ player->SEND_POI(-5585.6, -539.99, 7, 6, 0, "Azar Stronghammer");
player->SEND_GOSSIP_MENU(4295,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Priest
- player->SEND_POI(-5591.74, -525.61, 6, 6, 0, "Maxan Anvol");
+ player->SEND_POI(-5591.74, -525.61, 7, 6, 0, "Maxan Anvol");
player->SEND_GOSSIP_MENU(4296,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Rogue
- player->SEND_POI(-5602.75, -542.4, 6, 6, 0, "Hogral Bakkan");
+ player->SEND_POI(-5602.75, -542.4, 7, 6, 0, "Hogral Bakkan");
player->SEND_GOSSIP_MENU(4297,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Warlock
- player->SEND_POI(-5641.97, -523.76, 6, 6, 0, "Gimrizz Shadowcog");
+ player->SEND_POI(-5641.97, -523.76, 7, 6, 0, "Gimrizz Shadowcog");
player->SEND_GOSSIP_MENU(4298,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Warrior
- player->SEND_POI(-5604.79, -529.38, 6, 6, 0, "Granis Swiftaxe");
+ player->SEND_POI(-5604.79, -529.38, 7, 6, 0, "Granis Swiftaxe");
player->SEND_GOSSIP_MENU(4299,_Creature->GetGUID());
break;
}
@@ -805,26 +805,26 @@ void SendProfTrainerMenu_guard_dunmorogh(Player *player, Creature *_Creature, ui
player->SEND_GOSSIP_MENU(4301,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Blacksmithing
- player->SEND_POI(-5584.72, -428.41, 6, 6, 0, "Tognus Flintfire");
+ player->SEND_POI(-5584.72, -428.41, 7, 6, 0, "Tognus Flintfire");
player->SEND_GOSSIP_MENU(4302,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Cooking
- player->SEND_POI(-5596.85, -541.43, 6, 6, 0, "Gremlock Pilsnor");
+ player->SEND_POI(-5596.85, -541.43, 7, 6, 0, "Gremlock Pilsnor");
player->SEND_GOSSIP_MENU(4303,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Enchanting
player->SEND_GOSSIP_MENU(4304,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Engineering
- player->SEND_POI(-5531, -666.53, 6, 6, 0, "Bronk Guzzlegear");
+ player->SEND_POI(-5531, -666.53, 7, 6, 0, "Bronk Guzzlegear");
player->SEND_GOSSIP_MENU(4305,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //First Aid
- player->SEND_POI(-5603.67, -523.57, 6, 6, 0, "Thamner Pol");
+ player->SEND_POI(-5603.67, -523.57, 7, 6, 0, "Thamner Pol");
player->SEND_GOSSIP_MENU(4306,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Fishing
- player->SEND_POI(-5199.9, 58.58, 6, 6, 0, "Paxton Ganter");
+ player->SEND_POI(-5199.9, 58.58, 7, 6, 0, "Paxton Ganter");
player->SEND_GOSSIP_MENU(4307,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Herbalism
@@ -834,7 +834,7 @@ void SendProfTrainerMenu_guard_dunmorogh(Player *player, Creature *_Creature, ui
player->SEND_GOSSIP_MENU(4310,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Mining
- player->SEND_POI(-5531, -666.53, 6, 6, 0, "Yarr Hamerstone");
+ player->SEND_POI(-5531, -666.53, 7, 6, 0, "Yarr Hamerstone");
player->SEND_GOSSIP_MENU(4311,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Skinning
@@ -893,11 +893,11 @@ void SendDefaultMenu_guard_durotar(Player *player, Creature *_Creature, uint32 a
player->SEND_GOSSIP_MENU(4033,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Inn
- player->SEND_POI(338.7, -4688.87, 6, 6, 0, "Razor Hill Inn");
+ player->SEND_POI(338.7, -4688.87, 7, 6, 0, "Razor Hill Inn");
player->SEND_GOSSIP_MENU(4034,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Stable master
- player->SEND_POI(330.31, -4710.66, 6, 6, 0, "Shoja'my");
+ player->SEND_POI(330.31, -4710.66, 7, 6, 0, "Shoja'my");
player->SEND_GOSSIP_MENU(5973,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Class trainer
@@ -933,31 +933,31 @@ void SendClassTrainerMenu_guard_durotar(Player *player, Creature *_Creature, uin
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Hunter
- player->SEND_POI(276, -4706.72, 6, 6, 0, "Thotar");
+ player->SEND_POI(276, -4706.72, 7, 6, 0, "Thotar");
player->SEND_GOSSIP_MENU(4013,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Mage
- player->SEND_POI(-839.33, -4935.6, 6, 6, 0, "Un'Thuwa");
+ player->SEND_POI(-839.33, -4935.6, 7, 6, 0, "Un'Thuwa");
player->SEND_GOSSIP_MENU(4014,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Priest
- player->SEND_POI(296.22, -4828.1, 6, 6, 0, "Tai'jin");
+ player->SEND_POI(296.22, -4828.1, 7, 6, 0, "Tai'jin");
player->SEND_GOSSIP_MENU(4015,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Rogue
- player->SEND_POI(265.76, -4709, 6, 6, 0, "Kaplak");
+ player->SEND_POI(265.76, -4709, 7, 6, 0, "Kaplak");
player->SEND_GOSSIP_MENU(4016,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Shaman
- player->SEND_POI(307.79, -4836.97, 6, 6, 0, "Swart");
+ player->SEND_POI(307.79, -4836.97, 7, 6, 0, "Swart");
player->SEND_GOSSIP_MENU(4017,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Warlock
- player->SEND_POI(355.88, -4836.45, 6, 6, 0, "Dhugru Gorelust");
+ player->SEND_POI(355.88, -4836.45, 7, 6, 0, "Dhugru Gorelust");
player->SEND_GOSSIP_MENU(4018,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Warrior
- player->SEND_POI(312.3, -4824.66, 6, 6, 0, "Tarshaw Jaggedscar");
+ player->SEND_POI(312.3, -4824.66, 7, 6, 0, "Tarshaw Jaggedscar");
player->SEND_GOSSIP_MENU(4019,_Creature->GetGUID());
break;
}
@@ -968,11 +968,11 @@ void SendProfTrainerMenu_guard_durotar(Player *player, Creature *_Creature, uint
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(-800.25, -4894.33, 6, 6, 0, "Miao'zan");
+ player->SEND_POI(-800.25, -4894.33, 7, 6, 0, "Miao'zan");
player->SEND_GOSSIP_MENU(4020,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Blacksmithing
- player->SEND_POI(373.24, -4716.45, 6, 6, 0, "Dwukk");
+ player->SEND_POI(373.24, -4716.45, 7, 6, 0, "Dwukk");
player->SEND_GOSSIP_MENU(4021,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Cooking
@@ -982,26 +982,26 @@ void SendProfTrainerMenu_guard_durotar(Player *player, Creature *_Creature, uint
player->SEND_GOSSIP_MENU(4023,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Engineering
- player->SEND_POI(368.95, -4723.95, 6, 6, 0, "Mukdrak");
+ player->SEND_POI(368.95, -4723.95, 7, 6, 0, "Mukdrak");
player->SEND_GOSSIP_MENU(4024,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //First Aid
- player->SEND_POI(327.17, -4825.62, 6, 6, 0, "Rawrk");
+ player->SEND_POI(327.17, -4825.62, 7, 6, 0, "Rawrk");
player->SEND_GOSSIP_MENU(4025,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Fishing
- player->SEND_POI(-1065.48, -4777.43, 6, 6, 0, "Lau'Tiki");
+ player->SEND_POI(-1065.48, -4777.43, 7, 6, 0, "Lau'Tiki");
player->SEND_GOSSIP_MENU(4026,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Herbalism
- player->SEND_POI(-836.25, -4896.89, 6, 6, 0, "Mishiki");
+ player->SEND_POI(-836.25, -4896.89, 7, 6, 0, "Mishiki");
player->SEND_GOSSIP_MENU(4027,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Leatherworking
player->SEND_GOSSIP_MENU(4028,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Mining
- player->SEND_POI(366.94, -4705, 6, 6, 0, "Krunn");
+ player->SEND_POI(366.94, -4705, 7, 6, 0, "Krunn");
player->SEND_GOSSIP_MENU(4029,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Skinning
@@ -1064,11 +1064,11 @@ void SendDefaultMenu_guard_elwynnforest(Player *player, Creature *_Creature, uin
player->SEND_GOSSIP_MENU(4262,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Inn
- player->SEND_POI(-9459.34, 42.08, 6, 6, 0, "Lion's Pride Inn");
+ player->SEND_POI(-9459.34, 42.08, 7, 6, 0, "Lion's Pride Inn");
player->SEND_GOSSIP_MENU(4263,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Stable Master
- player->SEND_POI(-9466.62, 45.87, 6, 6, 0, "Erma");
+ player->SEND_POI(-9466.62, 45.87, 7, 6, 0, "Erma");
player->SEND_GOSSIP_MENU(5983,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Class trainer
@@ -1111,27 +1111,27 @@ void SendClassTrainerMenu_guard_elwynnforest(Player *player, Creature *_Creature
player->SEND_GOSSIP_MENU(4266,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Mage
- player->SEND_POI(-9471.12, 33.44, 6, 6, 0, "Zaldimar Wefhellt");
+ player->SEND_POI(-9471.12, 33.44, 7, 6, 0, "Zaldimar Wefhellt");
player->SEND_GOSSIP_MENU(4268,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Paladin
- player->SEND_POI(-9469, 108.05, 6, 6, 0, "Brother Wilhelm");
+ player->SEND_POI(-9469, 108.05, 7, 6, 0, "Brother Wilhelm");
player->SEND_GOSSIP_MENU(4269,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Priest
- player->SEND_POI(-9461.07, 32.6, 6, 6, 0, "Priestess Josetta");
+ player->SEND_POI(-9461.07, 32.6, 7, 6, 0, "Priestess Josetta");
player->SEND_GOSSIP_MENU(4267,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Rogue
- player->SEND_POI(-9465.13, 13.29, 6, 6, 0, "Keryn Sylvius");
+ player->SEND_POI(-9465.13, 13.29, 7, 6, 0, "Keryn Sylvius");
player->SEND_GOSSIP_MENU(4270,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Warlock
- player->SEND_POI(-9473.21, -4.08, 6, 6, 0, "Maximillian Crowe");
+ player->SEND_POI(-9473.21, -4.08, 7, 6, 0, "Maximillian Crowe");
player->SEND_GOSSIP_MENU(4272,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Warrior
- player->SEND_POI(-9461.82, 109.50, 6, 6, 0, "Lyria Du Lac");
+ player->SEND_POI(-9461.82, 109.50, 7, 6, 0, "Lyria Du Lac");
player->SEND_GOSSIP_MENU(4271,_Creature->GetGUID());
break;
}
@@ -1142,15 +1142,15 @@ void SendProfTrainerMenu_guard_elwynnforest(Player *player, Creature *_Creature,
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(-9057.04, 153.63, 6, 6, 0, "Alchemist Mallory");
+ player->SEND_POI(-9057.04, 153.63, 7, 6, 0, "Alchemist Mallory");
player->SEND_GOSSIP_MENU(4274,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Blacksmithing
- player->SEND_POI(-9456.58, 87.90, 6, 6, 0, "Smith Argus");
+ player->SEND_POI(-9456.58, 87.90, 7, 6, 0, "Smith Argus");
player->SEND_GOSSIP_MENU(4275,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Cooking
- player->SEND_POI(-9467.54, -3.16, 6, 6, 0, "Tomas");
+ player->SEND_POI(-9467.54, -3.16, 7, 6, 0, "Tomas");
player->SEND_GOSSIP_MENU(4276,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Enchanting
@@ -1160,30 +1160,30 @@ void SendProfTrainerMenu_guard_elwynnforest(Player *player, Creature *_Creature,
player->SEND_GOSSIP_MENU(4278,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //First Aid
- player->SEND_POI(-9456.82, 30.49, 6, 6, 0, "Michelle Belle");
+ player->SEND_POI(-9456.82, 30.49, 7, 6, 0, "Michelle Belle");
player->SEND_GOSSIP_MENU(4279,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Fishing
- player->SEND_POI(-9386.54, -118.73, 6, 6, 0, "Lee Brown");
+ player->SEND_POI(-9386.54, -118.73, 7, 6, 0, "Lee Brown");
player->SEND_GOSSIP_MENU(4280,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Herbalism
- player->SEND_POI(-9060.70, 149.23, 6, 6, 0, "Herbalist Pomeroy");
+ player->SEND_POI(-9060.70, 149.23, 7, 6, 0, "Herbalist Pomeroy");
player->SEND_GOSSIP_MENU(4281,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Leatherworking
- player->SEND_POI(-9376.12, -75.23, 6, 6, 0, "Adele Fielder");
+ player->SEND_POI(-9376.12, -75.23, 7, 6, 0, "Adele Fielder");
player->SEND_GOSSIP_MENU(4282,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Mining
player->SEND_GOSSIP_MENU(4283,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Skinning
- player->SEND_POI(-9536.91, -1212.76, 6, 6, 0, "Helene Peltskinner");
+ player->SEND_POI(-9536.91, -1212.76, 7, 6, 0, "Helene Peltskinner");
player->SEND_GOSSIP_MENU(4284,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 12: //Tailoring
- player->SEND_POI(-9376.12, -75.23, 6, 6, 0, "Eldrin");
+ player->SEND_POI(-9376.12, -75.23, 7, 6, 0, "Eldrin");
player->SEND_GOSSIP_MENU(4285,_Creature->GetGUID());
break;
}
@@ -1230,18 +1230,18 @@ void SendDefaultMenu_guard_eversong(Player *player, Creature *_Creature, uint32
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Bat Handler
- player->SEND_POI(9371.93, -7164.80, 6, 6, 0, "Skymistress Gloaming");
+ player->SEND_POI(9371.93, -7164.80, 7, 6, 0, "Skymistress Gloaming");
player->SEND_GOSSIP_MENU(10181,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Guild master
player->SEND_GOSSIP_MENU(10182,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Inn
- player->SEND_POI(9483.74, -6844.58, 6, 6, 0, "Delaniel's inn");
+ player->SEND_POI(9483.74, -6844.58, 7, 6, 0, "Delaniel's inn");
player->SEND_GOSSIP_MENU(10183,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Stable Master
- player->SEND_POI(9489.62, -6829.93, 6, 6, 0, "Anathos");
+ player->SEND_POI(9489.62, -6829.93, 7, 6, 0, "Anathos");
player->SEND_GOSSIP_MENU(10184,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Class trainer
@@ -1280,27 +1280,27 @@ void SendClassTrainerMenu_guard_eversong(Player *player, Creature *_Creature, ui
player->SEND_GOSSIP_MENU(10185,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Hunter
- player->SEND_POI(9527.44, -6865.25, 6, 6, 0, "Hannovia");
+ player->SEND_POI(9527.44, -6865.25, 7, 6, 0, "Hannovia");
player->SEND_GOSSIP_MENU(10186,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Mage
- player->SEND_POI(9464.24, -6855.52, 6, 6, 0, "Garridel");
+ player->SEND_POI(9464.24, -6855.52, 7, 6, 0, "Garridel");
player->SEND_GOSSIP_MENU(10187,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Paladin
- player->SEND_POI(9517.61, -6871.04, 6, 6, 0, "Noellene");
+ player->SEND_POI(9517.61, -6871.04, 7, 6, 0, "Noellene");
player->SEND_GOSSIP_MENU(10189,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Priest
- player->SEND_POI(9467.39, -6845.72, 6, 6, 0, "Ponaris");
+ player->SEND_POI(9467.39, -6845.72, 7, 6, 0, "Ponaris");
player->SEND_GOSSIP_MENU(10190,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Rogue
- player->SEND_POI(9533.67, -6877.39, 6, 6, 0, "Tannaria");
+ player->SEND_POI(9533.67, -6877.39, 7, 6, 0, "Tannaria");
player->SEND_GOSSIP_MENU(10191,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Warlock
- player->SEND_POI(9468.99, -6865.60, 6, 6, 0, "Celoenus");
+ player->SEND_POI(9468.99, -6865.60, 7, 6, 0, "Celoenus");
player->SEND_GOSSIP_MENU(10192,_Creature->GetGUID());
break;
}
@@ -1311,48 +1311,48 @@ void SendProfTrainerMenu_guard_eversong(Player *player, Creature *_Creature, uin
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(8659.90, -6368.12, 6, 6, 0, "Arcanist Sheynathren");
+ player->SEND_POI(8659.90, -6368.12, 7, 6, 0, "Arcanist Sheynathren");
player->SEND_GOSSIP_MENU(10193,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Blacksmithing
- player->SEND_POI(8984.21, -7419.21, 6, 6, 0, "Arathel Sunforge");
+ player->SEND_POI(8984.21, -7419.21, 7, 6, 0, "Arathel Sunforge");
player->SEND_GOSSIP_MENU(10194,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Cooking
- player->SEND_POI(9494.04, -6881.51, 6, 6, 0, "Quarelestra");
+ player->SEND_POI(9494.04, -6881.51, 7, 6, 0, "Quarelestra");
player->SEND_GOSSIP_MENU(10195,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Engineering
player->SEND_GOSSIP_MENU(10197,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //First Aid
- player->SEND_POI(9479.46, -6879.16, 6, 6, 0, "Kanaria");
+ player->SEND_POI(9479.46, -6879.16, 7, 6, 0, "Kanaria");
player->SEND_GOSSIP_MENU(10198,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Fishing
player->SEND_GOSSIP_MENU(10199,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Herbalism
- player->SEND_POI(8678.92, -6329.09, 6, 6, 0, "Botanist Tyniarrel");
+ player->SEND_POI(8678.92, -6329.09, 7, 6, 0, "Botanist Tyniarrel");
player->SEND_GOSSIP_MENU(10200,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Jewelcrafting
- player->SEND_POI(9484.32, -6874.98, 6, 6, 0, "Aleinia");
+ player->SEND_POI(9484.32, -6874.98, 7, 6, 0, "Aleinia");
player->SEND_GOSSIP_MENU(10203,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Leatherworking
- player->SEND_POI(9362.04, -7130.33, 6, 6, 0, "Sathein");
+ player->SEND_POI(9362.04, -7130.33, 7, 6, 0, "Sathein");
player->SEND_GOSSIP_MENU(10204,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Mining
player->SEND_GOSSIP_MENU(10205,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Skinning
- player->SEND_POI(9362.04, -7130.33, 6, 6, 0, "Mathreyn");
+ player->SEND_POI(9362.04, -7130.33, 7, 6, 0, "Mathreyn");
player->SEND_GOSSIP_MENU(10206,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 12: //Tailoring
- player->SEND_POI(8680.36, -6327.51, 6, 6, 0, "Sempstress Ambershine");
+ player->SEND_POI(8680.36, -6327.51, 7, 6, 0, "Sempstress Ambershine");
player->SEND_GOSSIP_MENU(10207,_Creature->GetGUID());
break;
}
@@ -1404,35 +1404,35 @@ void SendDefaultMenu_guard_exodar(Player *player, Creature *_Creature, uint32 ac
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Auction house
- player->SEND_POI(-4023.6, -11739.3, 6, 6, 0, "Exodar Auction House");
+ player->SEND_POI(-4023.6, -11739.3, 7, 6, 0, "Exodar Auction House");
player->SEND_GOSSIP_MENU(9528, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Bank
- player->SEND_POI(-3923.89, -11544.5, 6, 6, 0, "Exodar Bank");
+ player->SEND_POI(-3923.89, -11544.5, 7, 6, 0, "Exodar Bank");
player->SEND_GOSSIP_MENU(9529, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Guild master
- player->SEND_POI(-4092.57, -11626.5, 6, 6, 0, "Exodar Guild Master");
+ player->SEND_POI(-4092.57, -11626.5, 7, 6, 0, "Exodar Guild Master");
player->SEND_GOSSIP_MENU(9539, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Hippogryph master
- player->SEND_POI(-4060.46, -11787.1, 6, 6, 0, "Exodar Hippogryph Master");
+ player->SEND_POI(-4060.46, -11787.1, 7, 6, 0, "Exodar Hippogryph Master");
player->SEND_GOSSIP_MENU(9530, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Inn
- player->SEND_POI(-3741.87, -11695.1, 6, 6, 0, "Exodar Inn");
+ player->SEND_POI(-3741.87, -11695.1, 7, 6, 0, "Exodar Inn");
player->SEND_GOSSIP_MENU(9545, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Mailbox
- player->SEND_POI(-3972.5, -11696.0, 6, 6, 0, "Mailbox");
+ player->SEND_POI(-3972.5, -11696.0, 7, 6, 0, "Mailbox");
player->SEND_GOSSIP_MENU(10254, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Stable master
- player->SEND_POI(-3786.5, -11702.5, 6, 6, 0, "Stable Master Arthaid");
+ player->SEND_POI(-3786.5, -11702.5, 7, 6, 0, "Stable Master Arthaid");
player->SEND_GOSSIP_MENU(9558, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Weapon trainer
- player->SEND_POI(-4215.68, -11628.9, 6, 6, 0, "Weapon Master Handiir");
+ player->SEND_POI(-4215.68, -11628.9, 7, 6, 0, "Weapon Master Handiir");
player->SEND_GOSSIP_MENU(9565, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Battlemaster
@@ -1477,23 +1477,23 @@ void SendBattleMasterMenu_guard_exodar(Player *player, Creature *_Creature, uint
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //AV
- player->SEND_POI(-3978.1, -11357, 6, 6, 0, "Alterac Valley Battlemaster");
+ player->SEND_POI(-3978.1, -11357, 7, 6, 0, "Alterac Valley Battlemaster");
player->SEND_GOSSIP_MENU(9531, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //AB
- player->SEND_POI(-3998.9, -11345.2, 6, 6, 0, "Arathi Basin Battlemaster");
+ player->SEND_POI(-3998.9, -11345.2, 7, 6, 0, "Arathi Basin Battlemaster");
player->SEND_GOSSIP_MENU(9531, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //A
- player->SEND_POI(-3759.27, -11695.63, 6, 6, 0, "Miglik Blotstrom");
+ player->SEND_POI(-3759.27, -11695.63, 7, 6, 0, "Miglik Blotstrom");
player->SEND_GOSSIP_MENU(10223, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //EOS
- player->SEND_POI(-3978.1, -11357, 6, 6, 0, "Eye Of The Storm Battlemaster");
+ player->SEND_POI(-3978.1, -11357, 7, 6, 0, "Eye Of The Storm Battlemaster");
player->SEND_GOSSIP_MENU(9531, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //WSG
- player->SEND_POI(-3977.5, -11381.2, 6, 6, 0, "Warsong Gulch Battlemaster");
+ player->SEND_POI(-3977.5, -11381.2, 7, 6, 0, "Warsong Gulch Battlemaster");
player->SEND_GOSSIP_MENU(9531, _Creature->GetGUID());
break;
}
@@ -1504,31 +1504,31 @@ void SendClassTrainerMenu_guard_exodar(Player *player, Creature *_Creature, uint
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Druid
- player->SEND_POI(-4276.0, -11495, 6, 6, 0, "Exodar Druid Trainer");
+ player->SEND_POI(-4276.0, -11495, 7, 6, 0, "Exodar Druid Trainer");
player->SEND_GOSSIP_MENU(9534, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Hunter
- player->SEND_POI(-4210.6, -11575.2, 6, 6, 0, "Exodar Hunter Trainer");
+ player->SEND_POI(-4210.6, -11575.2, 7, 6, 0, "Exodar Hunter Trainer");
player->SEND_GOSSIP_MENU(9544, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Mage
- player->SEND_POI(-4057.32, -11556.5, 6, 6, 0, "Exodar Mage Trainer");
+ player->SEND_POI(-4057.32, -11556.5, 7, 6, 0, "Exodar Mage Trainer");
player->SEND_GOSSIP_MENU(9550, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Paladin
- player->SEND_POI(-4191.2, -11470.4, 6, 6, 0, "Exodar Paladin Trainer");
+ player->SEND_POI(-4191.2, -11470.4, 7, 6, 0, "Exodar Paladin Trainer");
player->SEND_GOSSIP_MENU(9553, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Priest
- player->SEND_POI(-3969.63, -11482.8, 6, 6, 0, "Exodar Priest Trainer");
+ player->SEND_POI(-3969.63, -11482.8, 7, 6, 0, "Exodar Priest Trainer");
player->SEND_GOSSIP_MENU(9554, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Shaman
- player->SEND_POI(-3805.5, -11380.7, 6, 6, 0, "Exodar Shaman Trainer");
+ player->SEND_POI(-3805.5, -11380.7, 7, 6, 0, "Exodar Shaman Trainer");
player->SEND_GOSSIP_MENU(9556, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Warrior
- player->SEND_POI(-4189.43, -11653.7, 6, 6, 0, "Exodar Warrior Trainer");
+ player->SEND_POI(-4189.43, -11653.7, 7, 6, 0, "Exodar Warrior Trainer");
player->SEND_GOSSIP_MENU(9562, _Creature->GetGUID());
break;
}
@@ -1539,55 +1539,55 @@ void SendProfTrainerMenu_guard_exodar(Player *player, Creature *_Creature, uint3
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(-4040.6, -11364.5, 6, 6, 0, "Exodar Alchemy Trainer");
+ player->SEND_POI(-4040.6, -11364.5, 7, 6, 0, "Exodar Alchemy Trainer");
player->SEND_GOSSIP_MENU(9527, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Blacksmithing
- player->SEND_POI(-4229.5, -11706, 6, 6, 0, "Exodar Blacksmithing Trainer");
+ player->SEND_POI(-4229.5, -11706, 7, 6, 0, "Exodar Blacksmithing Trainer");
player->SEND_GOSSIP_MENU(9532, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Cooking
- player->SEND_POI(-3798.3, -11651.7, 6, 6, 0, "Exodar Cooking Trainer");
+ player->SEND_POI(-3798.3, -11651.7, 7, 6, 0, "Exodar Cooking Trainer");
player->SEND_GOSSIP_MENU(9551, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Enchanting
- player->SEND_POI(-3889.3, -11495, 6, 6, 0, "Exodar Enchanting Trainer");
+ player->SEND_POI(-3889.3, -11495, 7, 6, 0, "Exodar Enchanting Trainer");
player->SEND_GOSSIP_MENU(9535, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Engineering
- player->SEND_POI(-4257.68, -11640.3, 6, 6, 0, "Exodar Engineering Trainer");
+ player->SEND_POI(-4257.68, -11640.3, 7, 6, 0, "Exodar Engineering Trainer");
player->SEND_GOSSIP_MENU(9536, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //First Aid
- player->SEND_POI(-3769.5, -11479.6, 6, 6, 0, "Exodar First Aid Trainer");
+ player->SEND_POI(-3769.5, -11479.6, 7, 6, 0, "Exodar First Aid Trainer");
player->SEND_GOSSIP_MENU(9537, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Fishing
- player->SEND_POI(-3725.5, -11385.2, 6, 6, 0, "Exodar Fishing Trainer");
+ player->SEND_POI(-3725.5, -11385.2, 7, 6, 0, "Exodar Fishing Trainer");
player->SEND_GOSSIP_MENU(9538, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Jewelcrafting
- player->SEND_POI(-3783, -11546, 6, 6, 0, "Exodar Jewelcrafting Trainer");
+ player->SEND_POI(-3783, -11546, 7, 6, 0, "Exodar Jewelcrafting Trainer");
player->SEND_GOSSIP_MENU(9547, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Herbalism
- player->SEND_POI(-4040.6, -11364.5, 6, 6, 0, "Exodar Herbalist Trainer");
+ player->SEND_POI(-4040.6, -11364.5, 7, 6, 0, "Exodar Herbalist Trainer");
player->SEND_GOSSIP_MENU(9543, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Leatherworking
- player->SEND_POI(-4140.6, -11776.7, 6, 6, 0, "Exodar Leatherworking Trainer");
+ player->SEND_POI(-4140.6, -11776.7, 7, 6, 0, "Exodar Leatherworking Trainer");
player->SEND_GOSSIP_MENU(9549, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Mining
- player->SEND_POI(-4228, -11697, 6, 6, 0, "Exodar Mining Trainer");
+ player->SEND_POI(-4228, -11697, 7, 6, 0, "Exodar Mining Trainer");
player->SEND_GOSSIP_MENU(9552, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 12: //Skinning
- player->SEND_POI(-4134.97, -11760.5, 6, 6, 0, "Exodar Skinning Trainer");
+ player->SEND_POI(-4134.97, -11760.5, 7, 6, 0, "Exodar Skinning Trainer");
player->SEND_GOSSIP_MENU(9557, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 13: //Tailoring
- player->SEND_POI(-4092.5, -11744.5, 6, 6, 0, "Exodar Tailor Trainer");
+ player->SEND_POI(-4092.5, -11744.5, 7, 6, 0, "Exodar Tailor Trainer");
player->SEND_GOSSIP_MENU(9559, _Creature->GetGUID());
break;
}
@@ -1641,39 +1641,39 @@ void SendDefaultMenu_guard_ironforge(Player *player, Creature *_Creature, uint32
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Auction House
- player->SEND_POI(-4957.39, -911.6, 6, 6, 0, "Ironforge Auction House");
+ player->SEND_POI(-4957.39, -911.6, 7, 6, 0, "Ironforge Auction House");
player->SEND_GOSSIP_MENU(3014, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Bank
- player->SEND_POI(-4891.91, -991.47, 6, 6, 0, "The Vault");
+ player->SEND_POI(-4891.91, -991.47, 7, 6, 0, "The Vault");
player->SEND_GOSSIP_MENU(2761, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Tram
- player->SEND_POI(-4835.27, -1294.69, 6, 6, 0, "Deeprun Tram");
+ player->SEND_POI(-4835.27, -1294.69, 7, 6, 0, "Deeprun Tram");
player->SEND_GOSSIP_MENU(3814, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Gryphon Master
- player->SEND_POI(-4821.52, -1152.3, 6, 6, 0, "Ironforge Gryphon Master");
+ player->SEND_POI(-4821.52, -1152.3, 7, 6, 0, "Ironforge Gryphon Master");
player->SEND_GOSSIP_MENU(2762, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Guild Master
- player->SEND_POI(-5021, -996.45, 6, 6, 0, "Ironforge Visitor's Center");
+ player->SEND_POI(-5021, -996.45, 7, 6, 0, "Ironforge Visitor's Center");
player->SEND_GOSSIP_MENU(2764, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Inn
- player->SEND_POI(-4850.47, -872.57, 6, 6, 0, "Stonefire Tavern");
+ player->SEND_POI(-4850.47, -872.57, 7, 6, 0, "Stonefire Tavern");
player->SEND_GOSSIP_MENU(2768, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Mailbox
- player->SEND_POI(-4845.7, -880.55, 6, 6, 0, "Ironforge Mailbox");
+ player->SEND_POI(-4845.7, -880.55, 7, 6, 0, "Ironforge Mailbox");
player->SEND_GOSSIP_MENU(2769, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Stable Master
- player->SEND_POI(-5010.2, -1262, 6, 6, 0, "Ulbrek Firehand");
+ player->SEND_POI(-5010.2, -1262, 7, 6, 0, "Ulbrek Firehand");
player->SEND_GOSSIP_MENU(5986, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Weapons Trainer
- player->SEND_POI(-5040, -1201.88, 6, 6, 0, "Bixi and Buliwyf");
+ player->SEND_POI(-5040, -1201.88, 7, 6, 0, "Bixi and Buliwyf");
player->SEND_GOSSIP_MENU(4518, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Battlemaster
@@ -1716,15 +1716,15 @@ void SendBattleMasterMenu_guard_ironforge(Player *player, Creature *_Creature, u
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //AV
- player->SEND_POI(-5047.87, -1263.77, 6, 6, 0, "Glordrum Steelbeard");
+ player->SEND_POI(-5047.87, -1263.77, 7, 6, 0, "Glordrum Steelbeard");
player->SEND_GOSSIP_MENU(7483, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //AB
- player->SEND_POI(-5038.37, -1266.39, 6, 6, 0, "Donal Osgood");
+ player->SEND_POI(-5038.37, -1266.39, 7, 6, 0, "Donal Osgood");
player->SEND_GOSSIP_MENU(7649, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //WSG
- player->SEND_POI(-5037.24, -1274.82, 6, 6, 0, "Lylandris");
+ player->SEND_POI(-5037.24, -1274.82, 7, 6, 0, "Lylandris");
player->SEND_GOSSIP_MENU(7528, _Creature->GetGUID());
break;
}
@@ -1735,35 +1735,35 @@ void SendClassTrainerMenu_guard_ironforge(Player *player, Creature *_Creature, u
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Hunter
- player->SEND_POI(-5023, -1253.68, 6, 6, 0, "Hall of Arms");
+ player->SEND_POI(-5023, -1253.68, 7, 6, 0, "Hall of Arms");
player->SEND_GOSSIP_MENU(2770, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Mage
- player->SEND_POI(-4627, -926.45, 6, 6, 0, "Hall of Mysteries");
+ player->SEND_POI(-4627, -926.45, 7, 6, 0, "Hall of Mysteries");
player->SEND_GOSSIP_MENU(2771, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Paladin
- player->SEND_POI(-4627.02, -926.45, 6, 6, 0, "Hall of Mysteries");
+ player->SEND_POI(-4627.02, -926.45, 7, 6, 0, "Hall of Mysteries");
player->SEND_GOSSIP_MENU(2773, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Priest
- player->SEND_POI(-4627, -926.45, 6, 6, 0, "Hall of Mysteries");
+ player->SEND_POI(-4627, -926.45, 7, 6, 0, "Hall of Mysteries");
player->SEND_GOSSIP_MENU(2772, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Rogue
- player->SEND_POI(-4647.83, -1124, 6, 6, 0, "Ironforge Rogue Trainer");
+ player->SEND_POI(-4647.83, -1124, 7, 6, 0, "Ironforge Rogue Trainer");
player->SEND_GOSSIP_MENU(2774, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Warlock
- player->SEND_POI(-4605, -1110.45, 6, 6, 0, "Ironforge Warlock Trainer");
+ player->SEND_POI(-4605, -1110.45, 7, 6, 0, "Ironforge Warlock Trainer");
player->SEND_GOSSIP_MENU(2775, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Warrior
- player->SEND_POI(-5023.08, -1253.68, 6, 6, 0, "Hall of Arms");
+ player->SEND_POI(-5023.08, -1253.68, 7, 6, 0, "Hall of Arms");
player->SEND_GOSSIP_MENU(2776, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Shaman
- player->SEND_POI(-4732, -1147, 6, 6, 0, "Ironforge Shaman Trainer");
+ player->SEND_POI(-4732, -1147, 7, 6, 0, "Ironforge Shaman Trainer");
//incorrect id
player->SEND_GOSSIP_MENU(2766, _Creature->GetGUID());
break;
@@ -1775,51 +1775,51 @@ void SendProfTrainerMenu_guard_ironforge(Player *player, Creature *_Creature, ui
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(-4858.5, -1241.83, 6, 6, 0, "Berryfizz's Potions and Mixed Drinks");
+ player->SEND_POI(-4858.5, -1241.83, 7, 6, 0, "Berryfizz's Potions and Mixed Drinks");
player->SEND_GOSSIP_MENU(2794, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Blacksmithing
- player->SEND_POI(-4796.97, -1110.17, 6, 6, 0, "The Great Forge");
+ player->SEND_POI(-4796.97, -1110.17, 7, 6, 0, "The Great Forge");
player->SEND_GOSSIP_MENU(2795, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Cooking
- player->SEND_POI(-4767.83, -1184.59, 6, 6, 0, "The Bronze Kettle");
+ player->SEND_POI(-4767.83, -1184.59, 7, 6, 0, "The Bronze Kettle");
player->SEND_GOSSIP_MENU(2796, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Enchanting
- player->SEND_POI(-4803.72, -1196.53, 6, 6, 0, "Thistlefuzz Arcanery");
+ player->SEND_POI(-4803.72, -1196.53, 7, 6, 0, "Thistlefuzz Arcanery");
player->SEND_GOSSIP_MENU(2797, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Engineering
- player->SEND_POI(-4799.56, -1250.23, 6, 6, 0, "Springspindle's Gadgets");
+ player->SEND_POI(-4799.56, -1250.23, 7, 6, 0, "Springspindle's Gadgets");
player->SEND_GOSSIP_MENU(2798, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //First Aid
- player->SEND_POI(-4881.6, -1153.13, 6, 6, 0, "Ironforge Physician");
+ player->SEND_POI(-4881.6, -1153.13, 7, 6, 0, "Ironforge Physician");
player->SEND_GOSSIP_MENU(2799, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Fishing
- player->SEND_POI(-4597.91, -1091.93, 6, 6, 0, "Traveling Fisherman");
+ player->SEND_POI(-4597.91, -1091.93, 7, 6, 0, "Traveling Fisherman");
player->SEND_GOSSIP_MENU(2800, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Herbalism
- player->SEND_POI(-4876.9, -1151.92, 6, 6, 0, "Ironforge Physician");
+ player->SEND_POI(-4876.9, -1151.92, 7, 6, 0, "Ironforge Physician");
player->SEND_GOSSIP_MENU(2801, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Leatherworking
- player->SEND_POI(-4745, -1027.57, 6, 6, 0, "Finespindle's Leather Goods");
+ player->SEND_POI(-4745, -1027.57, 7, 6, 0, "Finespindle's Leather Goods");
player->SEND_GOSSIP_MENU(2802, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Minning
- player->SEND_POI(-4705.06, -1116.43, 6, 6, 0, "Deepmountain Mining Guild");
+ player->SEND_POI(-4705.06, -1116.43, 7, 6, 0, "Deepmountain Mining Guild");
player->SEND_GOSSIP_MENU(2804, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Skinning
- player->SEND_POI(-4745, -1027.57, 6, 6, 0, "Finespindle's Leather Goods");
+ player->SEND_POI(-4745, -1027.57, 7, 6, 0, "Finespindle's Leather Goods");
player->SEND_GOSSIP_MENU(2805, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 12: //Tailoring
- player->SEND_POI(-4719.60, -1056.96, 6, 6, 0, "Stonebrow's Clothier");
+ player->SEND_POI(-4719.60, -1056.96, 7, 6, 0, "Stonebrow's Clothier");
player->SEND_GOSSIP_MENU(2807, _Creature->GetGUID());
break;
}
@@ -1873,11 +1873,11 @@ void SendDefaultMenu_guard_mulgore(Player *player, Creature *_Creature, uint32 a
player->SEND_GOSSIP_MENU(4052,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Inn
- player->SEND_POI(-2361.38, -349.19, 6, 6, 0, "Bloodhoof Village Inn");
+ player->SEND_POI(-2361.38, -349.19, 7, 6, 0, "Bloodhoof Village Inn");
player->SEND_GOSSIP_MENU(4053,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Stable master
- player->SEND_POI(-2338.86, -357.56, 6, 6, 0, "Seikwa");
+ player->SEND_POI(-2338.86, -357.56, 7, 6, 0, "Seikwa");
player->SEND_GOSSIP_MENU(5976,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Class trainer
@@ -1909,19 +1909,19 @@ void SendClassTrainerMenu_guard_mulgore(Player *player, Creature *_Creature, uin
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Druid
- player->SEND_POI(-2312.15, -443.69, 6, 6, 0, "Gennia Runetotem");
+ player->SEND_POI(-2312.15, -443.69, 7, 6, 0, "Gennia Runetotem");
player->SEND_GOSSIP_MENU(4054,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Hunter
- player->SEND_POI(-2178.14, -406.14, 6, 6, 0, "Yaw Sharpmane");
+ player->SEND_POI(-2178.14, -406.14, 7, 6, 0, "Yaw Sharpmane");
player->SEND_GOSSIP_MENU(4055,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Shaman
- player->SEND_POI(-2301.5, -439.87, 6, 6, 0, "Narm Skychaser");
+ player->SEND_POI(-2301.5, -439.87, 7, 6, 0, "Narm Skychaser");
player->SEND_GOSSIP_MENU(4056,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Warrior
- player->SEND_POI(-2345.43, -494.11, 6, 6, 0, "Krang Stonehoof");
+ player->SEND_POI(-2345.43, -494.11, 7, 6, 0, "Krang Stonehoof");
player->SEND_GOSSIP_MENU(4057,_Creature->GetGUID());
break;
}
@@ -1938,32 +1938,32 @@ void SendProfTrainerMenu_guard_mulgore(Player *player, Creature *_Creature, uint
player->SEND_GOSSIP_MENU(4059,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Cooking
- player->SEND_POI(-2263.34, -287.91, 6, 6, 0, "Pyall Silentstride");
+ player->SEND_POI(-2263.34, -287.91, 7, 6, 0, "Pyall Silentstride");
player->SEND_GOSSIP_MENU(4060,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Enchanting
player->SEND_GOSSIP_MENU(4061,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //First Aid
- player->SEND_POI(-2353.52, -355.82, 6, 6, 0, "Vira Younghoof");
+ player->SEND_POI(-2353.52, -355.82, 7, 6, 0, "Vira Younghoof");
player->SEND_GOSSIP_MENU(4062,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Fishing
- player->SEND_POI(-2349.21, -241.37, 6, 6, 0, "Uthan Stillwater");
+ player->SEND_POI(-2349.21, -241.37, 7, 6, 0, "Uthan Stillwater");
player->SEND_GOSSIP_MENU(4063,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Herbalism
player->SEND_GOSSIP_MENU(4064,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Leatherworking
- player->SEND_POI(-2257.12, -288.63, 6, 6, 0, "Chaw Stronghide");
+ player->SEND_POI(-2257.12, -288.63, 7, 6, 0, "Chaw Stronghide");
player->SEND_GOSSIP_MENU(4065,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Mining
player->SEND_GOSSIP_MENU(4066,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Skinning
- player->SEND_POI(-2252.94, -291.32, 6, 6, 0, "Yonn Deepcut");
+ player->SEND_POI(-2252.94, -291.32, 7, 6, 0, "Yonn Deepcut");
player->SEND_GOSSIP_MENU(4067,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Tailoring
@@ -2021,43 +2021,43 @@ void SendDefaultMenu_guard_orgrimmar(Player *player, Creature *_Creature, uint32
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Bank
- player->SEND_POI(1631.51, -4375.33, 6, 6, 0, "Bank of Orgrimmar");
+ player->SEND_POI(1631.51, -4375.33, 7, 6, 0, "Bank of Orgrimmar");
player->SEND_GOSSIP_MENU(2554,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //wind rider
- player->SEND_POI(1676.6, -4332.72, 6, 6, 0, "The Sky Tower");
+ player->SEND_POI(1676.6, -4332.72, 7, 6, 0, "The Sky Tower");
player->SEND_GOSSIP_MENU(2555,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //guild master
- player->SEND_POI(1576.93, -4294.75, 6, 6, 0, "Horde Embassy");
+ player->SEND_POI(1576.93, -4294.75, 7, 6, 0, "Horde Embassy");
player->SEND_GOSSIP_MENU(2556,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Inn
- player->SEND_POI(1644.51, -4447.27, 6, 6, 0, "Orgrimmar Inn");
+ player->SEND_POI(1644.51, -4447.27, 7, 6, 0, "Orgrimmar Inn");
player->SEND_GOSSIP_MENU(2557,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //mailbox
- player->SEND_POI(1622.53, -4388.79, 6, 6, 0, "Orgrimmar Mailbox");
+ player->SEND_POI(1622.53, -4388.79, 7, 6, 0, "Orgrimmar Mailbox");
player->SEND_GOSSIP_MENU(2558,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //auction house
- player->SEND_POI(1679.21, -4450.1, 6, 6, 0, "Orgrimmar Auction House");
+ player->SEND_POI(1679.21, -4450.1, 7, 6, 0, "Orgrimmar Auction House");
player->SEND_GOSSIP_MENU(3075,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //zeppelin
- player->SEND_POI(1337.36, -4632.7, 6, 6, 0, "Orgrimmar Zeppelin Tower");
+ player->SEND_POI(1337.36, -4632.7, 7, 6, 0, "Orgrimmar Zeppelin Tower");
player->SEND_GOSSIP_MENU(3173,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //weapon master
- player->SEND_POI(2092.56, -4823.95, 6, 6, 0, "Sayoc & Hanashi");
+ player->SEND_POI(2092.56, -4823.95, 7, 6, 0, "Sayoc & Hanashi");
player->SEND_GOSSIP_MENU(4519,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //stable master
- player->SEND_POI(2133.12, -4663.93, 6, 6, 0, "Xon'cha");
+ player->SEND_POI(2133.12, -4663.93, 7, 6, 0, "Xon'cha");
player->SEND_GOSSIP_MENU(5974,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //officers lounge
- player->SEND_POI(1633.56, -4249.37, 6, 6, 0, "Hall of Legends");
+ player->SEND_POI(1633.56, -4249.37, 7, 6, 0, "Hall of Legends");
player->SEND_GOSSIP_MENU(7046,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //battlemaster
@@ -2100,15 +2100,15 @@ void SendBattleMasterMenu_guard_orgrimmar(Player *player, Creature *_Creature, u
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //AV
- player->SEND_POI(1983.92, -4794.2, 6, 6, 0, "Hall of the Brave");
+ player->SEND_POI(1983.92, -4794.2, 7, 6, 0, "Hall of the Brave");
player->SEND_GOSSIP_MENU(7484,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //AB
- player->SEND_POI(1983.92, -4794.2, 6, 6, 0, "Hall of the Brave");
+ player->SEND_POI(1983.92, -4794.2, 7, 6, 0, "Hall of the Brave");
player->SEND_GOSSIP_MENU(7644,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //WSG
- player->SEND_POI(1983.92, -4794.2, 6, 6, 0, "Hall of the Brave");
+ player->SEND_POI(1983.92, -4794.2, 7, 6, 0, "Hall of the Brave");
player->SEND_GOSSIP_MENU(7520,_Creature->GetGUID());
break;
}
@@ -2119,35 +2119,35 @@ void SendClassTrainerMenu_guard_orgrimmar(Player *player, Creature *_Creature, u
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Hunter
- player->SEND_POI(2114.84, -4625.31, 6, 6, 0, "Orgrimmar Hunter's Hall");
+ player->SEND_POI(2114.84, -4625.31, 7, 6, 0, "Orgrimmar Hunter's Hall");
player->SEND_GOSSIP_MENU(2559,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Mage
- player->SEND_POI(1451.26, -4223.33, 6, 6, 0, "Darkbriar Lodge");
+ player->SEND_POI(1451.26, -4223.33, 7, 6, 0, "Darkbriar Lodge");
player->SEND_GOSSIP_MENU(2560,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Priest
- player->SEND_POI(1442.21, -4183.24, 6, 6, 0, "Spirit Lodge");
+ player->SEND_POI(1442.21, -4183.24, 7, 6, 0, "Spirit Lodge");
player->SEND_GOSSIP_MENU(2561,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Shaman
- player->SEND_POI(1925.34, -4181.89, 6, 6, 0, "Thrall's Fortress");
+ player->SEND_POI(1925.34, -4181.89, 7, 6, 0, "Thrall's Fortress");
player->SEND_GOSSIP_MENU(2562,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Rogue
- player->SEND_POI(1773.39, -4278.97, 6, 6, 0, "Shadowswift Brotherhood");
+ player->SEND_POI(1773.39, -4278.97, 7, 6, 0, "Shadowswift Brotherhood");
player->SEND_GOSSIP_MENU(2563,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Warlock
- player->SEND_POI(1849.57, -4359.68, 6, 6, 0, "Darkfire Enclave");
+ player->SEND_POI(1849.57, -4359.68, 7, 6, 0, "Darkfire Enclave");
player->SEND_GOSSIP_MENU(2564,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Warrior
- player->SEND_POI(1983.92, -4794.2, 6, 6, 0, "Hall of the Brave");
+ player->SEND_POI(1983.92, -4794.2, 7, 6, 0, "Hall of the Brave");
player->SEND_GOSSIP_MENU(2565,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Paladin
- player->SEND_POI(1906.65, -4134.26, 6, 6, 0, "Valley of Wisdom");
+ player->SEND_POI(1906.65, -4134.26, 7, 6, 0, "Valley of Wisdom");
player->SEND_GOSSIP_MENU(10843,_Creature->GetGUID());
break;
}
@@ -2158,51 +2158,51 @@ void SendProfTrainerMenu_guard_orgrimmar(Player *player, Creature *_Creature, ui
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(1955.17, -4475.79, 6, 6, 0, "Yelmak's Alchemy and Potions");
+ player->SEND_POI(1955.17, -4475.79, 7, 6, 0, "Yelmak's Alchemy and Potions");
player->SEND_GOSSIP_MENU(2497,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Blacksmithing
- player->SEND_POI(2054.34, -4831.85, 6, 6, 0, "The Burning Anvil");
+ player->SEND_POI(2054.34, -4831.85, 7, 6, 0, "The Burning Anvil");
player->SEND_GOSSIP_MENU(2499,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Cooking
- player->SEND_POI(1780.96, -4481.31, 6, 6, 0, "Borstan's Firepit");
+ player->SEND_POI(1780.96, -4481.31, 7, 6, 0, "Borstan's Firepit");
player->SEND_GOSSIP_MENU(2500,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Enchanting
- player->SEND_POI(1917.5, -4434.95, 6, 6, 0, "Godan's Runeworks");
+ player->SEND_POI(1917.5, -4434.95, 7, 6, 0, "Godan's Runeworks");
player->SEND_GOSSIP_MENU(2501,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Engineering
- player->SEND_POI(2038.45, -4744.75, 6, 6, 0, "Nogg's Machine Shop");
+ player->SEND_POI(2038.45, -4744.75, 7, 6, 0, "Nogg's Machine Shop");
player->SEND_GOSSIP_MENU(2653,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //First Aid
- player->SEND_POI(1485.21, -4160.91, 6, 6, 0, "Survival of the Fittest");
+ player->SEND_POI(1485.21, -4160.91, 7, 6, 0, "Survival of the Fittest");
player->SEND_GOSSIP_MENU(2502,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Fishing
- player->SEND_POI(1994.15, -4655.7, 6, 6, 0, "Lumak's Fishing");
+ player->SEND_POI(1994.15, -4655.7, 7, 6, 0, "Lumak's Fishing");
player->SEND_GOSSIP_MENU(2503,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Herbalism
- player->SEND_POI(1898.61, -4454.93, 6, 6, 0, "Jandi's Arboretum");
+ player->SEND_POI(1898.61, -4454.93, 7, 6, 0, "Jandi's Arboretum");
player->SEND_GOSSIP_MENU(2504,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Leatherworking
- player->SEND_POI(1852.82, -4562.31, 6, 6, 0, "Kodohide Leatherworkers");
+ player->SEND_POI(1852.82, -4562.31, 7, 6, 0, "Kodohide Leatherworkers");
player->SEND_GOSSIP_MENU(2513,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Mining
- player->SEND_POI(2029.79, -4704, 6, 6, 0, "Red Canyon Mining");
+ player->SEND_POI(2029.79, -4704, 7, 6, 0, "Red Canyon Mining");
player->SEND_GOSSIP_MENU(2515,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Skinning
- player->SEND_POI(1852.82, -4562.31, 6, 6, 0, "Kodohide Leatherworkers");
+ player->SEND_POI(1852.82, -4562.31, 7, 6, 0, "Kodohide Leatherworkers");
player->SEND_GOSSIP_MENU(2516,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 12: //Tailoring
- player->SEND_POI(1802.66, -4560.66, 6, 6, 0, "Magar's Cloth Goods");
+ player->SEND_POI(1802.66, -4560.66, 7, 6, 0, "Magar's Cloth Goods");
player->SEND_GOSSIP_MENU(2518,_Creature->GetGUID());
break;
}
@@ -2263,7 +2263,7 @@ void SendDefaultMenu_guard_shattrath(Player *player, Creature *_Creature, uint32
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Tavern
- player->SEND_POI(-1759.5, 5165, 6, 6, 0, "Worlds End Tavern");
+ player->SEND_POI(-1759.5, 5165, 7, 6, 0, "Worlds End Tavern");
player->SEND_GOSSIP_MENU(10394, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Bank
@@ -2277,7 +2277,7 @@ void SendDefaultMenu_guard_shattrath(Player *player, Creature *_Creature, uint32
player->SEND_GOSSIP_MENU(10382, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Flight master
- player->SEND_POI(-1832, 5299, 6, 6, 0, "Flight Master");
+ player->SEND_POI(-1832, 5299, 7, 6, 0, "Flight Master");
player->SEND_GOSSIP_MENU(10385, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Mailbox
@@ -2310,11 +2310,11 @@ void SendDefaultMenu_guard_shattrath(Player *player, Creature *_Creature, uint32
player->SEND_GOSSIP_MENU(10391, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Mana Loom
- player->SEND_POI(-2070, 5265.5, 6, 6, 0, "Mana Loom");
+ player->SEND_POI(-2070, 5265.5, 7, 6, 0, "Mana Loom");
player->SEND_GOSSIP_MENU(10503, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Alchemy Lab
- player->SEND_POI(-1648.5, 5540, 6, 6, 0, "Alchemy Lab");
+ player->SEND_POI(-1648.5, 5540, 7, 6, 0, "Alchemy Lab");
player->SEND_GOSSIP_MENU(10321, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Gem Merchant
@@ -2329,12 +2329,12 @@ void SendBankMenu_guard_shattrath(Player *player, Creature *_Creature, uint32 ac
{
if (action == GOSSIP_ACTION_INFO_DEF + 1)
{
- player->SEND_POI(-1730.5, 5496, 6, 6, 0, "Aldor Bank");
+ player->SEND_POI(-1730.5, 5496, 7, 6, 0, "Aldor Bank");
player->SEND_GOSSIP_MENU(10380, _Creature->GetGUID());
}
if (action == GOSSIP_ACTION_INFO_DEF + 2)
{
- player->SEND_POI(-1997.7, 5363, 6, 6, 0, "Scyers Bank");
+ player->SEND_POI(-1997.7, 5363, 7, 6, 0, "Scyers Bank");
player->SEND_GOSSIP_MENU(10381, _Creature->GetGUID());
}
}
@@ -2343,12 +2343,12 @@ void SendInnMenu_guard_shattrath(Player *player, Creature *_Creature, uint32 act
{
if (action == GOSSIP_ACTION_INFO_DEF + 1)
{
- player->SEND_POI(-1895, 5767, 6, 6, 0, "Aldor Inn");
+ player->SEND_POI(-1895, 5767, 7, 6, 0, "Aldor Inn");
player->SEND_GOSSIP_MENU(10383, _Creature->GetGUID());
}
if (action == GOSSIP_ACTION_INFO_DEF + 2)
{
- player->SEND_POI(-2178, 5405, 6, 6, 0, "Scyers Inn");
+ player->SEND_POI(-2178, 5405, 7, 6, 0, "Scyers Inn");
player->SEND_GOSSIP_MENU(10384, _Creature->GetGUID());
}
}
@@ -2358,19 +2358,19 @@ void SendMailboxMenu_guard_shattrath(Player *player, Creature *_Creature, uint32
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1:
- player->SEND_POI(-1730.5, 5496, 6, 6, 0, "Aldor Bank");
+ player->SEND_POI(-1730.5, 5496, 7, 6, 0, "Aldor Bank");
player->SEND_GOSSIP_MENU(10380, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2:
- player->SEND_POI(-1895, 5767, 6, 6, 0, "Aldor Inn");
+ player->SEND_POI(-1895, 5767, 7, 6, 0, "Aldor Inn");
player->SEND_GOSSIP_MENU(10383, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3:
- player->SEND_POI(-1997.7, 5363, 6, 6, 0, "Scyers Bank");
+ player->SEND_POI(-1997.7, 5363, 7, 6, 0, "Scyers Bank");
player->SEND_GOSSIP_MENU(10381, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4:
- player->SEND_POI(-2178, 5405, 6, 6, 0, "Scyers Inn");
+ player->SEND_POI(-2178, 5405, 7, 6, 0, "Scyers Inn");
player->SEND_GOSSIP_MENU(10384, _Creature->GetGUID());
break;
}
@@ -2380,12 +2380,12 @@ void SendStableMasterMenu_guard_shattrath(Player *player, Creature *_Creature, u
{
if (action == GOSSIP_ACTION_INFO_DEF + 1)
{
- player->SEND_POI(-1888.5, 5761, 6, 6, 0, "Aldor Stable");
+ player->SEND_POI(-1888.5, 5761, 7, 6, 0, "Aldor Stable");
player->SEND_GOSSIP_MENU(10321, _Creature->GetGUID());
}
if (action == GOSSIP_ACTION_INFO_DEF + 2)
{
- player->SEND_POI(-2170, 5404, 6, 6, 0, "Scyers Stable");
+ player->SEND_POI(-2170, 5404, 7, 6, 0, "Scyers Stable");
player->SEND_GOSSIP_MENU(10321, _Creature->GetGUID());
}
}
@@ -2395,15 +2395,15 @@ void SendBattleMasterMenu_guard_shattrath(Player *player, Creature *_Creature, u
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1:
- player->SEND_POI(-1774, 5251, 6, 6, 0, "Alliance Battlemasters");
+ player->SEND_POI(-1774, 5251, 7, 6, 0, "Alliance Battlemasters");
player->SEND_GOSSIP_MENU(10389, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2:
- player->SEND_POI(-1963, 5263, 6, 6, 0, "Horde Battlemasters");
+ player->SEND_POI(-1963, 5263, 7, 6, 0, "Horde Battlemasters");
player->SEND_GOSSIP_MENU(10390, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3:
- player->SEND_POI(-1960, 5175, 6, 6, 0, "Arena Battlemasters");
+ player->SEND_POI(-1960, 5175, 7, 6, 0, "Arena Battlemasters");
player->SEND_GOSSIP_MENU(12510, _Creature->GetGUID());
break;
}
@@ -2414,35 +2414,35 @@ void SendProfTrainerMenu_guard_shattrath(Player *player, Creature *_Creature, ui
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(-1648.5, 5534, 6, 6, 0, "Lorokeem");
+ player->SEND_POI(-1648.5, 5534, 7, 6, 0, "Lorokeem");
player->SEND_GOSSIP_MENU(10392, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Blacksmithing
- player->SEND_POI(-1847, 5222, 6, 6, 0, "Kradu Grimblade and Zula Slagfury");
+ player->SEND_POI(-1847, 5222, 7, 6, 0, "Kradu Grimblade and Zula Slagfury");
player->SEND_GOSSIP_MENU(10400, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Cooking
- player->SEND_POI(-2067.4, 5316.5, 6, 6, 0, "Jack Trapper");
+ player->SEND_POI(-2067.4, 5316.5, 7, 6, 0, "Jack Trapper");
player->SEND_GOSSIP_MENU(10393, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Enchanting
- player->SEND_POI(-2263.5, 5563.5, 6, 6, 0, "High Enchanter Bardolan");
+ player->SEND_POI(-2263.5, 5563.5, 7, 6, 0, "High Enchanter Bardolan");
player->SEND_GOSSIP_MENU(10395, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //First Aid
- player->SEND_POI(-1591, 5265.5, 6, 6, 0, "Mildred Fletcher");
+ player->SEND_POI(-1591, 5265.5, 7, 6, 0, "Mildred Fletcher");
player->SEND_GOSSIP_MENU(10396, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Jewelcrafting
- player->SEND_POI(-1654, 5667.5, 6, 6, 0, "Hamanar");
+ player->SEND_POI(-1654, 5667.5, 7, 6, 0, "Hamanar");
player->SEND_GOSSIP_MENU(10397, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Leatherworking
- player->SEND_POI(-2060.5, 5256.5, 6, 6, 0, "Darmari");
+ player->SEND_POI(-2060.5, 5256.5, 7, 6, 0, "Darmari");
player->SEND_GOSSIP_MENU(10399, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Skinning
- player->SEND_POI(-2048, 5300, 6, 6, 0, "Seymour");
+ player->SEND_POI(-2048, 5300, 7, 6, 0, "Seymour");
player->SEND_GOSSIP_MENU(10398, _Creature->GetGUID());
break;
}
@@ -2452,12 +2452,12 @@ void SendGemMerchantMenu_guard_shattrath(Player *player, Creature *_Creature, ui
{
if (action == GOSSIP_ACTION_INFO_DEF + 1)
{
- player->SEND_POI(-1645, 5669.5, 6, 6, 0, "Aldor Gem Merchant");
+ player->SEND_POI(-1645, 5669.5, 7, 6, 0, "Aldor Gem Merchant");
player->SEND_GOSSIP_MENU(10698, _Creature->GetGUID());
}
if (action == GOSSIP_ACTION_INFO_DEF + 2)
{
- player->SEND_POI(-2193, 5424.5, 6, 6, 0, "Scyers Gem Merchant");
+ player->SEND_POI(-2193, 5424.5, 7, 6, 0, "Scyers Gem Merchant");
player->SEND_GOSSIP_MENU(10699, _Creature->GetGUID());
}
}
@@ -2513,7 +2513,7 @@ struct TRINITY_DLL_DECL guard_shattrath_aldorAI : public guardAI
CanTeleport = false;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void UpdateAI(const uint32 diff)
{
@@ -2573,28 +2573,28 @@ void SendDefaultMenu_guard_shattrath_aldor(Player *player, Creature *_Creature,
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Tavern
- player->SEND_POI(-1759.5, 5165, 6, 6, 0, "Worlds End Tavern");
+ player->SEND_POI(-1759.5, 5165, 7, 6, 0, "Worlds End Tavern");
player->SEND_GOSSIP_MENU(10394, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Bank
- player->SEND_POI(-1730.5, 5496, 6, 6, 0, "Aldor Bank");
+ player->SEND_POI(-1730.5, 5496, 7, 6, 0, "Aldor Bank");
player->SEND_GOSSIP_MENU(10380, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Inn
- player->SEND_POI(-1895, 5767, 6, 6, 0, "Aldor Inn");
+ player->SEND_POI(-1895, 5767, 7, 6, 0, "Aldor Inn");
player->SEND_GOSSIP_MENU(10525, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Flight master
- player->SEND_POI(-1832, 5299, 6, 6, 0, "Shattrath Flight Master");
+ player->SEND_POI(-1832, 5299, 7, 6, 0, "Shattrath Flight Master");
player->SEND_GOSSIP_MENU(10402, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Mailbox
- player->SEND_POI(0, 0, 6, 6, 0, "Aldor Mailbox");
+ player->SEND_POI(0, 0, 7, 6, 0, "Aldor Mailbox");
//unknown
player->SEND_GOSSIP_MENU(10524, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Stable master
- player->SEND_POI(-1888.5, 5761, 6, 6, 0, "Aldor Stable Master");
+ player->SEND_POI(-1888.5, 5761, 7, 6, 0, "Aldor Stable Master");
player->SEND_GOSSIP_MENU(10527, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Battlemaster
@@ -2615,15 +2615,15 @@ void SendDefaultMenu_guard_shattrath_aldor(Player *player, Creature *_Creature,
player->SEND_GOSSIP_MENU(10391, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Mana Loom
- player->SEND_POI(-2070, 5265.5, 6, 6, 0, "Mana Loom");
+ player->SEND_POI(-2070, 5265.5, 7, 6, 0, "Mana Loom");
player->SEND_GOSSIP_MENU(10522, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Alchemy Lab
- player->SEND_POI(-1648.5, 5540, 6, 6, 0, "Alchemy Lab");
+ player->SEND_POI(-1648.5, 5540, 7, 6, 0, "Alchemy Lab");
player->SEND_GOSSIP_MENU(10696, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Gem Merchant
- player->SEND_POI(-1645, 5669.5, 6, 6, 0, "Aldor Gem Merchant");
+ player->SEND_POI(-1645, 5669.5, 7, 6, 0, "Aldor Gem Merchant");
player->SEND_GOSSIP_MENU(10411, _Creature->GetGUID());
break;
}
@@ -2634,35 +2634,35 @@ void SendProfTrainerMenu_guard_shattrath_aldor(Player *player, Creature *_Creatu
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(-1648.5, 5534, 6, 6, 0, "Lorokeem");
+ player->SEND_POI(-1648.5, 5534, 7, 6, 0, "Lorokeem");
player->SEND_GOSSIP_MENU(10392, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Blacksmithing
- player->SEND_POI(-1847, 5222, 6, 6, 0, "Kradu Grimblade and Zula Slagfury");
+ player->SEND_POI(-1847, 5222, 7, 6, 0, "Kradu Grimblade and Zula Slagfury");
player->SEND_GOSSIP_MENU(10400, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Cooking
- player->SEND_POI(-2067.4, 5316.5, 6, 6, 0, "Jack Trapper");
+ player->SEND_POI(-2067.4, 5316.5, 7, 6, 0, "Jack Trapper");
player->SEND_GOSSIP_MENU(10393, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Enchanting
- player->SEND_POI(-2263.5, 5563.5, 6, 6, 0, "High Enchanter Bardolan");
+ player->SEND_POI(-2263.5, 5563.5, 7, 6, 0, "High Enchanter Bardolan");
player->SEND_GOSSIP_MENU(10528, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //First Aid
- player->SEND_POI(-1591, 5265.5, 6, 6, 0, "Mildred Fletcher");
+ player->SEND_POI(-1591, 5265.5, 7, 6, 0, "Mildred Fletcher");
player->SEND_GOSSIP_MENU(10396, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Jewelcrafting
- player->SEND_POI(-1654, 5667.5, 6, 6, 0, "Hamanar");
+ player->SEND_POI(-1654, 5667.5, 7, 6, 0, "Hamanar");
player->SEND_GOSSIP_MENU(10529, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Leatherworking
- player->SEND_POI(-2060.5, 5256.5, 6, 6, 0, "Darmari");
+ player->SEND_POI(-2060.5, 5256.5, 7, 6, 0, "Darmari");
player->SEND_GOSSIP_MENU(10399, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Skinning
- player->SEND_POI(-2048, 5300, 6, 6, 0, "Seymour");
+ player->SEND_POI(-2048, 5300, 7, 6, 0, "Seymour");
player->SEND_GOSSIP_MENU(10419, _Creature->GetGUID());
break;
}
@@ -2709,7 +2709,7 @@ struct TRINITY_DLL_DECL guard_shattrath_scryerAI : public guardAI
CanTeleport = false;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void UpdateAI(const uint32 diff)
{
@@ -2769,27 +2769,27 @@ void SendDefaultMenu_guard_shattrath_scryer(Player *player, Creature *_Creature,
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Tavern
- player->SEND_POI(-1759.5, 5165, 6, 6, 0, "Worlds End Tavern");
+ player->SEND_POI(-1759.5, 5165, 7, 6, 0, "Worlds End Tavern");
player->SEND_GOSSIP_MENU(10431, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Bank
- player->SEND_POI(-1996.6, 5363.7, 6, 6, 0, "Scryer Bank");
+ player->SEND_POI(-1996.6, 5363.7, 7, 6, 0, "Scryer Bank");
player->SEND_GOSSIP_MENU(10432, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Inn
- player->SEND_POI(-2176.6, 5405.8, 6, 6, 0, "Scryer Inn");
+ player->SEND_POI(-2176.6, 5405.8, 7, 6, 0, "Scryer Inn");
player->SEND_GOSSIP_MENU(10433, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Flight master
- player->SEND_POI(-1832, 5299, 6, 6, 0, "Shattrath Flight Master");
+ player->SEND_POI(-1832, 5299, 7, 6, 0, "Shattrath Flight Master");
player->SEND_GOSSIP_MENU(10435, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Mailbox
- player->SEND_POI(-2174.3, 5411.4, 6, 6, 0, "Scryer Mailbox");
+ player->SEND_POI(-2174.3, 5411.4, 7, 6, 0, "Scryer Mailbox");
player->SEND_GOSSIP_MENU(10436, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Stable master
- player->SEND_POI(-2169.9, 5405.1, 6, 6, 0, "Scryer Stable Master");
+ player->SEND_POI(-2169.9, 5405.1, 7, 6, 0, "Scryer Stable Master");
player->SEND_GOSSIP_MENU(10437, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Battlemaster
@@ -2810,15 +2810,15 @@ void SendDefaultMenu_guard_shattrath_scryer(Player *player, Creature *_Creature,
player->SEND_GOSSIP_MENU(10504, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Mana Loom
- player->SEND_POI(-2070, 5265.5, 6, 6, 0, "Mana Loom");
+ player->SEND_POI(-2070, 5265.5, 7, 6, 0, "Mana Loom");
player->SEND_GOSSIP_MENU(10522, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Alchemy Lab
- player->SEND_POI(-1648.5, 5540, 6, 6, 0, "Alchemy Lab");
+ player->SEND_POI(-1648.5, 5540, 7, 6, 0, "Alchemy Lab");
player->SEND_GOSSIP_MENU(10701, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Gem Merchant
- player->SEND_POI(-1645, 5669.5, 6, 6, 0, "Scryer Gem Merchant");
+ player->SEND_POI(-1645, 5669.5, 7, 6, 0, "Scryer Gem Merchant");
player->SEND_GOSSIP_MENU(10702, _Creature->GetGUID());
break;
}
@@ -2829,35 +2829,35 @@ void SendProfTrainerMenu_guard_shattrath_scryer(Player *player, Creature *_Creat
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(-1648.5, 5534, 6, 6, 0, "Lorokeem");
+ player->SEND_POI(-1648.5, 5534, 7, 6, 0, "Lorokeem");
player->SEND_GOSSIP_MENU(10516, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Blacksmithing
- player->SEND_POI(-1847, 5222, 6, 6, 0, "Kradu Grimblade and Zula Slagfury");
+ player->SEND_POI(-1847, 5222, 7, 6, 0, "Kradu Grimblade and Zula Slagfury");
player->SEND_GOSSIP_MENU(10517, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Cooking
- player->SEND_POI(-2067.4, 5316.5, 6, 6, 0, "Jack Trapper");
+ player->SEND_POI(-2067.4, 5316.5, 7, 6, 0, "Jack Trapper");
player->SEND_GOSSIP_MENU(10518, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Enchanting
- player->SEND_POI(-2263.5, 5563.5, 6, 6, 0, "High Enchanter Bardolan");
+ player->SEND_POI(-2263.5, 5563.5, 7, 6, 0, "High Enchanter Bardolan");
player->SEND_GOSSIP_MENU(10519, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //First Aid
- player->SEND_POI(-1591, 5265.5, 6, 6, 0, "Mildred Fletcher");
+ player->SEND_POI(-1591, 5265.5, 7, 6, 0, "Mildred Fletcher");
player->SEND_GOSSIP_MENU(10520, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Jewelcrafting
- player->SEND_POI(-1654, 5667.5, 6, 6, 0, "Hamanar");
+ player->SEND_POI(-1654, 5667.5, 7, 6, 0, "Hamanar");
player->SEND_GOSSIP_MENU(10521, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Leatherworking
- player->SEND_POI(-2060.5, 5256.5, 6, 6, 0, "Darmari");
+ player->SEND_POI(-2060.5, 5256.5, 7, 6, 0, "Darmari");
player->SEND_GOSSIP_MENU(10523, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Skinning
- player->SEND_POI(-2048, 5300, 6, 6, 0, "Seymour");
+ player->SEND_POI(-2048, 5300, 7, 6, 0, "Seymour");
player->SEND_GOSSIP_MENU(10523, _Creature->GetGUID());
break;
}
@@ -2914,11 +2914,11 @@ void SendDefaultMenu_guard_silvermoon(Player *player, Creature *_Creature, uint3
player->SEND_GOSSIP_MENU(9317, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Bank
- player->SEND_POI(9808.4, -7488.16, 6, 6, 0, "Silvermoon Bank");
+ player->SEND_POI(9808.4, -7488.16, 7, 6, 0, "Silvermoon Bank");
player->SEND_GOSSIP_MENU(9322, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Guild master
- player->SEND_POI(9474.97, -7345.21, 6, 6, 0, "Tandrine");
+ player->SEND_POI(9474.97, -7345.21, 7, 6, 0, "Tandrine");
player->SEND_GOSSIP_MENU(9324, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Inn
@@ -2927,19 +2927,19 @@ void SendDefaultMenu_guard_silvermoon(Player *player, Creature *_Creature, uint3
player->SEND_GOSSIP_MENU(9602, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Mailbox
- player->SEND_POI(9658.33, -7492.17, 6, 6, 0, "Silvermoon Mailbox");
+ player->SEND_POI(9658.33, -7492.17, 7, 6, 0, "Silvermoon Mailbox");
player->SEND_GOSSIP_MENU(9326, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Stable master
- player->SEND_POI(9904.95, -7404.31, 6, 6, 0, "Shalenn");
+ player->SEND_POI(9904.95, -7404.31, 7, 6, 0, "Shalenn");
player->SEND_GOSSIP_MENU(9327, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Weapon trainer
- player->SEND_POI(9841.17, -7505.13, 6, 6, 0, "Ileda");
+ player->SEND_POI(9841.17, -7505.13, 7, 6, 0, "Ileda");
player->SEND_GOSSIP_MENU(9328, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Wind master
- player->SEND_POI(9378.45, -7163.94, 6, 6, 0, "Silvermoon Wind Master");
+ player->SEND_POI(9378.45, -7163.94, 7, 6, 0, "Silvermoon Wind Master");
player->SEND_GOSSIP_MENU(10181, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Battlemaster
@@ -2983,12 +2983,12 @@ void SendAuctionhouseMenu_guard_silvermoon(Player *player, Creature *_Creature,
{
if (action == GOSSIP_ACTION_INFO_DEF + 1)
{
- player->SEND_POI(9644.47, -7140.22, 6, 6, 0, "Western Auction House");
+ player->SEND_POI(9644.47, -7140.22, 7, 6, 0, "Western Auction House");
player->SEND_GOSSIP_MENU(9318, _Creature->GetGUID());
}
if (action == GOSSIP_ACTION_INFO_DEF + 2)
{
- player->SEND_POI(9683.27, -7521.22, 6, 6, 0, "Royal Exchange Auction House");
+ player->SEND_POI(9683.27, -7521.22, 7, 6, 0, "Royal Exchange Auction House");
player->SEND_GOSSIP_MENU(9319, _Creature->GetGUID());
}
}
@@ -2997,12 +2997,12 @@ void SendInnMenu_guard_silvermoon(Player *player, Creature *_Creature, uint32 ac
{
if (action == GOSSIP_ACTION_INFO_DEF + 1)
{
- player->SEND_POI(9677.7, -7368, 6, 6, 0, "Silvermoon City Inn");
+ player->SEND_POI(9677.7, -7368, 7, 6, 0, "Silvermoon City Inn");
player->SEND_GOSSIP_MENU(9325, _Creature->GetGUID());
}
if (action == GOSSIP_ACTION_INFO_DEF + 2)
{
- player->SEND_POI(9561.1, -7517.5, 6, 6, 0, "Wayfarer's Rest tavern");
+ player->SEND_POI(9561.1, -7517.5, 7, 6, 0, "Wayfarer's Rest tavern");
player->SEND_GOSSIP_MENU(9603, _Creature->GetGUID());
}
}
@@ -3012,23 +3012,23 @@ void SendBattleMasterMenu_guard_silvermoon(Player *player, Creature *_Creature,
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //AV
- player->SEND_POI(9850.49, -7572.26, 6, 6, 0, "Gurak");
+ player->SEND_POI(9850.49, -7572.26, 7, 6, 0, "Gurak");
player->SEND_GOSSIP_MENU(9329, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //AB
- player->SEND_POI(9857.18, -7564.36, 6, 6, 0, "Karen Wentworth");
+ player->SEND_POI(9857.18, -7564.36, 7, 6, 0, "Karen Wentworth");
player->SEND_GOSSIP_MENU(9329, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //A
- player->SEND_POI(9850.6, -7559.25, 6, 6, 0, "Bipp Glizzitor");
+ player->SEND_POI(9850.6, -7559.25, 7, 6, 0, "Bipp Glizzitor");
player->SEND_GOSSIP_MENU(9329, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //EOS
- player->SEND_POI(9857.18, -7564.36, 6, 6, 0, "Karen Wentworth");
+ player->SEND_POI(9857.18, -7564.36, 7, 6, 0, "Karen Wentworth");
player->SEND_GOSSIP_MENU(9329, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //WSG
- player->SEND_POI(9845.45, -7562.58, 6, 6, 0, "Krukk");
+ player->SEND_POI(9845.45, -7562.58, 7, 6, 0, "Krukk");
player->SEND_GOSSIP_MENU(9329, _Creature->GetGUID());
break;
}
@@ -3039,31 +3039,31 @@ void SendClassTrainerMenu_guard_silvermoon(Player *player, Creature *_Creature,
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Druid
- player->SEND_POI(9700.55, -7262.57, 6, 6, 0, "Harene Plainwalker");
+ player->SEND_POI(9700.55, -7262.57, 7, 6, 0, "Harene Plainwalker");
player->SEND_GOSSIP_MENU(9330, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Hunter
- player->SEND_POI(9927.48, -7426.14, 6, 6, 0, "Zandine");
+ player->SEND_POI(9927.48, -7426.14, 7, 6, 0, "Zandine");
player->SEND_GOSSIP_MENU(9332, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Mage
- player->SEND_POI(9995.07, -7118.17, 6, 6, 0, "Quithas");
+ player->SEND_POI(9995.07, -7118.17, 7, 6, 0, "Quithas");
player->SEND_GOSSIP_MENU(9333, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Paladin
- player->SEND_POI(9850.22, -7516.93, 6, 6, 0, "Champion Bachi");
+ player->SEND_POI(9850.22, -7516.93, 7, 6, 0, "Champion Bachi");
player->SEND_GOSSIP_MENU(9334, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Priest
- player->SEND_POI(9926.79, -7066.66, 6, 6, 0, "Belestra");
+ player->SEND_POI(9926.79, -7066.66, 7, 6, 0, "Belestra");
player->SEND_GOSSIP_MENU(9335, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Rogue
- player->SEND_POI(9739.88, -7374.33, 6, 6, 0, "Zelanis");
+ player->SEND_POI(9739.88, -7374.33, 7, 6, 0, "Zelanis");
player->SEND_GOSSIP_MENU(9336, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Warlock
- player->SEND_POI(9787.57, -7284.63, 6, 6, 0, "Alamma");
+ player->SEND_POI(9787.57, -7284.63, 7, 6, 0, "Alamma");
player->SEND_GOSSIP_MENU(9337, _Creature->GetGUID());
break;
}
@@ -3074,55 +3074,55 @@ void SendProfTrainerMenu_guard_silvermoon(Player *player, Creature *_Creature, u
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(9998.09, -7214.36, 6, 6, 0, "Silvermoon Alchemy Trainer");
+ player->SEND_POI(9998.09, -7214.36, 7, 6, 0, "Silvermoon Alchemy Trainer");
player->SEND_GOSSIP_MENU(9316, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Blacksmithing
- player->SEND_POI(9841.43, -7361.53, 6, 6, 0, "Silvermoon Blacksmithing Trainer");
+ player->SEND_POI(9841.43, -7361.53, 7, 6, 0, "Silvermoon Blacksmithing Trainer");
player->SEND_GOSSIP_MENU(9340, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Cooking
- player->SEND_POI(9577.26, -7243.6, 6, 6, 0, "Silvermoon Cooking Trainer");
+ player->SEND_POI(9577.26, -7243.6, 7, 6, 0, "Silvermoon Cooking Trainer");
player->SEND_GOSSIP_MENU(9316, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Enchanting
- player->SEND_POI(9962.57, -7246.18, 6, 6, 0, "Silvermoon Enchanting Trainer");
+ player->SEND_POI(9962.57, -7246.18, 7, 6, 0, "Silvermoon Enchanting Trainer");
player->SEND_GOSSIP_MENU(9341, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Engineering
- player->SEND_POI(9820.18, -7329.56, 6, 6, 0, "Silvermoon Engineering Trainer");
+ player->SEND_POI(9820.18, -7329.56, 7, 6, 0, "Silvermoon Engineering Trainer");
player->SEND_GOSSIP_MENU(9316, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //First Aid
- player->SEND_POI(9579.8, -7343.71, 6, 6, 0, "Silvermoon First Aid Trainer");
+ player->SEND_POI(9579.8, -7343.71, 7, 6, 0, "Silvermoon First Aid Trainer");
player->SEND_GOSSIP_MENU(9316, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Fishing
- player->SEND_POI(9602.73, -7328.3, 6, 6, 0, "Silvermoon Fishing Trainer");
+ player->SEND_POI(9602.73, -7328.3, 7, 6, 0, "Silvermoon Fishing Trainer");
player->SEND_GOSSIP_MENU(9316, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Jewelcrafting
- player->SEND_POI(9553.54, -7506.43, 6, 6, 0, "Silvermoon Jewelcrafting Trainer");
+ player->SEND_POI(9553.54, -7506.43, 7, 6, 0, "Silvermoon Jewelcrafting Trainer");
player->SEND_GOSSIP_MENU(9346, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Herbalism
- player->SEND_POI(10004.4, -7216.86, 6, 6, 0, "Silvermoon Herbalism Trainer");
+ player->SEND_POI(10004.4, -7216.86, 7, 6, 0, "Silvermoon Herbalism Trainer");
player->SEND_GOSSIP_MENU(9316, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Leatherworking
- player->SEND_POI(9503.72, -7430.16, 6, 6, 0, "Silvermoon Leatherworking Trainer");
+ player->SEND_POI(9503.72, -7430.16, 7, 6, 0, "Silvermoon Leatherworking Trainer");
player->SEND_GOSSIP_MENU(9347, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Mining
- player->SEND_POI(9805.1, -7355.56, 6, 6, 0, "Silvermoon Mining Trainer");
+ player->SEND_POI(9805.1, -7355.56, 7, 6, 0, "Silvermoon Mining Trainer");
player->SEND_GOSSIP_MENU(9348, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 12: //Skinning
- player->SEND_POI(9513.37, -7429.4, 6, 6, 0, "Silvermoon Skinning Trainer");
+ player->SEND_POI(9513.37, -7429.4, 7, 6, 0, "Silvermoon Skinning Trainer");
player->SEND_GOSSIP_MENU(9316, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 13: //Tailoring
- player->SEND_POI(9750.55, -7095.28, 6, 6, 0, "Silvermoon Tailor");
+ player->SEND_POI(9750.55, -7095.28, 7, 6, 0, "Silvermoon Tailor");
player->SEND_GOSSIP_MENU(9350, _Creature->GetGUID());
break;
}
@@ -3179,43 +3179,43 @@ void SendDefaultMenu_guard_stormwind(Player *player, Creature *_Creature, uint32
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Auction House
- player->SEND_POI(-8811.46, 667.46, 6, 6, 0, "Stormwind Auction House");
+ player->SEND_POI(-8811.46, 667.46, 7, 6, 0, "Stormwind Auction House");
player->SEND_GOSSIP_MENU(3834,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Bank
- player->SEND_POI(-8916.87, 622.87, 6, 6, 0, "Stormwind Bank");
+ player->SEND_POI(-8916.87, 622.87, 7, 6, 0, "Stormwind Bank");
player->SEND_GOSSIP_MENU(764,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Deeprun tram
- player->SEND_POI(-8378.88, 554.23, 6, 6, 0, "The Deeprun Tram");
+ player->SEND_POI(-8378.88, 554.23, 7, 6, 0, "The Deeprun Tram");
player->SEND_GOSSIP_MENU(3813,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Inn
- player->SEND_POI(-8869.0, 675.4, 6, 6, 0, "The Gilded Rose");
+ player->SEND_POI(-8869.0, 675.4, 7, 6, 0, "The Gilded Rose");
player->SEND_GOSSIP_MENU(3860,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Gryphon Master
- player->SEND_POI(-8837.0, 493.5, 6, 6, 0, "Stormwind Gryphon Master");
+ player->SEND_POI(-8837.0, 493.5, 7, 6, 0, "Stormwind Gryphon Master");
player->SEND_GOSSIP_MENU(879,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Guild Master
- player->SEND_POI(-8894.0, 611.2, 6, 6, 0, "Stormwind Vistor`s Center");
+ player->SEND_POI(-8894.0, 611.2, 7, 6, 0, "Stormwind Vistor`s Center");
player->SEND_GOSSIP_MENU(882,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Mailbox
- player->SEND_POI(-8876.48, 649.18, 6, 6, 0, "Stormwind Mailbox");
+ player->SEND_POI(-8876.48, 649.18, 7, 6, 0, "Stormwind Mailbox");
player->SEND_GOSSIP_MENU(3861,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Stable Master
- player->SEND_POI(-8433.0, 554.7, 6, 6, 0, "Jenova Stoneshield");
+ player->SEND_POI(-8433.0, 554.7, 7, 6, 0, "Jenova Stoneshield");
player->SEND_GOSSIP_MENU(5984,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Weapon Trainer
- player->SEND_POI(-8797.0, 612.8, 6, 6, 0, "Woo Ping");
+ player->SEND_POI(-8797.0, 612.8, 7, 6, 0, "Woo Ping");
player->SEND_GOSSIP_MENU(4516,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Officers Lounge
- player->SEND_POI(-8759.92, 399.69, 6, 6, 0, "Champions` Hall");
+ player->SEND_POI(-8759.92, 399.69, 7, 6, 0, "Champions` Hall");
player->SEND_GOSSIP_MENU(7047,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Battlemasters
@@ -3259,15 +3259,15 @@ void SendBattleMasterMenu_guard_stormwind(Player *player, Creature *_Creature, u
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //AV
- player->SEND_POI(-8443.88, 335.99, 6, 6, 0, "Thelman Slatefist");
+ player->SEND_POI(-8443.88, 335.99, 7, 6, 0, "Thelman Slatefist");
player->SEND_GOSSIP_MENU(7500, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //AB
- player->SEND_POI(-8443.88, 335.99, 6, 6, 0, "Lady Hoteshem");
+ player->SEND_POI(-8443.88, 335.99, 7, 6, 0, "Lady Hoteshem");
player->SEND_GOSSIP_MENU(7650, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //WSG
- player->SEND_POI(-8443.88, 335.99, 6, 6, 0, "Elfarran");
+ player->SEND_POI(-8443.88, 335.99, 7, 6, 0, "Elfarran");
player->SEND_GOSSIP_MENU(7501, _Creature->GetGUID());
break;
}
@@ -3278,39 +3278,39 @@ void SendClassTrainerMenu_guard_stormwind(Player *player, Creature *_Creature, u
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Mage
- player->SEND_POI(-9012.0, 867.6, 6, 6, 0, "Wizard`s Sanctum");
+ player->SEND_POI(-9012.0, 867.6, 7, 6, 0, "Wizard`s Sanctum");
player->SEND_GOSSIP_MENU(899,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Rogue
- player->SEND_POI(-8753.0, 367.8, 6, 6, 0, "Stormwind - Rogue House");
+ player->SEND_POI(-8753.0, 367.8, 7, 6, 0, "Stormwind - Rogue House");
player->SEND_GOSSIP_MENU(900,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Warrior
- player->SEND_POI(-8690.11, 324.85, 6, 6, 0, "Command Center");
+ player->SEND_POI(-8690.11, 324.85, 7, 6, 0, "Command Center");
player->SEND_GOSSIP_MENU(901,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Druid
- player->SEND_POI(-8751.0, 1124.5, 6, 6, 0, "The Park");
+ player->SEND_POI(-8751.0, 1124.5, 7, 6, 0, "The Park");
player->SEND_GOSSIP_MENU(902,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Priest
- player->SEND_POI(-8512.0, 862.4, 6, 6, 0, "Catedral Of Light");
+ player->SEND_POI(-8512.0, 862.4, 7, 6, 0, "Catedral Of Light");
player->SEND_GOSSIP_MENU(903,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Paladin
- player->SEND_POI(-8577.0, 881.7, 6, 6, 0, "Catedral Of Light");
+ player->SEND_POI(-8577.0, 881.7, 7, 6, 0, "Catedral Of Light");
player->SEND_GOSSIP_MENU(904,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Hunter
- player->SEND_POI(-8413.0, 541.5, 6, 6, 0, "Hunter Lodge");
+ player->SEND_POI(-8413.0, 541.5, 7, 6, 0, "Hunter Lodge");
player->SEND_GOSSIP_MENU(905,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Warlock
- player->SEND_POI(-8948.91, 998.35, 6, 6, 0, "The Slaughtered Lamb");
+ player->SEND_POI(-8948.91, 998.35, 7, 6, 0, "The Slaughtered Lamb");
player->SEND_GOSSIP_MENU(906,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Shaman
- player->SEND_POI(-9033, 550, 6, 6, 0, "Valley Of Heroes");
+ player->SEND_POI(-9033, 550, 7, 6, 0, "Valley Of Heroes");
//incorrect id
player->SEND_GOSSIP_MENU(2593,_Creature->GetGUID());
break;
@@ -3322,51 +3322,51 @@ void SendProfTrainerMenu_guard_stormwind(Player *player, Creature *_Creature, ui
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(-8988.0, 759.60, 6, 6, 0, "Alchemy Needs");
+ player->SEND_POI(-8988.0, 759.60, 7, 6, 0, "Alchemy Needs");
player->SEND_GOSSIP_MENU(919,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Blacksmithing
- player->SEND_POI(-8424.0, 616.9, 6, 6, 0, "Therum Deepforge");
+ player->SEND_POI(-8424.0, 616.9, 7, 6, 0, "Therum Deepforge");
player->SEND_GOSSIP_MENU(920,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Cooking
- player->SEND_POI(-8611.0, 364.6, 6, 6, 0, "Pig and Whistle Tavern");
+ player->SEND_POI(-8611.0, 364.6, 7, 6, 0, "Pig and Whistle Tavern");
player->SEND_GOSSIP_MENU(921,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Enchanting
- player->SEND_POI(-8858.0, 803.7, 6, 6, 0, "Lucan Cordell");
+ player->SEND_POI(-8858.0, 803.7, 7, 6, 0, "Lucan Cordell");
player->SEND_GOSSIP_MENU(941,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Engineering
- player->SEND_POI(-8347.0, 644.1, 6, 6, 0, "Lilliam Sparkspindle");
+ player->SEND_POI(-8347.0, 644.1, 7, 6, 0, "Lilliam Sparkspindle");
player->SEND_GOSSIP_MENU(922,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //First Aid
- player->SEND_POI(-8513.0, 801.8, 6, 6, 0, "Shaina Fuller");
+ player->SEND_POI(-8513.0, 801.8, 7, 6, 0, "Shaina Fuller");
player->SEND_GOSSIP_MENU(923,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Fishing
- player->SEND_POI(-8803.0, 767.5, 6, 6, 0, "Arnold Leland");
+ player->SEND_POI(-8803.0, 767.5, 7, 6, 0, "Arnold Leland");
player->SEND_GOSSIP_MENU(940,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Herbalism
- player->SEND_POI(-8967.0, 779.5, 6, 6, 0, "Alchemy Needs");
+ player->SEND_POI(-8967.0, 779.5, 7, 6, 0, "Alchemy Needs");
player->SEND_GOSSIP_MENU(924,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Leatherworking
- player->SEND_POI(-8726.0, 477.4, 6, 6, 0, "The Protective Hide");
+ player->SEND_POI(-8726.0, 477.4, 7, 6, 0, "The Protective Hide");
player->SEND_GOSSIP_MENU(925,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Mining
- player->SEND_POI(-8434.0, 692.8, 6, 6, 0, "Gelman Stonehand");
+ player->SEND_POI(-8434.0, 692.8, 7, 6, 0, "Gelman Stonehand");
player->SEND_GOSSIP_MENU(927,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Skinning
- player->SEND_POI(-8716.0, 469.4, 6, 6, 0, "The Protective Hide");
+ player->SEND_POI(-8716.0, 469.4, 7, 6, 0, "The Protective Hide");
player->SEND_GOSSIP_MENU(928,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 12: //Tailoring
- player->SEND_POI(-8938.0, 800.7, 6, 6, 0, "Duncan`s Textiles");
+ player->SEND_POI(-8938.0, 800.7, 7, 6, 0, "Duncan`s Textiles");
player->SEND_GOSSIP_MENU(929,_Creature->GetGUID());
break;
}
@@ -3431,11 +3431,11 @@ void SendDefaultMenu_guard_teldrassil(Player *player, Creature *_Creature, uint3
player->SEND_GOSSIP_MENU(4319,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Inn
- player->SEND_POI(9821.49, 960.13, 6, 6, 0, "Dolanaar Inn");
+ player->SEND_POI(9821.49, 960.13, 7, 6, 0, "Dolanaar Inn");
player->SEND_GOSSIP_MENU(4320,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //stable master
- player->SEND_POI(9808.37, 931.1, 6, 6, 0, "Seriadne");
+ player->SEND_POI(9808.37, 931.1, 7, 6, 0, "Seriadne");
player->SEND_GOSSIP_MENU(5982,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //class trainer
@@ -3466,23 +3466,23 @@ void SendClassTrainerMenu_guard_teldrassil(Player *player, Creature *_Creature,
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Druid
- player->SEND_POI(9741.58, 963.7, 6, 6, 0, "Kal");
+ player->SEND_POI(9741.58, 963.7, 7, 6, 0, "Kal");
player->SEND_GOSSIP_MENU(4323,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Hunter
- player->SEND_POI(9815.12, 926.28, 6, 6, 0, "Dazalar");
+ player->SEND_POI(9815.12, 926.28, 7, 6, 0, "Dazalar");
player->SEND_GOSSIP_MENU(4324,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Priest
- player->SEND_POI(9906.16, 986.63, 6, 6, 0, "Laurna Morninglight");
+ player->SEND_POI(9906.16, 986.63, 7, 6, 0, "Laurna Morninglight");
player->SEND_GOSSIP_MENU(4325,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Rogue
- player->SEND_POI(9789, 942.86, 6, 6, 0, "Jannok Breezesong");
+ player->SEND_POI(9789, 942.86, 7, 6, 0, "Jannok Breezesong");
player->SEND_GOSSIP_MENU(4326,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Warrior
- player->SEND_POI(9821.96, 950.61, 6, 6, 0, "Kyra Windblade");
+ player->SEND_POI(9821.96, 950.61, 7, 6, 0, "Kyra Windblade");
player->SEND_GOSSIP_MENU(4327,_Creature->GetGUID());
break;
}
@@ -3493,34 +3493,34 @@ void SendProfTrainerMenu_guard_teldrassil(Player *player, Creature *_Creature, u
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(9767.59, 878.81, 6, 6, 0, "Cyndra Kindwhisper");
+ player->SEND_POI(9767.59, 878.81, 7, 6, 0, "Cyndra Kindwhisper");
player->SEND_GOSSIP_MENU(4329,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Cooking
- player->SEND_POI(9751.19, 906.13, 6, 6, 0, "Zarrin");
+ player->SEND_POI(9751.19, 906.13, 7, 6, 0, "Zarrin");
player->SEND_GOSSIP_MENU(4330,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Enchanting
- player->SEND_POI(10677.59, 1946.56, 6, 6, 0, "Alanna Raveneye");
+ player->SEND_POI(10677.59, 1946.56, 7, 6, 0, "Alanna Raveneye");
player->SEND_GOSSIP_MENU(4331,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //First Aid
- player->SEND_POI(9903.12, 999, 6, 6, 0, "Byancie");
+ player->SEND_POI(9903.12, 999, 7, 6, 0, "Byancie");
player->SEND_GOSSIP_MENU(4332,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Fishing
player->SEND_GOSSIP_MENU(4333,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Herbalism
- player->SEND_POI(9773.78, 875.88, 6, 6, 0, "Malorne Bladeleaf");
+ player->SEND_POI(9773.78, 875.88, 7, 6, 0, "Malorne Bladeleaf");
player->SEND_GOSSIP_MENU(4334,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Leatherworking
- player->SEND_POI(10152.59, 1681.46, 6, 6, 0, "Nadyia Maneweaver");
+ player->SEND_POI(10152.59, 1681.46, 7, 6, 0, "Nadyia Maneweaver");
player->SEND_GOSSIP_MENU(4335,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Skinning
- player->SEND_POI(10135.59, 1673.18, 6, 6, 0, "Radnaal Maneweaver");
+ player->SEND_POI(10135.59, 1673.18, 7, 6, 0, "Radnaal Maneweaver");
player->SEND_GOSSIP_MENU(4336,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Tailoring
@@ -3576,11 +3576,11 @@ void SendDefaultMenu_guard_tirisfal(Player *player, Creature *_Creature, uint32
player->SEND_GOSSIP_MENU(4075,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Inn
- player->SEND_POI(2246.68, 241.89, 6, 6, 0, "Gallows` End Tavern");
+ player->SEND_POI(2246.68, 241.89, 7, 6, 0, "Gallows` End Tavern");
player->SEND_GOSSIP_MENU(4076,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Stable Master
- player->SEND_POI(2267.66, 319.32, 6, 6, 0, "Morganus");
+ player->SEND_POI(2267.66, 319.32, 7, 6, 0, "Morganus");
player->SEND_GOSSIP_MENU(5978,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Class trainer
@@ -3614,23 +3614,23 @@ void SendClassTrainerMenu_guard_tirisfal(Player *player, Creature *_Creature, ui
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Mage
- player->SEND_POI(2259.18, 240.93, 6, 6, 0, "Cain Firesong");
+ player->SEND_POI(2259.18, 240.93, 7, 6, 0, "Cain Firesong");
player->SEND_GOSSIP_MENU(4077,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Priest
- player->SEND_POI(2259.18, 240.93, 6, 6, 0, "Dark Cleric Beryl");
+ player->SEND_POI(2259.18, 240.93, 7, 6, 0, "Dark Cleric Beryl");
player->SEND_GOSSIP_MENU(4078,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Rogue
- player->SEND_POI(2259.18, 240.93, 6, 6, 0, "Marion Call");
+ player->SEND_POI(2259.18, 240.93, 7, 6, 0, "Marion Call");
player->SEND_GOSSIP_MENU(4079,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Warlock
- player->SEND_POI(2259.18, 240.93, 6, 6, 0, "Rupert Boch");
+ player->SEND_POI(2259.18, 240.93, 7, 6, 0, "Rupert Boch");
player->SEND_GOSSIP_MENU(4080,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Warrior
- player->SEND_POI(2256.48, 240.32, 6, 6, 0, "Austil de Mon");
+ player->SEND_POI(2256.48, 240.32, 7, 6, 0, "Austil de Mon");
player->SEND_GOSSIP_MENU(4081,_Creature->GetGUID());
break;
}
@@ -3641,7 +3641,7 @@ void SendProfTrainerMenu_guard_tirisfal(Player *player, Creature *_Creature, uin
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(2263.25, 344.23, 6, 6, 0, "Carolai Anise");
+ player->SEND_POI(2263.25, 344.23, 7, 6, 0, "Carolai Anise");
player->SEND_GOSSIP_MENU(4082,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Blacksmithing
@@ -3651,37 +3651,37 @@ void SendProfTrainerMenu_guard_tirisfal(Player *player, Creature *_Creature, uin
player->SEND_GOSSIP_MENU(4084,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Enchanting
- player->SEND_POI(2250.35, 249.12, 6, 6, 0, "Vance Undergloom");
+ player->SEND_POI(2250.35, 249.12, 7, 6, 0, "Vance Undergloom");
player->SEND_GOSSIP_MENU(4085,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Engineering
player->SEND_GOSSIP_MENU(4086,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //First Aid
- player->SEND_POI(2246.68, 241.89, 6, 6, 0, "Nurse Neela");
+ player->SEND_POI(2246.68, 241.89, 7, 6, 0, "Nurse Neela");
player->SEND_GOSSIP_MENU(4087,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Fishing
- player->SEND_POI(2292.37, -10.72, 6, 6, 0, "Clyde Kellen");
+ player->SEND_POI(2292.37, -10.72, 7, 6, 0, "Clyde Kellen");
player->SEND_GOSSIP_MENU(4088,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Herbalism
- player->SEND_POI(2268.21, 331.69, 6, 6, 0, "Faruza");
+ player->SEND_POI(2268.21, 331.69, 7, 6, 0, "Faruza");
player->SEND_GOSSIP_MENU(4089,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Leatherworking
- player->SEND_POI(2027, 78.72, 6, 6, 0, "Shelene Rhobart");
+ player->SEND_POI(2027, 78.72, 7, 6, 0, "Shelene Rhobart");
player->SEND_GOSSIP_MENU(4090,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Mining
player->SEND_GOSSIP_MENU(4091,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Skinning
- player->SEND_POI(2027, 78.72, 6, 6, 0, "Rand Rhobart");
+ player->SEND_POI(2027, 78.72, 7, 6, 0, "Rand Rhobart");
player->SEND_GOSSIP_MENU(4092,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 12: //Tailoring
- player->SEND_POI(2160.45, 659.93, 6, 6, 0, "Bowen Brisboise");
+ player->SEND_POI(2160.45, 659.93, 7, 6, 0, "Bowen Brisboise");
player->SEND_GOSSIP_MENU(4093,_Creature->GetGUID());
break;
}
@@ -3734,39 +3734,39 @@ void SendDefaultMenu_guard_undercity(Player *player, Creature *_Creature, uint32
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Bank
- player->SEND_POI(1595.64, 232.45, 6, 6, 0, "Undercity Bank");
+ player->SEND_POI(1595.64, 232.45, 7, 6, 0, "Undercity Bank");
player->SEND_GOSSIP_MENU(3514,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Bat handler
- player->SEND_POI(1565.9, 271.43, 6, 6, 0, "Undercity Bat Handler");
+ player->SEND_POI(1565.9, 271.43, 7, 6, 0, "Undercity Bat Handler");
player->SEND_GOSSIP_MENU(3515,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Guild master
- player->SEND_POI(1594.17, 205.57, 6, 6, 0, "Undercity Guild Master");
+ player->SEND_POI(1594.17, 205.57, 7, 6, 0, "Undercity Guild Master");
player->SEND_GOSSIP_MENU(3516,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Inn
- player->SEND_POI(1639.43, 220.99, 6, 6, 0, "Undercity Inn");
+ player->SEND_POI(1639.43, 220.99, 7, 6, 0, "Undercity Inn");
player->SEND_GOSSIP_MENU(3517,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Mailbox
- player->SEND_POI(1632.68, 219.4, 6, 6, 0, "Undercity Mailbox");
+ player->SEND_POI(1632.68, 219.4, 7, 6, 0, "Undercity Mailbox");
player->SEND_GOSSIP_MENU(3518,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //Auction House
- player->SEND_POI(1647.9, 258.49, 6, 6, 0, "Undercity Auction House");
+ player->SEND_POI(1647.9, 258.49, 7, 6, 0, "Undercity Auction House");
player->SEND_GOSSIP_MENU(3519,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Zeppelin
- player->SEND_POI(2059, 274.86, 6, 6, 0, "Undercity Zeppelin");
+ player->SEND_POI(2059, 274.86, 7, 6, 0, "Undercity Zeppelin");
player->SEND_GOSSIP_MENU(3520,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Weapon Master
- player->SEND_POI(1670.31, 324.66, 6, 6, 0, "Archibald");
+ player->SEND_POI(1670.31, 324.66, 7, 6, 0, "Archibald");
player->SEND_GOSSIP_MENU(4521,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Stable master
- player->SEND_POI(1634.18, 226.76, 6, 6, 0, "Anya Maulray");
+ player->SEND_POI(1634.18, 226.76, 7, 6, 0, "Anya Maulray");
player->SEND_GOSSIP_MENU(5979,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Battlemaster
@@ -3806,15 +3806,15 @@ void SendBattleMasterMenu_guard_undercity(Player *player, Creature *_Creature, u
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //AV
- player->SEND_POI(1329, 333.92, 6, 6, 0, "Grizzle Halfmane");
+ player->SEND_POI(1329, 333.92, 7, 6, 0, "Grizzle Halfmane");
player->SEND_GOSSIP_MENU(7525,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //AB
- player->SEND_POI(1283.3, 287.16, 6, 6, 0, "Sir Malory Wheeler");
+ player->SEND_POI(1283.3, 287.16, 7, 6, 0, "Sir Malory Wheeler");
player->SEND_GOSSIP_MENU(7646,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //WSG
- player->SEND_POI(1265, 351.18, 6, 6, 0, "Kurden Bloodclaw");
+ player->SEND_POI(1265, 351.18, 7, 6, 0, "Kurden Bloodclaw");
player->SEND_GOSSIP_MENU(7526,_Creature->GetGUID());
break;
}
@@ -3825,23 +3825,23 @@ void SendClassTrainerMenu_guard_undercity(Player *player, Creature *_Creature, u
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Mage
- player->SEND_POI(1781, 53, 6, 6, 0, "Undercity Mage Trainers");
+ player->SEND_POI(1781, 53, 7, 6, 0, "Undercity Mage Trainers");
player->SEND_GOSSIP_MENU(3513,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Priest
- player->SEND_POI(1758.33, 401.5, 6, 6, 0, "Undercity Priest Trainers");
+ player->SEND_POI(1758.33, 401.5, 7, 6, 0, "Undercity Priest Trainers");
player->SEND_GOSSIP_MENU(3521,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Rogue
- player->SEND_POI(1418.56, 65, 6, 6, 0, "Undercity Rogue Trainers");
+ player->SEND_POI(1418.56, 65, 7, 6, 0, "Undercity Rogue Trainers");
player->SEND_GOSSIP_MENU(3524,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Warlock
- player->SEND_POI(1780.92, 53.16, 6, 6, 0, "Undercity Warlock Trainers");
+ player->SEND_POI(1780.92, 53.16, 7, 6, 0, "Undercity Warlock Trainers");
player->SEND_GOSSIP_MENU(3526,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Warrior
- player->SEND_POI(1775.59, 418.19, 6, 6, 0, "Undercity Warrior Trainers");
+ player->SEND_POI(1775.59, 418.19, 7, 6, 0, "Undercity Warrior Trainers");
player->SEND_GOSSIP_MENU(3527,_Creature->GetGUID());
break;
}
@@ -3852,51 +3852,51 @@ void SendProfTrainerMenu_guard_undercity(Player *player, Creature *_Creature, ui
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1: //Alchemy
- player->SEND_POI(1419.82, 417.19, 6, 6, 0, "The Apothecarium");
+ player->SEND_POI(1419.82, 417.19, 7, 6, 0, "The Apothecarium");
player->SEND_GOSSIP_MENU(3528,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2: //Blacksmithing
- player->SEND_POI(1696, 285, 6, 6, 0, "Undercity Blacksmithing Trainer");
+ player->SEND_POI(1696, 285, 7, 6, 0, "Undercity Blacksmithing Trainer");
player->SEND_GOSSIP_MENU(3529,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 3: //Cooking
- player->SEND_POI(1596.34, 274.68, 6, 6, 0, "Undercity Cooking Trainer");
+ player->SEND_POI(1596.34, 274.68, 7, 6, 0, "Undercity Cooking Trainer");
player->SEND_GOSSIP_MENU(3530,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 4: //Enchanting
- player->SEND_POI(1488.54, 280.19, 6, 6, 0, "Undercity Enchanting Trainer");
+ player->SEND_POI(1488.54, 280.19, 7, 6, 0, "Undercity Enchanting Trainer");
player->SEND_GOSSIP_MENU(3531,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 5: //Engineering
- player->SEND_POI(1408.58, 143.43, 6, 6, 0, "Undercity Engineering Trainer");
+ player->SEND_POI(1408.58, 143.43, 7, 6, 0, "Undercity Engineering Trainer");
player->SEND_GOSSIP_MENU(3532,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 6: //First Aid
- player->SEND_POI(1519.65, 167.19, 6, 6, 0, "Undercity First Aid Trainer");
+ player->SEND_POI(1519.65, 167.19, 7, 6, 0, "Undercity First Aid Trainer");
player->SEND_GOSSIP_MENU(3533,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 7: //Fishing
- player->SEND_POI(1679.9, 89, 6, 6, 0, "Undercity Fishing Trainer");
+ player->SEND_POI(1679.9, 89, 7, 6, 0, "Undercity Fishing Trainer");
player->SEND_GOSSIP_MENU(3534,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 8: //Herbalism
- player->SEND_POI(1558, 349.36, 6, 6, 0, "Undercity Herbalism Trainer");
+ player->SEND_POI(1558, 349.36, 7, 6, 0, "Undercity Herbalism Trainer");
player->SEND_GOSSIP_MENU(3535,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 9: //Leatherworking
- player->SEND_POI(1498.76, 196.43, 6, 6, 0, "Undercity Leatherworking Trainer");
+ player->SEND_POI(1498.76, 196.43, 7, 6, 0, "Undercity Leatherworking Trainer");
player->SEND_GOSSIP_MENU(3536,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 10: //Mining
- player->SEND_POI(1642.88, 335.58, 6, 6, 0, "Undercity Mining Trainer");
+ player->SEND_POI(1642.88, 335.58, 7, 6, 0, "Undercity Mining Trainer");
player->SEND_GOSSIP_MENU(3537,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 11: //Skinning
- player->SEND_POI(1498.6, 196.46, 6, 6, 0, "Undercity Skinning Trainer");
+ player->SEND_POI(1498.6, 196.46, 7, 6, 0, "Undercity Skinning Trainer");
player->SEND_GOSSIP_MENU(3538,_Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 12: //Tailoring
- player->SEND_POI(1689.55, 193, 6, 6, 0, "Undercity Tailoring Trainer");
+ player->SEND_POI(1689.55, 193, 7, 6, 0, "Undercity Tailoring Trainer");
player->SEND_GOSSIP_MENU(3539,_Creature->GetGUID());
break;
}
@@ -4010,7 +4010,7 @@ void AddSC_guards()
newscript->Name="guard_orgrimmar";
newscript->pGossipHello = &GossipHello_guard_orgrimmar;
newscript->pGossipSelect = &GossipSelect_guard_orgrimmar;
- newscript->pReceiveEmote = &ReceiveEmote_guard_orgrimmar;
+ //newscript->pReceiveEmote = &ReceiveEmote_guard_orgrimmar;
newscript->GetAI = &GetAI_guard_orgrimmar;
newscript->RegisterSelf();
@@ -4046,7 +4046,7 @@ void AddSC_guards()
newscript->Name="guard_stormwind";
newscript->pGossipHello = &GossipHello_guard_stormwind;
newscript->pGossipSelect = &GossipSelect_guard_stormwind;
- newscript->pReceiveEmote = &ReceiveEmote_guard_stormwind;
+ //newscript->pReceiveEmote = &ReceiveEmote_guard_stormwind;
newscript->GetAI = &GetAI_guard_stormwind;
newscript->RegisterSelf();
diff --git a/src/bindings/scripts/scripts/item/item_scripts.cpp b/src/bindings/scripts/scripts/item/item_scripts.cpp
index b8c79e01ab7..4e1b1096ab8 100644
--- a/src/bindings/scripts/scripts/item/item_scripts.cpp
+++ b/src/bindings/scripts/scripts/item/item_scripts.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -223,7 +223,7 @@ bool ItemUse_item_flying_machine(Player *player, Item* _Item, SpellCastTargets c
bool ItemUse_item_gor_dreks_ointment(Player *player, Item* _Item, SpellCastTargets const& targets)
{
if( targets.getUnitTarget() && targets.getUnitTarget()->GetTypeId()==TYPEID_UNIT &&
- targets.getUnitTarget()->GetEntry() == 20748 && !targets.getUnitTarget()->HasAura(32578,0) )
+ targets.getUnitTarget()->GetEntry() == 20748 && !targets.getUnitTarget()->HasAura(32578) )
return false;
player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,_Item,NULL);
diff --git a/src/bindings/scripts/scripts/npc/npc_escortAI.cpp b/src/bindings/scripts/scripts/npc/npc_escortAI.cpp
index 3e4d416f44a..78f5ea850c1 100644
--- a/src/bindings/scripts/scripts/npc/npc_escortAI.cpp
+++ b/src/bindings/scripts/scripts/npc/npc_escortAI.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
@@ -13,6 +13,7 @@ EndScriptData */
#include "npc_escortAI.h"
#define WP_LAST_POINT -1
+extern std::list<PointMovement> PointMovementList;
bool npc_escortAI::IsVisible(Unit* who) const
{
@@ -30,28 +31,20 @@ void npc_escortAI::AttackStart(Unit *who)
if (IsBeingEscorted && !Defend)
return;
+ if ( m_creature->Attack(who, true) )
+ {
+ m_creature->GetMotionMaster()->MoveChase(who);
+ }
+}
- if ( m_creature->Attack(who, true) )
- {
- m_creature->AddThreat(who, 0.0f);
-
- if (!InCombat)
- {
- InCombat = true;
-
- if (IsBeingEscorted)
- {
- //Store last position
- m_creature->GetPosition(LastPos.x, LastPos.y, LastPos.z);
-
- debug_log("TSCR: EscortAI has entered combat and stored last location.");
- }
-
- Aggro(who);
- }
+void npc_escortAI::EnterCombat(Unit *who)
+{
+ if (IsBeingEscorted)
+ {
+ //Store last position
+ m_creature->GetPosition(LastPos.x, LastPos.y, LastPos.z);
- m_creature->GetMotionMaster()->MovementExpired();
- m_creature->GetMotionMaster()->MoveChase(who);
+ debug_log("TSCR: EscortAI has entered combat and stored last location.");
}
}
@@ -68,7 +61,6 @@ void npc_escortAI::MoveInLineOfSight(Unit *who)
void npc_escortAI::JustRespawned()
{
- InCombat = false;
IsBeingEscorted = false;
IsOnHold = false;
@@ -80,8 +72,6 @@ void npc_escortAI::JustRespawned()
void npc_escortAI::EnterEvadeMode()
{
- InCombat = false;
-
m_creature->RemoveAllAuras();
m_creature->DeleteThreatList();
m_creature->CombatStop();
@@ -94,7 +84,8 @@ void npc_escortAI::EnterEvadeMode()
m_creature->GetMotionMaster()->MovementExpired();
m_creature->GetMotionMaster()->MovePoint(WP_LAST_POINT, LastPos.x, LastPos.y, LastPos.z);
- }else
+ }
+ else
{
m_creature->GetMotionMaster()->MovementExpired();
m_creature->GetMotionMaster()->MoveTargetedHome();
@@ -106,25 +97,32 @@ void npc_escortAI::EnterEvadeMode()
void npc_escortAI::UpdateAI(const uint32 diff)
{
//Waypoint Updating
- if (IsBeingEscorted && !InCombat && WaitTimer && !Returning)
+ if (IsBeingEscorted && !m_creature->isInCombat() && WaitTimer && !Returning)
{
if (WaitTimer <= diff)
{
if (ReconnectWP)
{
//Correct movement speed
- if (Run)
+ if (bIsRunning && m_creature->HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE))
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
- else m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ else if (!bIsRunning && !m_creature->HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE))
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
//Continue with waypoints
if( !IsOnHold )
{
- m_creature->GetMotionMaster()->MovePoint(CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z );
- debug_log("TSCR: EscortAI Reconnect WP is: %u, %f, %f, %f", CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z);
- WaitTimer = 0;
- ReconnectWP = false;
- return;
+ if (CurrentWP != WaypointList.end())
+ {
+ m_creature->GetMotionMaster()->MovePoint(CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z );
+ debug_log("TSCR: EscortAI Reconnect WP is: %u, %f, %f, %f", CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z);
+
+ WaitTimer = 0;
+ ReconnectWP = false;
+ return;
+ }
+ else
+ debug_log("TSCR: EscortAI Reconnected to end of WP list");
}
}
@@ -142,13 +140,15 @@ void npc_escortAI::UpdateAI(const uint32 diff)
m_creature->Respawn();
m_creature->GetMotionMaster()->Clear(true);
- //Re-Enable gossip
- m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ //Restore original NpcFlags
+ m_creature->SetUInt32Value(UNIT_NPC_FLAGS, m_uiNpcFlags);
IsBeingEscorted = false;
WaitTimer = 0;
return;
- }else{
+ }
+ else
+ {
debug_log("TSCR: EscortAI reached end of waypoints with Despawn off");
IsBeingEscorted = false;
WaitTimer = 0;
@@ -166,7 +166,7 @@ void npc_escortAI::UpdateAI(const uint32 diff)
}
//Check if player is within range
- if (IsBeingEscorted && !InCombat && PlayerGUID)
+ if (IsBeingEscorted && !m_creature->isInCombat() && PlayerGUID)
{
if (PlayerTimer < diff)
{
@@ -186,8 +186,9 @@ void npc_escortAI::UpdateAI(const uint32 diff)
m_creature->Respawn();
m_creature->GetMotionMaster()->Clear(true);
- //Re-Enable gossip
- m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ //Restore original NpcFlags
+ m_creature->SetUInt32Value(UNIT_NPC_FLAGS, m_uiNpcFlags);
+
}
PlayerTimer = 1000;
@@ -225,7 +226,8 @@ void npc_escortAI::MovementInform(uint32 type, uint32 id)
Returning = false;
WaitTimer = 1;
- }else
+ }
+ else
{
//Make sure that we are still on the right waypoint
if (CurrentWP->id != id)
@@ -271,33 +273,87 @@ void npc_escortAI::AddWaypoint(uint32 id, float x, float y, float z, uint32 Wait
WaypointList.push_back(t);
}
+void npc_escortAI::FillPointMovementListForCreature()
+{
+ UNORDERED_MAP<uint32, std::vector<PointMovement> >::iterator pPointsEntries = PointMovementMap.find(m_creature->GetEntry());
+
+ if (pPointsEntries != PointMovementMap.end())
+ {
+ std::vector<PointMovement>::iterator itr;
+
+ for (itr = pPointsEntries->second.begin(); itr != pPointsEntries->second.end(); ++itr)
+ {
+ Escort_Waypoint pPoint(itr->m_uiPointId,itr->m_fX,itr->m_fY,itr->m_fZ,itr->m_uiWaitTime);
+ WaypointList.push_back(pPoint);
+ }
+ }
+}
+
+void npc_escortAI::SetRun(bool bRun)
+{
+ if (bRun)
+ {
+ if (!bIsRunning)
+ {
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ bIsRunning = true;
+ }
+ else
+ debug_log("TSCR: EscortAI attempt to set run mode, but is already running.");
+ }
+ else
+ {
+ if (bIsRunning)
+ {
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ bIsRunning = false;
+ }
+ else
+ debug_log("TSCR: EscortAI attempt to set walk mode, but is already walking.");
+ }
+}
+
void npc_escortAI::Start(bool bAttack, bool bDefend, bool bRun, uint64 pGUID)
{
- if (InCombat)
+ if (m_creature->isInCombat())
{
debug_log("SD2 ERROR: EscortAI attempt to Start while in combat");
return;
}
+ if (IsBeingEscorted)
+ {
+ error_log("TSCR: EscortAI attempt to Start while already escorting");
+ return;
+ }
+
if (WaypointList.empty())
{
- debug_log("SD2 ERROR: Call to escortAI::Start with 0 waypoints");
+ error_db_log("TSCR: EscortAI Start with 0 waypoints (possible missing entry in script_waypoint)");
return;
}
Attack = bAttack;
Defend = bDefend;
- Run = bRun;
+ bIsRunning = bRun;
PlayerGUID = pGUID;
- debug_log("TSCR: EscortAI started with %d waypoints. Attack = %d, Defend = %d, Run = %d, PlayerGUID = %d", WaypointList.size(), Attack, Defend, Run, PlayerGUID);
+ //store original NpcFlags
+ m_uiNpcFlags = m_creature->GetUInt32Value(UNIT_NPC_FLAGS);
+
+ //remove them if any
+ if (m_uiNpcFlags)
+ m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
+
+ debug_log("TSCR: EscortAI started with %d waypoints. Attack = %d, Defend = %d, Run = %d, PlayerGUID = %d", WaypointList.size(), Attack, Defend, bIsRunning, PlayerGUID);
CurrentWP = WaypointList.begin();
//Set initial speed
- if (Run)
+ if (bIsRunning)
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
- else m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ else
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
//Start WP
m_creature->GetMotionMaster()->MovePoint(CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z );
@@ -307,7 +363,5 @@ void npc_escortAI::Start(bool bAttack, bool bDefend, bool bRun, uint64 pGUID)
Returning = false;
IsOnHold = false;
- //Disable questgiver flag
- m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
}
diff --git a/src/bindings/scripts/scripts/npc/npc_escortAI.h b/src/bindings/scripts/scripts/npc/npc_escortAI.h
index a2ec7fc50ed..362c7ed902a 100644
--- a/src/bindings/scripts/scripts/npc/npc_escortAI.h
+++ b/src/bindings/scripts/scripts/npc/npc_escortAI.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
@@ -7,6 +7,8 @@
#define DEFAULT_MAX_PLAYER_DISTANCE 50
+extern UNORDERED_MAP<uint32, std::vector<PointMovement> > PointMovementMap;
+
struct Escort_Waypoint
{
Escort_Waypoint(uint32 _id, float _x, float _y, float _z, uint32 _w)
@@ -32,15 +34,13 @@ struct TRINITY_DLL_DECL npc_escortAI : public ScriptedAI
// Pure Virtual Functions
virtual void WaypointReached(uint32) = 0;
- virtual void Aggro(Unit*) = 0;
-
- virtual void Reset() = 0;
-
// CreatureAI functions
npc_escortAI(Creature *c) : ScriptedAI(c), IsBeingEscorted(false), PlayerTimer(1000), MaxPlayerDistance(DEFAULT_MAX_PLAYER_DISTANCE), CanMelee(true), DespawnAtEnd(true), DespawnAtFar(true) {m_creature->GetPosition(LastPos.x, LastPos.y, LastPos.z);}
bool IsVisible(Unit*) const;
+ void EnterCombat(Unit *);
+
void AttackStart(Unit*);
void MoveInLineOfSight(Unit*);
@@ -58,7 +58,10 @@ struct TRINITY_DLL_DECL npc_escortAI : public ScriptedAI
// EscortAI functions
void AddWaypoint(uint32 id, float x, float y, float z, uint32 WaitTimeMs = 0);
+ void FillPointMovementListForCreature();
+
void Start(bool bAttack, bool bDefend, bool bRun, uint64 pGUID = 0);
+ void SetRun(bool bRun = true);
void SetMaxPlayerDistance(float newMax) { MaxPlayerDistance = newMax; }
float GetMaxPlayerDistance() { return MaxPlayerDistance; }
@@ -77,6 +80,7 @@ struct TRINITY_DLL_DECL npc_escortAI : public ScriptedAI
private:
uint32 WaitTimer;
uint32 PlayerTimer;
+ uint32 m_uiNpcFlags;
float MaxPlayerDistance;
struct
@@ -93,7 +97,7 @@ struct TRINITY_DLL_DECL npc_escortAI : public ScriptedAI
bool Defend;
bool Returning;
bool ReconnectWP;
- bool Run;
+ bool bIsRunning;
bool CanMelee;
bool DespawnAtEnd;
bool DespawnAtFar;
diff --git a/src/bindings/scripts/scripts/npc/npc_innkeeper.cpp b/src/bindings/scripts/scripts/npc/npc_innkeeper.cpp
index f96011266b9..ccd2b69f8bf 100644
--- a/src/bindings/scripts/scripts/npc/npc_innkeeper.cpp
+++ b/src/bindings/scripts/scripts/npc/npc_innkeeper.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -52,7 +52,7 @@ bool GossipHello_npc_innkeeper(Player *player, Creature *_Creature)
if (_Creature->isQuestGiver())
player->PrepareQuestMenu( _Creature->GetGUID() );
- if (isEventActive()&& !player->GetAura(SPELL_TRICK_OR_TREATED,0))
+ if (isEventActive()&& !player->GetAura(SPELL_TRICK_OR_TREATED, player->GetGUID()))
{
char* localizedEntry;
switch (player->GetSession()->GetSessionDbLocaleIndex())
@@ -83,7 +83,7 @@ bool GossipHello_npc_innkeeper(Player *player, Creature *_Creature)
bool GossipSelect_npc_innkeeper(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
- if (action == GOSSIP_ACTION_INFO_DEF+HALLOWEEN_EVENTID && isEventActive() && !player->GetAura(SPELL_TRICK_OR_TREATED,0))
+ if (action == GOSSIP_ACTION_INFO_DEF+HALLOWEEN_EVENTID && isEventActive() && !player->GetAura(SPELL_TRICK_OR_TREATED, player->GetGUID()))
{
player->CLOSE_GOSSIP_MENU();
player->CastSpell(player, SPELL_TRICK_OR_TREATED, true);
diff --git a/src/bindings/scripts/scripts/npc/npc_professions.cpp b/src/bindings/scripts/scripts/npc/npc_professions.cpp
index 00c9b602c6e..b391798eae5 100644
--- a/src/bindings/scripts/scripts/npc/npc_professions.cpp
+++ b/src/bindings/scripts/scripts/npc/npc_professions.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -634,8 +634,6 @@ void SendActionMenu_npc_prof_blacksmith(Player *player, Creature *_Creature, uin
{
//unknown textID (TALK_MUST_UNLEARN_WEAPON)
player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
- //Temporary, not offilike
- _Creature->MonsterSay(TALK_MUST_UNLEARN_WEAPON,0,player->GetGUID());
}
else if( EquippedOk(player,S_UNLEARN_WEAPON) )
{
diff --git a/src/bindings/scripts/scripts/npc/npcs_special.cpp b/src/bindings/scripts/scripts/npc/npcs_special.cpp
index 252ca107031..82cb02123df 100644
--- a/src/bindings/scripts/scripts/npc/npcs_special.cpp
+++ b/src/bindings/scripts/scripts/npc/npcs_special.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -17,7 +17,7 @@
/* ScriptData
SDName: Npcs_Special
SD%Complete: 100
-SDComment: To be used for special NPCs that are located globally. Support for quest 3861 (Cluck!), 6622 and 6624 (Triage)
+SDComment: To be used for special NPCs that are located globally.
SDCategory: NPCs
EndScriptData
*/
@@ -26,8 +26,10 @@ EndScriptData
npc_chicken_cluck 100% support for quest 3861 (Cluck!)
npc_dancing_flames 100% midsummer event NPC
npc_guardian 100% guardianAI used to prevent players from accessing off-limits areas. Not in use by SD2
+npc_garments_of_quests 80% NPC's related to all Garments of-quests 5621, 5624, 5625, 5648, 565
npc_injured_patient 100% patients for triage-quests (6622 and 6624)
npc_doctor 100% Gustaf Vanhowzen and Gregory Victor, quest 6622 and 6624 (Triage)
+npc_kingdom_of_dalaran_quests Misc NPC's gossip option related to quests 12791, 12794 and 12796
npc_mount_vendor 100% Regular mount vendors all over the world. Display gossip if player doesn't meet the requirements to buy
npc_rogue_trainer 80% Scripted trainers, so they are able to offer item 17126 for class quest 6681
npc_sayge 100% Darkmoon event fortune teller, buff player based on answers given
@@ -35,15 +37,17 @@ npc_snake_trap_serpents 80% AI for snakes that summoned by Snake Trap
EndContentData */
#include "precompiled.h"
+#include "../npc/npc_escortAI.h"
/*########
# npc_chicken_cluck
#########*/
+#define EMOTE_A_HELLO -1070004
+#define EMOTE_H_HELLO -1070005
+#define EMOTE_CLUCK_TEXT2 -1070006
+
#define QUEST_CLUCK 3861
-#define EMOTE_A_HELLO "looks up at you quizzically. Maybe you should inspect it?"
-#define EMOTE_H_HELLO "looks at you unexpectadly."
-#define CLUCK_TEXT2 "starts pecking at the feed."
#define FACTION_FRIENDLY 84
#define FACTION_CHICKEN 31
@@ -61,7 +65,7 @@ struct TRINITY_DLL_DECL npc_chicken_cluckAI : public ScriptedAI
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void UpdateAI(const uint32 diff)
{
@@ -76,40 +80,37 @@ struct TRINITY_DLL_DECL npc_chicken_cluckAI : public ScriptedAI
if(UpdateVictim())
DoMeleeAttackIfReady();
}
-};
-
-CreatureAI* GetAI_npc_chicken_cluck(Creature *_Creature)
-{
- return new npc_chicken_cluckAI(_Creature);
-}
-bool ReceiveEmote_npc_chicken_cluck( Player *player, Creature *_Creature, uint32 emote )
-{
- if( emote == TEXTEMOTE_CHICKEN )
+ void ReceiveEmote( Player *player, uint32 emote )
{
- if( player->GetTeam() == ALLIANCE )
+ if( emote == TEXTEMOTE_CHICKEN )
{
- if( rand()%30 == 1 )
+ if( player->GetTeam() == ALLIANCE )
{
- if( player->GetQuestStatus(QUEST_CLUCK) == QUEST_STATUS_NONE )
+ if( rand()%30 == 1 )
{
- _Creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
- _Creature->setFaction(FACTION_FRIENDLY);
- _Creature->MonsterTextEmote(EMOTE_A_HELLO, 0);
+ if( player->GetQuestStatus(QUEST_CLUCK) == QUEST_STATUS_NONE )
+ {
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->setFaction(FACTION_FRIENDLY);
+ DoScriptText(EMOTE_A_HELLO, m_creature);
+ }
}
- }
- } else
- _Creature->MonsterTextEmote(EMOTE_H_HELLO,0);
- }
- if( emote == TEXTEMOTE_CHEER && player->GetTeam() == ALLIANCE )
- if( player->GetQuestStatus(QUEST_CLUCK) == QUEST_STATUS_COMPLETE )
- {
- _Creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
- _Creature->setFaction(FACTION_FRIENDLY);
- _Creature->MonsterTextEmote(CLUCK_TEXT2, 0);
+ } else DoScriptText(EMOTE_H_HELLO,m_creature);
+ }
+ if( emote == TEXTEMOTE_CHEER && player->GetTeam() == ALLIANCE )
+ if( player->GetQuestStatus(QUEST_CLUCK) == QUEST_STATUS_COMPLETE )
+ {
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->setFaction(FACTION_FRIENDLY);
+ DoScriptText(EMOTE_CLUCK_TEXT2, m_creature);
+ }
}
+};
- return true;
+CreatureAI* GetAI_npc_chicken_cluck(Creature *_Creature)
+{
+ return new npc_chicken_cluckAI(_Creature);
}
bool QuestAccept_npc_chicken_cluck(Player *player, Creature *_Creature, const Quest *_Quest )
@@ -152,7 +153,7 @@ struct TRINITY_DLL_DECL npc_dancing_flamesAI : public ScriptedAI
float x, y, z;
m_creature->GetPosition(x,y,z);
m_creature->Relocate(x,y,z + 0.94f);
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT | MOVEMENTFLAG_LEVITATING);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_DANCE);
WorldPacket data; //send update position to client
m_creature->BuildHeartBeatMsg(&data);
@@ -171,115 +172,84 @@ struct TRINITY_DLL_DECL npc_dancing_flamesAI : public ScriptedAI
}
}
- void Aggro(Unit* who){}
-};
+ void EnterCombat(Unit* who){}
-CreatureAI* GetAI_npc_dancing_flames(Creature *_Creature)
-{
- return new npc_dancing_flamesAI(_Creature);
-}
-
-bool ReceiveEmote_npc_dancing_flames( Player *player, Creature *flame, uint32 emote )
-{
- if ( ((npc_dancing_flamesAI*)flame->AI())->active &&
- flame->IsWithinLOS(player->GetPositionX(),player->GetPositionY(),player->GetPositionZ()) && flame->IsWithinDistInMap(player,30.0f))
+ void ReceiveEmote( Player *player, uint32 emote )
{
- flame->SetInFront(player);
- ((npc_dancing_flamesAI*)flame->AI())->active = false;
-
- WorldPacket data;
- flame->BuildHeartBeatMsg(&data);
- flame->SendMessageToSet(&data,true);
- switch(emote)
+ if (m_creature->IsWithinLOS(player->GetPositionX(),player->GetPositionY(),player->GetPositionZ()) && m_creature->IsWithinDistInMap(player,30.0f))
{
- case TEXTEMOTE_KISS: flame->HandleEmoteCommand(EMOTE_ONESHOT_SHY); break;
- case TEXTEMOTE_WAVE: flame->HandleEmoteCommand(EMOTE_ONESHOT_WAVE); break;
- case TEXTEMOTE_BOW: flame->HandleEmoteCommand(EMOTE_ONESHOT_BOW); break;
- case TEXTEMOTE_JOKE: flame->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH); break;
- case TEXTEMOTE_DANCE:
+ m_creature->SetInFront(player);
+ active = false;
+
+ WorldPacket data;
+ m_creature->BuildHeartBeatMsg(&data);
+ m_creature->SendMessageToSet(&data,true);
+ switch(emote)
{
- if (!player->HasAura(SPELL_SEDUCTION,0))
- flame->CastSpell(player,SPELL_SEDUCTION,true);
+ case TEXTEMOTE_KISS: m_creature->HandleEmoteCommand(EMOTE_ONESHOT_SHY); break;
+ case TEXTEMOTE_WAVE: m_creature->HandleEmoteCommand(EMOTE_ONESHOT_WAVE); break;
+ case TEXTEMOTE_BOW: m_creature->HandleEmoteCommand(EMOTE_ONESHOT_BOW); break;
+ case TEXTEMOTE_JOKE: m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH); break;
+ case TEXTEMOTE_DANCE:
+ {
+ if (!player->HasAura(SPELL_SEDUCTION))
+ m_creature->CastSpell(player,SPELL_SEDUCTION,true);
+ }
+ break;
}
- break;
}
}
- return true;
+};
+
+CreatureAI* GetAI_npc_dancing_flames(Creature *_Creature)
+{
+ return new npc_dancing_flamesAI(_Creature);
}
/*######
## Triage quest
######*/
-#define SAY_DOC1 "I'm saved! Thank you, doctor!"
-#define SAY_DOC2 "HOORAY! I AM SAVED!"
-#define SAY_DOC3 "Sweet, sweet embrace... take me..."
+#define SAY_DOC1 -1000201
+#define SAY_DOC2 -1000202
+#define SAY_DOC3 -1000203
+
+#define DOCTOR_ALLIANCE 12939
+#define DOCTOR_HORDE 12920
+#define ALLIANCE_COORDS 7
+#define HORDE_COORDS 6
struct Location
{
float x, y, z, o;
};
-#define DOCTOR_ALLIANCE 12939
-
static Location AllianceCoords[]=
{
- { // Top-far-right bunk as seen from entrance
- -3757.38, -4533.05, 14.16, 3.62
- },
- { // Top-far-left bunk
- -3754.36, -4539.13, 14.16, 5.13
- },
- { // Far-right bunk
- -3749.54, -4540.25, 14.28, 3.34
- },
- { // Right bunk near entrance
- -3742.10, -4536.85, 14.28, 3.64
- },
- { // Far-left bunk
- -3755.89, -4529.07, 14.05, 0.57
- },
- { // Mid-left bunk
- -3749.51, -4527.08, 14.07, 5.26
- },
- { // Left bunk near entrance
- -3746.37, -4525.35, 14.16, 5.22
- },
+ {-3757.38, -4533.05, 14.16, 3.62}, // Top-far-right bunk as seen from entrance
+ {-3754.36, -4539.13, 14.16, 5.13}, // Top-far-left bunk
+ {-3749.54, -4540.25, 14.28, 3.34}, // Far-right bunk
+ {-3742.10, -4536.85, 14.28, 3.64}, // Right bunk near entrance
+ {-3755.89, -4529.07, 14.05, 0.57}, // Far-left bunk
+ {-3749.51, -4527.08, 14.07, 5.26}, // Mid-left bunk
+ {-3746.37, -4525.35, 14.16, 5.22}, // Left bunk near entrance
};
-#define ALLIANCE_COORDS 7
-
//alliance run to where
#define A_RUNTOX -3742.96
#define A_RUNTOY -4531.52
#define A_RUNTOZ 11.91
-#define DOCTOR_HORDE 12920
-
static Location HordeCoords[]=
{
- { // Left, Behind
- -1013.75, -3492.59, 62.62, 4.34
- },
- { // Right, Behind
- -1017.72, -3490.92, 62.62, 4.34
- },
- { // Left, Mid
- -1015.77, -3497.15, 62.82, 4.34
- },
- { // Right, Mid
- -1019.51, -3495.49, 62.82, 4.34
- },
- { // Left, front
- -1017.25, -3500.85, 62.98, 4.34
- },
- { // Right, Front
- -1020.95, -3499.21, 62.98, 4.34
- }
+ {-1013.75, -3492.59, 62.62, 4.34}, // Left, Behind
+ {-1017.72, -3490.92, 62.62, 4.34}, // Right, Behind
+ {-1015.77, -3497.15, 62.82, 4.34}, // Left, Mid
+ {-1019.51, -3495.49, 62.82, 4.34}, // Right, Mid
+ {-1017.25, -3500.85, 62.98, 4.34}, // Left, front
+ {-1020.95, -3499.21, 62.98, 4.34} // Right, Front
};
-#define HORDE_COORDS 6
-
//horde run to where
#define H_RUNTOX -1016.44
#define H_RUNTOY -3508.48
@@ -305,6 +275,8 @@ const uint32 HordeSoldierId[3] =
struct TRINITY_DLL_DECL npc_doctorAI : public ScriptedAI
{
+ npc_doctorAI(Creature *c) : ScriptedAI(c) {}
+
uint64 Playerguid;
uint32 SummonPatient_Timer;
@@ -317,16 +289,24 @@ struct TRINITY_DLL_DECL npc_doctorAI : public ScriptedAI
std::list<uint64> Patients;
std::vector<Location*> Coordinates;
- npc_doctorAI(Creature *c) : ScriptedAI(c) {}
+ void Reset()
+ {
+ Playerguid = 0;
+
+ SummonPatient_Timer = 10000;
+ SummonPatientCount = 0;
+ PatientDiedCount = 0;
+ PatientSavedCount = 0;
- void Reset(){}
+ Event = false;
+ }
void BeginEvent(Player* player);
void PatientDied(Location* Point);
void PatientSaved(Creature* soldier, Player* player, Location* Point);
void UpdateAI(const uint32 diff);
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
};
/*#####
@@ -338,20 +318,21 @@ struct TRINITY_DLL_DECL npc_injured_patientAI : public ScriptedAI
npc_injured_patientAI(Creature *c) : ScriptedAI(c) {}
uint64 Doctorguid;
-
Location* Coord;
void Reset()
{
Doctorguid = 0;
-
Coord = NULL;
- //no select
+
+ //no select
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- //no regen health
+
+ //no regen health
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
- //to make them lay with face down
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_DEAD);
+
+ //to make them lay with face down
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
uint32 mobId = m_creature->GetEntry();
@@ -372,31 +353,40 @@ struct TRINITY_DLL_DECL npc_injured_patientAI : public ScriptedAI
}
}
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void SpellHit(Unit *caster, const SpellEntry *spell)
{
if (caster->GetTypeId() == TYPEID_PLAYER && m_creature->isAlive() && spell->Id == 20804)
{
- if( (((Player*)caster)->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (((Player*)caster)->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE))
+ if((((Player*)caster)->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (((Player*)caster)->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE))
{
- if(Doctorguid)
+ if (Doctorguid)
{
- Creature* Doctor = (Unit::GetCreature((*m_creature), Doctorguid));
- if(Doctor)
+ if(Creature* Doctor = Unit::GetCreature(*m_creature, Doctorguid))
((npc_doctorAI*)Doctor->AI())->PatientSaved(m_creature, ((Player*)caster), Coord);
}
}
- //make not selectable
+
+ //make not selectable
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- //regen health
+
+ //regen health
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
- //stand up
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_NONE);
- DoSay(SAY_DOC1,LANG_UNIVERSAL,NULL);
+
+ //stand up
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND);
+
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_DOC1,m_creature); break;
+ case 1: DoScriptText(SAY_DOC2,m_creature); break;
+ case 2: DoScriptText(SAY_DOC3,m_creature); break;
+ }
uint32 mobId = m_creature->GetEntry();
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+
switch (mobId)
{
case 12923:
@@ -416,8 +406,9 @@ struct TRINITY_DLL_DECL npc_injured_patientAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
+ //lower HP on every world tick makes it a useful counter, not officlone though
if (m_creature->isAlive() && m_creature->GetHealth() > 6)
- { //lower HP on every world tick makes it a useful counter, not officlone though
+ {
m_creature->SetHealth(uint32(m_creature->GetHealth()-5) );
}
@@ -428,10 +419,9 @@ struct TRINITY_DLL_DECL npc_injured_patientAI : public ScriptedAI
m_creature->setDeathState(JUST_DIED);
m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, 32);
- if(Doctorguid)
+ if (Doctorguid)
{
- Creature* Doctor = (Unit::GetCreature((*m_creature), Doctorguid));
- if(Doctor)
+ if(Creature* Doctor = Unit::GetCreature((*m_creature), Doctorguid))
((npc_doctorAI*)Doctor->AI())->PatientDied(Coord);
}
}
@@ -462,7 +452,6 @@ void npc_doctorAI::BeginEvent(Player* player)
for(uint8 i = 0; i < ALLIANCE_COORDS; ++i)
Coordinates.push_back(&AllianceCoords[i]);
break;
-
case DOCTOR_HORDE:
for(uint8 i = 0; i < HORDE_COORDS; ++i)
Coordinates.push_back(&HordeCoords[i]);
@@ -470,7 +459,6 @@ void npc_doctorAI::BeginEvent(Player* player)
}
Event = true;
-
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
@@ -489,6 +477,7 @@ void npc_doctorAI::PatientDied(Location* Point)
Event = false;
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ Reset();
}
Coordinates.push_back(Point);
@@ -497,31 +486,31 @@ void npc_doctorAI::PatientDied(Location* Point)
void npc_doctorAI::PatientSaved(Creature* soldier, Player* player, Location* Point)
{
- if(player && Playerguid == player->GetGUID())
+ if (player && Playerguid == player->GetGUID())
{
- if((player->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (player->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE))
+ if ((player->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (player->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE))
{
PatientSavedCount++;
- if(PatientSavedCount == 15)
+ if (PatientSavedCount == 15)
{
- if(!Patients.empty())
+ if (!Patients.empty())
{
std::list<uint64>::iterator itr;
for(itr = Patients.begin(); itr != Patients.end(); ++itr)
{
- Creature* Patient = (Unit::GetCreature((*m_creature), *itr));
- if( Patient )
+ if(Creature* Patient = Unit::GetCreature((*m_creature), *itr))
Patient->setDeathState(JUST_DIED);
}
}
- if(player->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE)
+ if (player->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE)
player->AreaExploredOrEventHappens(6624);
- else if(player->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)
+ else if (player->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)
player->AreaExploredOrEventHappens(6622);
Event = false;
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ Reset();
}
Coordinates.push_back(Point);
@@ -531,53 +520,61 @@ void npc_doctorAI::PatientSaved(Creature* soldier, Player* player, Location* Poi
void npc_doctorAI::UpdateAI(const uint32 diff)
{
- if(Event && SummonPatientCount >= 20)
+ if (Event && SummonPatientCount >= 20)
{
Event = false;
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ Reset();
}
- if(Event)
- if(SummonPatient_Timer < diff)
+ if (Event)
{
- Creature* Patient = NULL;
- Location* Point = NULL;
+ if (SummonPatient_Timer < diff)
+ {
+ Creature* Patient = NULL;
+ Location* Point = NULL;
- if(Coordinates.empty())
- return;
+ if (Coordinates.empty())
+ return;
- std::vector<Location*>::iterator itr = Coordinates.begin()+rand()%Coordinates.size();
- uint32 patientEntry = 0;
+ std::vector<Location*>::iterator itr = Coordinates.begin()+rand()%Coordinates.size();
+ uint32 patientEntry = 0;
- switch(m_creature->GetEntry())
- {
- case DOCTOR_ALLIANCE: patientEntry = AllianceSoldierId[rand()%3]; break;
- case DOCTOR_HORDE: patientEntry = HordeSoldierId[rand()%3]; break;
- default:
- error_log("TSCR: Invalid entry for Triage doctor. Please check your database");
- return;
- }
+ switch(m_creature->GetEntry())
+ {
+ case DOCTOR_ALLIANCE: patientEntry = AllianceSoldierId[rand()%3]; break;
+ case DOCTOR_HORDE: patientEntry = HordeSoldierId[rand()%3]; break;
+ default:
+ error_log("TSCR: Invalid entry for Triage doctor. Please check your database");
+ return;
+ }
- Point = *itr;
+ Point = *itr;
- Patient = m_creature->SummonCreature(patientEntry, Point->x, Point->y, Point->z, Point->o, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ Patient = m_creature->SummonCreature(patientEntry, Point->x, Point->y, Point->z, Point->o, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
- if(Patient)
- {
- Patients.push_back(Patient->GetGUID());
- ((npc_injured_patientAI*)Patient->AI())->Doctorguid = m_creature->GetGUID();
- if(Point)
- ((npc_injured_patientAI*)Patient->AI())->Coord = Point;
- Coordinates.erase(itr);
- }
- SummonPatient_Timer = 10000;
- SummonPatientCount++;
- }else SummonPatient_Timer -= diff;
+ if (Patient)
+ {
+ //303, this flag appear to be required for client side item->spell to work (TARGET_SINGLE_FRIEND)
+ Patient->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+
+ Patients.push_back(Patient->GetGUID());
+ ((npc_injured_patientAI*)Patient->AI())->Doctorguid = m_creature->GetGUID();
+
+ if (Point)
+ ((npc_injured_patientAI*)Patient->AI())->Coord = Point;
+
+ Coordinates.erase(itr);
+ }
+ SummonPatient_Timer = 10000;
+ SummonPatientCount++;
+ }else SummonPatient_Timer -= diff;
+ }
}
bool QuestAccept_npc_doctor(Player *player, Creature *creature, Quest const *quest )
{
- if((quest->GetQuestId() == 6624) || (quest->GetQuestId() == 6622))
+ if ((quest->GetQuestId() == 6624) || (quest->GetQuestId() == 6622))
((npc_doctorAI*)creature->AI())->BeginEvent(player);
return true;
@@ -589,11 +586,226 @@ CreatureAI* GetAI_npc_doctor(Creature *_Creature)
}
/*######
+## npc_garments_of_quests
+######*/
+
+//TODO: get text for each NPC
+
+enum
+{
+ SPELL_LESSER_HEAL_R2 = 2052,
+ SPELL_FORTITUDE_R1 = 1243,
+
+ QUEST_MOON = 5621,
+ QUEST_LIGHT_1 = 5624,
+ QUEST_LIGHT_2 = 5625,
+ QUEST_SPIRIT = 5648,
+ QUEST_DARKNESS = 5650,
+
+ ENTRY_SHAYA = 12429,
+ ENTRY_ROBERTS = 12423,
+ ENTRY_DOLF = 12427,
+ ENTRY_KORJA = 12430,
+ ENTRY_DG_KEL = 12428,
+
+ SAY_COMMON_HEALED = -1000164,
+ SAY_DG_KEL_THANKS = -1000165,
+ SAY_DG_KEL_GOODBYE = -1000166,
+ SAY_ROBERTS_THANKS = -1000167,
+ SAY_ROBERTS_GOODBYE = -1000168,
+ SAY_KORJA_THANKS = -1000169,
+ SAY_KORJA_GOODBYE = -1000170,
+ SAY_DOLF_THANKS = -1000171,
+ SAY_DOLF_GOODBYE = -1000172,
+ SAY_SHAYA_THANKS = -1000173,
+ SAY_SHAYA_GOODBYE = -1000174,
+};
+
+struct TRINITY_DLL_DECL npc_garments_of_questsAI : public npc_escortAI
+{
+ npc_garments_of_questsAI(Creature *c) : npc_escortAI(c) {Reset();}
+
+ uint64 caster;
+
+ bool bIsHealed;
+ bool bCanRun;
+
+ uint32 RunAwayTimer;
+
+ void Reset()
+ {
+ caster = 0;
+
+ bIsHealed = false;
+ bCanRun = false;
+
+ RunAwayTimer = 5000;
+
+ m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
+ //expect database to have RegenHealth=0
+ m_creature->SetHealth(int(m_creature->GetMaxHealth()*0.7));
+ }
+
+ void EnterCombat(Unit *who) {}
+
+ void SpellHit(Unit* pCaster, const SpellEntry *Spell)
+ {
+ if (Spell->Id == SPELL_LESSER_HEAL_R2 || Spell->Id == SPELL_FORTITUDE_R1)
+ {
+ //not while in combat
+ if (m_creature->isInCombat())
+ return;
+
+ //nothing to be done now
+ if (bIsHealed && bCanRun)
+ return;
+
+ if (pCaster->GetTypeId() == TYPEID_PLAYER)
+ {
+ switch(m_creature->GetEntry())
+ {
+ case ENTRY_SHAYA:
+ if (((Player*)pCaster)->GetQuestStatus(QUEST_MOON) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (bIsHealed && !bCanRun && Spell->Id == SPELL_FORTITUDE_R1)
+ {
+ DoScriptText(SAY_SHAYA_THANKS,m_creature,pCaster);
+ bCanRun = true;
+ }
+ else if (!bIsHealed && Spell->Id == SPELL_LESSER_HEAL_R2)
+ {
+ caster = pCaster->GetGUID();
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ DoScriptText(SAY_COMMON_HEALED,m_creature,pCaster);
+ bIsHealed = true;
+ }
+ }
+ break;
+ case ENTRY_ROBERTS:
+ if (((Player*)pCaster)->GetQuestStatus(QUEST_LIGHT_1) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (bIsHealed && !bCanRun && Spell->Id == SPELL_FORTITUDE_R1)
+ {
+ DoScriptText(SAY_ROBERTS_THANKS,m_creature,pCaster);
+ bCanRun = true;
+ }
+ else if (!bIsHealed && Spell->Id == SPELL_LESSER_HEAL_R2)
+ {
+ caster = pCaster->GetGUID();
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ DoScriptText(SAY_COMMON_HEALED,m_creature,pCaster);
+ bIsHealed = true;
+ }
+ }
+ break;
+ case ENTRY_DOLF:
+ if (((Player*)pCaster)->GetQuestStatus(QUEST_LIGHT_2) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (bIsHealed && !bCanRun && Spell->Id == SPELL_FORTITUDE_R1)
+ {
+ DoScriptText(SAY_DOLF_THANKS,m_creature,pCaster);
+ bCanRun = true;
+ }
+ else if (!bIsHealed && Spell->Id == SPELL_LESSER_HEAL_R2)
+ {
+ caster = pCaster->GetGUID();
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ DoScriptText(SAY_COMMON_HEALED,m_creature,pCaster);
+ bIsHealed = true;
+ }
+ }
+ break;
+ case ENTRY_KORJA:
+ if (((Player*)pCaster)->GetQuestStatus(QUEST_SPIRIT) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (bIsHealed && !bCanRun && Spell->Id == SPELL_FORTITUDE_R1)
+ {
+ DoScriptText(SAY_KORJA_THANKS,m_creature,pCaster);
+ bCanRun = true;
+ }
+ else if (!bIsHealed && Spell->Id == SPELL_LESSER_HEAL_R2)
+ {
+ caster = pCaster->GetGUID();
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ DoScriptText(SAY_COMMON_HEALED,m_creature,pCaster);
+ bIsHealed = true;
+ }
+ }
+ break;
+ case ENTRY_DG_KEL:
+ if (((Player*)pCaster)->GetQuestStatus(QUEST_DARKNESS) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (bIsHealed && !bCanRun && Spell->Id == SPELL_FORTITUDE_R1)
+ {
+ DoScriptText(SAY_DG_KEL_THANKS,m_creature,pCaster);
+ bCanRun = true;
+ }
+ else if (!bIsHealed && Spell->Id == SPELL_LESSER_HEAL_R2)
+ {
+ caster = pCaster->GetGUID();
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ DoScriptText(SAY_COMMON_HEALED,m_creature,pCaster);
+ bIsHealed = true;
+ }
+ }
+ break;
+ }
+
+ //give quest credit, not expect any special quest objectives
+ if (bCanRun)
+ ((Player*)pCaster)->TalkedToCreature(m_creature->GetEntry(),m_creature->GetGUID());
+ }
+ }
+ }
+
+ void WaypointReached(uint32 uiPoint)
+ {
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (bCanRun && !m_creature->isInCombat())
+ {
+ if (RunAwayTimer <= diff)
+ {
+ if (Unit *pUnit = Unit::GetUnit(*m_creature,caster))
+ {
+ switch(m_creature->GetEntry())
+ {
+ case ENTRY_SHAYA: DoScriptText(SAY_SHAYA_GOODBYE,m_creature,pUnit); break;
+ case ENTRY_ROBERTS: DoScriptText(SAY_ROBERTS_GOODBYE,m_creature,pUnit); break;
+ case ENTRY_DOLF: DoScriptText(SAY_DOLF_GOODBYE,m_creature,pUnit); break;
+ case ENTRY_KORJA: DoScriptText(SAY_KORJA_GOODBYE,m_creature,pUnit); break;
+ case ENTRY_DG_KEL: DoScriptText(SAY_DG_KEL_GOODBYE,m_creature,pUnit); break;
+ }
+
+ Start(false,true,true);
+ }
+ else
+ EnterEvadeMode(); //something went wrong
+
+ RunAwayTimer = 30000;
+ }else RunAwayTimer -= diff;
+ }
+
+ npc_escortAI::UpdateAI(diff);
+ }
+};
+
+CreatureAI* GetAI_npc_garments_of_quests(Creature* pCreature)
+{
+ npc_garments_of_questsAI* tempAI = new npc_garments_of_questsAI(pCreature);
+
+ tempAI->FillPointMovementListForCreature();
+
+ return (CreatureAI*)tempAI;
+}
+
+/*######
## npc_guardian
######*/
#define SPELL_DEATHTOUCH 5
-#define SAY_AGGRO "This area is closed!"
struct TRINITY_DLL_DECL npc_guardianAI : public ScriptedAI
{
@@ -604,9 +816,8 @@ struct TRINITY_DLL_DECL npc_guardianAI : public ScriptedAI
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
- DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL);
}
void UpdateAI(const uint32 diff)
@@ -628,6 +839,44 @@ CreatureAI* GetAI_npc_guardian(Creature *_Creature)
}
/*######
+## npc_kingdom_of_dalaran_quests
+######*/
+
+enum
+{
+ SPELL_TELEPORT_DALARAN = 53360,
+ ITEM_KT_SIGNET = 39740,
+ QUEST_MAGICAL_KINGDOM_A = 12794,
+ QUEST_MAGICAL_KINGDOM_H = 12791,
+ QUEST_MAGICAL_KINGDOM_N = 12796
+};
+
+#define GOSSIP_ITEM_TELEPORT_TO "I am ready to be teleported to Dalaran."
+
+bool GossipHello_npc_kingdom_of_dalaran_quests(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->HasItemCount(ITEM_KT_SIGNET,1) && (!pPlayer->GetQuestRewardStatus(QUEST_MAGICAL_KINGDOM_A) ||
+ !pPlayer->GetQuestRewardStatus(QUEST_MAGICAL_KINGDOM_H) || !pPlayer->GetQuestRewardStatus(QUEST_MAGICAL_KINGDOM_N)))
+ pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_TELEPORT_TO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->SEND_GOSSIP_MENU(pCreature->GetNpcTextId(), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_kingdom_of_dalaran_quests(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,SPELL_TELEPORT_DALARAN,false);
+ }
+ return true;
+}
+
+/*######
## npc_mount_vendor
######*/
@@ -898,7 +1147,7 @@ struct TRINITY_DLL_DECL npc_steam_tonkAI : public ScriptedAI
npc_steam_tonkAI(Creature *c) : ScriptedAI(c) {}
void Reset() {}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void OnPossess(bool apply)
{
@@ -937,7 +1186,7 @@ struct TRINITY_DLL_DECL npc_tonk_mineAI : public ScriptedAI
ExplosionTimer = 3000;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void AttackStart(Unit *who) {}
void MoveInLineOfSight(Unit *who) {}
@@ -964,7 +1213,7 @@ CreatureAI* GetAI_npc_tonk_mine(Creature *_Creature)
bool ReceiveEmote_npc_winter_reveler( Player *player, Creature *_Creature, uint32 emote )
{
//TODO: check auralist.
- if(player->HasAura(26218, 0))
+ if(player->HasAura(26218))
return false;
if( emote == TEXTEMOTE_KISS )
@@ -1016,7 +1265,7 @@ struct TRINITY_DLL_DECL npc_snake_trap_serpentsAI : public ScriptedAI
Unit *Owner;
bool IsViper;
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void Reset()
{
@@ -1040,9 +1289,6 @@ struct TRINITY_DLL_DECL npc_snake_trap_serpentsAI : public ScriptedAI
uint32 delta = (rand() % 7) *100;
m_creature->SetStatFloatValue(UNIT_FIELD_BASEATTACKTIME, Info->baseattacktime + delta);
m_creature->SetStatFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER , Info->attackpower);
-
- InCombat = false;
-
}
//Redefined for random target selection:
@@ -1064,7 +1310,6 @@ struct TRINITY_DLL_DECL npc_snake_trap_serpentsAI : public ScriptedAI
m_creature->setAttackTimer(BASE_ATTACK, (rand() % 10) * 100);
SpellTimer = (rand() % 10) * 100;
AttackStart(who);
- InCombat = true;
}
}
}
@@ -1076,7 +1321,7 @@ struct TRINITY_DLL_DECL npc_snake_trap_serpentsAI : public ScriptedAI
return;
//Follow if not in combat
- if (!m_creature->hasUnitState(UNIT_STAT_FOLLOW)&& !InCombat)
+ if (!m_creature->hasUnitState(UNIT_STAT_FOLLOW)&& !m_creature->isInCombat())
{
m_creature->GetMotionMaster()->Clear();
m_creature->GetMotionMaster()->MoveFollow(Owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
@@ -1085,11 +1330,9 @@ struct TRINITY_DLL_DECL npc_snake_trap_serpentsAI : public ScriptedAI
//No victim -> get new from owner (need this because MoveInLineOfSight won't work while following -> corebug)
if (!m_creature->getVictim())
{
- if (InCombat)
+ if (m_creature->isInCombat())
DoStopAttack();
- InCombat = false;
-
if(Owner->getAttackerForHelper())
AttackStart(Owner->getAttackerForHelper());
@@ -1136,7 +1379,6 @@ void AddSC_npcs_special()
newscript = new Script;
newscript->Name="npc_chicken_cluck";
newscript->GetAI = &GetAI_npc_chicken_cluck;
- newscript->pReceiveEmote = &ReceiveEmote_npc_chicken_cluck;
newscript->pQuestAccept = &QuestAccept_npc_chicken_cluck;
newscript->pQuestComplete = &QuestComplete_npc_chicken_cluck;
newscript->RegisterSelf();
@@ -1144,7 +1386,6 @@ void AddSC_npcs_special()
newscript = new Script;
newscript->Name="npc_dancing_flames";
newscript->GetAI = &GetAI_npc_dancing_flames;
- newscript->pReceiveEmote = &ReceiveEmote_npc_dancing_flames;
newscript->RegisterSelf();
newscript = new Script;
@@ -1159,11 +1400,22 @@ void AddSC_npcs_special()
newscript->RegisterSelf();
newscript = new Script;
+ newscript->Name = "npc_garments_of_quests";
+ newscript->GetAI = &GetAI_npc_garments_of_quests;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
newscript->Name="npc_guardian";
newscript->GetAI = &GetAI_npc_guardian;
newscript->RegisterSelf();
newscript = new Script;
+ newscript->Name="npc_kingdom_of_dalaran_quests";
+ newscript->pGossipHello = &GossipHello_npc_kingdom_of_dalaran_quests;
+ newscript->pGossipSelect = &GossipSelect_npc_kingdom_of_dalaran_quests;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
newscript->Name="npc_mount_vendor";
newscript->pGossipHello = &GossipHello_npc_mount_vendor;
newscript->pGossipSelect = &GossipSelect_npc_mount_vendor;
@@ -1193,12 +1445,12 @@ void AddSC_npcs_special()
newscript = new Script;
newscript->Name="npc_winter_reveler";
- newscript->pReceiveEmote = &ReceiveEmote_npc_winter_reveler;
+ //newscript->pReceiveEmote = &ReceiveEmote_npc_winter_reveler;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_brewfest_reveler";
- newscript->pReceiveEmote = &ReceiveEmote_npc_brewfest_reveler;
+ //newscript->pReceiveEmote = &ReceiveEmote_npc_brewfest_reveler;
newscript->RegisterSelf();
newscript = new Script;
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 72dda8dd835..a6959cc5268 100644
--- a/src/bindings/scripts/scripts/zone/alterac_mountains/alterac_mountains.cpp
+++ b/src/bindings/scripts/scripts/zone/alterac_mountains/alterac_mountains.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -44,7 +44,7 @@ struct TRINITY_DLL_DECL npc_ravenholdtAI : public ScriptedAI
((Player*)who)->KilledMonster(m_creature->GetEntry(),m_creature->GetGUID() );
}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
};
CreatureAI* GetAI_npc_ravenholdt(Creature *_Creature)
{
diff --git a/src/bindings/scripts/scripts/zone/arathi_highlands/arathi_highlands.cpp b/src/bindings/scripts/scripts/zone/arathi_highlands/arathi_highlands.cpp
index d83cb9b3281..ba3b6aa8e9a 100644
--- a/src/bindings/scripts/scripts/zone/arathi_highlands/arathi_highlands.cpp
+++ b/src/bindings/scripts/scripts/zone/arathi_highlands/arathi_highlands.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -91,7 +91,7 @@ struct TRINITY_DLL_DECL npc_professor_phizzlethorpeAI : public npc_escortAI
m_creature->setFaction(35);
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature, NULL);
}
@@ -127,27 +127,7 @@ CreatureAI* GetAI_npc_professor_phizzlethorpeAI(Creature *_Creature)
{
npc_professor_phizzlethorpeAI* professor_phizzlethorpeAI = new npc_professor_phizzlethorpeAI(_Creature);
- professor_phizzlethorpeAI->AddWaypoint(0, -2066.45, -2085.96, 9.08);
- professor_phizzlethorpeAI->AddWaypoint(1, -2077.99, -2105.33, 13.24);
- professor_phizzlethorpeAI->AddWaypoint(2, -2074.60, -2109.67, 14.24);
- professor_phizzlethorpeAI->AddWaypoint(3, -2076.60, -2117.46, 16.67);
- professor_phizzlethorpeAI->AddWaypoint(4, -2073.51, -2123.46, 18.42, 2000);
- professor_phizzlethorpeAI->AddWaypoint(5, -2073.51, -2123.46, 18.42, 4000);
- professor_phizzlethorpeAI->AddWaypoint(6, -2066.60, -2131.85, 21.56);
- professor_phizzlethorpeAI->AddWaypoint(7, -2053.85, -2143.19, 20.31);
- professor_phizzlethorpeAI->AddWaypoint(8, -2043.49, -2153.73, 20.20, 12000);
- professor_phizzlethorpeAI->AddWaypoint(9, -2043.49, -2153.73, 20.20, 14000);
- professor_phizzlethorpeAI->AddWaypoint(10, -2043.49, -2153.73, 20.20, 10000);
- professor_phizzlethorpeAI->AddWaypoint(11, -2043.49, -2153.73, 20.20, 2000);
- professor_phizzlethorpeAI->AddWaypoint(12, -2053.85, -2143.19, 20.31);
- professor_phizzlethorpeAI->AddWaypoint(13, -2066.60, -2131.85, 21.56);
- professor_phizzlethorpeAI->AddWaypoint(14, -2073.51, -2123.46, 18.42);
- professor_phizzlethorpeAI->AddWaypoint(15, -2076.60, -2117.46, 16.67);
- professor_phizzlethorpeAI->AddWaypoint(16, -2074.60, -2109.67, 14.24);
- professor_phizzlethorpeAI->AddWaypoint(17, -2077.99, -2105.33, 13.24);
- professor_phizzlethorpeAI->AddWaypoint(18, -2066.45, -2085.96, 9.08);
- professor_phizzlethorpeAI->AddWaypoint(19, -2066.41, -2086.21, 8.97, 6000);
- professor_phizzlethorpeAI->AddWaypoint(20, -2066.41, -2086.21, 8.97, 2000);
+ professor_phizzlethorpeAI->FillPointMovementListForCreature();
return (CreatureAI*)professor_phizzlethorpeAI;
}
diff --git a/src/bindings/scripts/scripts/zone/ashenvale_forest/ashenvale.cpp b/src/bindings/scripts/scripts/zone/ashenvale_forest/ashenvale.cpp
index 16de0d2a8c3..edf762360ad 100644
--- a/src/bindings/scripts/scripts/zone/ashenvale_forest/ashenvale.cpp
+++ b/src/bindings/scripts/scripts/zone/ashenvale_forest/ashenvale.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -97,7 +97,7 @@ struct TRINITY_DLL_DECL npc_torekAI : public npc_escortAI
Completed = false;
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
}
@@ -108,6 +108,9 @@ struct TRINITY_DLL_DECL npc_torekAI : public npc_escortAI
void JustDied(Unit* killer)
{
+ if (killer->GetEntry() == m_creature->GetEntry())
+ return;
+
if (PlayerGUID && !Completed)
{
if (Player* player = Unit::GetPlayer(PlayerGUID))
@@ -149,34 +152,12 @@ bool QuestAccept_npc_torek(Player* player, Creature* creature, Quest const* ques
return true;
}
-CreatureAI* GetAI_npc_torek(Creature *_Creature)
+CreatureAI* GetAI_npc_torek(Creature* pCreature)
{
- npc_torekAI* thisAI = new npc_torekAI(_Creature);
-
- thisAI->AddWaypoint(0, 1782.63, -2241.11, 109.73, 5000);
- thisAI->AddWaypoint(1, 1788.88, -2240.17, 111.71);
- thisAI->AddWaypoint(2, 1797.49, -2238.11, 112.31);
- thisAI->AddWaypoint(3, 1803.83, -2232.77, 111.22);
- thisAI->AddWaypoint(4, 1806.65, -2217.83, 107.36);
- thisAI->AddWaypoint(5, 1811.81, -2208.01, 107.45);
- thisAI->AddWaypoint(6, 1820.85, -2190.82, 100.49);
- thisAI->AddWaypoint(7, 1829.60, -2177.49, 96.44);
- thisAI->AddWaypoint(8, 1837.98, -2164.19, 96.71); //prepare
- thisAI->AddWaypoint(9, 1839.99, -2149.29, 96.78);
- thisAI->AddWaypoint(10, 1835.14, -2134.98, 96.80);
- thisAI->AddWaypoint(11, 1823.57, -2118.27, 97.43);
- thisAI->AddWaypoint(12, 1814.99, -2110.35, 98.38);
- thisAI->AddWaypoint(13, 1806.60, -2103.09, 99.19);
- thisAI->AddWaypoint(14, 1798.27, -2095.77, 100.04);
- thisAI->AddWaypoint(15, 1783.59, -2079.92, 100.81);
- thisAI->AddWaypoint(16, 1776.79, -2069.48, 101.77);
- thisAI->AddWaypoint(17, 1776.82, -2054.59, 109.82);
- thisAI->AddWaypoint(18, 1776.88, -2047.56, 109.83);
- thisAI->AddWaypoint(19, 1776.86, -2036.55, 109.83);
- thisAI->AddWaypoint(20, 1776.90, -2024.56, 109.83); //win
- thisAI->AddWaypoint(21, 1776.87, -2028.31, 109.83,60000);//stay
- thisAI->AddWaypoint(22, 1776.90, -2028.30, 109.83);
+ npc_torekAI* thisAI = new npc_torekAI(pCreature);
+ thisAI->FillPointMovementListForCreature();
+
return (CreatureAI*)thisAI;
}
@@ -204,7 +185,7 @@ struct TRINITY_DLL_DECL npc_ruul_snowhoofAI : public npc_escortAI
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
GameObject* Cage = FindGameObject(GO_CAGE, 20, m_creature);
if(Cage)
- Cage->SetGoState(0);
+ Cage->SetGoState(GO_STATE_ACTIVE);
break;}
case 13:
m_creature->SummonCreature(3922, 3449.218018, -587.825073, 174.978867, 4.714445, TEMPSUMMON_DEAD_DESPAWN, 60000);
@@ -225,7 +206,7 @@ struct TRINITY_DLL_DECL npc_ruul_snowhoofAI : public npc_escortAI
}
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void Reset()
{
@@ -234,7 +215,7 @@ struct TRINITY_DLL_DECL npc_ruul_snowhoofAI : public npc_escortAI
GameObject* Cage = FindGameObject(GO_CAGE, 20, m_creature);
if(Cage)
- Cage->SetGoState(1);
+ Cage->SetGoState(GO_STATE_READY);
}
void JustSummoned(Creature* summoned)
@@ -272,28 +253,7 @@ CreatureAI* GetAI_npc_ruul_snowhoofAI(Creature *_Creature)
{
npc_ruul_snowhoofAI* ruul_snowhoofAI = new npc_ruul_snowhoofAI(_Creature);
- ruul_snowhoofAI->AddWaypoint(0, 3347.250089, -694.700989, 159.925995);
- ruul_snowhoofAI->AddWaypoint(1, 3341.527039, -694.725891, 161.124542, 4000);
- ruul_snowhoofAI->AddWaypoint(2, 3338.351074, -686.088138, 163.444000);
- ruul_snowhoofAI->AddWaypoint(3, 3352.744873, -677.721741, 162.316269);
- ruul_snowhoofAI->AddWaypoint(4, 3370.291016, -669.366943, 160.751358);
- ruul_snowhoofAI->AddWaypoint(5, 3381.479492, -659.449097, 162.545303);
- ruul_snowhoofAI->AddWaypoint(6, 3389.554199, -648.500000, 163.651825);
- ruul_snowhoofAI->AddWaypoint(7, 3396.645020, -641.508911, 164.216019);
- ruul_snowhoofAI->AddWaypoint(8, 3410.498535, -634.299622, 165.773453);
- ruul_snowhoofAI->AddWaypoint(9, 3418.461426, -631.791992, 166.477615);
- ruul_snowhoofAI->AddWaypoint(10, 3429.500000, -631.588745, 166.921265);
- ruul_snowhoofAI->AddWaypoint(11,3434.950195, -629.245483, 168.333969);
- ruul_snowhoofAI->AddWaypoint(12,3438.927979, -618.503235, 171.503143);
- ruul_snowhoofAI->AddWaypoint(13,3444.217529, -609.293640, 173.077972, 1000); // Ambush 1
- ruul_snowhoofAI->AddWaypoint(14,3460.505127, -593.794189, 174.342255);
- ruul_snowhoofAI->AddWaypoint(15,3480.283203, -578.210327, 176.652313);
- ruul_snowhoofAI->AddWaypoint(16,3492.912842, -562.335449, 181.396301);
- ruul_snowhoofAI->AddWaypoint(17,3495.230957, -550.977600, 184.652267);
- ruul_snowhoofAI->AddWaypoint(18,3496.247070, -529.194214, 188.172028);
- ruul_snowhoofAI->AddWaypoint(19,3497.619385, -510.411499, 188.345322, 1000); // Ambush 2
- ruul_snowhoofAI->AddWaypoint(20,3498.498047, -497.787506, 185.806274);
- ruul_snowhoofAI->AddWaypoint(21,3484.218750, -489.717529, 182.389862, 4000); // End
+ ruul_snowhoofAI->FillPointMovementListForCreature();
return (CreatureAI*)ruul_snowhoofAI;
}
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 e469dc6f618..fb81cde9f6b 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -51,7 +51,7 @@ struct TRINITY_DLL_DECL mob_stolen_soulAI : public ScriptedAI
Class_Timer = 1000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{ }
void SetMyClass(uint8 myclass)
@@ -184,7 +184,7 @@ struct TRINITY_DLL_DECL boss_exarch_maladaarAI : public ScriptedAI
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch (rand()%3)
{
@@ -299,7 +299,7 @@ CreatureAI* GetAI_boss_exarch_maladaar(Creature *_Creature)
}
#define SPELL_AV_MORTAL_STRIKE 16856
-#define SPELL_AV_MORTAL_STRIKE 16856
+#define SPELL_AV_SUNDER_ARMOR 16145
struct TRINITY_DLL_DECL mob_avatar_of_martyredAI : public ScriptedAI
{
@@ -312,7 +312,7 @@ struct TRINITY_DLL_DECL mob_avatar_of_martyredAI : public ScriptedAI
Mortal_Strike_timer = 10000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/auchenai_crypts/boss_shirrak_the_dead_watcher.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/auchenai_crypts/boss_shirrak_the_dead_watcher.cpp
index 86ae13e29c6..586a0f06a8d 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/auchenai_crypts/boss_shirrak_the_dead_watcher.cpp
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/auchenai_crypts/boss_shirrak_the_dead_watcher.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -59,7 +59,7 @@ struct TRINITY_DLL_DECL boss_shirrak_the_dead_watcherAI : public ScriptedAI
focusedTarget = NULL;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{ }
void JustSummoned(Creature *summoned)
@@ -165,7 +165,7 @@ struct TRINITY_DLL_DECL mob_focus_fireAI : public ScriptedAI
fiery1 = fiery2 = true;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{ }
void UpdateAI(const uint32 diff)
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 325b5aeb8dd..5a32bb8635b 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -99,7 +99,7 @@ struct TRINITY_DLL_DECL boss_nexusprince_shaffarAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
@@ -201,7 +201,7 @@ CreatureAI* GetAI_boss_nexusprince_shaffar(Creature *_Creature)
struct TRINITY_DLL_DECL mob_ethereal_beaconAI : public ScriptedAI
{
- mob_ethereal_beaconAI(Creature *c) : ScriptedAI(c)
+ mob_ethereal_beaconAI(Creature *c) : ScriptedAI(c), CanEvade(false)
{
HeroicMode = m_creature->GetMap()->IsHeroic();
CanEvade = false;
@@ -222,7 +222,7 @@ struct TRINITY_DLL_DECL mob_ethereal_beaconAI : public ScriptedAI
ArcaneBolt_Timer = 1000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 d366400b97d..1aaf53bde7b 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -72,7 +72,7 @@ struct TRINITY_DLL_DECL boss_pandemoniusAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
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 dbf41ed777d..86727837219 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -83,7 +83,7 @@ struct TRINITY_DLL_DECL boss_darkweaver_sythAI : public ScriptedAI
summon10 = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
@@ -222,7 +222,7 @@ struct TRINITY_DLL_DECL mob_syth_fireAI : public ScriptedAI
flamebuffet_timer = 5000;
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void UpdateAI(const uint32 diff)
{
@@ -273,7 +273,7 @@ struct TRINITY_DLL_DECL mob_syth_arcaneAI : public ScriptedAI
arcanebuffet_timer = 5000;
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void UpdateAI(const uint32 diff)
{
@@ -324,7 +324,7 @@ struct TRINITY_DLL_DECL mob_syth_frostAI : public ScriptedAI
frostbuffet_timer = 5000;
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void UpdateAI(const uint32 diff)
{
@@ -375,7 +375,7 @@ struct TRINITY_DLL_DECL mob_syth_shadowAI : public ScriptedAI
shadowbuffet_timer = 5000;
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void UpdateAI(const uint32 diff)
{
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 e1d1e98206e..f17d1a133ce 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -105,7 +105,7 @@ struct TRINITY_DLL_DECL boss_talon_king_ikissAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
@@ -147,7 +147,7 @@ struct TRINITY_DLL_DECL boss_talon_king_ikissAI : public ScriptedAI
if (ArcaneVolley_Timer < diff)
{
DoCast(m_creature,HeroicMode ? H_SPELL_ARCANE_VOLLEY : SPELL_ARCANE_VOLLEY);
- ArcaneVolley_Timer = 10000+rand()%5000;
+ ArcaneVolley_Timer = 7000+rand()%5000;
}else ArcaneVolley_Timer -= diff;
if (Sheep_Timer < diff)
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/def_sethekk_halls.h b/src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/def_sethekk_halls.h
index 52ba2206c21..698571faecc 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/def_sethekk_halls.h
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/def_sethekk_halls.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
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 e22ac68ff02..57584769cfa 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -53,7 +53,7 @@ struct TRINITY_DLL_DECL instance_sethekk_halls : public ScriptedInstance
{
case DATA_IKISSDOOREVENT:
if( IkissDoor )
- IkissDoor->SetGoState(0);
+ IkissDoor->SetGoState(GO_STATE_ACTIVE);
break;
}
}
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 1154f71cb64..ca589b268a5 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -38,7 +38,7 @@ EndScriptData */
#define SAY_DEATH -1555007
#define SPELL_BANISH 30231
-#define SPELL_CORROSIVE_ACID 23313
+#define SPELL_CORROSIVE_ACID 33551
#define SPELL_FEAR 33547
#define SPELL_ENRAGE 0 //need to find proper spell
@@ -80,7 +80,7 @@ struct TRINITY_DLL_DECL boss_ambassador_hellmawAI : public ScriptedAI
if (pInstance->GetData(TYPE_OVERSEER) == DONE)
{
- if (m_creature->HasAura(SPELL_BANISH,0))
+ if (m_creature->HasAura(SPELL_BANISH))
m_creature->RemoveAurasDueToSpell(SPELL_BANISH);
Intro = true;
}
@@ -89,7 +89,7 @@ struct TRINITY_DLL_DECL boss_ambassador_hellmawAI : public ScriptedAI
void MoveInLineOfSight(Unit *who)
{
- if (m_creature->HasAura(SPELL_BANISH,0))
+ if (m_creature->HasAura(SPELL_BANISH))
return;
ScriptedAI::MoveInLineOfSight(who);
@@ -105,7 +105,7 @@ struct TRINITY_DLL_DECL boss_ambassador_hellmawAI : public ScriptedAI
{
DoScriptText(SAY_INTRO, m_creature);
- if (m_creature->HasAura(SPELL_BANISH,0))
+ if (m_creature->HasAura(SPELL_BANISH))
m_creature->RemoveAurasDueToSpell(SPELL_BANISH);
IsBanished = false;
@@ -115,7 +115,7 @@ struct TRINITY_DLL_DECL boss_ambassador_hellmawAI : public ScriptedAI
pInstance->SetData(TYPE_HELLMAW, IN_PROGRESS);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
@@ -157,7 +157,7 @@ struct TRINITY_DLL_DECL boss_ambassador_hellmawAI : public ScriptedAI
}else EventCheck_Timer -= diff;
}
- if (!InCombat && !IsBanished)
+ if (!m_creature->isInCombat() && !IsBanished)
{
//this is where we add MovePoint()
//DoWhine("I haz no mount!", LANG_UNIVERSAL, NULL);
@@ -174,14 +174,14 @@ struct TRINITY_DLL_DECL boss_ambassador_hellmawAI : public ScriptedAI
if (CorrosiveAcid_Timer < diff)
{
- DoCast(m_creature,SPELL_CORROSIVE_ACID);
- CorrosiveAcid_Timer = 25000;
+ DoCast(m_creature->getVictim(),SPELL_CORROSIVE_ACID);
+ CorrosiveAcid_Timer = 15000 + rand()%10000;
}else CorrosiveAcid_Timer -= diff;
if (Fear_Timer < diff)
{
DoCast(m_creature,SPELL_FEAR);
- Fear_Timer = 35000;
+ Fear_Timer = 20000 + rand()%15000;
}else Fear_Timer -= diff;
/*if (HeroicMode)
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 43b01ba752f..6d683c09764 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -95,7 +95,7 @@ struct TRINITY_DLL_DECL boss_blackheart_the_inciterAI : public ScriptedAI
pInstance->SetData(DATA_BLACKHEARTTHEINCITEREVENT, DONE);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
@@ -148,14 +148,14 @@ struct TRINITY_DLL_DECL boss_blackheart_the_inciterAI : public ScriptedAI
{
if (Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_CHARGE);
- Charge_Timer = 25000;
+ Charge_Timer = 15000 + rand()%10000;
}else Charge_Timer -= diff;
//Knockback_Timer
if (Knockback_Timer < diff)
{
DoCast(m_creature, SPELL_WAR_STOMP);
- Knockback_Timer = 20000;
+ Knockback_Timer = 18000 + rand()%6000;
}else Knockback_Timer -= diff;
DoMeleeAttackIfReady();
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 32aa9c3e844..80260e673f3 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
@@ -60,12 +60,6 @@ float VoidPortalCoords[5][3] =
{-261.4533, -297.3298, 17.1}
};
-class EmpoweringShadowsAura: public Aura
-{
- public:
- EmpoweringShadowsAura(SpellEntry *spell, uint32 eff, int32 *bp, Unit *target, Unit *caster) : Aura(spell, eff, bp, target, caster, NULL) {}
-};
-
struct TRINITY_DLL_DECL mob_voidtravelerAI : public ScriptedAI
{
mob_voidtravelerAI(Creature *c) : ScriptedAI(c)
@@ -85,7 +79,7 @@ struct TRINITY_DLL_DECL mob_voidtravelerAI : public ScriptedAI
sacrificed = false;
}
- void Aggro(Unit *who){}
+ void EnterCombat(Unit *who){}
void UpdateAI(const uint32 diff)
{
@@ -100,7 +94,7 @@ struct TRINITY_DLL_DECL mob_voidtravelerAI : public ScriptedAI
{
SpellEntry *spell = (SpellEntry *)GetSpellStore()->LookupEntry(HeroicMode?H_SPELL_EMPOWERING_SHADOWS:SPELL_EMPOWERING_SHADOWS);
if( spell )
- Vorpil->AddAura(new EmpoweringShadowsAura(spell, 0, NULL, Vorpil, m_creature));
+ Vorpil->AddAura(new Aura(spell, 1, NULL, Vorpil, m_creature));
Vorpil->SetHealth(Vorpil->GetHealth()+Vorpil->GetMaxHealth()/25);
DoCast(m_creature, SPELL_SHADOW_NOVA, true);
m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
@@ -150,7 +144,7 @@ struct TRINITY_DLL_DECL boss_grandmaster_vorpilAI : public ScriptedAI
void Reset()
{
- ShadowBoltVolley_Timer = 15000;
+ ShadowBoltVolley_Timer = 7000 + rand()%7000;
DrawShadows_Timer = 45000;
summonTraveler_Timer = 90000;
banish_Timer = 17000;
@@ -225,7 +219,7 @@ struct TRINITY_DLL_DECL boss_grandmaster_vorpilAI : public ScriptedAI
pInstance->SetData(DATA_GRANDMASTERVORPILEVENT, DONE);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
@@ -258,7 +252,7 @@ struct TRINITY_DLL_DECL boss_grandmaster_vorpilAI : public ScriptedAI
if (ShadowBoltVolley_Timer < diff)
{
DoCast(m_creature,SPELL_SHADOWBOLT_VOLLEY);
- ShadowBoltVolley_Timer = 15000;
+ ShadowBoltVolley_Timer = 15000 + rand()%15000;;
}else ShadowBoltVolley_Timer -= diff;
if (HeroicMode && banish_Timer < diff)
@@ -277,7 +271,7 @@ struct TRINITY_DLL_DECL boss_grandmaster_vorpilAI : public ScriptedAI
Map::PlayerList const &PlayerList = map->GetPlayers();
for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
if (Player* i_pl = i->getSource())
- if (i_pl->isAlive() && !i_pl->HasAura(SPELL_BANISH,0))
+ if (i_pl->isAlive() && !i_pl->HasAura(SPELL_BANISH))
i_pl->TeleportTo(m_creature->GetMapId(), VorpilPosition[0],VorpilPosition[1],VorpilPosition[2], 0, TELE_TO_NOT_LEAVE_COMBAT);
m_creature->Relocate(VorpilPosition[0],VorpilPosition[1],VorpilPosition[2]);
@@ -286,7 +280,7 @@ struct TRINITY_DLL_DECL boss_grandmaster_vorpilAI : public ScriptedAI
DoCast(m_creature,HeroicMode?H_SPELL_RAIN_OF_FIRE:SPELL_RAIN_OF_FIRE);
ShadowBoltVolley_Timer = 6000;
- DrawShadows_Timer = 30000;
+ DrawShadows_Timer = 3000;
}else DrawShadows_Timer -= diff;
if ( summonTraveler_Timer < diff)
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 aae194de9b8..99bce54be62 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
@@ -52,9 +52,9 @@ struct TRINITY_DLL_DECL boss_murmurAI : public Scripted_NoMovementAI
void Reset()
{
SonicBoom_Timer = 30000;
- MurmursTouch_Timer = 20000;
- Resonance_Timer = 10000;
- MagneticPull_Timer = 20000;
+ MurmursTouch_Timer = 8000 + rand()%12000;
+ Resonance_Timer = 5000;
+ MagneticPull_Timer = 15000 + rand()%15000;
ThunderingStorm_Timer = 15000;
SonicShock_Timer = 10000;
SonicBoom = false;
@@ -64,7 +64,25 @@ struct TRINITY_DLL_DECL boss_murmurAI : public Scripted_NoMovementAI
if (hp) m_creature->SetHealth(hp);
}
- void Aggro(Unit *who) { }
+ void SonicBoomEffect()
+ {
+ std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList();
+ for( std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr )
+ {
+ Unit* target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
+ if (target && target->GetTypeId() == TYPEID_PLAYER)
+ {
+ //Not do anything without aura, spell can be resisted!
+ if (target->HasAura(SPELL_SONIC_BOOM_CAST) && m_creature->IsWithinDistInMap(target, 34.0f))
+ {
+ //This will be wrong calculation. Also, comments suggest it must deal damage
+ target->SetHealth(uint32(target->GetMaxHealth() - target->GetMaxHealth() * 0.8));
+ }
+ }
+ }
+ }
+
+ void EnterCombat(Unit *who) { }
// Sonic Boom instant damage (needs core fix instead of this)
void SpellHitTarget(Unit *target, const SpellEntry *spell)
@@ -83,12 +101,14 @@ struct TRINITY_DLL_DECL boss_murmurAI : public Scripted_NoMovementAI
if(SonicBoom)
{
DoCast(m_creature, SPELL_SONIC_BOOM_EFFECT, true);
+ SonicBoomEffect();
+
SonicBoom = false;
Resonance_Timer = 1500;
}
if (SonicBoom_Timer < diff)
{
- DoScriptText(EMOTE_SONIC_BOOM, m_creature);
+ DoScriptText(EMOTE_SONIC_BOOM, m_creature);
DoCast(m_creature, SPELL_SONIC_BOOM_CAST);
SonicBoom_Timer = 30000;
SonicBoom = true;
@@ -100,16 +120,18 @@ struct TRINITY_DLL_DECL boss_murmurAI : public Scripted_NoMovementAI
{
if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,80,true))
DoCast(target, SPELL_MURMURS_TOUCH);
- MurmursTouch_Timer = 30000;
+ MurmursTouch_Timer = 25000 + rand()%10000;
}else MurmursTouch_Timer -= diff;
// Resonance
- if (Resonance_Timer < diff)
+ if (!SonicBoom && !(m_creature->IsWithinMeleeRange(m_creature->getVictim())))
{
- if (!m_creature->IsWithinMeleeRange(SelectUnit(SELECT_TARGET_NEAREST,0,20,true)))
+ if (Resonance_Timer < diff)
+ {
DoCast(m_creature, SPELL_RESONANCE);
- Resonance_Timer = 5000;
- }else Resonance_Timer -= diff;
+ Resonance_Timer = 5000;
+ }else Resonance_Timer -= diff;
+ }
// Magnetic Pull
if (MagneticPull_Timer < diff)
@@ -118,7 +140,7 @@ struct TRINITY_DLL_DECL boss_murmurAI : public Scripted_NoMovementAI
if (target->GetTypeId() == TYPEID_PLAYER && target->isAlive())
{
DoCast(target, SPELL_MAGNETIC_PULL);
- MagneticPull_Timer = 20000+rand()%15000;
+ MagneticPull_Timer = 15000+rand()%15000;
return;
}
MagneticPull_Timer = 500;
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/def_shadow_labyrinth.h b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/def_shadow_labyrinth.h
index d03c9270181..a78955368bf 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/def_shadow_labyrinth.h
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/def_shadow_labyrinth.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
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 ec0c8a47d7a..3cfb0af2fa1 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -80,7 +80,7 @@ struct TRINITY_DLL_DECL instance_shadow_labyrinth : public ScriptedInstance
void OnCreatureCreate(Creature *creature, uint32 creature_entry)
{
- switch(creature_entry)
+ switch(creature->GetEntry())
{
case 18732:
GrandmasterVorpil = creature->GetGUID();
@@ -109,20 +109,6 @@ struct TRINITY_DLL_DECL instance_shadow_labyrinth : public ScriptedInstance
return NULL;
}
- void HandleGameObject(uint64 guid, uint32 state)
- {
- Player *player = GetPlayerInMap();
-
- if (!player || !guid)
- {
- debug_log("TSCR: Shadow Labyrinth: HandleGameObject fail");
- return;
- }
-
- if (GameObject *go = GameObject::GetGameObject(*player,guid))
- go->SetGoState(state);
- }
-
void SetData(uint32 type, uint32 data)
{
switch(type)
@@ -149,7 +135,7 @@ struct TRINITY_DLL_DECL instance_shadow_labyrinth : public ScriptedInstance
case DATA_BLACKHEARTTHEINCITEREVENT:
if( data == DONE )
{
- HandleGameObject(RefectoryDoorGUID,0);
+ HandleGameObject(RefectoryDoorGUID, true);
}
Encounter[2] = data;
break;
@@ -157,7 +143,7 @@ struct TRINITY_DLL_DECL instance_shadow_labyrinth : public ScriptedInstance
case DATA_GRANDMASTERVORPILEVENT:
if( data == DONE )
{
- HandleGameObject(ScreamingHallDoorGUID,0);
+ HandleGameObject(ScreamingHallDoorGUID, true);
}
Encounter[3] = data;
break;
diff --git a/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_amanitar.cpp b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_amanitar.cpp
new file mode 100644
index 00000000000..84f092d12f6
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_amanitar.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2009 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
+ */
+
+/* Script Data Start
+SDName: boss_amanitar
+SDAuthor: LordVanMartin
+SD%Complete: 0
+SDComment: Only appears in heroic mode
+SDCategory: Ahn'kahet
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_amanitar' where entry = '';
+*** SQL END ***/
+
+#include "precompiled.h"
+#include "def_ahnkahet.h"
+
+#define SPELL_BASH 57094
+#define SPELL_ENTANGLING_ROOTS 57095
+#define SPELL_MINI 57055
+#define SPELL_VENOM_BOLT_VOLLEY 57088
+
+struct TRINITY_DLL_DECL boss_amanitarAI : public ScriptedAI
+{
+ boss_amanitarAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+
+ void EnterCombat(Unit* who) {}
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* killer) {}
+
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+ }
+};
+
+CreatureAI* GetAI_boss_amanitar(Creature *_Creature)
+{
+ return new boss_amanitarAI (_Creature);
+}
+
+void AddSC_boss_amanitar()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_amanitar";
+ newscript->GetAI = GetAI_boss_amanitar;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_elder_nadox.cpp b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_elder_nadox.cpp
new file mode 100644
index 00000000000..9990d5d8891
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_elder_nadox.cpp
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2009 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
+ */
+
+/* ScriptData
+SDName: boss_elder_nadox
+SD%Complete: 100
+SDComment:
+SDCategory: Ahn'kahet
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_ahnkahet.h"
+
+#define SAY_AGGRO -1619014
+#define SAY_SLAY_1 -1619015
+#define SAY_SLAY_2 -1619016
+#define SAY_SLAY_3 -1619017
+#define SAY_DEATH -1619018
+#define SAY_EGG_SAC_1 -1619019
+#define SAY_EGG_SAC_2 -1619020
+
+#define SPELL_BROOD_PLAGUE 56130
+#define H_SPELL_BROOD_PLAGUE 59467
+#define H_SPELL_BROOD_RAGE 59465
+#define SPELL_ENRAGE 26662// Enraged if too far away from home
+
+#define MOB_AHNKAHAR_SWARMER 30178
+#define SPELL_SUMMON_SWARMERS 56119//2x 30178 -- 2x every 10secs
+
+#define MOB_AHNKAHAR_SWARM_GUARD 30176
+#define SPELL_SUMMON_SWARM_GUARD 56120//1x 30176 -- every 25secs
+#define SPELL_GUARDIAN_AURA 56151
+
+struct TRINITY_DLL_DECL boss_elder_nadoxAI : public ScriptedAI
+{
+ boss_elder_nadoxAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ HeroicMode = c->GetMap()->IsHeroic();
+ }
+
+ bool HeroicMode;
+ uint32 plague_Timer;
+ uint32 rage_Timer;
+
+ uint32 swarmer_spawn_Timer;
+ uint32 guard_spawn_Timer;
+ uint32 enrage_Timer;
+
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ plague_Timer = 13000;
+ rage_Timer = 20000;
+
+ swarmer_spawn_Timer = 10000;
+ guard_spawn_Timer = 25000;
+
+ enrage_Timer = 5000;
+
+ if(pInstance)
+ pInstance->SetData(DATA_ELDER_NADOX_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit *who)
+ {
+ DoScriptText(SAY_DEATH,m_creature);
+
+ if(pInstance)
+ pInstance->SetData(DATA_ELDER_NADOX_EVENT, IN_PROGRESS);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1,m_creature); break;
+ case 1: DoScriptText(SAY_SLAY_2,m_creature); break;
+ case 2: DoScriptText(SAY_SLAY_3,m_creature); break;
+ }
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_SLAY_3,m_creature);
+
+ if(pInstance)
+ pInstance->SetData(DATA_ELDER_NADOX_EVENT, DONE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!UpdateVictim())
+ return;
+
+ if(plague_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(),HeroicMode ? H_SPELL_BROOD_PLAGUE : SPELL_BROOD_PLAGUE);
+ plague_Timer = 15000;
+ }else plague_Timer -= diff;
+
+ if(HeroicMode)
+ if(rage_Timer < diff)
+ {
+ Unit* Swarmer = FindCreature(MOB_AHNKAHAR_SWARMER,35,m_creature);
+
+ if(Swarmer)
+ {
+ DoCast(Swarmer,H_SPELL_BROOD_RAGE,true);
+ rage_Timer = 15000;
+ }
+ }else rage_Timer -= diff;
+
+ if(swarmer_spawn_Timer < diff)
+ {
+ DoCast(m_creature,SPELL_SUMMON_SWARMERS,true);
+ DoCast(m_creature,SPELL_SUMMON_SWARMERS);
+ if(rand()%3 == 0)
+ {
+ switch(rand()%2)
+ {
+ case 0: DoScriptText(SAY_EGG_SAC_1,m_creature); break;
+ case 1: DoScriptText(SAY_EGG_SAC_2,m_creature); break;
+ }
+ }
+ swarmer_spawn_Timer = 10000;
+ }else swarmer_spawn_Timer -= diff;
+
+ if(guard_spawn_Timer < diff)
+ {
+ m_creature->MonsterTextEmote("An Ahn'kahar Guardian hatches!",m_creature->GetGUID(),true);
+ DoCast(m_creature,SPELL_SUMMON_SWARM_GUARD);
+ guard_spawn_Timer = 25000;
+ }else guard_spawn_Timer -= diff;
+
+ if(enrage_Timer < diff)
+ {
+ if(m_creature->HasAura(SPELL_ENRAGE,0))
+ return;
+
+ float x, y, z, o;
+ m_creature->GetHomePosition(x, y, z, o);
+ if(z < 24 )
+ {
+ if(!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ DoCast(m_creature,SPELL_ENRAGE,true);
+ }
+ }
+ enrage_Timer = 5000;
+ }else enrage_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_elder_nadox(Creature *_Creature)
+{
+ return new boss_elder_nadoxAI(_Creature);
+}
+#define SPELL_SPRINT 56354
+struct TRINITY_DLL_DECL mob_ahnkahar_nerubianAI : public ScriptedAI
+{
+ mob_ahnkahar_nerubianAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ uint32 sprint_Timer;
+
+ void Reset()
+ {
+ if(m_creature->GetEntry() == 30176)
+ DoCast(m_creature,SPELL_GUARDIAN_AURA,true);
+ sprint_Timer = 10000;
+ }
+ void EnterCombat(Unit *who){}
+ void UpdateAI(const uint32 diff)
+ {
+ if(m_creature->GetEntry() == 30176)
+ m_creature->RemoveAurasDueToSpell(SPELL_GUARDIAN_AURA);
+
+ if(pInstance)
+ {
+ if(pInstance->GetData(DATA_ELDER_NADOX_EVENT) != IN_PROGRESS)
+ {
+ m_creature->DealDamage(m_creature,m_creature->GetHealth());
+ m_creature->RemoveCorpse();
+ }
+ }
+
+ if(!UpdateVictim())
+ return;
+
+ if(sprint_Timer < diff)
+ {
+ DoCast(m_creature,SPELL_SPRINT);
+ sprint_Timer = 25000;
+ }else sprint_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_ahnkahar_nerubian(Creature *_Creature)
+{
+ return new mob_ahnkahar_nerubianAI(_Creature);
+}
+
+void AddSC_boss_elder_nadox()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_elder_nadox";
+ newscript->GetAI = &GetAI_boss_elder_nadox;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_ahnkahar_nerubian";
+ newscript->GetAI = &GetAI_mob_ahnkahar_nerubian;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_herald_volazj.cpp b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_herald_volazj.cpp
new file mode 100644
index 00000000000..9c249ad4031
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_herald_volazj.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2009 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
+ */
+
+/* ScriptData
+SDName: boss_herald_volazj
+SDAuthor: LordVanMartin
+SD%Complete: 0
+SDComment:
+SDCategory: Ahn'kahet
+EndScriptData */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_volazj' where entry = '';
+*** SQL END ***/
+
+#include "precompiled.h"
+#include "def_ahnkahet.h"
+
+//Spells
+#define SPELL_INSANITY 57496 //Dummy
+#define INSANITY_VISUAL 57561
+#define SPELL_MIND_FLAY_N 57941
+#define SPELL_MIND_FLAY_H 59974
+#define SPELL_SHADOW_BOLT_VOLLEY_1 57942
+#define SPELL_SHADOW_BOLT_VOLLEY_2 59975
+#define SPELL_SHIVER_N 57949
+#define SPELL_SHIVER_H 59978
+
+//Yell
+#define SAY_AGGRO -1619030
+#define SAY_SLAY_1 -1619031
+#define SAY_SLAY_2 -1619032
+#define SAY_SLAY_3 -1619033
+#define SAY_DEATH_1 -1619034
+#define SAY_DEATH_2 -1619035
+#define SAY_PHASE -1619036
+
+struct TRINITY_DLL_DECL boss_volazjAI : public ScriptedAI
+{
+ boss_volazjAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 phase;
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ phase =1;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ if(phase == 1)
+ DoScriptText(SAY_DEATH_1, m_creature);
+ else
+ DoScriptText(SAY_DEATH_2, m_creature);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_volazj(Creature *_Creature)
+{
+ return new boss_volazjAI (_Creature);
+}
+
+void AddSC_boss_volazj()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_volazj";
+ newscript->GetAI = GetAI_boss_volazj;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_jedoga_shadowseeker.cpp b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_jedoga_shadowseeker.cpp
new file mode 100644
index 00000000000..d42fe688137
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_jedoga_shadowseeker.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2009 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
+ */
+
+/* ScriptData
+SDName: boss_jedoga_shadowseeker
+SDAuthor: LordVanMartin
+SD%Complete: 0
+SDComment:
+SDCategory: Ahn'kahet
+EndScriptData */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_jedoga' where entry = '';
+*** SQL END ***/
+
+#include "precompiled.h"
+#include "def_ahnkahet.h"
+
+#define SPELL_CYCLONE_STRIKE 56855
+#define H_SPELL_CYCLONE_STRIKE 60030//kein unterschied zu 56855 außer das 60030 1,5sec cast ist
+#define SPELL_LIGHTNING_BOLT 56891
+#define H_SPELL_LIGHTNING_BOLT 60032
+#define SPELL_THUNDERSHOCK 56926//AOE works
+#define H_SPELL_THUNDERSHOCK 60029//AOE works
+#define SPELL_GIFT_OF_THE_HERALD 56219//triggert if sucessfull sacreficed
+
+#define SAY_AGGRO -1619000
+#define SAY_C_SACRIFICE_1 -1619001
+#define SAY_C_SACRIFICE_2 -1619002
+#define SAY_SACRIFICE_1 -1619003
+#define SAY_SACRIFICE_2 -1619004
+#define SAY_SLAY_1 -1619005
+#define SAY_SLAY_2 -1619006
+#define SAY_SLAY_3 -1619007
+#define SAY_DEATH -1619008
+#define SAY_PREACHING_1 -1619009
+#define SAY_PREACHING_2 -1619010
+#define SAY_PREACHING_3 -1619011
+#define SAY_PREACHING_4 -1619012
+#define SAY_PREACHING_5 -1619013
+
+struct TRINITY_DLL_DECL boss_jedogaAI : public ScriptedAI
+{
+ boss_jedogaAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_jedoga(Creature *_Creature)
+{
+ return new boss_jedogaAI (_Creature);
+}
+
+void AddSC_boss_jedoga()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_jedoga";
+ newscript->GetAI = GetAI_boss_jedoga;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp
new file mode 100644
index 00000000000..03b5b5777c9
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2009 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
+ */
+
+/* ScriptData
+SDName: boss_prince_taldaram
+SDAuthor: LordVanMartin
+SD%Complete: 0
+SDComment:
+SDCategory: Ahn'kahet
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_ahnkahet.h"
+
+#define SPELL_BLOODTHIRST 55968 //Trigger Spell + add aura
+#define SPELL_CONJURE_FLAME_SPHERE 55931
+
+#define SPELL_FLAME_SPHERE_SUMMON_1 55895// 1x 30106
+#define H_SPELL_FLAME_SPHERE_SUMMON_1 59511// 1x 31686
+#define H_SPELL_FLAME_SPHERE_SUMMON_2 59512// 1x 31687
+#define SPELL_FLAME_SPHERE_SPAWN_EFFEKT 55891
+#define SPELL_FLAME_SPHERE_VISUAL 55928
+#define SPELL_FLAME_SPHERE_PERIODIC 55926
+#define H_SPELL_FLAME_SPHERE_PERIODIC 59508
+#define SPELL_FLAME_SPHERE_DEATH_EFFEKT 55947
+
+#define SPELL_EMBRACE_OF_THE_VAMPYR 55959
+#define H_SPELL_EMBRACE_OF_THE_VAMPYR 59513
+
+#define SPELL_VANISH 55964
+
+//Yell
+#define SAY_AGGRO -1619021
+#define SAY_SLAY_1 -1619022
+#define SAY_SLAY_2 -1619023
+#define SAY_SLAY_3 -1619024
+#define SAY_DEATH -1619025
+#define SAY_FEED_1 -1619026
+#define SAY_FEED_2 -1619027
+#define SAY_VANISH_1 -1619028
+#define SAY_VANISH_2 -1619029
+
+struct TRINITY_DLL_DECL boss_taldaramAI : public ScriptedAI
+{
+ boss_taldaramAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_taldaram(Creature *_Creature)
+{
+ return new boss_taldaramAI (_Creature);
+}
+
+void AddSC_boss_taldaram()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_taldaram";
+ newscript->GetAI = GetAI_boss_taldaram;
+ newscript->RegisterSelf();
+}
diff --git a/src/shared/Database/QueryResultSqlite.h b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/def_ahnkahet.h
index b2622f96707..97c0db55d72 100644
--- a/src/shared/Database/QueryResultSqlite.h
+++ b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/def_ahnkahet.h
@@ -1,7 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
- *
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2009 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
@@ -18,29 +16,18 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef DO_POSTGRESQL
-
-#if !defined(QUERYRESULTSQLITE_H)
-#define QUERYRESULTSQLITE_H
-
-#include <sqlite/sqlite.h>
-
-class QueryResultSqlite : public QueryResult
-{
- public:
- QueryResultSqlite(char **tableData, uint32 rowCount, uint32 fieldCount);
+#ifndef DEF_AHNKAHET_H
+#define DEF_AHNKAHET_H
- ~QueryResultSqlite();
+#define DATA_ELDER_NADOX 1
+#define DATA_PRINCE_TALDARAM 2
+#define DATA_JEDOGA_SHADOWSEEKER 3
+#define DATA_HERALD_VOLAZJ 4
+#define DATA_AMANITAR 5
- bool NextRow();
-
- private:
- enum Field::DataTypes ConvertNativeType(const char* sqliteType) const;
- void EndQuery();
-
- char **mTableData;
- uint32 mTableIndex;
-};
+#define DATA_ELDER_NADOX_EVENT 6
+#define DATA_PRINCE_TALDARAM_EVENT 7
+#define DATA_JEDOGA_SHADOWSEEKER_EVENT 8
+#define DATA_HERALD_VOLAZJ_EVENT 9
+#define DATA_AMANITAR_EVENT 10
#endif
-#endif
-
diff --git a/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/instance_ahnkahet.cpp b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/instance_ahnkahet.cpp
new file mode 100644
index 00000000000..41cb91f86b7
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/instance_ahnkahet.cpp
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2009 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
+ */
+
+/* ScriptData
+SDName: Instance_Azjol_Nerub
+SD%Complete: 0
+SDComment:
+SDCategory: Azjol Nerub
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_ahnkahet.h"
+
+#define ENCOUNTERS 5
+
+/* Ahn'kahet encounters:
+0 - Elder Nadox
+1 - Prince Taldaram
+2 - Jedoga Shadowseeker
+3 - Herald Volazj
+4 - Amanitar (Heroic only)
+*/
+
+struct TRINITY_DLL_DECL instance_ahnkahet : public ScriptedInstance
+{
+ instance_ahnkahet(Map *Map) : ScriptedInstance(Map) {Initialize();};
+
+ uint64 Elder_Nadox;
+ uint64 Prince_Taldaram;
+ uint64 Jedoga_Shadowseeker;
+ uint64 Herald_Volazj;
+ uint64 Amanitar;
+
+ uint32 Encounters[ENCOUNTERS];
+
+ void Initialize()
+ {
+ Elder_Nadox =0;
+ Prince_Taldaram =0;
+ Jedoga_Shadowseeker =0;
+ Herald_Volazj =0;
+ Amanitar =0;
+
+ for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ Encounters[i] = NOT_STARTED;
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ if(Encounters[i] == IN_PROGRESS) return true;
+
+ return false;
+ }
+
+
+ void OnCreatureCreate(Creature *creature, uint32 creature_entry)
+ {
+ switch(creature_entry)
+ {
+ case 29309: Elder_Nadox = creature->GetGUID(); break;
+ case 29308: Prince_Taldaram = creature->GetGUID(); break;
+ case 29310: Jedoga_Shadowseeker = creature->GetGUID(); break;
+ case 29311: Herald_Volazj = creature->GetGUID(); break;
+ case 30258: Amanitar = creature->GetGUID(); break;
+ }
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_ELDER_NADOX: return Elder_Nadox;
+ case DATA_PRINCE_TALDARAM: return Prince_Taldaram;
+ case DATA_JEDOGA_SHADOWSEEKER: return Jedoga_Shadowseeker;
+ case DATA_HERALD_VOLAZJ: return Herald_Volazj;
+ case DATA_AMANITAR: return Amanitar;
+ }
+ return 0;
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_ELDER_NADOX_EVENT:
+ Encounters[0] = data;break;
+ case DATA_PRINCE_TALDARAM_EVENT:
+ Encounters[1] = data; break;
+ case DATA_JEDOGA_SHADOWSEEKER_EVENT:
+ Encounters[2] = data; break;
+ case DATA_HERALD_VOLAZJ:
+ Encounters[3] = data; break;
+ case DATA_AMANITAR:
+ Encounters[4] = data; break;
+ }
+
+ if (data == DONE)
+ {
+ SaveToDB();
+ }
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_ELDER_NADOX_EVENT: return Encounters[0];
+ case DATA_PRINCE_TALDARAM_EVENT: return Encounters[1];
+ case DATA_JEDOGA_SHADOWSEEKER_EVENT: return Encounters[2];
+ case DATA_HERALD_VOLAZJ: return Encounters[3];
+ case DATA_AMANITAR: return Encounters[4];
+ }
+ return 0;
+ }
+
+ const char* Save()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::string str_data;
+
+ std::ostringstream saveStream;
+ saveStream << "A K " << Encounters[0] << " " << Encounters[1] << " "
+ << Encounters[2] << Encounters[3] << Encounters[4];
+
+ str_data = saveStream.str();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return str_data.c_str();
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0,data1,data2,data3,data4;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4;
+
+ if( dataHead1 == 'A' && dataHead2 == 'K')
+ {
+ Encounters[0] = data0;
+ Encounters[1] = data1;
+ Encounters[2] = data2;
+ Encounters[3] = data3;
+ Encounters[4] = data4;
+
+ for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ if (Encounters[i] == IN_PROGRESS)
+ Encounters[i] = NOT_STARTED;
+
+ }else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_ahnkahet(Map* map)
+{
+ return new instance_ahnkahet(map);
+}
+
+void AddSC_instance_ahnkahet()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_ahnkahet";
+ newscript->GetInstanceData = &GetInstanceData_instance_ahnkahet;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/boss_anubarak.cpp b/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/boss_anubarak.cpp
new file mode 100644
index 00000000000..65d9d012f14
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/boss_anubarak.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2009 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
+ */
+
+/* ScriptData
+SDName: boss_anubarak
+SDAuthor: LordVanMartin
+SD%Complete: 0
+SDComment:
+SDCategory: Azjol Nerub
+EndScriptData */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_anub_arak' where entry = '';
+*** SQL END ***/
+
+#include "precompiled.h"
+#include "def_azjol_nerub.h"
+
+//Spells
+#define SPELL_CARRION_BEETLES 53520
+#define SPELL_LOCUST_SWARM 53467
+#define SPELL_IMPALE 53454
+#define SPELL_POUND 53472
+
+//Yell
+#define SAY_INTRO -1601010
+#define SAY_AGGRO -1601000
+#define SAY_SLAY_1 -1601001
+#define SAY_SLAY_2 -1601002
+#define SAY_SLAY_3 -1601003
+#define SAY_LOCUST_1 -1601005
+#define SAY_LOCUST_2 -1601006
+#define SAY_LOCUST_3 -1601007
+#define SAY_SUBMERGE_1 -1601008
+#define SAY_SUBMERGE_2 -1601009
+#define SAY_DEATH -1601004
+
+struct TRINITY_DLL_DECL boss_anub_arakAI : public ScriptedAI
+{
+ boss_anub_arakAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 phase;
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ phase =1;
+
+ if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) <= 33)
+ phase = 2;
+ if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) == 15)
+ phase = 3;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_anub_arak(Creature *_Creature)
+{
+ return new boss_anub_arakAI (_Creature);
+}
+
+void AddSC_boss_anub_arak()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_anub_arak";
+ newscript->GetAI = GetAI_boss_anub_arak;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/boss_hadronox.cpp b/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/boss_hadronox.cpp
new file mode 100644
index 00000000000..e509a4c7d39
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/boss_hadronox.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2009 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
+ */
+
+/* ScriptData
+SDName: boss_hadronox
+SD%Complete: 0
+SDComment: Placeholder
+SDCategory: Azjol Nerub
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_azjol_nerub.h"
+
+#define SPELL_WEB_FRONT_DOORS 53177//dummy
+
+#define SPELL_ACID_CLOUD 53400
+#define H_SPELL_ACID_CLOUD 59419
+#define SPELL_LEECH_POISON 53030
+#define H_SPELL_LEECH_POISON 59417
+#define SPELL_LEECH_POISON_DEADTRIGGER 53800//heal 10% heroic und normal
+#define SPELL_PIECE_ARMOR 53418
+#define SPELL_WEB_GRAB 53406
+#define H_SPELL_WEB_GRAB 59420
+
+/* Script Data Start
+SDName: Boss hadronox
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_hadronox' where entry = '';
+*** SQL END ***/
+
+//Spells
+#define SPELL_LEECH_POISON 53030
+#define SPELL_ACID_CLOUD 53400
+#define SPELL_PIERCE_ARMOR 53418 //Source SUN++
+#define SPELL_WEB_GRAB 53406
+
+//Phase 0 => Gauntlet Event described below
+//Phase 1 => Boss Encounter
+
+/*When your group enters the main room (the one after the bridge), you will notice a group of 3 Nerubians.
+When you engage them, 2 more groups like this one spawn behind the first one - it is important to pull the first group back,
+so you don't aggro all 3. Hadronox will be under you, fighting Nerubians.
+
+This is the timed gauntlet - waves of non-elite spiders
+ will spawn from the 3 doors located a little above the main room, and will then head down to fight Hadronox. After clearing the
+ main room, it is recommended to just stay in it, kill the occasional non-elites that will attack you instead of the boss, and wait for
+ Hadronox to make his way to you. When Hadronox enters the main room, she will web the doors, and no more non-elites will spawn.*/
+
+struct TRINITY_DLL_DECL boss_hadronoxAI : public ScriptedAI
+{
+ boss_hadronoxAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 phase;
+
+ void Reset() {}
+ void EnterCombat(Unit* who) {}
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ phase =1;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer) {}
+
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ //when Hadronox kills any enemy (that includes a party member) she will regain 10% of her HP if the target had Leech Poison on
+ }
+};
+
+CreatureAI* GetAI_boss_hadronox(Creature *_Creature)
+{
+ return new boss_hadronoxAI (_Creature);
+}
+
+void AddSC_boss_hadronox()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_hadronox";
+ newscript->GetAI = GetAI_boss_hadronox;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/boss_krikthir_the_gatewatcher.cpp b/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/boss_krikthir_the_gatewatcher.cpp
new file mode 100644
index 00000000000..c8250011906
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/boss_krikthir_the_gatewatcher.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2009 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
+ */
+
+/* ScriptData
+SDName: boss_krikthir_the_gatewatcher
+SDAuthor: LordVanMartin
+SD%Complete: 0
+SDComment: Placeholder
+SDCategory: Azjol Nerub
+EndScriptData */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_krik_thir' where entry = '';
+*** SQL END ***/
+
+#include "precompiled.h"
+#include "def_azjol_nerub.h"
+
+#define SPELL_MIND_FLAY 52586
+#define H_SPELL_MIND_FLAY 59367
+#define SPELL_CURSE_OF_FATIGUE 52592
+#define H_SPELL_CURSE_OF_FATIGUE 59368
+#define SPELL_FRENZY 28747 // maybe 53361
+
+#define MOB_SKITTERING_SWARMER 28735
+#define MOB_SKITTERING_SWARMER_CONTROLLER 32593
+
+#define SPELL_SUMMON_SKITTERING_SWARMER 52438//AOE Effekt 140, maybe 52439
+#define SPELL_SUMMON_SKITTERING_SWARMER 52439//Summon 3x 28735
+
+//Yell
+#define SAY_AGGRO -1601011
+#define SAY_SLAY_1 -1601012
+#define SAY_SLAY_2 -1601013
+#define SAY_SLAY_3 -1601014
+#define SAY_DEATH -1601015
+#define SAY_SEND_GROUP_1 -1601018
+#define SAY_SEND_GROUP_2 -1601019
+#define SAY_SEND_GROUP_3 -1601020
+#define SAY_SWARM_1 -1601016
+#define SAY_SWARM_2 -1601017
+#define SAY_PREFIGHT_1 -1601021
+#define SAY_PREFIGHT_2 -1601022
+#define SAY_PREFIGHT_3 -1601023
+
+struct TRINITY_DLL_DECL boss_krik_thirAI : public ScriptedAI
+{
+ boss_krik_thirAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!UpdateVictim())
+ return;
+
+ if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) >= 10)
+ {
+ //Frenzy
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_krik_thir(Creature *_Creature)
+{
+ return new boss_krik_thirAI (_Creature);
+}
+
+void AddSC_boss_krik_thir()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_krik_thir";
+ newscript->GetAI = GetAI_boss_krik_thir;
+ newscript->RegisterSelf();
+
+}
diff --git a/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/def_azjol_nerub.h b/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/def_azjol_nerub.h
new file mode 100644
index 00000000000..9e319e8fde0
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/def_azjol_nerub.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009 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 DEF_AZJOL_NERUB_H
+#define DEF_AZJOL_NERUB_H
+
+#define DATA_KRIKTHIR_THE_GATEWATCHER 1
+#define DATA_HADRONOX 2
+#define DATA_ANUBARAK 3
+
+#define DATA_KRIKTHIR_THE_GATEWATCHER_EVENT 4
+#define DATA_HADRONOX_EVENT 5
+#define DATA_ANUBARAK_EVENT 6
+#endif
diff --git a/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp b/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp
new file mode 100644
index 00000000000..bd3fccd98d9
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2009 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
+ */
+
+/* ScriptData
+SDName: Instance_Azjol_Nerub
+SD%Complete: 0
+SDComment: Placeholder
+SDCategory: Azjol Nerub
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_azjol_nerub.h"
+
+#define ENCOUNTERS 3
+
+/* Azjol Nerub encounters:
+0 - Krik'thir the Gatewatcher
+1 - Hadronox
+2 - Anub'arak
+*/
+
+struct TRINITY_DLL_DECL instance_azjol_nerub : public ScriptedInstance
+{
+ instance_azjol_nerub(Map *Map) : ScriptedInstance(Map) {Initialize();};
+
+ uint64 Krikthir;
+ uint64 Hadronox;
+ uint64 Anubarak;
+
+ uint32 Encounters[ENCOUNTERS];
+
+ void Initialize()
+ {
+ Krikthir = 0;
+ Hadronox = 0;
+ Anubarak =0;
+
+
+ for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ Encounters[i] = NOT_STARTED;
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ if(Encounters[i] == IN_PROGRESS) return true;
+
+ return false;
+ }
+
+
+ void OnCreatureCreate(Creature *creature, uint32 creature_entry)
+ {
+ switch(creature_entry)
+ {
+ case 28684: Krikthir = creature->GetGUID(); break;
+ case 28921: Hadronox = creature->GetGUID(); break;
+ case 29120: Anubarak = creature->GetGUID(); break;
+
+ }
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_KRIKTHIR_THE_GATEWATCHER: return Krikthir;
+ case DATA_HADRONOX: return Hadronox;
+ case DATA_ANUBARAK: return Anubarak;
+ }
+
+ return 0;
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_KRIKTHIR_THE_GATEWATCHER_EVENT:
+ Encounters[0] = data;break;
+ case DATA_HADRONOX_EVENT:
+ Encounters[1] = data; break;
+ case DATA_ANUBARAK_EVENT:
+ Encounters[2] = data; break;
+ }
+
+ if (data == DONE)
+ {
+ SaveToDB();
+ }
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_KRIKTHIR_THE_GATEWATCHER_EVENT: return Encounters[0];
+ case DATA_HADRONOX_EVENT: return Encounters[1];
+ case DATA_ANUBARAK_EVENT: return Encounters[2];
+ }
+
+ return 0;
+ }
+
+ const char* Save()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::string str_data;
+
+ std::ostringstream saveStream;
+ saveStream << "A N " << Encounters[0] << " " << Encounters[1] << " "
+ << Encounters[2];
+
+ str_data = saveStream.str();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return str_data.c_str();
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0,data1,data2;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2;
+
+ if( dataHead1 == 'A' && dataHead2 == 'N')
+ {
+ Encounters[0] = data0;
+ Encounters[1] = data1;
+ Encounters[2] = data2;
+
+ for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ if (Encounters[i] == IN_PROGRESS)
+ Encounters[i] = NOT_STARTED;
+
+ }else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_azjol_nerub(Map* map)
+{
+ return new instance_azjol_nerub(map);
+}
+
+void AddSC_instance_azjol_nerub()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_azjol_nerub";
+ newscript->GetInstanceData = &GetInstanceData_instance_azjol_nerub;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/azshara/azshara.cpp b/src/bindings/scripts/scripts/zone/azshara/azshara.cpp
index a94d3e003b7..db3f7fd1da9 100644
--- a/src/bindings/scripts/scripts/zone/azshara/azshara.cpp
+++ b/src/bindings/scripts/scripts/zone/azshara/azshara.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -49,7 +49,7 @@ struct TRINITY_DLL_DECL mobs_spitelashesAI : public ScriptedAI
spellhit = false;
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void SpellHit(Unit *Hitter, const SpellEntry *Spellkind)
{
@@ -382,7 +382,7 @@ struct TRINITY_DLL_DECL mob_rizzle_sprysprocketAI : public ScriptedAI
}
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void MovementInform(uint32 type, uint32 id)
{
@@ -475,7 +475,7 @@ struct TRINITY_DLL_DECL mob_depth_chargeAI : public ScriptedAI
return;
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
return;
}
diff --git a/src/bindings/scripts/scripts/zone/azshara/boss_azuregos.cpp b/src/bindings/scripts/scripts/zone/azshara/boss_azuregos.cpp
index 97e21ccbe1b..ae5e5db68f6 100644
--- a/src/bindings/scripts/scripts/zone/azshara/boss_azuregos.cpp
+++ b/src/bindings/scripts/scripts/zone/azshara/boss_azuregos.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -60,7 +60,7 @@ struct TRINITY_DLL_DECL boss_azuregosAI : public ScriptedAI
Enraged = false;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void UpdateAI(const uint32 diff)
{
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 d87cf571baf..0962207575f 100644
--- a/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp
+++ b/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp
@@ -1,4 +1,4 @@
- /* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ /* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -39,155 +39,140 @@ EndContentData */
## npc_draenei_survivor
######*/
-#define HEAL1 -1000248
-#define HEAL2 -1000249
-#define HEAL3 -1000250
-#define HEAL4 -1000251
+#define SAY_HEAL1 -1000248
+#define SAY_HEAL2 -1000249
+#define SAY_HEAL3 -1000250
+#define SAY_HEAL4 -1000251
-#define HELP1 -1000252
-#define HELP2 -1000253
-#define HELP3 -1000254
-#define HELP4 -1000255
+#define SAY_HELP1 -1000252
+#define SAY_HELP2 -1000253
+#define SAY_HELP3 -1000254
+#define SAY_HELP4 -1000255
+
+#define SPELL_IRRIDATION 35046
+#define SPELL_STUNNED 28630
struct TRINITY_DLL_DECL npc_draenei_survivorAI : public ScriptedAI
{
npc_draenei_survivorAI(Creature *c) : ScriptedAI(c) {}
- uint32 UnSpawnTimer;
- uint32 ResetlifeTimer;
- uint32 SayingTimer;
- uint32 HealSayTimer;
- bool UnSpawn;
- bool say;
- bool HealSay;
- bool isRun;
- bool isMove;
+ uint64 pCaster;
+
+ uint32 SayThanksTimer;
+ uint32 RunAwayTimer;
+ uint32 SayHelpTimer;
+
+ bool CanSayHelp;
void Reset()
{
- UnSpawnTimer = 2500;
- ResetlifeTimer= 60000;
- SayingTimer = 5000;
- HealSayTimer = 6000;
- say = false;
- isRun = false;
- isMove = false;
- UnSpawn = false;
- HealSay = false;
+ pCaster = 0;
+
+ SayThanksTimer = 0;
+ RunAwayTimer = 0;
+ SayHelpTimer = 10000;
+
+ CanSayHelp = true;
+
+ m_creature->CastSpell(m_creature, SPELL_IRRIDATION, true);
+
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
- //cast red shining
- m_creature->CastSpell(m_creature, 29152, false, NULL);
- //set creature health
m_creature->SetHealth(int(m_creature->GetMaxHealth()*.1));
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 3);
+ m_creature->SetStandState(UNIT_STAND_STATE_SLEEP);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
- void MoveInLineOfSight(Unit *who) //MoveInLineOfSight is called if creature could see you, updated all 100 ms
+ void MoveInLineOfSight(Unit *who)
{
- if (!who)
- return;
-
- if(who->GetTypeId() == TYPEID_PLAYER && m_creature->IsFriendlyTo(who) && m_creature->IsWithinDistInMap(who, 15) && say && !isRun)
+ if (CanSayHelp && who->GetTypeId() == TYPEID_PLAYER && m_creature->IsFriendlyTo(who) && m_creature->IsWithinDistInMap(who, 25.0f))
{
- switch (rand()%4) //Random switch between 4 texts
+ //Random switch between 4 texts
+ switch (rand()%4)
{
- case 0:
- DoScriptText(HELP1, m_creature);
- SayingTimer = 15000;
- say = false;
- break;
- case 1:
- DoScriptText(HELP2, m_creature);
- SayingTimer = 15000;
- say = false;
- break;
- case 2:
- DoScriptText(HELP3, m_creature);
- SayingTimer = 15000;
- say = false;
- break;
- case 3:
- DoScriptText(HELP4, m_creature);
- SayingTimer = 15000;
- say = false;
- break;
- }
- }
- else
- {
- isRun = false;
+ case 0: DoScriptText(SAY_HELP1, m_creature, who); break;
+ case 1: DoScriptText(SAY_HELP2, m_creature, who); break;
+ case 2: DoScriptText(SAY_HELP3, m_creature, who); break;
+ case 3: DoScriptText(SAY_HELP4, m_creature, who); break;
+ }
+
+ SayHelpTimer = 20000;
+ CanSayHelp = false;
}
}
- void UpdateAI(const uint32 diff) //Is also called each ms for Creature AI Updates...
+ void SpellHit(Unit *Caster, const SpellEntry *Spell)
{
- if (m_creature->GetHealth() > 50)
+ if (Spell->SpellFamilyFlags[2] & 0x080000000)
{
- if(ResetlifeTimer < diff)
- {
- ResetlifeTimer = 60000;
- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
- //set creature health
- m_creature->SetHealth(int(m_creature->GetMaxHealth()*.1));
- // ley down
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,3);
- }
- else ResetlifeTimer -= diff;
- }
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
- if(HealSay)
- {
- if (HealSayTimer < diff)
- {
- UnSpawn = true;
- isRun = true;
- isMove = true;
- }else HealSayTimer -= diff;
+ m_creature->CastSpell(m_creature, SPELL_STUNNED, true);
+
+ pCaster = Caster->GetGUID();
+
+ SayThanksTimer = 5000;
}
+ }
- if(UnSpawn)
+ void UpdateAI(const uint32 diff)
+ {
+ if (SayThanksTimer)
{
- if(isMove)
+ if (SayThanksTimer <= diff)
{
+ m_creature->RemoveAurasDueToSpell(SPELL_IRRIDATION);
+
+ if (Player *pPlayer = Unit::GetPlayer(pCaster))
+ {
+ if (pPlayer->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ switch (rand()%4)
+ {
+ case 0: DoScriptText(SAY_HEAL1, m_creature, pPlayer); break;
+ case 1: DoScriptText(SAY_HEAL2, m_creature, pPlayer); break;
+ case 2: DoScriptText(SAY_HEAL3, m_creature, pPlayer); break;
+ case 3: DoScriptText(SAY_HEAL4, m_creature, pPlayer); break;
+ }
+
+ pPlayer->TalkedToCreature(m_creature->GetEntry(),m_creature->GetGUID());
+ }
+
m_creature->GetMotionMaster()->Clear();
m_creature->GetMotionMaster()->MovePoint(0, -4115.053711f, -13754.831055f, 73.508949f);
- isMove = false;
- }
- if (UnSpawnTimer < diff)
- {
- m_creature->StopMoving();
- EnterEvadeMode();
- //set creature health
- m_creature->SetHealth(int(m_creature->GetMaxHealth()*.1));
+ RunAwayTimer = 10000;
+ SayThanksTimer = 0;
+ }else SayThanksTimer -= diff;
- }else UnSpawnTimer -= diff;
+ return;
}
- if(SayingTimer < diff)
- {
- say = true;
- }else SayingTimer -= diff;
- }
-
- void SpellHit(Unit *Hitter, const SpellEntry *Spellkind)//Called if you cast a spell and do some things if Specified spell is true!
- {
- if (Hitter && Spellkind->Id == 28880)
+ if (RunAwayTimer)
{
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
- m_creature->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
- m_creature->HandleEmoteCommand(ANIM_RISE);
- switch (rand()%4) //This switch doesn't work at all, creature say nothing!
+ if (RunAwayTimer <= diff)
{
- case 0: DoScriptText(HEAL1, m_creature, Hitter); break;
- case 1: DoScriptText(HEAL2, m_creature, Hitter); break;
- case 2: DoScriptText(HEAL3, m_creature, Hitter); break;
- case 3: DoScriptText(HEAL4, m_creature, Hitter); break;
- }
- HealSay = true;
+ m_creature->RemoveAllAuras();
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveIdle();
+ m_creature->setDeathState(JUST_DIED);
+ m_creature->SetHealth(0);
+ m_creature->CombatStop();
+ m_creature->DeleteThreatList();
+ m_creature->RemoveCorpse();
+ }else RunAwayTimer -= diff;
+
+ return;
}
+
+ if (SayHelpTimer < diff)
+ {
+ CanSayHelp = true;
+ SayHelpTimer = 20000;
+ }else SayHelpTimer -= diff;
}
};
CreatureAI* GetAI_npc_draenei_survivor(Creature *_Creature)
@@ -221,11 +206,11 @@ struct TRINITY_DLL_DECL npc_engineer_spark_overgrindAI : public ScriptedAI
m_creature->setFaction(875);
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void UpdateAI(const uint32 diff)
{
- if( !InCombat )
+ if( !m_creature->isInCombat() )
{
if (Emote_Timer < diff)
{
@@ -288,12 +273,12 @@ struct TRINITY_DLL_DECL npc_injured_draeneiAI : public ScriptedAI
m_creature->SetHealth(int(m_creature->GetMaxHealth()*.15));
switch (rand()%2)
{
- case 0: m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 1); break;
- case 1: m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 3); break;
+ case 0: m_creature->SetStandState(UNIT_STAND_STATE_SIT); break;
+ case 1: m_creature->SetStandState(UNIT_STAND_STATE_SLEEP); break;
}
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void MoveInLineOfSight(Unit *who)
{
@@ -322,7 +307,7 @@ CreatureAI* GetAI_npc_injured_draenei(Creature *_Creature)
#define SAY_END2 -1000115
#define EMOTE_HUG -1000116
-#define QUEST_A_CRY_FOR_HELP 9528
+#define QUEST_A_CRY_FOR_SAY_HELP 9528
struct TRINITY_DLL_DECL npc_magwinAI : public npc_escortAI
{
@@ -351,12 +336,12 @@ struct TRINITY_DLL_DECL npc_magwinAI : public npc_escortAI
DoScriptText(EMOTE_HUG, m_creature, player);
DoScriptText(SAY_END2, m_creature, player);
if (player && player->GetTypeId() == TYPEID_PLAYER)
- ((Player*)player)->GroupEventHappens(QUEST_A_CRY_FOR_HELP,m_creature);
+ ((Player*)player)->GroupEventHappens(QUEST_A_CRY_FOR_SAY_HELP,m_creature);
break;
}
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature, who);
}
@@ -373,7 +358,7 @@ struct TRINITY_DLL_DECL npc_magwinAI : public npc_escortAI
{
Player* player = Unit::GetPlayer(PlayerGUID);
if (player)
- ((Player*)player)->FailQuest(QUEST_A_CRY_FOR_HELP);
+ ((Player*)player)->FailQuest(QUEST_A_CRY_FOR_SAY_HELP);
}
}
@@ -385,7 +370,7 @@ struct TRINITY_DLL_DECL npc_magwinAI : public npc_escortAI
bool QuestAccept_npc_magwin(Player* player, Creature* creature, Quest const* quest)
{
- if (quest->GetQuestId() == QUEST_A_CRY_FOR_HELP)
+ if (quest->GetQuestId() == QUEST_A_CRY_FOR_SAY_HELP)
{
creature->setFaction(113);
((npc_escortAI*)(creature->AI()))->Start(true, true, false, player->GetGUID());
@@ -393,41 +378,11 @@ bool QuestAccept_npc_magwin(Player* player, Creature* creature, Quest const* que
return true;
}
-CreatureAI* GetAI_npc_magwinAI(Creature *_Creature)
+CreatureAI* GetAI_npc_magwinAI(Creature* pCreature)
{
- npc_magwinAI* magwinAI = new npc_magwinAI(_Creature);
-
- magwinAI->AddWaypoint(0, -4784.532227, -11051.060547, 3.484263);
- magwinAI->AddWaypoint(1, -4805.509277, -11037.293945, 3.043942);
- magwinAI->AddWaypoint(2, -4827.826172, -11034.398438, 1.741959);
- magwinAI->AddWaypoint(3, -4852.630859, -11033.695313, 2.208656);
- magwinAI->AddWaypoint(4, -4876.791992, -11034.517578, 3.175228);
- magwinAI->AddWaypoint(5, -4895.486816, -11038.306641, 9.390890);
- magwinAI->AddWaypoint(6, -4915.464844, -11048.402344, 12.369793);
- magwinAI->AddWaypoint(7, -4937.288086, -11067.041992, 13.857983);
- magwinAI->AddWaypoint(8, -4966.577637, -11067.507813, 15.754786);
- magwinAI->AddWaypoint(9, -4993.799805, -11056.544922, 19.175295);
- magwinAI->AddWaypoint(10, -5017.836426, -11052.569336, 22.476587);
- magwinAI->AddWaypoint(11, -5039.706543, -11058.459961, 25.831593);
- magwinAI->AddWaypoint(12, -5057.289063, -11045.474609, 26.972496);
- magwinAI->AddWaypoint(13, -5078.828125, -11037.601563, 29.053417);
- magwinAI->AddWaypoint(14, -5104.158691, -11039.195313, 29.440195);
- magwinAI->AddWaypoint(15, -5120.780273, -11039.518555, 30.142139);
- magwinAI->AddWaypoint(16, -5140.833008, -11039.810547, 28.788074);
- magwinAI->AddWaypoint(17, -5161.201660, -11040.050781, 27.879545, 4000);
- magwinAI->AddWaypoint(18, -5171.842285, -11046.803711, 27.183821);
- magwinAI->AddWaypoint(19, -5185.995117, -11056.359375, 20.234867);
- magwinAI->AddWaypoint(20, -5198.485840, -11065.065430, 18.872593);
- magwinAI->AddWaypoint(21, -5214.062500, -11074.653320, 19.215731);
- magwinAI->AddWaypoint(22, -5220.157227, -11088.377930, 19.818476);
- magwinAI->AddWaypoint(23, -5233.652832, -11098.846680, 18.349432);
- magwinAI->AddWaypoint(24, -5250.163086, -11111.653320, 16.438959);
- magwinAI->AddWaypoint(25, -5268.194336, -11125.639648, 12.668313);
- magwinAI->AddWaypoint(26, -5286.270508, -11130.669922, 6.912246);
- magwinAI->AddWaypoint(27, -5317.449707, -11137.392578, 4.963446);
- magwinAI->AddWaypoint(28, -5334.854492, -11154.384766, 6.742664);
- magwinAI->AddWaypoint(29, -5353.874512, -11171.595703, 6.903912, 20000);
- magwinAI->AddWaypoint(30, -5354.240000, -11171.940000, 6.890000);
+ npc_magwinAI* magwinAI = new npc_magwinAI(pCreature);
+
+ magwinAI->FillPointMovementListForCreature();
return (CreatureAI*)magwinAI;
}
@@ -505,7 +460,7 @@ struct TRINITY_DLL_DECL npc_geezleAI : public ScriptedAI
StartEvent();
}
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void StartEvent()
{
@@ -562,7 +517,7 @@ struct TRINITY_DLL_DECL npc_geezleAI : public ScriptedAI
cell.SetNoCreate();
Trinity::AllGameObjectsWithEntryInGrid go_check(GO_NAGA_FLAG);
- Trinity::GameObjectListSearcher<Trinity::AllGameObjectsWithEntryInGrid> go_search(FlagList, go_check);
+ Trinity::GameObjectListSearcher<Trinity::AllGameObjectsWithEntryInGrid> go_search(m_creature, FlagList, go_check);
TypeContainerVisitor
<Trinity::GameObjectListSearcher<Trinity::AllGameObjectsWithEntryInGrid>, GridTypeMapContainer> go_visit(go_search);
CellLock<GridReadGuard> cell_lock(cell, pair);
@@ -621,7 +576,7 @@ struct TRINITY_DLL_DECL mob_nestlewood_owlkinAI : public ScriptedAI
Hitted = false;
}
- void Aggro(Unit *who){}
+ void EnterCombat(Unit *who){}
void SpellHit(Unit* caster, const SpellEntry* spell)
{
diff --git a/src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp b/src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp
index 37d0ee089f5..1adc651788b 100644
--- a/src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp
+++ b/src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -89,60 +89,64 @@ bool GossipSelect_npc_sputtervalve(Player *player, Creature *_Creature, uint32 s
## npc_taskmaster_fizzule
######*/
-//#define FACTION_HOSTILE_F 430
-#define FACTION_HOSTILE_F 16
-#define FACTION_FRIENDLY_F 35
-
-#define SPELL_FLARE 10113
-#define SPELL_FOLLY 10137
+enum
+{
+ FACTION_FRIENDLY_F = 35,
+ SPELL_FLARE = 10113,
+ SPELL_FOLLY = 10137,
+};
struct TRINITY_DLL_DECL npc_taskmaster_fizzuleAI : public ScriptedAI
{
- npc_taskmaster_fizzuleAI(Creature* c) : ScriptedAI(c) {}
+ npc_taskmaster_fizzuleAI(Creature* c) : ScriptedAI(c)
+ {
+ factionNorm = c->getFaction();
+ }
+ uint32 factionNorm;
bool IsFriend;
uint32 Reset_Timer;
- uint32 FlareCount;
+ uint8 FlareCount;
void Reset()
{
IsFriend = false;
Reset_Timer = 120000;
FlareCount = 0;
- m_creature->setFaction(FACTION_HOSTILE_F);
- m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->setFaction(factionNorm);
}
- //This is a hack. Spellcast will make creature aggro but that is not
- //supposed to happen (Trinity not implemented/not found way to detect this spell kind)
- void DoUglyHack()
+ void DoFriend()
{
m_creature->RemoveAllAuras();
m_creature->DeleteThreatList();
m_creature->CombatStop();
+
+ m_creature->StopMoving();
+ m_creature->GetMotionMaster()->MoveIdle();
+
+ m_creature->setFaction(FACTION_FRIENDLY_F);
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
}
void SpellHit(Unit *caster, const SpellEntry *spell)
{
- if( spell->Id == SPELL_FLARE || spell->Id == SPELL_FOLLY )
+ if (spell->Id == SPELL_FLARE || spell->Id == SPELL_FOLLY)
{
- DoUglyHack();
++FlareCount;
- if( FlareCount >= 2 )
- {
- m_creature->setFaction(FACTION_FRIENDLY_F);
+
+ if (FlareCount >= 2)
IsFriend = true;
- }
}
}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void UpdateAI(const uint32 diff)
{
- if( IsFriend )
+ if (IsFriend)
{
- if( Reset_Timer < diff )
+ if (Reset_Timer < diff)
{
EnterEvadeMode();
} else Reset_Timer -= diff;
@@ -153,24 +157,27 @@ struct TRINITY_DLL_DECL npc_taskmaster_fizzuleAI : public ScriptedAI
DoMeleeAttackIfReady();
}
-};
-CreatureAI* GetAI_npc_taskmaster_fizzule(Creature *_Creature)
-{
- return new npc_taskmaster_fizzuleAI (_Creature);
-}
-bool ReciveEmote_npc_taskmaster_fizzule(Player *player, Creature *_Creature, uint32 emote)
-{
- if( emote == TEXTEMOTE_SALUTE )
+ void ReciveEmote(Player* pPlayer, uint32 emote)
{
- if( ((npc_taskmaster_fizzuleAI*)_Creature->AI())->FlareCount >= 2 )
+ if (emote == TEXTEMOTE_SALUTE)
{
- _Creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
- _Creature->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
+ if (FlareCount >= 2)
+ {
+ if (m_creature->getFaction() == FACTION_FRIENDLY_F)
+ return;
+ else
+ DoFriend();
+ }
}
}
- return true;
+};
+
+CreatureAI* GetAI_npc_taskmaster_fizzule(Creature* pCreature)
+{
+ return new npc_taskmaster_fizzuleAI(pCreature);
}
+
/*#####
## npc_twiggy_flathead
#####*/
@@ -226,7 +233,7 @@ struct TRINITY_DLL_DECL npc_twiggy_flatheadAI : public ScriptedAI
BigWill = 0;
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void MoveInLineOfSight(Unit *who)
{
@@ -357,7 +364,6 @@ struct TRINITY_DLL_DECL npc_twiggy_flatheadAI : public ScriptedAI
//pCreature->GetMotionMaster()->MovePoint(0, -1693, -4343, 4.32);
//pCreature->GetMotionMaster()->MovePoint(1, -1684, -4333, 2.78);
pCreature->GetMotionMaster()->MovePoint(2, -1682, -4329, 2.79);
- //pCreature->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
pCreature->HandleEmoteCommand(EMOTE_STATE_READYUNARMED);
EventBigWill = true;
Wave_Timer = 1000;
@@ -456,7 +462,7 @@ struct TRINITY_DLL_DECL npc_wizzlecrank_shredderAI : public npc_escortAI
m_creature->setFaction(69);
}
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void JustDied(Unit* killer)
{
@@ -543,7 +549,6 @@ void AddSC_the_barrens()
newscript = new Script;
newscript->Name="npc_taskmaster_fizzule";
newscript->GetAI = &GetAI_npc_taskmaster_fizzule;
- newscript->pReceiveEmote = &ReciveEmote_npc_taskmaster_fizzule;
newscript->RegisterSelf();
newscript = new Script;
diff --git a/src/bindings/scripts/scripts/zone/black_temple/.boss_teron_gorefiend.cpp-woains b/src/bindings/scripts/scripts/zone/black_temple/.boss_teron_gorefiend.cpp-woains
new file mode 100644
index 00000000000..327b670c6d3
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/black_temple/.boss_teron_gorefiend.cpp-woains
@@ -0,0 +1,536 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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
+ */
+
+/* ScriptData
+SDName: Boss_Teron_Gorefiend
+SD%Complete: 60
+SDComment: Requires Mind Control support for Ghosts.
+SDCategory: Black Temple
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_black_temple.h"
+
+ //Speech'n'sound
+#define SAY_INTRO -1564037
+#define SAY_AGGRO -1564038
+#define SAY_SLAY1 -1564039
+#define SAY_SLAY2 -1564040
+#define SAY_SPELL1 -1564041
+#define SAY_SPELL2 -1564042
+#define SAY_SPECIAL1 -1564043
+#define SAY_SPECIAL2 -1564044
+#define SAY_ENRAGE -1564045
+#define SAY_DEATH -1564046
+
+//Spells
+#define SPELL_INCINERATE 40239
+#define SPELL_CRUSHING_SHADOWS 40243
+#define SPELL_SHADOWBOLT 40185
+#define SPELL_PASSIVE_SHADOWFORM 40326
+#define SPELL_SHADOW_OF_DEATH 40251
+#define SPELL_BERSERK 45078
+
+#define SPELL_ATROPHY 40327 // Shadowy Constructs use this when they get within melee range of a player
+
+#define CREATURE_DOOM_BLOSSOM 23123
+#define CREATURE_SHADOWY_CONSTRUCT 23111
+
+struct TRINITY_DLL_DECL mob_doom_blossomAI : public ScriptedAI
+{
+ mob_doom_blossomAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 CheckTeronTimer;
+ uint32 ShadowBoltTimer;
+ uint64 TeronGUID;
+
+ void Reset()
+ {
+ CheckTeronTimer = 5000;
+ ShadowBoltTimer = 12000;
+ TeronGUID = 0;
+ }
+
+ void Aggro(Unit *who) { }
+ void AttackStart(Unit* who) { }
+ void MoveInLineOfSight(Unit* who) { }
+
+ void Despawn()
+ {
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ m_creature->RemoveCorpse();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(CheckTeronTimer < diff)
+ {
+ if(TeronGUID)
+ {
+ DoZoneInCombat();
+
+ Creature* Teron = ((Creature*)Unit::GetUnit((*m_creature), TeronGUID));
+ if((Teron) && (!Teron->isAlive() || Teron->IsInEvadeMode()))
+ Despawn();
+ }
+ else
+ Despawn();
+
+ CheckTeronTimer = 5000;
+ }else CheckTeronTimer -= diff;
+
+ if(ShadowBoltTimer < diff && InCombat)
+ {
+ DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_SHADOWBOLT);
+ ShadowBoltTimer = 10000;
+ }else ShadowBoltTimer -= diff;
+ return;
+ }
+
+ void SetTeronGUID(uint64 guid){ TeronGUID = guid; }
+};
+
+//This is used to sort the players by distance for Constructs to see who to cast Atrophy on
+struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool>
+{
+ const Unit* MainTarget;
+ TargetDistanceOrder(const Unit* Target) : MainTarget(Target) {};
+ // functor for operator "<"
+ bool operator()(const Unit* _Left, const Unit* _Right) const
+ {
+ return (MainTarget->GetDistance(_Left) < MainTarget->GetDistance(_Right));
+ }
+};
+
+struct TRINITY_DLL_DECL mob_shadowy_constructAI : public ScriptedAI
+{
+ mob_shadowy_constructAI(Creature* c) : ScriptedAI(c) {}
+
+ uint64 GhostGUID;
+ uint64 TeronGUID;
+
+ uint32 CheckPlayerTimer;
+ uint32 CheckTeronTimer;
+
+ void Reset()
+ {
+ GhostGUID = 0;
+ TeronGUID = 0;
+
+ CheckPlayerTimer = 2000;
+ CheckTeronTimer = 5000;
+ }
+
+ void Aggro(Unit* who) { }
+
+ void MoveInLineOfSight(Unit *who)
+ {
+ if(!who || (!who->isAlive()) || (who->GetGUID() == GhostGUID))
+ return;
+
+ ScriptedAI::MoveInLineOfSight(who);
+ }
+
+/* Comment it out for now. NOTE TO FUTURE DEV: UNCOMMENT THIS OUT ONLY AFTER MIND CONTROL IS IMPLEMENTED
+ void DamageTaken(Unit* done_by, uint32 &damage)
+ {
+ if(done_by->GetGUID() != GhostGUID)
+ damage = 0; // Only the ghost can deal damage.
+ }
+ */
+
+ void CheckPlayers()
+ {
+ std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
+ if(m_threatlist.empty())
+ return; // No threat list. Don't continue.
+ std::list<HostilReference*>::iterator itr = m_threatlist.begin();
+ std::list<Unit*> targets;
+ for( ; itr != m_threatlist.end(); ++itr)
+ {
+ Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid());
+ if(pUnit && pUnit->isAlive())
+ targets.push_back(pUnit);
+ }
+ targets.sort(TargetDistanceOrder(m_creature));
+ Unit* target = targets.front();
+ if(target && m_creature->IsWithinDistInMap(target, m_creature->GetAttackDistance(target)))
+ {
+ DoCast(target, SPELL_ATROPHY);
+ m_creature->AI()->AttackStart(target);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(CheckPlayerTimer < diff)
+ {
+ CheckPlayers();
+ CheckPlayerTimer = 3000;
+ }else CheckPlayerTimer -= diff;
+
+ if(CheckTeronTimer < diff)
+ {
+ Creature* Teron = ((Creature*)Unit::GetUnit((*m_creature), TeronGUID));
+ if(!Teron || !Teron->isAlive() || Teron->IsInEvadeMode())
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+
+ CheckTeronTimer = 5000;
+ }else CheckTeronTimer -= diff;
+ }
+};
+
+struct TRINITY_DLL_DECL boss_teron_gorefiendAI : public ScriptedAI
+{
+ boss_teron_gorefiendAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 IncinerateTimer;
+ uint32 SummonDoomBlossomTimer;
+ uint32 EnrageTimer;
+ uint32 CrushingShadowsTimer;
+ uint32 ShadowOfDeathTimer;
+ uint32 SummonShadowsTimer;
+ uint32 RandomYellTimer;
+ uint32 AggroTimer;
+
+ uint64 AggroTargetGUID;
+ uint64 GhostGUID; // Player that gets killed by Shadow of Death and gets turned into a ghost
+
+ bool Intro;
+
+ void Reset()
+ {
+ if(pInstance)
+ pInstance->SetData(DATA_TERONGOREFIENDEVENT, NOT_STARTED);
+
+ IncinerateTimer = 20000 + rand()%11000;
+ SummonDoomBlossomTimer = 12000;
+ EnrageTimer = 600000;
+ CrushingShadowsTimer = 22000;
+ SummonShadowsTimer = 60000;
+ RandomYellTimer = 50000;
+
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ // Start off unattackable so that the intro is done properly
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ AggroTimer = 20000;
+ AggroTargetGUID = 0;
+ Intro = false;
+ }
+
+ void Aggro(Unit *who) {}
+
+ void MoveInLineOfSight(Unit *who)
+ {
+ if(!who || (!who->isAlive())) return;
+
+ if(who->isTargetableForAttack() && who->isInAccessiblePlaceFor(m_creature) && m_creature->IsHostileTo(who))
+ {
+ float attackRadius = m_creature->GetAttackDistance(who);
+
+ if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
+ {
+ //if(who->HasStealthAura())
+ // who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+
+ m_creature->AddThreat(who, 1.0f);
+ }
+
+ if(!InCombat && !Intro && m_creature->IsWithinDistInMap(who, 60.0f) && (who->GetTypeId() == TYPEID_PLAYER))
+ {
+ if(pInstance)
+ pInstance->SetData(DATA_TERONGOREFIENDEVENT, IN_PROGRESS);
+
+ m_creature->GetMotionMaster()->Clear(false);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ DoScriptText(SAY_INTRO, m_creature);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_TALK);
+ AggroTargetGUID = who->GetGUID();
+ Intro = true;
+ }
+ }
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ switch(rand()%2)
+ {
+ case 0: DoScriptText(SAY_SLAY1, m_creature); break;
+ case 1: DoScriptText(SAY_SLAY2, m_creature); break;
+ }
+ }
+
+ void JustDied(Unit *victim)
+ {
+ if(pInstance)
+ pInstance->SetData(DATA_TERONGOREFIENDEVENT, DONE);
+
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+
+ float CalculateRandomLocation(float Loc, uint32 radius)
+ {
+ float coord = Loc;
+ switch(rand()%2)
+ {
+ case 0:
+ coord += rand()%radius;
+ break;
+ case 1:
+ coord -= rand()%radius;
+ break;
+ }
+ return coord;
+ }
+
+ void SetThreatList(Creature* Blossom)
+ {
+ if(!Blossom) return;
+
+ std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
+ std::list<HostilReference*>::iterator i = m_threatlist.begin();
+ for(i = m_threatlist.begin(); i != m_threatlist.end(); i++)
+ {
+ Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
+ if(pUnit && pUnit->isAlive())
+ {
+ float threat = DoGetThreat(pUnit);
+ Blossom->AddThreat(pUnit, threat);
+ }
+ }
+ }
+
+ void MindControlGhost()
+ {
+ /************************************************************************/
+ /** NOTE FOR FUTURE DEVELOPER: PROPERLY IMPLEMENT THE GHOST PORTION *****/
+ /** ONLY AFTER TrinIty FULLY IMPLEMENTS MIND CONTROL ABILITIES *****/
+ /** THE CURRENT CODE IN THIS FUNCTION IS ONLY THE BEGINNING OF *****/
+ /** WHAT IS FULLY NECESSARY FOR GOREFIEND TO BE 100% COMPLETE *****/
+ /************************************************************************/
+
+ Unit* Ghost = NULL;
+ if(GhostGUID)
+ Ghost = Unit::GetUnit((*m_creature), GhostGUID);
+ if(Ghost && Ghost->isAlive() && Ghost->HasAura(SPELL_SHADOW_OF_DEATH, 0))
+ {
+ /*float x,y,z;
+ Ghost->GetPosition(x,y,z);
+ Creature* control = m_creature->SummonCreature(CREATURE_GHOST, x, y, z, 0, TEMPSUMMON_TIMED_DESAWN, 30000);
+ if(control)
+ {
+ ((Player*)Ghost)->Possess(control);
+ Ghost->DealDamage(Ghost, Ghost->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL,
+ false);
+ }*/
+ for(uint8 i = 0; i < 4; ++i)
+ {
+ Creature* Construct = NULL;
+ float X = CalculateRandomLocation(Ghost->GetPositionX(), 10);
+ float Y = CalculateRandomLocation(Ghost->GetPositionY(), 10);
+ Construct = m_creature->SummonCreature(CREATURE_SHADOWY_CONSTRUCT, X, Y, Ghost->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);
+ if(Construct)
+ {
+ Construct->CastSpell(Construct, SPELL_PASSIVE_SHADOWFORM, true);
+ SetThreatList(Construct); // Use same function as Doom Blossom to set Threat List.
+ ((mob_shadowy_constructAI*)Construct->AI())->GhostGUID = GhostGUID;
+ Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
+ if(!target) // someone's trying to solo.
+ target = m_creature->getVictim();
+
+ if(target)
+ Construct->GetMotionMaster()->MoveChase(target);
+ }
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(Intro)
+ {
+ if(AggroTimer < diff)
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ DoScriptText(SAY_AGGRO, m_creature);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
+ Intro = false;
+ if(AggroTargetGUID)
+ {
+ Unit* pUnit = Unit::GetUnit((*m_creature), AggroTargetGUID);
+ if(pUnit)
+ AttackStart(pUnit);
+
+ DoZoneInCombat();
+ }else EnterEvadeMode();
+
+ }else AggroTimer -= diff;
+ }
+
+ if(!UpdateVictim() || Intro)
+ return;
+
+ if(SummonShadowsTimer < diff)
+ {
+ //MindControlGhost();
+
+ for(uint8 i = 0; i < 2; ++i)
+ {
+ Creature* Shadow = NULL;
+ float X = CalculateRandomLocation(m_creature->GetPositionX(), 10);
+ Shadow = m_creature->SummonCreature(CREATURE_SHADOWY_CONSTRUCT, X, m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 0);
+ if(Shadow)
+ {
+ Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
+ if(!target)
+ target = m_creature->getVictim();
+
+ if(target)
+ Shadow->AI()->AttackStart(target);
+ }
+ }
+ SummonShadowsTimer = 60000;
+ }else SummonShadowsTimer -= diff;
+
+ if(SummonDoomBlossomTimer < diff)
+ {
+ if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ float X = CalculateRandomLocation(target->GetPositionX(), 20);
+ float Y = CalculateRandomLocation(target->GetPositionY(), 20);
+ float Z = target->GetPositionZ();
+ Z = m_creature->GetMap()->GetVmapHeight(X, Y, Z, true);
+ Creature* DoomBlossom = m_creature->SummonCreature(CREATURE_DOOM_BLOSSOM, X, Y, Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000);
+ if(DoomBlossom)
+ {
+ DoomBlossom->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ DoomBlossom->setFaction(m_creature->getFaction());
+ DoomBlossom->AddThreat(target, 1.0f);
+ ((mob_doom_blossomAI*)DoomBlossom->AI())->SetTeronGUID(m_creature->GetGUID());
+ ((mob_doom_blossomAI*)DoomBlossom->AI())->InCombat = true;
+ SetThreatList(DoomBlossom);
+ SummonDoomBlossomTimer = 35000;
+ }
+ }
+ }else SummonDoomBlossomTimer -= diff;
+
+ if(IncinerateTimer < diff)
+ {
+ Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
+ if(!target)
+ target = m_creature->getVictim();
+
+ if(target)
+ {
+ switch(rand()%2)
+ {
+ case 0: DoScriptText(SAY_SPECIAL1, m_creature); break;
+ case 1: DoScriptText(SAY_SPECIAL2, m_creature); break;
+ }
+ DoCast(target, SPELL_INCINERATE);
+ IncinerateTimer = 20000 + rand()%31 * 1000;
+ }
+ }else IncinerateTimer -= diff;
+
+ if(CrushingShadowsTimer < diff)
+ {
+ Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ if(target && target->isAlive())
+ DoCast(target, SPELL_CRUSHING_SHADOWS);
+ CrushingShadowsTimer = 10000 + rand()%16 * 1000;
+ }else CrushingShadowsTimer -= diff;
+
+ /*** NOTE FOR FUTURE DEV: UNCOMMENT BELOW ONLY IF MIND CONTROL IS FULLY IMPLEMENTED **/
+ /*if(ShadowOfDeathTimer < diff)
+ {
+ Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
+
+ if(!target)
+ target = m_creature->getVictim();
+
+ if(target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER)
+ {
+ DoCast(target, SPELL_SHADOW_OF_DEATH);
+ GhostGUID = target->GetGUID();
+ ShadowOfDeathTimer = 30000;
+ SummonShadowsTimer = 53000; // Make it VERY close but slightly less so that we can check if the aura is still on the player
+ }
+ }else ShadowOfDeathTimer -= diff;*/
+
+ if(RandomYellTimer < diff)
+ {
+ switch(rand()%2)
+ {
+ case 0: DoScriptText(SAY_SPELL1, m_creature); break;
+ case 1: DoScriptText(SAY_SPELL2, m_creature); break;
+ }
+ RandomYellTimer = 50000 + rand()%51 * 1000;
+ }else RandomYellTimer -= diff;
+
+ if(!m_creature->HasAura(SPELL_BERSERK, 0))
+ {
+ if(EnrageTimer < diff)
+ {
+ DoCast(m_creature, SPELL_BERSERK);
+ DoScriptText(SAY_ENRAGE, m_creature);
+ }else EnrageTimer -= diff;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_doom_blossom(Creature *_Creature)
+{
+ return new mob_doom_blossomAI(_Creature);
+}
+
+CreatureAI* GetAI_mob_shadowy_construct(Creature *_Creature)
+{
+ return new mob_shadowy_constructAI(_Creature);
+}
+
+CreatureAI* GetAI_boss_teron_gorefiend(Creature *_Creature)
+{
+ return new boss_teron_gorefiendAI (_Creature);
+}
+
+void AddSC_boss_teron_gorefiend()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "mob_doom_blossom";
+ newscript->GetAI = &GetAI_mob_doom_blossom;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_shadowy_construct";
+ newscript->GetAI = &GetAI_mob_shadowy_construct;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="boss_teron_gorefiend";
+ newscript->GetAI = &GetAI_boss_teron_gorefiend;
+ newscript->RegisterSelf();
+}
+
diff --git a/src/bindings/scripts/scripts/zone/black_temple/.instance_black_temple.cpp-s8inyu b/src/bindings/scripts/scripts/zone/black_temple/.instance_black_temple.cpp-s8inyu
new file mode 100644
index 00000000000..43646746505
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/black_temple/.instance_black_temple.cpp-s8inyu
@@ -0,0 +1,347 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+* 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
+*/
+
+/* ScriptData
+SDName: Instance_Black_Temple
+SD%Complete: 100
+SDComment: Instance Data Scripts and functions to acquire mobs and set encounter status for use in various Black Temple Scripts
+SDCategory: Black Temple
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_black_temple.h"
+
+#define ENCOUNTERS 9
+
+/* Black Temple encounters:
+0 - High Warlord Naj'entus event
+1 - Supremus Event
+2 - Shade of Akama Event
+3 - Teron Gorefiend Event
+4 - Gurtogg Bloodboil Event
+5 - Reliquary Of Souls Event
+6 - Mother Shahraz Event
+7 - Illidari Council Event
+8 - Illidan Stormrage Event
+*/
+
+struct TRINITY_DLL_DECL instance_black_temple : public ScriptedInstance
+{
+ instance_black_temple(Map *map) : ScriptedInstance(map) {Initialize();};
+
+ uint32 Encounters[ENCOUNTERS];
+ std::string str_data;
+
+ uint64 Najentus;
+ uint64 Akama; // This is the Akama that starts the Illidan encounter.
+ uint64 Akama_Shade; // This is the Akama that starts the Shade of Akama encounter.
+ uint64 ShadeOfAkama;
+ uint64 Supremus;
+ uint64 LadyMalande;
+ uint64 GathiosTheShatterer;
+ uint64 HighNethermancerZerevor;
+ uint64 VerasDarkshadow;
+ uint64 IllidariCouncil;
+ uint64 BloodElfCouncilVoice;
+ uint64 IllidanStormrage;
+
+ uint64 NajentusGate;
+ uint64 MainTempleDoors;
+ uint64 ShadeOfAkamaDoor;
+ uint64 CommonDoor;//Teron
+ uint64 TeronDoor;
+ uint64 GuurtogDoor;
+ uint64 MotherDoor;
+ uint64 TempleDoor;//Befor mother
+ uint64 CouncilDoor;
+ uint64 SimpleDoor;//council
+ uint64 IllidanGate;
+ uint64 IllidanDoor[2];
+
+ void Initialize()
+ {
+ Najentus = 0;
+ Akama = 0;
+ Akama_Shade = 0;
+ ShadeOfAkama = 0;
+ Supremus = 0;
+ LadyMalande = 0;
+ GathiosTheShatterer = 0;
+ HighNethermancerZerevor = 0;
+ VerasDarkshadow = 0;
+ IllidariCouncil = 0;
+ BloodElfCouncilVoice = 0;
+ IllidanStormrage = 0;
+
+ NajentusGate = 0;
+ MainTempleDoors = 0;
+ ShadeOfAkamaDoor= 0;
+ CommonDoor = 0;//teron
+ TeronDoor = 0;
+ GuurtogDoor = 0;
+ MotherDoor = 0;
+ TempleDoor = 0;
+ SimpleDoor = 0;//Bycouncil
+ CouncilDoor = 0;
+ IllidanGate = 0;
+ IllidanDoor[0] = 0;
+ IllidanDoor[1] = 0;
+
+ for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ Encounters[i] = NOT_STARTED;
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ if(Encounters[i] == IN_PROGRESS) return true;
+
+ return false;
+ }
+
+ Player* GetPlayerInMap()
+ {
+ Map::PlayerList const& players = instance->GetPlayers();
+
+ if (!players.isEmpty())
+ {
+ for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ {
+ if (Player* plr = itr->getSource())
+ return plr;
+ }
+ }
+
+ debug_log("TSCR: Instance Black Temple: GetPlayerInMap, but PlayerList is empty!");
+ return NULL;
+ }
+
+ void OnCreatureCreate(Creature *creature, uint32 creature_entry)
+ {
+ switch(creature->GetEntry())
+ {
+ case 22887: Najentus = creature->GetGUID(); break;
+ case 23089: Akama = creature->GetGUID(); break;
+ case 22990: Akama_Shade = creature->GetGUID(); break;
+ case 22841: ShadeOfAkama = creature->GetGUID(); break;
+ case 22898: Supremus = creature->GetGUID(); break;
+ case 22917: IllidanStormrage = creature->GetGUID(); break;
+ case 22949: GathiosTheShatterer = creature->GetGUID(); break;
+ case 22950: HighNethermancerZerevor = creature->GetGUID(); break;
+ case 22951: LadyMalande = creature->GetGUID(); break;
+ case 22952: VerasDarkshadow = creature->GetGUID(); break;
+ case 23426: IllidariCouncil = creature->GetGUID(); break;
+ case 23499: BloodElfCouncilVoice = creature->GetGUID(); break;
+ }
+ }
+
+ void OnObjectCreate(GameObject* go)
+ {
+ switch(go->GetEntry())
+ {
+ case 185483: NajentusGate = go->GetGUID();// Gate past Naj'entus (at the entrance to Supermoose's courtyards)
+ if(Encounters[0] == DONE)HandleGameObject(NULL,true,go);break;
+ case 185882: MainTempleDoors = go->GetGUID();// Main Temple Doors - right past Supermoose (Supremus)
+ if(Encounters[1] == DONE)HandleGameObject(NULL,true,go);break;
+ case 185478: ShadeOfAkamaDoor = go->GetGUID();break;
+ case 185480: CommonDoor = go->GetGUID();
+ if(Encounters[3] == DONE)HandleGameObject(NULL,true,go);;break;
+ case 186153: TeronDoor = go->GetGUID();
+ if(Encounters[3] == DONE)HandleGameObject(NULL,true,go);;break;
+ case 185892: GuurtogDoor = go->GetGUID();
+ if(Encounters[4] == DONE)HandleGameObject(NULL,true,go);break;
+ case 185479: TempleDoor = go->GetGUID();
+ if(Encounters[5] == DONE)HandleGameObject(NULL,true,go);break;
+ case 185482: MotherDoor = go->GetGUID();
+ if(Encounters[6] == DONE)HandleGameObject(NULL,true,go);break;
+ case 185481: CouncilDoor = go->GetGUID();
+ if(Encounters[7] == DONE)HandleGameObject(NULL,true,go);break;
+ case 186152: SimpleDoor = go->GetGUID();
+ if(Encounters[7] == DONE)HandleGameObject(NULL,true,go);break;
+ case 185905: IllidanGate = go->GetGUID(); break; // Gate leading to Temple Summit
+ case 186261: IllidanDoor[0] = go->GetGUID(); break; // Right door at Temple Summit
+ case 186262: IllidanDoor[1] = go->GetGUID(); break; // Left door at Temple Summit
+ }
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_HIGHWARLORDNAJENTUS: return Najentus;
+ case DATA_AKAMA: return Akama;
+ case DATA_AKAMA_SHADE: return Akama_Shade;
+ case DATA_SHADEOFAKAMA: return ShadeOfAkama;
+ case DATA_SUPREMUS: return Supremus;
+ case DATA_ILLIDANSTORMRAGE: return IllidanStormrage;
+ case DATA_GATHIOSTHESHATTERER: return GathiosTheShatterer;
+ case DATA_HIGHNETHERMANCERZEREVOR: return HighNethermancerZerevor;
+ case DATA_LADYMALANDE: return LadyMalande;
+ case DATA_VERASDARKSHADOW: return VerasDarkshadow;
+ case DATA_ILLIDARICOUNCIL: return IllidariCouncil;
+ case DATA_GAMEOBJECT_NAJENTUS_GATE: return NajentusGate;
+ case DATA_GAMEOBJECT_ILLIDAN_GATE: return IllidanGate;
+ case DATA_GAMEOBJECT_ILLIDAN_DOOR_R: return IllidanDoor[0];
+ case DATA_GAMEOBJECT_ILLIDAN_DOOR_L: return IllidanDoor[1];
+ case DATA_GAMEOBJECT_SUPREMUS_DOORS: return MainTempleDoors;
+ case DATA_BLOOD_ELF_COUNCIL_VOICE: return BloodElfCouncilVoice;
+ }
+
+ return 0;
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_HIGHWARLORDNAJENTUSEVENT:
+ if(data == DONE)
+ {
+ HandleGameObject(NajentusGate, true);
+ }
+ Encounters[0] = data;break;
+ case DATA_SUPREMUSEVENT:
+ if(data == DONE)
+ {
+ HandleGameObject(NajentusGate, true);
+ }
+ Encounters[1] = data; break;
+ case DATA_SHADEOFAKAMAEVENT:
+ if(data == IN_PROGRESS)
+ {
+ HandleGameObject(ShadeOfAkamaDoor, false);
+ }else HandleGameObject(ShadeOfAkamaDoor, true);
+ Encounters[2] = data; break;
+ case DATA_TERONGOREFIENDEVENT:
+ if(data == IN_PROGRESS)
+ {
+ HandleGameObject(TeronDoor, false);
+ HandleGameObject(CommonDoor, false);
+ }else
+ {
+ HandleGameObject(TeronDoor, true);
+ HandleGameObject(CommonDoor, true);
+ }
+ Encounters[3] = data; break;
+ case DATA_GURTOGGBLOODBOILEVENT:
+ if(data == DONE)
+ {
+ HandleGameObject(GuurtogDoor, true);
+ }
+ Encounters[4] = data; break;
+ case DATA_RELIQUARYOFSOULSEVENT:
+ if(data == DONE)
+ {
+ HandleGameObject(TempleDoor, true);
+ }
+ Encounters[5] = data; break;
+ case DATA_MOTHERSHAHRAZEVENT:
+ if(data == DONE)
+ {
+ HandleGameObject(MotherDoor, true);
+ }
+ Encounters[6] = data; break;
+ case DATA_ILLIDARICOUNCILEVENT:
+ if(data == IN_PROGRESS)
+ {
+ HandleGameObject(CouncilDoor, false);
+ HandleGameObject(SimpleDoor, false);
+ }else
+ {
+ HandleGameObject(CouncilDoor, true);
+ HandleGameObject(SimpleDoor, true);
+ }
+ Encounters[7] = data; break;
+ case DATA_ILLIDANSTORMRAGEEVENT: Encounters[8] = data; break;
+ }
+
+ if (data == DONE)
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << Encounters[0] << " " << Encounters[1] << " "
+ << Encounters[2] << " " << Encounters[3] << " " << Encounters[4]
+ << " " << Encounters[5] << " " << Encounters[6] << " " << Encounters[7]
+ << " " << Encounters[8];
+
+ str_data = saveStream.str();
+
+ SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
+ }
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_HIGHWARLORDNAJENTUSEVENT: return Encounters[0];
+ case DATA_SUPREMUSEVENT: return Encounters[1];
+ case DATA_SHADEOFAKAMAEVENT: return Encounters[2];
+ case DATA_TERONGOREFIENDEVENT: return Encounters[3];
+ case DATA_GURTOGGBLOODBOILEVENT: return Encounters[4];
+ case DATA_RELIQUARYOFSOULSEVENT: return Encounters[5];
+ case DATA_MOTHERSHAHRAZEVENT: return Encounters[6];
+ case DATA_ILLIDARICOUNCILEVENT: return Encounters[7];
+ case DATA_ILLIDANSTORMRAGEEVENT: return Encounters[8];
+ }
+
+ return 0;
+ }
+
+ const char* Save()
+ {
+ return str_data.c_str();
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ std::istringstream loadStream(in);
+ loadStream >> Encounters[0] >> Encounters[1] >> Encounters[2]
+ >> Encounters[3] >> Encounters[4] >> Encounters[5] >> Encounters[6]
+ >> Encounters[7] >> Encounters[8];
+
+ for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ if (Encounters[i] == IN_PROGRESS)
+ Encounters[i] = NOT_STARTED;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_black_temple(Map* map)
+{
+ return new instance_black_temple(map);
+}
+
+void AddSC_instance_black_temple()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_black_temple";
+ newscript->GetInstanceData = &GetInstanceData_instance_black_temple;
+ 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 da9b20ef63e..738c58eab2e 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/black_temple.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/black_temple.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
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 656496c268f..e70f144d460 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_bloodboil.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_bloodboil.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -115,7 +115,7 @@ struct TRINITY_DLL_DECL boss_gurtogg_bloodboilAI : public ScriptedAI
m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, false);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoZoneInCombat();
DoScriptText(SAY_AGGRO, m_creature);
@@ -215,7 +215,7 @@ struct TRINITY_DLL_DECL boss_gurtogg_bloodboilAI : public ScriptedAI
FelAcidTimer = 25000;
}else FelAcidTimer -= diff;
- if(!m_creature->HasAura(SPELL_BERSERK, 0))
+ if(!m_creature->HasAura(SPELL_BERSERK))
{
if(EnrageTimer < diff)
{
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 4b0190c1dd5..7775f3e3e4d 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -137,6 +137,9 @@ EndScriptData */
#define FLAME_ENRAGE_DISTANCE 30
#define FLAME_CHARGE_DISTANCE 50
+#define EQUIP_ID_MAIN_HAND 32837
+#define EQUIP_ID_OFF_HAND 32838
+
/**** Creature Summon and Recognition IDs ****/
enum CreatureEntry
{
@@ -365,6 +368,10 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true);
+
+ SpellEntry *TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_SHADOWFIEND_PASSIVE);
+ if(TempSpell)
+ TempSpell->EffectApplyAuraName[0] = 4; // proc debuff, and summon infinite fiends
}
ScriptedInstance* pInstance;
@@ -422,7 +429,7 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI
Timer[EVENT_FLIGHT_SEQUENCE] = 1000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
m_creature->setActive(true);
DoZoneInCombat();
@@ -454,7 +461,7 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI
{
GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(i));
if(Door)
- Door->SetUInt32Value(GAMEOBJECT_STATE, 0); // Open Doors
+ Door->SetGoState(GO_STATE_ACTIVE); // Open Doors
}
}
@@ -487,10 +494,10 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI
{
if(spell->Id == SPELL_GLAIVE_RETURNS) // Re-equip our warblades!
{
- if(!m_creature->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY))
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479);
+ if(!m_creature->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID))
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 45479);
else
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 45481);
m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
}
}
@@ -524,7 +531,7 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI
if(Conversation[count].emote)
creature->HandleEmoteCommand(Conversation[count].emote); // Make the creature do some animation!
if(Conversation[count].text)
- creature->Yell(Conversation[count].text, LANG_UNIVERSAL, 0); // Have the creature yell out some text
+ creature->MonsterYell(Conversation[count].text, LANG_UNIVERSAL, 0); // Have the creature yell out some text
if(Conversation[count].sound)
DoPlaySoundToSet(creature, Conversation[count].sound); // Play some sound on the creature
}
@@ -541,7 +548,7 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI
{
case 1://lift off
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
- m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT);
+ m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING);
m_creature->StopMoving();
DoYell(SAY_TAKEOFF, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_TAKEOFF);
@@ -567,8 +574,8 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI
Timer[EVENT_FLIGHT_SEQUENCE] = 700;
break;
case 4://throw another
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
{
uint8 i=0;
Creature* Glaive = m_creature->SummonCreature(BLADE_OF_AZZINOTH, GlaivePosition[i].x, GlaivePosition[i].y, GlaivePosition[i].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
@@ -611,7 +618,7 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI
Timer[EVENT_FLIGHT_SEQUENCE] = 2000;
break;
case 9://land
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->StopMoving();
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
for(uint8 i = 0; i < 2; i++)
@@ -653,14 +660,14 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI
if(DemonTransformation[TransformCount].equip)
{
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); // Requip warglaives if needed
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 45479); // Requip warglaives if needed
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 45481);
m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
}
else
{
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); // Unequip warglaives if needed
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+0, 0); // Unequip warglaives if needed
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
}
switch(TransformCount)
@@ -741,7 +748,7 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI
if(m_creature->IsNonMeleeSpellCasted(false))
return;
- if(Phase == PHASE_NORMAL || Phase == PHASE_NORMAL_2 || Phase == PHASE_NORMAL_MAIEV && !m_creature->HasAura(SPELL_CAGED, 0))
+ if(Phase == PHASE_NORMAL || Phase == PHASE_NORMAL_2 || Phase == PHASE_NORMAL_MAIEV && !m_creature->HasAura(SPELL_CAGED))
{
switch(Event)
{
@@ -896,7 +903,7 @@ struct TRINITY_DLL_DECL flame_of_azzinothAI : public ScriptedAI
GlaiveGUID = 0;
}
- void Aggro(Unit *who) {DoZoneInCombat();}
+ void EnterCombat(Unit *who) {DoZoneInCombat();}
void ChargeCheck()
{
@@ -926,7 +933,7 @@ struct TRINITY_DLL_DECL flame_of_azzinothAI : public ScriptedAI
AttackStart(m_creature->getVictim());
}
}
- else if(!m_creature->HasAura(SPELL_AZZINOTH_CHANNEL, 0))
+ else if(!m_creature->HasAura(SPELL_AZZINOTH_CHANNEL))
{
Glaive->CastSpell(m_creature, SPELL_AZZINOTH_CHANNEL, false);
m_creature->RemoveAurasDueToSpell(SPELL_FLAME_ENRAGE);
@@ -998,10 +1005,10 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI
DoorGUID[1] = pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_DOOR_L);
if(GETGO(Gate, GateGUID))
- Gate->SetUInt32Value(GAMEOBJECT_STATE, 1);
+ Gate->SetGoState(GO_STATE_READY);
for(uint8 i = 0; i < 2; i++)
if(GETGO(Door, DoorGUID[i]))
- Door->SetUInt32Value(GAMEOBJECT_STATE, 1);
+ Door->SetGoState(GO_STATE_READY);
}
else
{
@@ -1036,10 +1043,9 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI
m_creature->RemoveAllAuras();
m_creature->DeleteThreatList();
m_creature->CombatStop();
- InCombat = false;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void MoveInLineOfSight(Unit *) {}
void MovementInform(uint32 MovementType, uint32 Data) {Timer = 1;}
@@ -1071,7 +1077,7 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI
for(uint8 i = 0; i < 2; i++)
if(GETGO(Door, DoorGUID[i]))
- Door->SetUInt32Value(GAMEOBJECT_STATE, 1);
+ Door->SetGoState(GO_STATE_READY);
if(GETCRE(Illidan, IllidanGUID))
{
@@ -1186,7 +1192,7 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI
if(GETCRE(Illidan, IllidanGUID))
{
((boss_illidan_stormrageAI*)Illidan->AI())->Timer[EVENT_TAUNT] += 30000;
- Illidan->Yell(SAY_AKAMA_MINION, LANG_UNIVERSAL, 0);
+ Illidan->MonsterYell(SAY_AKAMA_MINION, LANG_UNIVERSAL, 0);
DoPlaySoundToSet(Illidan, SOUND_AKAMA_MINION);
}
Timer = 8000;
@@ -1237,7 +1243,7 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI
Spirit[0]->InterruptNonMeleeSpells(true);
Spirit[1]->InterruptNonMeleeSpells(true);
if(GETGO(Gate, GateGUID))
- Gate->SetUInt32Value(GAMEOBJECT_STATE, 0);
+ Gate->SetGoState(GO_STATE_ACTIVE);
Timer = 2000;
break;
case 4:
@@ -1268,7 +1274,7 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI
case 6:
for(uint8 i = 0; i < 2; i++)
if(GETGO(Door, DoorGUID[i]))
- Door->SetUInt32Value(GAMEOBJECT_STATE, 0);
+ Door->SetGoState(GO_STATE_ACTIVE);
break;
case 8:
if(Phase == PHASE_WALK)
@@ -1378,12 +1384,12 @@ struct TRINITY_DLL_DECL boss_maievAI : public ScriptedAI
Timer[EVENT_MAIEV_STEALTH] = 0;
Timer[EVENT_MAIEV_TAUNT] = 22000 + rand()%21 * 1000;
Timer[EVENT_MAIEV_SHADOW_STRIKE] = 30000;
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 44850);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 2, 45738);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 44850);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, 45738);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void MoveInLineOfSight(Unit *who) {}
void EnterEvadeMode() {}
void GetIllidanGUID(uint64 guid) { IllidanGUID = guid; }
@@ -1607,7 +1613,7 @@ struct TRINITY_DLL_DECL cage_trap_triggerAI : public ScriptedAI
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
- void Aggro(Unit *who){}
+ void EnterCombat(Unit *who){}
void MoveInLineOfSight(Unit *who)
{
@@ -1618,12 +1624,12 @@ struct TRINITY_DLL_DECL cage_trap_triggerAI : public ScriptedAI
{
if(who->GetEntry() == ILLIDAN_STORMRAGE) // Check if who is Illidan
{
- if(!IllidanGUID && m_creature->IsWithinDistInMap(who, 3) && (!who->HasAura(SPELL_CAGED, 0)))
+ if(!IllidanGUID && m_creature->IsWithinDistInMap(who, 3) && (!who->HasAura(SPELL_CAGED)))
{
IllidanGUID = who->GetGUID();
who->CastSpell(who, SPELL_CAGED, true);
DespawnTimer = 5000;
- if(who->HasAura(SPELL_ENRAGE, 0))
+ if(who->HasAura(SPELL_ENRAGE))
who->RemoveAurasDueToSpell(SPELL_ENRAGE); // Dispel his enrage
//if(GameObject* CageTrap = GameObject::GetGameObject(*m_creature, CageTrapGUID))
// CageTrap->SetLootState(GO_JUST_DEACTIVATED);
@@ -1663,7 +1669,7 @@ bool GOHello_cage_trap(Player* plr, GameObject* go)
// Grid search for nearest live creature of entry 23304 within 10 yards
Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck check(*plr, 23304, true, 10);
- Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(trigger, check);
+ Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(plr, trigger, check);
TypeContainerVisitor<Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer> cSearcher(searcher);
@@ -1671,7 +1677,7 @@ bool GOHello_cage_trap(Player* plr, GameObject* go)
cell_lock->Visit(cell_lock, cSearcher, *(plr->GetMap()));
((cage_trap_triggerAI*)trigger->AI())->Active = true;
- go->SetUInt32Value(GAMEOBJECT_STATE, 0);
+ go->SetGoState(GO_STATE_ACTIVE);
return true;
}
@@ -1681,7 +1687,7 @@ struct TRINITY_DLL_DECL shadow_demonAI : public ScriptedAI
uint64 TargetGUID;
- void Aggro(Unit *who) {DoZoneInCombat();}
+ void EnterCombat(Unit *who) {DoZoneInCombat();}
void Reset()
{
@@ -1701,7 +1707,7 @@ struct TRINITY_DLL_DECL shadow_demonAI : public ScriptedAI
if(m_creature->getVictim()->GetTypeId() != TYPEID_PLAYER) return; // Only cast the below on players.
- if(!m_creature->getVictim()->HasAura(SPELL_PARALYZE, 0))
+ if(!m_creature->getVictim()->HasAura(SPELL_PARALYZE))
{
TargetGUID = m_creature->getVictim()->GetGUID();
m_creature->AddThreat(m_creature->getVictim(), 10000000.0f);
@@ -1737,14 +1743,14 @@ struct TRINITY_DLL_DECL mob_parasitic_shadowfiendAI : public ScriptedAI
DoCast(m_creature, SPELL_SHADOWFIEND_PASSIVE, true);
}
- void Aggro(Unit* who) { DoZoneInCombat(); }
+ void EnterCombat(Unit* who) { DoZoneInCombat(); }
void DoMeleeAttackIfReady()
{
if( m_creature->isAttackReady() && m_creature->IsWithinMeleeRange(m_creature->getVictim()))
{
- if(!m_creature->getVictim()->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0)
- && !m_creature->getVictim()->HasAura(SPELL_PARASITIC_SHADOWFIEND2, 0))
+ if(!m_creature->getVictim()->HasAura(SPELL_PARASITIC_SHADOWFIEND)
+ && !m_creature->getVictim()->HasAura(SPELL_PARASITIC_SHADOWFIEND2))
{
m_creature->CastSpell(m_creature->getVictim(), SPELL_PARASITIC_SHADOWFIEND2, true, 0, 0, IllidanGUID); //do not stack
}
@@ -1834,9 +1840,9 @@ void boss_illidan_stormrageAI::Reset()
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->setActive(false);
Summons.DespawnAll();
}
@@ -1855,8 +1861,8 @@ void boss_illidan_stormrageAI::JustSummoned(Creature* summon)
return;
}
Unit *target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0, 999, true);
- if(!target || target->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0)
- || target->HasAura(SPELL_PARASITIC_SHADOWFIEND2, 0))
+ if(!target || target->HasAura(SPELL_PARASITIC_SHADOWFIEND)
+ || target->HasAura(SPELL_PARASITIC_SHADOWFIEND2))
target = SelectUnit(SELECT_TARGET_RANDOM, 0, 999, true);
if(target)
summon->AI()->AttackStart(target);
@@ -1892,8 +1898,8 @@ void boss_illidan_stormrageAI::HandleTalkSequence()
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
break;
case 8:
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); // Equip our warglaives!
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 45479); // Equip our warglaives!
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 45481);
m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
break;
@@ -1953,7 +1959,7 @@ void boss_illidan_stormrageAI::HandleTalkSequence()
{
Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true);
Maiev->setDeathState(JUST_DIED);
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,PLAYER_STATE_DEAD);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,UNIT_STAND_STATE_DEAD);
}
break;
case 21: // Kill ourself.
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 4b63b092c53..0321ea6d9ad 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -123,7 +123,7 @@ struct TRINITY_DLL_DECL boss_shahrazAI : public ScriptedAI
Enraged = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
pInstance->SetData(DATA_MOTHERSHAHRAZEVENT, IN_PROGRESS);
@@ -276,7 +276,7 @@ struct TRINITY_DLL_DECL boss_shahrazAI : public ScriptedAI
}else SaberTimer -= diff;
//Enrage
- if(!m_creature->HasAura(SPELL_BERSERK, 0))
+ if(!m_creature->HasAura(SPELL_BERSERK))
if(EnrageTimer < diff)
{
DoCast(m_creature, SPELL_BERSERK);
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 fb4d97780ed..04e01a94e69 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -107,7 +107,7 @@ struct TRINITY_DLL_DECL npc_enslaved_soulAI : public ScriptedAI
void Reset() {ReliquaryGUID = 0;}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
m_creature->CastSpell(m_creature, ENSLAVED_SOUL_PASSIVE, true);
DoZoneInCombat();
@@ -157,7 +157,7 @@ struct TRINITY_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI
m_creature->RemoveAurasDueToSpell(SPELL_SUBMERGE);
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
m_creature->AddThreat(who, 10000.0f);
DoZoneInCombat();
@@ -169,15 +169,6 @@ struct TRINITY_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI
Timer = 0;
}
- void AttackStart(Unit* who)
- {
- if (!InCombat)
- {
- Aggro(who);
- InCombat = true;
- }
- }
-
bool SummonSoul()
{
uint32 random = rand()%6;
@@ -197,8 +188,6 @@ struct TRINITY_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI
{
if(pInstance)
pInstance->SetData(DATA_RELIQUARYOFSOULSEVENT, DONE);
-
- InCombat = false;
}
void UpdateAI(const uint32 diff)
@@ -361,7 +350,7 @@ struct TRINITY_DLL_DECL boss_essence_of_sufferingAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SUFF_SAY_FREED, m_creature);
DoZoneInCombat();
@@ -405,7 +394,7 @@ struct TRINITY_DLL_DECL boss_essence_of_sufferingAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
- if(InCombat)
+ if(m_creature->isInCombat())
{
//Supposed to be cast on nearest target
if(FixateTimer < diff)
@@ -484,7 +473,7 @@ struct TRINITY_DLL_DECL boss_essence_of_desireAI : public ScriptedAI
m_creature->InterruptSpell(CURRENT_GENERIC_SPELL, false);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(DESI_SAY_FREED, m_creature);
DoZoneInCombat();
@@ -563,7 +552,7 @@ struct TRINITY_DLL_DECL boss_essence_of_angerAI : public ScriptedAI
CheckedAggro = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%2)
{
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 8dc8ca344dd..df535d2528c 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -113,7 +113,7 @@ struct TRINITY_DLL_DECL mob_ashtongue_channelerAI : public ScriptedAI
void Reset() { ShadeGUID = 0; }
void JustDied(Unit* killer);
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff) {}
@@ -135,7 +135,7 @@ struct TRINITY_DLL_DECL mob_ashtongue_sorcererAI : public ScriptedAI
}
void JustDied(Unit* killer);
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff)
@@ -274,8 +274,6 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
}
}
- void Aggro(Unit* who) { }
-
void AttackStart(Unit* who)
{
if(!who || IsBanished) return;
@@ -291,7 +289,7 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
debug_log("TSCR: Increasing Death Count for Shade of Akama encounter");
++DeathCount;
- m_creature->RemoveSingleAuraFromStack(SPELL_SHADE_SOUL_CHANNEL_2, 0);
+ m_creature->RemoveAuraFromStack(SPELL_SHADE_SOUL_CHANNEL_2);
if(guid)
{
if(Sorcerers.empty())
@@ -346,7 +344,7 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
std::list<Creature*> ChannelerList;
Trinity::AllCreaturesOfEntryInRange check(m_creature, CREATURE_CHANNELER, 50);
- Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(ChannelerList, check);
+ Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(m_creature, ChannelerList, check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> visitor(searcher);
CellLock<GridReadGuard> cell_lock(cell, pair);
@@ -381,7 +379,7 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
- if(!InCombat)
+ if(!m_creature->isInCombat())
return;
if(IsBanished)
@@ -555,7 +553,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
}
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void BeginEvent(Player* pl)
{
@@ -574,8 +572,8 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
((boss_shade_of_akamaAI*)Shade->AI())->SetAkamaGUID(m_creature->GetGUID());
((boss_shade_of_akamaAI*)Shade->AI())->SetSelectableChannelers();
- ((boss_shade_of_akamaAI*)Shade->AI())->InCombat = true;
Shade->AddThreat(m_creature, 1000000.0f);
+ m_creature->CombatStart(Shade);
Shade->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
Shade->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
if(pl) Shade->AddThreat(pl, 1.0f);
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 994f3d500ad..a479b7c162b 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp
@@ -39,6 +39,18 @@ EndScriptData */
#define CREATURE_VOLCANO 23085
#define CREATURE_STALKER 23095
+#define PHASE_STRIKE 1
+#define PHASE_CHASE 2
+
+#define EVENT_BERSERK 1
+#define EVENT_SWITCH_PHASE 2
+#define EVENT_FLAME 3
+#define EVENT_VOLCANO 4
+#define EVENT_SWITCH_TARGET 5
+#define EVENT_HATEFUL_STRIKE 6
+
+#define GCD_CAST 1
+
struct TRINITY_DLL_DECL molten_flameAI : public NullCreatureAI
{
molten_flameAI(Creature *c) : NullCreatureAI(c)
@@ -57,17 +69,9 @@ struct TRINITY_DLL_DECL boss_supremusAI : public ScriptedAI
}
ScriptedInstance* pInstance;
-
- uint32 SummonFlameTimer;
- uint32 SwitchTargetTimer;
- uint32 PhaseSwitchTimer;
- uint32 SummonVolcanoTimer;
- uint32 HatefulStrikeTimer;
- uint32 BerserkTimer;
-
- bool Phase1;
-
+ EventMap events;
SummonList summons;
+ uint32 phase;
void Reset()
{
@@ -81,35 +85,55 @@ struct TRINITY_DLL_DECL boss_supremusAI : public ScriptedAI
//else ToggleDoors(false);
}
- HatefulStrikeTimer = 5000;
- SummonFlameTimer = 20000;
- SwitchTargetTimer = 90000;
- PhaseSwitchTimer = 60000;
- SummonVolcanoTimer = 5000;
- BerserkTimer = 900000; // 15 minute enrage
+ phase = 0;
- Phase1 = true;
+ events.Reset();
summons.DespawnAll();
-
- m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
- m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, false);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
- DoZoneInCombat();
-
if(pInstance)
pInstance->SetData(DATA_SUPREMUSEVENT, IN_PROGRESS);
+
+ ChangePhase();
+ events.ScheduleEvent(EVENT_BERSERK, 900000, GCD_CAST);
+ events.ScheduleEvent(EVENT_FLAME, 20000, GCD_CAST);
}
void ToggleDoors(bool close)
{
if(GameObject* Doors = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_GAMEOBJECT_SUPREMUS_DOORS)))
{
- if(close) Doors->SetGoState(1); // Closed
- else Doors->SetGoState(0); // Open
+ if(close) Doors->SetGoState(GO_STATE_READY); // Closed
+ else Doors->SetGoState(GO_STATE_ACTIVE); // Open
+ }
+ }
+
+ void ChangePhase()
+ {
+ if(!phase || phase == PHASE_CHASE)
+ {
+ phase = PHASE_STRIKE;
+ summons.DoAction(EVENT_VOLCANO, 0);
+ events.ScheduleEvent(EVENT_HATEFUL_STRIKE, 5000, GCD_CAST, PHASE_STRIKE);
+ m_creature->SetSpeed(MOVE_RUN, 1.2f);
+ m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
+ m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, false);
+ }
+ else
+ {
+ phase = PHASE_CHASE;
+ events.ScheduleEvent(EVENT_VOLCANO, 5000, GCD_CAST, PHASE_CHASE);
+ events.ScheduleEvent(EVENT_SWITCH_TARGET, 10000, 0, PHASE_CHASE);
+ m_creature->SetSpeed(MOVE_RUN, 0.9f);
+ m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
+ m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
}
+ DoResetThreat();
+ DoZoneInCombat();
+ events.SetPhase(phase);
+ events.ScheduleEvent(EVENT_SWITCH_PHASE, 60000, GCD_CAST);
}
void JustDied(Unit *killer)
@@ -153,83 +177,53 @@ struct TRINITY_DLL_DECL boss_supremusAI : public ScriptedAI
if (!UpdateVictim())
return;
- if(!m_creature->HasAura(SPELL_BERSERK, 0))
- {
- if(BerserkTimer < diff)
- DoCast(m_creature, SPELL_BERSERK);
- else BerserkTimer -= diff;
- }
-
- if(SummonFlameTimer < diff)
- {
- DoCast(m_creature, SPELL_MOLTEN_PUNCH);
- SummonFlameTimer = 20000;
- }else SummonFlameTimer -= diff;
-
- if(Phase1)
- {
- if(HatefulStrikeTimer < diff)
- {
- if(Unit* target = CalculateHatefulStrikeTarget())
- {
- DoCast(target, SPELL_HATEFUL_STRIKE);
- HatefulStrikeTimer = 5000;
- }
- }else HatefulStrikeTimer -= diff;
- }
+ events.Update(diff);
- if(!Phase1)
+ while(uint32 eventId = events.ExecuteEvent())
{
- if(SwitchTargetTimer < diff)
+ switch(eventId)
{
- if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1, 100, true))
+ case EVENT_BERSERK:
+ m_creature->CastSpell(m_creature, SPELL_BERSERK, true);
+ break;
+ case EVENT_FLAME:
+ DoCast(m_creature, SPELL_MOLTEN_PUNCH);
+ events.DelayEvents(1500, GCD_CAST);
+ events.ScheduleEvent(EVENT_FLAME, 20000, GCD_CAST);
+ break;
+ case EVENT_HATEFUL_STRIKE:
+ if(Unit* target = CalculateHatefulStrikeTarget())
+ DoCast(target, SPELL_HATEFUL_STRIKE);
+ events.DelayEvents(1000, GCD_CAST);
+ events.ScheduleEvent(EVENT_HATEFUL_STRIKE, 5000, GCD_CAST, PHASE_STRIKE);
+ break;
+ case EVENT_SWITCH_TARGET:
+ if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1, 100, true))
+ {
+ DoResetThreat();
+ m_creature->AddThreat(target, 5000000.0f);
+ DoScriptText(EMOTE_NEW_TARGET, m_creature);
+ }
+ events.ScheduleEvent(EVENT_SWITCH_TARGET, 10000, 0, PHASE_CHASE);
+ break;
+ case EVENT_VOLCANO:
{
- DoResetThreat();
- m_creature->AddThreat(target, 5000000.0f);
- DoScriptText(EMOTE_NEW_TARGET, m_creature);
- SwitchTargetTimer = 10000;
+ Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 999, true);
+ if(!target) target = m_creature->getVictim();
+ if(target)
+ {
+ DoCast(target, SPELL_VOLCANIC_SUMMON);
+ DoScriptText(EMOTE_GROUND_CRACK, m_creature);
+ events.DelayEvents(1500, GCD_CAST);
+ }
+ events.ScheduleEvent(EVENT_VOLCANO, 10000, GCD_CAST, PHASE_CHASE);
+ return;
}
- }else SwitchTargetTimer -= diff;
-
- if(SummonVolcanoTimer < diff)
- {
- if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 999, true))
- {
- if(!target)
- target = m_creature->getVictim();
-
- DoCast(target, SPELL_VOLCANIC_SUMMON);
- DoScriptText(EMOTE_GROUND_CRACK, m_creature);
- SummonVolcanoTimer = 10000;
- }
- }else SummonVolcanoTimer -= diff;
- }
-
- if(PhaseSwitchTimer < diff)
- {
- if(!Phase1)
- {
- Phase1 = true;
- DoResetThreat();
- PhaseSwitchTimer = 60000;
- m_creature->SetSpeed(MOVE_RUN, 1.2f);
- DoZoneInCombat();
- m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
- m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, false);
- }
- else
- {
- Phase1 = false;
- DoResetThreat();
- SwitchTargetTimer = 10000;
- SummonVolcanoTimer = 2000;
- PhaseSwitchTimer = 60000;
- m_creature->SetSpeed(MOVE_RUN, 0.9f);
- DoZoneInCombat();
- m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
- m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
+ case EVENT_SWITCH_PHASE:
+ ChangePhase();
+ break;
}
- }else PhaseSwitchTimer -= diff;
+ }
DoMeleeAttackIfReady();
}
@@ -237,50 +231,25 @@ struct TRINITY_DLL_DECL boss_supremusAI : public ScriptedAI
struct TRINITY_DLL_DECL npc_volcanoAI : public ScriptedAI
{
- npc_volcanoAI(Creature *c) : ScriptedAI(c)
- {
- pInstance = ((ScriptedInstance*)c->GetInstanceData());
- }
-
- ScriptedInstance *pInstance;
-
- uint32 CheckTimer;
- bool Eruption;
+ npc_volcanoAI(Creature *c) : ScriptedAI(c) {}
void Reset()
{
- CheckTimer = 1500;
- Eruption = false;
-
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(m_creature, SPELL_VOLCANIC_ERUPTION);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
- void MoveInLineOfSight(Unit *who)
- {
- return; // paralyze the npc
- }
+ void MoveInLineOfSight(Unit *who) {}
- void UpdateAI(const uint32 diff)
+ void DoAction(const uint32 info)
{
- if(CheckTimer < diff)
- {
- uint64 SupremusGUID = pInstance->GetData64(DATA_SUPREMUS);
- Creature* Supremus = (Unit::GetCreature((*m_creature), SupremusGUID));
- if(!Eruption && !((boss_supremusAI*)Supremus->AI())->Phase1)
- {
- Eruption = true;
- DoCast(m_creature, SPELL_VOLCANIC_ERUPTION);
- }
- else if(Eruption && ((boss_supremusAI*)Supremus->AI())->Phase1)
- {
- m_creature->RemoveAura(SPELL_VOLCANIC_ERUPTION, 0);
- }
- CheckTimer = 1500;
- }else CheckTimer -= diff;
+ m_creature->RemoveAura(SPELL_VOLCANIC_ERUPTION);
}
+
+ void UpdateAI(const uint32 diff) {}
};
CreatureAI* GetAI_boss_supremus(Creature *_Creature)
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 a1800a4a951..72fc69d9378 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -64,7 +64,7 @@ struct TRINITY_DLL_DECL mob_doom_blossomAI : public ScriptedAI
TeronGUID = 0;
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void AttackStart(Unit* who) { }
void MoveInLineOfSight(Unit* who) { }
@@ -90,9 +90,9 @@ struct TRINITY_DLL_DECL mob_doom_blossomAI : public ScriptedAI
Despawn();
CheckTeronTimer = 5000;
- }else CheckTeronTimer -= diff;
+ }else CheckTeronTimer -= diff;
- if(ShadowBoltTimer < diff && InCombat)
+ if(ShadowBoltTimer < diff && m_creature->isInCombat())
{
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_SHADOWBOLT);
ShadowBoltTimer = 10000;
@@ -134,7 +134,7 @@ struct TRINITY_DLL_DECL mob_shadowy_constructAI : public ScriptedAI
CheckTeronTimer = 5000;
}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void MoveInLineOfSight(Unit *who)
{
@@ -237,7 +237,7 @@ struct TRINITY_DLL_DECL boss_teron_gorefiendAI : public ScriptedAI
Intro = false;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void MoveInLineOfSight(Unit *who)
{
@@ -255,7 +255,7 @@ struct TRINITY_DLL_DECL boss_teron_gorefiendAI : public ScriptedAI
m_creature->AddThreat(who, 1.0f);
}
- if(!InCombat && !Intro && m_creature->IsWithinDistInMap(who, 60.0f) && (who->GetTypeId() == TYPEID_PLAYER))
+ if(!m_creature->isInCombat() && !Intro && m_creature->IsWithinDistInMap(who, 60.0f) && (who->GetTypeId() == TYPEID_PLAYER))
{
if(pInstance)
pInstance->SetData(DATA_TERONGOREFIENDEVENT, IN_PROGRESS);
@@ -331,7 +331,7 @@ struct TRINITY_DLL_DECL boss_teron_gorefiendAI : public ScriptedAI
Unit* Ghost = NULL;
if(GhostGUID)
Ghost = Unit::GetUnit((*m_creature), GhostGUID);
- if(Ghost && Ghost->isAlive() && Ghost->HasAura(SPELL_SHADOW_OF_DEATH, 0))
+ if(Ghost && Ghost->isAlive() && Ghost->HasAura(SPELL_SHADOW_OF_DEATH))
{
/*float x,y,z;
Ghost->GetPosition(x,y,z);
@@ -427,7 +427,7 @@ struct TRINITY_DLL_DECL boss_teron_gorefiendAI : public ScriptedAI
DoomBlossom->setFaction(m_creature->getFaction());
DoomBlossom->AddThreat(target, 1.0f);
((mob_doom_blossomAI*)DoomBlossom->AI())->SetTeronGUID(m_creature->GetGUID());
- ((mob_doom_blossomAI*)DoomBlossom->AI())->InCombat = true;
+ target->CombatStart(DoomBlossom);
SetThreatList(DoomBlossom);
SummonDoomBlossomTimer = 35000;
}
@@ -487,7 +487,7 @@ struct TRINITY_DLL_DECL boss_teron_gorefiendAI : public ScriptedAI
RandomYellTimer = 50000 + rand()%51 * 1000;
}else RandomYellTimer -= diff;
- if(!m_creature->HasAura(SPELL_BERSERK, 0))
+ if(!m_creature->HasAura(SPELL_BERSERK))
{
if(EnrageTimer < diff)
{
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 538c94decf2..7d6b7140a9d 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -46,6 +46,15 @@ EndScriptData */
#define GOBJECT_SPINE 185584
+#define EVENT_BERSERK 1
+#define EVENT_YELL 2
+#define EVENT_NEEDLE 3
+#define EVENT_SPINE 4
+#define EVENT_SHIELD 5
+
+#define GCD_CAST 1
+#define GCD_YELL 2
+
struct TRINITY_DLL_DECL boss_najentusAI : public ScriptedAI
{
boss_najentusAI(Creature *c) : ScriptedAI(c)
@@ -54,21 +63,13 @@ struct TRINITY_DLL_DECL boss_najentusAI : public ScriptedAI
}
ScriptedInstance* pInstance;
-
- uint32 NeedleSpineTimer;
- uint32 EnrageTimer;
- uint32 SpecialYellTimer;
- uint32 TidalShieldTimer;
- uint32 ImpalingSpineTimer;
+ EventMap events;
uint64 SpineTargetGUID;
void Reset()
{
- EnrageTimer = 480000;
- SpecialYellTimer = 45000 + (rand()%76)*1000;
-
- ResetTimer();
+ events.Reset();
SpineTargetGUID = 0;
@@ -78,11 +79,8 @@ struct TRINITY_DLL_DECL boss_najentusAI : public ScriptedAI
void KilledUnit(Unit *victim)
{
- switch(rand()%2)
- {
- case 0: DoScriptText(SAY_SLAY1, m_creature); break;
- case 1: DoScriptText(SAY_SLAY2, m_creature); break;
- }
+ DoScriptText(rand()%2 ? SAY_SLAY1 : SAY_SLAY2, m_creature);
+ events.DelayEvents(5000, GCD_YELL);
}
void JustDied(Unit *victim)
@@ -95,7 +93,7 @@ struct TRINITY_DLL_DECL boss_najentusAI : public ScriptedAI
void SpellHit(Unit *caster, const SpellEntry *spell)
{
- if(spell->Id == SPELL_HURL_SPINE && m_creature->HasAura(SPELL_TIDAL_SHIELD, 0))
+ if(spell->Id == SPELL_HURL_SPINE && m_creature->HasAura(SPELL_TIDAL_SHIELD))
{
m_creature->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD);
m_creature->CastSpell(m_creature, SPELL_TIDAL_BURST, true);
@@ -103,20 +101,23 @@ struct TRINITY_DLL_DECL boss_najentusAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, IN_PROGRESS);
DoScriptText(SAY_AGGRO, m_creature);
DoZoneInCombat();
+ events.ScheduleEvent(EVENT_BERSERK, 480000, GCD_CAST);
+ events.ScheduleEvent(EVENT_YELL, 45000 + (rand()%76)*1000, GCD_YELL);
+ ResetTimer();
}
bool RemoveImpalingSpine()
{
if(!SpineTargetGUID) return false;
Unit* target = Unit::GetUnit(*m_creature, SpineTargetGUID);
- if(target && target->HasAura(SPELL_IMPALING_SPINE, 1))
+ if(target && target->HasAura(SPELL_IMPALING_SPINE))
target->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE);
SpineTargetGUID=0;
return true;
@@ -124,9 +125,9 @@ struct TRINITY_DLL_DECL boss_najentusAI : public ScriptedAI
void ResetTimer(uint32 inc = 0)
{
- NeedleSpineTimer = 10000 + inc;
- TidalShieldTimer = 60000 + inc;
- ImpalingSpineTimer = 20000 + inc;
+ events.ScheduleEvent(EVENT_NEEDLE, 10000 + inc, GCD_CAST);
+ events.ScheduleEvent(EVENT_SPINE, 20000 + inc, GCD_CAST);
+ events.ScheduleEvent(EVENT_SHIELD, 60000 + inc);
}
void UpdateAI(const uint32 diff)
@@ -134,58 +135,56 @@ struct TRINITY_DLL_DECL boss_najentusAI : public ScriptedAI
if (!UpdateVictim())
return;
- if(TidalShieldTimer < diff)
- {
- m_creature->CastSpell(m_creature, SPELL_TIDAL_SHIELD, true);
- ResetTimer(45000);
- }else TidalShieldTimer -= diff;
-
- if(EnrageTimer < diff)
- {
- DoScriptText(SAY_ENRAGE2, m_creature);
- m_creature->CastSpell(m_creature, SPELL_BERSERK, true);
- EnrageTimer = 600000;
- }else EnrageTimer -= diff;
-
- if(NeedleSpineTimer < diff)
- {
- //m_creature->CastSpell(m_creature, SPELL_NEEDLE_SPINE, true);
- std::list<Unit*> target;
- SelectUnitList(target, 3, SELECT_TARGET_RANDOM, 80, true);
- for(std::list<Unit*>::iterator i = target.begin(); i != target.end(); ++i)
- m_creature->CastSpell(*i, 39835, true);
- NeedleSpineTimer = 20000+rand()%5000;
- }else NeedleSpineTimer -= diff;
-
- if(SpecialYellTimer < diff)
- {
- switch(rand()%2)
- {
- case 0: DoScriptText(SAY_SPECIAL1, m_creature); break;
- case 1: DoScriptText(SAY_SPECIAL2, m_creature); break;
- }
- SpecialYellTimer = 25000 + (rand()%76)*1000;
- }else SpecialYellTimer -= diff;
+ events.Update(diff);
- if(ImpalingSpineTimer < diff)
+ while(uint32 eventId = events.ExecuteEvent())
{
- Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
- if(!target) target = m_creature->getVictim();
- if(target)
+ switch(eventId)
{
- m_creature->CastSpell(target, SPELL_IMPALING_SPINE, true);
- SpineTargetGUID = target->GetGUID();
- //must let target summon, otherwise you cannot click the spine
- target->SummonGameObject(GOBJECT_SPINE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), m_creature->GetOrientation(), 0, 0, 0, 0, 30);
-
- switch(rand()%2)
+ case EVENT_SHIELD:
+ m_creature->CastSpell(m_creature, SPELL_TIDAL_SHIELD, true);
+ ResetTimer(45000);
+ break;
+ case EVENT_BERSERK:
+ DoScriptText(SAY_ENRAGE2, m_creature);
+ m_creature->CastSpell(m_creature, SPELL_BERSERK, true);
+ events.DelayEvents(15000, GCD_YELL);
+ break;
+ case EVENT_SPINE:
{
- case 0: DoScriptText(SAY_NEEDLE1, m_creature); break;
- case 1: DoScriptText(SAY_NEEDLE2, m_creature); break;
+ Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
+ if(!target) target = m_creature->getVictim();
+ if(target)
+ {
+ m_creature->CastSpell(target, SPELL_IMPALING_SPINE, true);
+ SpineTargetGUID = target->GetGUID();
+ //must let target summon, otherwise you cannot click the spine
+ target->SummonGameObject(GOBJECT_SPINE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), m_creature->GetOrientation(), 0, 0, 0, 0, 30);
+ DoScriptText(rand()%2 ? SAY_NEEDLE1 : SAY_NEEDLE2, m_creature);
+ events.DelayEvents(1500, GCD_CAST);
+ events.DelayEvents(15000, GCD_YELL);
+ }
+ events.ScheduleEvent(EVENT_SPINE, 21000, GCD_CAST);
+ return;
}
- ImpalingSpineTimer = 21000;
+ case EVENT_NEEDLE:
+ {
+ //m_creature->CastSpell(m_creature, SPELL_NEEDLE_SPINE, true);
+ std::list<Unit*> target;
+ SelectUnitList(target, 3, SELECT_TARGET_RANDOM, 80, true);
+ for(std::list<Unit*>::iterator i = target.begin(); i != target.end(); ++i)
+ m_creature->CastSpell(*i, 39835, true);
+ events.ScheduleEvent(EVENT_NEEDLE, 15000+rand()%10000, GCD_CAST);
+ events.DelayEvents(1500, GCD_CAST);
+ return;
+ }
+ case EVENT_YELL:
+ DoScriptText(rand()%2 ? SAY_SPECIAL1 : SAY_SPECIAL2, m_creature);
+ events.ScheduleEvent(EVENT_YELL, 25000 + (rand()%76)*1000, GCD_YELL);
+ events.DelayEvents(15000, GCD_YELL);
+ break;
}
- }else ImpalingSpineTimer -= diff;
+ }
DoMeleeAttackIfReady();
}
@@ -199,7 +198,7 @@ bool GOHello_go_najentus_spine(Player *player, GameObject* _GO)
{
player->CastSpell(player, SPELL_CREATE_NAJENTUS_SPINE, true);
_GO->SetLootState(GO_NOT_READY);
- _GO->SetRespawnTime(0);
+ _GO->Delete();
}
return true;
}
diff --git a/src/bindings/scripts/scripts/zone/black_temple/def_black_temple.h b/src/bindings/scripts/scripts/zone/black_temple/def_black_temple.h
index 0d5bb184792..4779f92fa4d 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/def_black_temple.h
+++ b/src/bindings/scripts/scripts/zone/black_temple/def_black_temple.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
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 bbf1c600f59..08f6bb335f2 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/illidari_council.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/illidari_council.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -144,7 +144,7 @@ struct TRINITY_DLL_DECL mob_blood_elf_council_voice_triggerAI : public ScriptedA
}else error_log(ERROR_INST_DATA);
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
@@ -243,7 +243,7 @@ struct TRINITY_DLL_DECL mob_illidari_councilAI : public ScriptedAI
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
@@ -360,7 +360,7 @@ struct TRINITY_DLL_DECL boss_illidari_councilAI : public ScriptedAI
bool LoadedGUIDs;
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
if(pInstance)
{
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 80a749faa12..43646746505 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -42,6 +42,9 @@ struct TRINITY_DLL_DECL instance_black_temple : public ScriptedInstance
{
instance_black_temple(Map *map) : ScriptedInstance(map) {Initialize();};
+ uint32 Encounters[ENCOUNTERS];
+ std::string str_data;
+
uint64 Najentus;
uint64 Akama; // This is the Akama that starts the Illidan encounter.
uint64 Akama_Shade; // This is the Akama that starts the Shade of Akama encounter.
@@ -68,9 +71,6 @@ struct TRINITY_DLL_DECL instance_black_temple : public ScriptedInstance
uint64 IllidanGate;
uint64 IllidanDoor[2];
- uint32 Encounters[ENCOUNTERS];
- std::string str_data;
-
void Initialize()
{
Najentus = 0;
@@ -131,7 +131,7 @@ struct TRINITY_DLL_DECL instance_black_temple : public ScriptedInstance
void OnCreatureCreate(Creature *creature, uint32 creature_entry)
{
- switch(creature_entry)
+ switch(creature->GetEntry())
{
case 22887: Najentus = creature->GetGUID(); break;
case 23089: Akama = creature->GetGUID(); break;
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 7ad8ccaca9b..592e0aa52a4 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/blackrock_depths.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/blackrock_depths.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -65,16 +65,6 @@ uint32 RingBoss[]=
9032, // Hedrum
};
-float RingLocations[6][3]=
-{
- {604.802673, -191.081985, -54.058590}, // ring
- {604.072998, -222.106918, -52.743759}, // first gate
- {621.400391, -214.499054, -52.814453}, // hiding in corner
- {601.300781, -198.556992, -53.950256}, // ring
- {631.818359, -180.548126, -52.654770}, // second gate
- {627.390381, -201.075974, -52.692917} // hiding in corner
-};
-
bool AreaTrigger_at_ring_of_law(Player *player, AreaTriggerEntry *at)
{
ScriptedInstance* pInstance = ((ScriptedInstance*)player->GetInstanceData());
@@ -137,16 +127,6 @@ struct TRINITY_DLL_DECL npc_grimstoneAI : public npc_escortAI
CanWalk = false;
}
- void Aggro(Unit *who) { }
-
- void DoGate(uint32 id, uint32 state)
- {
- if (GameObject *go = GameObject::GetGameObject(*m_creature,pInstance->GetData64(id)))
- go->SetGoState(state);
-
- debug_log("TSCR: npc_grimstone, arena gate update state.");
- }
-
//TODO: move them to center
void SummonRingMob()
{
@@ -203,6 +183,11 @@ struct TRINITY_DLL_DECL npc_grimstoneAI : public npc_escortAI
}
}
+ void HandleGameObject(uint32 id, bool open)
+ {
+ pInstance->HandleGameObject(pInstance->GetData64(id), open);
+ }
+
void UpdateAI(const uint32 diff)
{
if (!pInstance)
@@ -254,7 +239,7 @@ struct TRINITY_DLL_DECL npc_grimstoneAI : public npc_escortAI
{
case 0:
DoScriptText(-1000000, m_creature);//1
- DoGate(DATA_ARENA4,1);
+ HandleGameObject(DATA_ARENA4, false);
Start(false, false, false);
CanWalk = true;
Event_Timer = 0;
@@ -267,7 +252,7 @@ struct TRINITY_DLL_DECL npc_grimstoneAI : public npc_escortAI
Event_Timer = 2000;
break;
case 3:
- DoGate(DATA_ARENA1,0);
+ HandleGameObject(DATA_ARENA1, true);
Event_Timer = 3000;
break;
case 4:
@@ -287,13 +272,13 @@ struct TRINITY_DLL_DECL npc_grimstoneAI : public npc_escortAI
break;
case 7:
m_creature->SetVisibility(VISIBILITY_ON);
- DoGate(DATA_ARENA1,1);
+ HandleGameObject(DATA_ARENA1, false);
DoScriptText(-1000000, m_creature);//4
CanWalk = true;
Event_Timer = 0;
break;
case 8:
- DoGate(DATA_ARENA2,0);
+ HandleGameObject(DATA_ARENA2, true);
Event_Timer = 5000;
break;
case 9:
@@ -303,9 +288,9 @@ struct TRINITY_DLL_DECL npc_grimstoneAI : public npc_escortAI
break;
case 10:
//if quest, complete
- DoGate(DATA_ARENA2,1);
- DoGate(DATA_ARENA3,0);
- DoGate(DATA_ARENA4,0);
+ HandleGameObject(DATA_ARENA2, false);
+ HandleGameObject(DATA_ARENA3, true);
+ HandleGameObject(DATA_ARENA4, true);
CanWalk = true;
Event_Timer = 0;
break;
@@ -323,11 +308,9 @@ CreatureAI* GetAI_npc_grimstone(Creature *_Creature)
{
npc_grimstoneAI* Grimstone_AI = new npc_grimstoneAI(_Creature);
- for(uint8 i = 0; i < 6; ++i)
- Grimstone_AI->AddWaypoint(i, RingLocations[i][0], RingLocations[i][1], RingLocations[i][2]);
+ Grimstone_AI->FillPointMovementListForCreature();
return (CreatureAI*)Grimstone_AI;
-
}
/*######
@@ -353,10 +336,6 @@ struct TRINITY_DLL_DECL mob_phalanxAI : public ScriptedAI
MightyBlow_Timer = 15000;
}
- void Aggro(Unit *who)
- {
- }
-
void UpdateAI(const uint32 diff)
{
//Return since we have no target
@@ -558,7 +537,7 @@ struct TRINITY_DLL_DECL npc_dughal_stormwingAI : public npc_escortAI
}
}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void Reset() {}
void JustDied(Unit* killer)
@@ -691,7 +670,7 @@ struct TRINITY_DLL_DECL npc_marshal_windsorAI : public npc_escortAI
}
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
switch(rand()%3)
{
@@ -887,7 +866,7 @@ struct TRINITY_DLL_DECL npc_marshal_reginald_windsorAI : public npc_escortAI
}
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
switch(rand()%3)
{
@@ -1003,7 +982,7 @@ struct TRINITY_DLL_DECL npc_tobias_seecherAI : public npc_escortAI
{
npc_tobias_seecherAI(Creature *c) :npc_escortAI(c) {}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void Reset() {}
void JustDied(Unit* killer)
@@ -1096,30 +1075,6 @@ bool GossipSelect_npc_tobias_seecher(Player *player, Creature *_Creature, uint32
#define SPELL_DRUNKEN_RAGE 14872
#define QUEST_ALE 4295
-float BarWpLocations[8][3]=
-{
- {883.294861, -188.926300, -43.703655},
- {872.763550, -185.605621, -43.703655}, //b1
- {867.923401, -188.006393, -43.703655}, //b2
- {863.295898, -190.795212, -43.703655}, //b3
- {856.139587, -194.652756, -43.703655}, //b4
- {851.878906, -196.928131, -43.703655}, //b5
- {877.035217, -187.048080, -43.703655},
- {891.198000, -197.924000, -43.620400} //home
-};
-
-uint32 BarWpWait[8]=
-{
- 0,
- 5000,
- 5000,
- 5000,
- 5000,
- 15000,
- 0,
- 0
-};
-
struct TRINITY_DLL_DECL npc_rocknotAI : public npc_escortAI
{
npc_rocknotAI(Creature *c) : npc_escortAI(c)
@@ -1141,12 +1096,10 @@ struct TRINITY_DLL_DECL npc_rocknotAI : public npc_escortAI
BreakDoor_Timer = 0;
}
- void Aggro(Unit *who) { }
-
void DoGo(uint32 id, uint32 state)
{
if (GameObject *go = GameObject::GetGameObject(*m_creature,pInstance->GetData64(id)))
- go->SetGoState(state);
+ go->SetGoState((GOState)state);
}
void WaypointReached(uint32 i)
@@ -1217,8 +1170,7 @@ CreatureAI* GetAI_npc_rocknot(Creature *_Creature)
{
npc_rocknotAI* Rocknot_AI = new npc_rocknotAI(_Creature);
- for(uint8 i = 0; i < 8; ++i)
- Rocknot_AI->AddWaypoint(i, BarWpLocations[i][0], BarWpLocations[i][1], BarWpLocations[i][2], BarWpWait[i]);
+ Rocknot_AI->FillPointMovementListForCreature();
return (CreatureAI*)Rocknot_AI;
}
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 b0c4bafb290..28f2e6935e2 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -42,7 +42,7 @@ struct TRINITY_DLL_DECL boss_ambassador_flamelashAI : public ScriptedAI
Spirit_Timer = 24000;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void SummonSpirits(Unit* victim)
{
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 ad9330528b9..a65d41e3170 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_anubshiah.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_anubshiah.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -48,7 +48,7 @@ struct TRINITY_DLL_DECL boss_anubshiahAI : public ScriptedAI
EnvelopingWeb_Timer = 16000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 978f4d8e9d7..378f8163f9d 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -23,12 +23,12 @@ EndScriptData */
#include "precompiled.h"
+#define SAY_AGGRO -1230001
+#define SAY_SLAY -1230002
+
#define SPELL_HANDOFTHAURISSAN 17492
#define SPELL_AVATAROFFLAME 15636
-#define SAY_AGGRO "Come to aid the Throne!"
-#define SAY_SLAY "Hail to the king, baby!"
-
struct TRINITY_DLL_DECL boss_draganthaurissanAI : public ScriptedAI
{
boss_draganthaurissanAI(Creature *c) : ScriptedAI(c) {}
@@ -44,14 +44,14 @@ struct TRINITY_DLL_DECL boss_draganthaurissanAI : public ScriptedAI
//Counter= 0;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
- DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL);
+ DoScriptText(SAY_AGGRO, m_creature);
}
void KilledUnit(Unit* victim)
{
- DoYell(SAY_SLAY, LANG_UNIVERSAL, NULL);
+ DoScriptText(SAY_SLAY, m_creature);
}
void UpdateAI(const uint32 diff)
@@ -62,9 +62,8 @@ struct TRINITY_DLL_DECL boss_draganthaurissanAI : public ScriptedAI
if (HandOfThaurissan_Timer < diff)
{
- Unit* target = NULL;
- target = SelectUnit(SELECT_TARGET_RANDOM,0);
- if (target) DoCast(target,SPELL_HANDOFTHAURISSAN);
+ if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0))
+ DoCast(target,SPELL_HANDOFTHAURISSAN);
//3 Hands of Thaurissan will be casted
//if (Counter < 3)
@@ -89,6 +88,7 @@ struct TRINITY_DLL_DECL boss_draganthaurissanAI : public ScriptedAI
DoMeleeAttackIfReady();
}
};
+
CreatureAI* GetAI_boss_draganthaurissan(Creature *_Creature)
{
return new boss_draganthaurissanAI (_Creature);
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 80df7fec20b..98e1e959314 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -54,7 +54,7 @@ struct TRINITY_DLL_DECL boss_general_angerforgeAI : public ScriptedAI
Medics = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 25367c6f4dd..6a89906faf7 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -39,7 +39,7 @@ struct TRINITY_DLL_DECL boss_gorosh_the_dervishAI : public ScriptedAI
MortalStrike_Timer = 22000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 389b2bc5b4d..5aa3786efce 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_grizzle.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_grizzle.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -23,6 +23,8 @@ EndScriptData */
#include "precompiled.h"
+#define EMOTE_GENERIC_FRENZY_KILL -1000001
+
#define SPELL_GROUNDTREMOR 6524
#define SPELL_FRENZY 28371
@@ -39,7 +41,7 @@ struct TRINITY_DLL_DECL boss_grizzleAI : public ScriptedAI
Frenzy_Timer =0;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -62,7 +64,7 @@ struct TRINITY_DLL_DECL boss_grizzleAI : public ScriptedAI
if (Frenzy_Timer < diff)
{
DoCast(m_creature,SPELL_FRENZY);
- DoTextEmote("goes into a killing frenzy!",NULL);
+ DoScriptText(EMOTE_GENERIC_FRENZY_KILL, m_creature);
Frenzy_Timer = 15000;
}else Frenzy_Timer -= diff;
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 422f0f25532..62ba94347d4 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -45,7 +45,7 @@ struct TRINITY_DLL_DECL boss_high_interrogator_gerstahnAI : public ScriptedAI
ShadowShield_Timer = 8000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 25f7f890e3f..f9016987dfa 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_magmus.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_magmus.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -39,7 +39,7 @@ struct TRINITY_DLL_DECL boss_magmusAI : public ScriptedAI
WarStomp_Timer =0;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 26c72404355..b60ad5cdbe5 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -51,7 +51,7 @@ struct TRINITY_DLL_DECL boss_moira_bronzebeardAI : public ScriptedAI
Smite_Timer = 8000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_tomb_of_seven.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_tomb_of_seven.cpp
index 3e99a09b266..3768422e323 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_tomb_of_seven.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_tomb_of_seven.cpp
@@ -46,7 +46,7 @@ struct TRINITY_DLL_DECL boss_angerrelAI : public ScriptedAI
Strike_Timer = 12000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -104,7 +104,7 @@ struct TRINITY_DLL_DECL boss_doperelAI : public ScriptedAI
Gouge_Timer = 6000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -164,7 +164,7 @@ struct TRINITY_DLL_DECL boss_haterelAI : public ScriptedAI
Strike_Timer = 12000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -236,7 +236,7 @@ struct TRINITY_DLL_DECL boss_vilerelAI : public ScriptedAI
Shield_Timer = 3000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -309,7 +309,7 @@ struct TRINITY_DLL_DECL boss_seethrelAI : public ScriptedAI
m_creature->CastSpell(m_creature,SPELL_FROSTARMOR,true);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -385,7 +385,7 @@ struct TRINITY_DLL_DECL boss_gloomrelAI : public ScriptedAI
m_creature->setFaction(FACTION_NEUTRAL);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -493,7 +493,7 @@ struct TRINITY_DLL_DECL boss_doomrelAI : public ScriptedAI
m_creature->setFaction(FACTION_NEUTRAL);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp
index ffdc304bc6e..6e26f3a0c03 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
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 45e5184e1d3..cf199073b77 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_drakkisath.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_drakkisath.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -45,7 +45,7 @@ struct TRINITY_DLL_DECL boss_drakkisathAI : public ScriptedAI
Thunderclap_Timer = 17000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 09656309e5c..e48c832e3b0 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_gyth.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_gyth.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -76,7 +76,7 @@ struct TRINITY_DLL_DECL boss_gythAI : public ScriptedAI
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 61ce2ea2cc4..f5f7e11f7db 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_halycon.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_halycon.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -46,7 +46,7 @@ struct TRINITY_DLL_DECL boss_halyconAI : public ScriptedAI
Summoned = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 6069bad85ed..e84d538bf79 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -54,7 +54,7 @@ struct TRINITY_DLL_DECL boss_highlordomokkAI : public ScriptedAI
Slow_Timer = 24000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 7188ae17770..749ff71f024 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -40,7 +40,7 @@ struct TRINITY_DLL_DECL boss_mothersmolderwebAI : public ScriptedAI
MothersMilk_Timer = 10000;
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void DamageTaken(Unit *done_by, uint32 &damage)
{
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 85113c9a1ab..cdb038588bf 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -58,7 +58,7 @@ struct TRINITY_DLL_DECL boss_overlordwyrmthalakAI : public ScriptedAI
Summoned = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -103,8 +103,10 @@ struct TRINITY_DLL_DECL boss_overlordwyrmthalakAI : public ScriptedAI
target = SelectUnit(SELECT_TARGET_RANDOM,0);
SummonedCreature = m_creature->SummonCreature(9216,ADD_1X,ADD_1Y,ADD_1Z,ADD_1O,TEMPSUMMON_TIMED_DESPAWN,300000);
+ if(SummonedCreature)
((CreatureAI*)SummonedCreature->AI())->AttackStart(target);
SummonedCreature = m_creature->SummonCreature(9268,ADD_2X,ADD_2Y,ADD_2Z,ADD_2O,TEMPSUMMON_TIMED_DESPAWN,300000);
+ if(SummonedCreature)
((CreatureAI*)SummonedCreature->AI())->AttackStart(target);
Summoned = true;
}
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 ea320b40b4d..474a3ffcfdd 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -42,7 +42,7 @@ struct TRINITY_DLL_DECL boss_pyroguard_emberseerAI : public ScriptedAI
PyroBlast_Timer = 14000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 b4b14ac5f89..d244567eafa 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -43,7 +43,7 @@ struct TRINITY_DLL_DECL boss_quatermasterzigrisAI : public ScriptedAI
//HelingPotion_Timer = 25000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 ee41701667b..58f487f846d 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -42,7 +42,7 @@ struct TRINITY_DLL_DECL boss_rend_blackhandAI : public ScriptedAI
Thunderclap_Timer = 9000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 7a1080226ea..43417a6996c 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -44,7 +44,7 @@ struct TRINITY_DLL_DECL boss_shadowvoshAI : public ScriptedAI
//m_creature->CastSpell(m_creature,SPELL_ICEARMOR,true);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 6eead9d4162..38bdd2f2c55 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -42,7 +42,7 @@ struct TRINITY_DLL_DECL boss_thebeastAI : public ScriptedAI
TerrifyingRoar_Timer = 23000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 625bbc0d28a..358e33969dd 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -51,7 +51,7 @@ struct TRINITY_DLL_DECL boss_warmastervooneAI : public ScriptedAI
ThrowAxe_Timer = 1000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 5c0b2a8d2f2..915c3062ea7 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -53,7 +53,7 @@ struct TRINITY_DLL_DECL boss_broodlordAI : public ScriptedAI
m_creature->ApplySpellImmune(1, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
DoZoneInCombat();
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 686c0be35db..555a0825b50 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_chromaggus.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_chromaggus.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -183,7 +183,7 @@ struct TRINITY_DLL_DECL boss_chromaggusAI : public ScriptedAI
Enraged = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -259,11 +259,11 @@ struct TRINITY_DLL_DECL boss_chromaggusAI : public ScriptedAI
DoCast(pUnit, SpellAfflict, true);
//Chromatic mutation if target is effected by all afflictions
- if (pUnit->HasAura(SPELL_BROODAF_BLUE,0)
- && pUnit->HasAura(SPELL_BROODAF_BLACK,0)
- && pUnit->HasAura(SPELL_BROODAF_RED,0)
- && pUnit->HasAura(SPELL_BROODAF_BRONZE,0)
- && pUnit->HasAura(SPELL_BROODAF_GREEN,0))
+ if (pUnit->HasAura(SPELL_BROODAF_BLUE)
+ && pUnit->HasAura(SPELL_BROODAF_BLACK)
+ && pUnit->HasAura(SPELL_BROODAF_RED)
+ && pUnit->HasAura(SPELL_BROODAF_BRONZE)
+ && pUnit->HasAura(SPELL_BROODAF_GREEN))
{
//target->RemoveAllAuras();
//DoCast(target,SPELL_CHROMATIC_MUT_1);
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 c30485ac327..90ff9b9b967 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_ebonroc.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_ebonroc.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -45,7 +45,7 @@ struct TRINITY_DLL_DECL boss_ebonrocAI : public ScriptedAI
Heal_Timer = 1000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoZoneInCombat();
}
@@ -76,7 +76,7 @@ struct TRINITY_DLL_DECL boss_ebonrocAI : public ScriptedAI
ShadowOfEbonroc_Timer = 25000 + rand()%10000;
}else ShadowOfEbonroc_Timer -= diff;
- if (m_creature->getVictim()->HasAura(SPELL_SHADOWOFEBONROC,0))
+ if (m_creature->getVictim()->HasAura(SPELL_SHADOWOFEBONROC))
{
if (Heal_Timer < diff)
{
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 64a01b228f0..0af2c66b54f 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -42,7 +42,7 @@ struct TRINITY_DLL_DECL boss_firemawAI : public ScriptedAI
FlameBuffet_Timer = 5000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoZoneInCombat();
}
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 49dfdaa896f..87ce0e3fb3b 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -44,7 +44,7 @@ struct TRINITY_DLL_DECL boss_flamegorAI : public ScriptedAI
Frenzy_Timer = 10000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoZoneInCombat();
}
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 d91714c0246..808f381d197 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_nefarian.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_nefarian.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -97,7 +97,7 @@ struct TRINITY_DLL_DECL boss_nefarianAI : public ScriptedAI
DoScriptText(SAY_DEATH, m_creature);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch (rand()%3)
{
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 1da3fb554df..763a3b3f7f4 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -55,7 +55,7 @@ struct TRINITY_DLL_DECL boss_razorgoreAI : public ScriptedAI
m_creature->ApplySpellImmune(1, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoZoneInCombat();
}
@@ -104,7 +104,7 @@ struct TRINITY_DLL_DECL boss_razorgoreAI : public ScriptedAI
}else Conflagration_Timer -= diff;
// Aura Check. If the gamer is affected by confliguration we attack a random gamer.
- if (m_creature->getVictim()->HasAura(SPELL_CONFLAGRATION,0))
+ if (m_creature->getVictim()->HasAura(SPELL_CONFLAGRATION))
{
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,1);
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 f0048e7a4fa..b11ac370804 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_vaelastrasz.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_vaelastrasz.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -98,7 +98,7 @@ struct TRINITY_DLL_DECL boss_vaelAI : public ScriptedAI
DoScriptText(SAY_KILLTARGET, m_creature, victim);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoCast(m_creature,SPELL_ESSENCEOFTHERED);
DoZoneInCombat();
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 093ca7b901d..b3aee0035df 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -203,7 +203,7 @@ struct TRINITY_DLL_DECL boss_victor_nefariusAI : public ScriptedAI
AttackStart(target);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/instance_blackwing_lair.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/instance_blackwing_lair.cpp
index ddd9e8b9aa3..97bf717589a 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/instance_blackwing_lair.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/instance_blackwing_lair.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
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 3617ae8cc14..8a40fd86b58 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -17,7 +17,7 @@
/* ScriptData
SDName: Blades_Edge_Mountains
SD%Complete: 90
-SDComment: Quest support: 10503, 10504, 10556, 10609, 10682, 10980. Ogri'la->Skettis Flight. (npc_daranelle needs bit more work before consider complete)
+SDComment: Quest support: 10503, 10504, 10556, 10609, 10682, 10821, 10980. Ogri'la->Skettis Flight. (npc_daranelle needs bit more work before consider complete)
SDCategory: Blade's Edge Mountains
EndScriptData */
@@ -28,10 +28,20 @@ npc_daranelle
npc_overseer_nuaar
npc_saikkal_the_elder
npc_skyguard_handler_irena
+go_legion_obelisk
EndContentData */
#include "precompiled.h"
+//Support for quest: You're Fired! (10821)
+bool obelisk_one, obelisk_two, obelisk_three, obelisk_four, obelisk_five;
+
+#define LEGION_OBELISK_ONE 185193
+#define LEGION_OBELISK_TWO 185195
+#define LEGION_OBELISK_THREE 185196
+#define LEGION_OBELISK_FOUR 185197
+#define LEGION_OBELISK_FIVE 185198
+
/*######
## mobs_bladespire_ogre
######*/
@@ -45,7 +55,7 @@ struct TRINITY_DLL_DECL mobs_bladespire_ogreAI : public ScriptedAI
{
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
}
@@ -96,154 +106,126 @@ struct TRINITY_DLL_DECL mobs_nether_drakeAI : public ScriptedAI
void Reset()
{
- NihilSpeech_Timer = 2000;
IsNihil = false;
- if( m_creature->GetEntry() == ENTRY_NIHIL )
- {
- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- IsNihil = true;
- }
- NihilSpeech_Phase = 1;
+ NihilSpeech_Timer = 3000;
+ NihilSpeech_Phase = 0;
ArcaneBlast_Timer = 7500;
ManaBurn_Timer = 10000;
IntangiblePresence_Timer = 15000;
}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
+
+ void MoveInLineOfSight(Unit *who)
+ {
+ if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ ScriptedAI::MoveInLineOfSight(who);
+ }
+
+ //in case creature was not summoned (not expected)
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ if (id == 0)
+ {
+ m_creature->setDeathState(JUST_DIED);
+ m_creature->RemoveCorpse();
+ m_creature->SetHealth(0);
+ }
+ }
void SpellHit(Unit *caster, const SpellEntry *spell)
{
- if( spell->Id == SPELL_T_PHASE_MODULATOR && caster->GetTypeId() == TYPEID_PLAYER )
+ if (spell->Id == SPELL_T_PHASE_MODULATOR && caster->GetTypeId() == TYPEID_PLAYER)
{
- uint32 cEntry = 0;
+ const uint32 entry_list[4] = {ENTRY_PROTO, ENTRY_ADOLE, ENTRY_MATUR, ENTRY_NIHIL};
+ int cid = rand()%(4-1);
+
+ if (entry_list[cid] == m_creature->GetEntry())
+ ++cid;
- switch( m_creature->GetEntry() )
+ //we are nihil, so say before transform
+ if (m_creature->GetEntry() == ENTRY_NIHIL)
{
- case ENTRY_WHELP:
- switch(rand()%4)
- {
- case 0: cEntry = ENTRY_PROTO; break;
- case 1: cEntry = ENTRY_ADOLE; break;
- case 2: cEntry = ENTRY_MATUR; break;
- case 3: cEntry = ENTRY_NIHIL; break;
- }
- break;
- case ENTRY_PROTO:
- switch(rand()%3)
- {
- case 0: cEntry = ENTRY_ADOLE; break;
- case 1: cEntry = ENTRY_MATUR; break;
- case 2: cEntry = ENTRY_NIHIL; break;
- }
- break;
- case ENTRY_ADOLE:
- switch(rand()%3)
- {
- case 0: cEntry = ENTRY_PROTO; break;
- case 1: cEntry = ENTRY_MATUR; break;
- case 2: cEntry = ENTRY_NIHIL; break;
- }
- break;
- case ENTRY_MATUR:
- switch(rand()%3)
- {
- case 0: cEntry = ENTRY_PROTO; break;
- case 1: cEntry = ENTRY_ADOLE; break;
- case 2: cEntry = ENTRY_NIHIL; break;
- }
- break;
- case ENTRY_NIHIL:
- if( NihilSpeech_Phase )
- {
- DoScriptText(SAY_NIHIL_INTERRUPT, m_creature);
- IsNihil = false;
- switch(rand()%3)
- {
- case 0: cEntry = ENTRY_PROTO; break;
- case 1: cEntry = ENTRY_ADOLE; break;
- case 2: cEntry = ENTRY_MATUR; break;
- }
- }
- break;
+ DoScriptText(SAY_NIHIL_INTERRUPT, m_creature);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ IsNihil = false;
}
- if( cEntry )
+ if (m_creature->UpdateEntry(entry_list[cid]))
{
- m_creature->UpdateEntry(cEntry);
-
- if( cEntry == ENTRY_NIHIL )
+ if (entry_list[cid] == ENTRY_NIHIL)
{
- m_creature->InterruptNonMeleeSpells(true);
- m_creature->RemoveAllAuras();
- m_creature->DeleteThreatList();
- m_creature->CombatStop();
- InCombat = false;
- Reset();
- }
+ EnterEvadeMode();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ IsNihil = true;
+ }else
+ AttackStart(caster);
}
}
}
void UpdateAI(const uint32 diff)
{
- if( IsNihil )
+ if (IsNihil)
{
- if( NihilSpeech_Phase )
+ if (NihilSpeech_Timer <= diff)
{
- if(NihilSpeech_Timer <= diff)
+ switch(NihilSpeech_Phase)
{
- switch( NihilSpeech_Phase )
- {
- case 1:
- DoScriptText(SAY_NIHIL_1, m_creature);
- ++NihilSpeech_Phase;
- break;
- case 2:
- DoScriptText(SAY_NIHIL_2, m_creature);
- ++NihilSpeech_Phase;
- break;
- case 3:
- DoScriptText(SAY_NIHIL_3, m_creature);
- ++NihilSpeech_Phase;
- break;
- case 4:
- DoScriptText(SAY_NIHIL_4, m_creature);
- ++NihilSpeech_Phase;
- break;
- case 5:
- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- // + MOVEMENTFLAG_LEVITATING
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
- //then take off to random location. creature is initially summoned, so don't bother do anything else.
- m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX()+100, m_creature->GetPositionY(), m_creature->GetPositionZ()+100);
- NihilSpeech_Phase = 0;
- break;
- }
- NihilSpeech_Timer = 5000;
- }else NihilSpeech_Timer -=diff;
- }
- return; //anything below here is not interesting for Nihil, so skip it
+ case 0:
+ DoScriptText(SAY_NIHIL_1, m_creature);
+ ++NihilSpeech_Phase;
+ break;
+ case 1:
+ DoScriptText(SAY_NIHIL_2, m_creature);
+ ++NihilSpeech_Phase;
+ break;
+ case 2:
+ DoScriptText(SAY_NIHIL_3, m_creature);
+ ++NihilSpeech_Phase;
+ break;
+ case 3:
+ DoScriptText(SAY_NIHIL_4, m_creature);
+ ++NihilSpeech_Phase;
+ break;
+ case 4:
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ //take off to location above
+ m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX()+50.0f, m_creature->GetPositionY(), m_creature->GetPositionZ()+50.0f);
+ ++NihilSpeech_Phase;
+ break;
+ }
+ NihilSpeech_Timer = 5000;
+ }else NihilSpeech_Timer -=diff;
+
+ //anything below here is not interesting for Nihil, so skip it
+ return;
}
- if( !UpdateVictim() )
+ if (!UpdateVictim() )
return;
- if( IntangiblePresence_Timer <= diff )
+ if (IntangiblePresence_Timer <= diff)
{
DoCast(m_creature->getVictim(),SPELL_INTANGIBLE_PRESENCE);
IntangiblePresence_Timer = 15000+rand()%15000;
}else IntangiblePresence_Timer -= diff;
- if( ManaBurn_Timer <= diff )
+ if (ManaBurn_Timer <= diff)
{
Unit* target = m_creature->getVictim();
- if( target && target->getPowerType() == POWER_MANA )
+ if (target && target->getPowerType() == POWER_MANA)
DoCast(target,SPELL_MANA_BURN);
ManaBurn_Timer = 8000+rand()%8000;
}else ManaBurn_Timer -= diff;
- if( ArcaneBlast_Timer <= diff )
+ if (ArcaneBlast_Timer <= diff)
{
DoCast(m_creature->getVictim(),SPELL_ARCANE_BLAST);
ArcaneBlast_Timer = 2500+rand()%5000;
@@ -252,6 +234,7 @@ struct TRINITY_DLL_DECL mobs_nether_drakeAI : public ScriptedAI
DoMeleeAttackIfReady();
}
};
+
CreatureAI* GetAI_mobs_nether_drake(Creature *_Creature)
{
return new mobs_nether_drakeAI (_Creature);
@@ -261,27 +244,23 @@ CreatureAI* GetAI_mobs_nether_drake(Creature *_Creature)
## npc_daranelle
######*/
-#define SAY_DARANELLE -1000401
+#define SAY_SPELL_INFLUENCE -1000174
struct TRINITY_DLL_DECL npc_daranelleAI : public ScriptedAI
{
npc_daranelleAI(Creature *c) : ScriptedAI(c) {}
- void Reset()
- {
- }
+ void Reset() { }
- void Aggro(Unit* who)
- {
- }
+ void EnterCombat(Unit* who) { }
void MoveInLineOfSight(Unit *who)
{
if (who->GetTypeId() == TYPEID_PLAYER)
{
- if(who->HasAura(36904,0))
+ if (who->HasAura(36904) && m_creature->IsWithinDistInMap(who, 10.0f))
{
- DoScriptText(SAY_DARANELLE, m_creature, who);
+ DoScriptText(SAY_SPELL_INFLUENCE, m_creature, who);
//TODO: Move the below to updateAI and run if this statement == true
((Player*)who)->KilledMonster(21511, m_creature->GetGUID());
((Player*)who)->RemoveAurasDueToSpell(36904);
@@ -301,12 +280,10 @@ CreatureAI* GetAI_npc_daranelle(Creature *_Creature)
## npc_overseer_nuaar
######*/
-#define GOSSIP_HON "Overseer, I am here to negotiate on behalf of the Cenarion Expedition."
-
bool GossipHello_npc_overseer_nuaar(Player *player, Creature *_Creature)
{
if (player->GetQuestStatus(10682) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM( 0, GOSSIP_HON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ player->ADD_GOSSIP_ITEM( 0, "Overseer, I am here to negotiate on behalf of the Cenarion Expedition.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->SEND_GOSSIP_MENU(10532, _Creature->GetGUID());
@@ -327,13 +304,10 @@ bool GossipSelect_npc_overseer_nuaar(Player *player, Creature *_Creature, uint32
## npc_saikkal_the_elder
######*/
-#define GOSSIP_HSTE "Yes... yes, it's me."
-#define GOSSIP_SSTE "Yes elder. Tell me more of the book."
-
bool GossipHello_npc_saikkal_the_elder(Player *player, Creature *_Creature)
{
if (player->GetQuestStatus(10980) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM( 0, GOSSIP_HSTE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ player->ADD_GOSSIP_ITEM( 0, "Yes... yes, it's me.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->SEND_GOSSIP_MENU(10794, _Creature->GetGUID());
@@ -345,7 +319,7 @@ bool GossipSelect_npc_saikkal_the_elder(Player *player, Creature *_Creature, uin
switch (action)
{
case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM( 0, GOSSIP_SSTE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ player->ADD_GOSSIP_ITEM( 0, "Yes elder. Tell me more of the book.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
player->SEND_GOSSIP_MENU(10795, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
@@ -380,18 +354,54 @@ bool GossipSelect_npc_skyguard_handler_irena(Player *player, Creature *_Creature
if (action == GOSSIP_ACTION_INFO_DEF+1)
{
player->CLOSE_GOSSIP_MENU();
-
- std::vector<uint32> nodes;
-
- nodes.resize(2);
- nodes[0] = 172; //from ogri'la
- nodes[1] = 171; //end at skettis
- player->ActivateTaxiPathTo(nodes); //TaxiPath 706
+ player->CastSpell(player,41278,true); //TaxiPath 706
}
return true;
}
/*######
+## go_legion_obelisk
+######*/
+
+bool GOHello_go_legion_obelisk(Player *player, GameObject* _GO)
+{
+ if ( player->GetQuestStatus(10821) == QUEST_STATUS_INCOMPLETE )
+ {
+ switch( _GO->GetEntry() )
+ {
+ case LEGION_OBELISK_ONE:
+ obelisk_one = true;
+ break;
+ case LEGION_OBELISK_TWO:
+ obelisk_two = true;
+ break;
+ case LEGION_OBELISK_THREE:
+ obelisk_three = true;
+ break;
+ case LEGION_OBELISK_FOUR:
+ obelisk_four = true;
+ break;
+ case LEGION_OBELISK_FIVE:
+ obelisk_five = true;
+ break;
+ }
+
+ if ( obelisk_one == true && obelisk_two == true && obelisk_three == true && obelisk_four == true && obelisk_five == true )
+ {
+ _GO->SummonCreature(19963,2943.40f,4778.20f,284.49f,0.94f,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,120000);
+ //reset global var
+ obelisk_one = false;
+ obelisk_two = false;
+ obelisk_three = false;
+ obelisk_four = false;
+ obelisk_five = false;
+ }
+ }
+
+ return true;
+}
+
+/*######
## AddSC
######*/
@@ -425,6 +435,11 @@ void AddSC_blades_edge_mountains()
newscript->pGossipHello = &GossipHello_npc_saikkal_the_elder;
newscript->pGossipSelect = &GossipSelect_npc_saikkal_the_elder;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="go_legion_obelisk";
+ newscript->pGOHello = &GOHello_go_legion_obelisk;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_skyguard_handler_irena";
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 954792a1044..432633e90fe 100644
--- a/src/bindings/scripts/scripts/zone/blasted_lands/blasted_lands.cpp
+++ b/src/bindings/scripts/scripts/zone/blasted_lands/blasted_lands.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
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 f186a58252c..062efcb1c4e 100644
--- a/src/bindings/scripts/scripts/zone/blasted_lands/boss_kruul.cpp
+++ b/src/bindings/scripts/scripts/zone/blasted_lands/boss_kruul.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -58,7 +58,7 @@ struct TRINITY_DLL_DECL boss_kruulAI : public ScriptedAI
Hound_Timer = 8000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 e7ce3b95c42..2dcc84eba80 100644
--- a/src/bindings/scripts/scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp
+++ b/src/bindings/scripts/scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -43,7 +43,7 @@ struct TRINITY_DLL_DECL mob_webbed_creatureAI : public ScriptedAI
{
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
}
@@ -81,7 +81,7 @@ CreatureAI* GetAI_mob_webbed_creature(Creature *_Creature)
bool GossipHello_npc_captured_sunhawk_agent(Player *player, Creature *_Creature)
{
- if (player->HasAura(31609,1) && player->GetQuestStatus(9756) == QUEST_STATUS_INCOMPLETE)
+ if (player->HasAura(31609) && player->GetQuestStatus(9756) == QUEST_STATUS_INCOMPLETE)
{
player->ADD_GOSSIP_ITEM( 0, "[PH] ", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->SEND_GOSSIP_MENU(9136, _Creature->GetGUID());
diff --git a/src/bindings/scripts/scripts/zone/borean_tundra/borean_tundra.cpp b/src/bindings/scripts/scripts/zone/borean_tundra/borean_tundra.cpp
new file mode 100644
index 00000000000..c776c1f9271
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/borean_tundra/borean_tundra.cpp
@@ -0,0 +1,105 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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
+ */
+
+/* ScriptData
+SDName: Borean_Tundra
+SD%Complete: 100
+SDComment:
+SDCategory: Borean Tundra
+EndScriptData */
+
+/* ContentData
+npc_tiare
+npc_surristrasz
+EndContentData */
+
+#include "precompiled.h"
+
+/*######
+## npc_tiare
+######*/
+
+#define GOSSIP_ITEM_TELEPORT "Teleport me to Amber Ledge, please."
+
+bool GossipHello_npc_tiare(Player *player, Creature *_Creature)
+{
+ player->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_TELEPORT, GOSSIP_SENDER_MAIN, GOSSIP_OPTION_GOSSIP);
+ player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_tiare(Player *player, Creature *_Creature, uint32 sender, uint32 action)
+{
+ if (action == GOSSIP_OPTION_GOSSIP)
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->CastSpell(player,50135,true);
+ }
+ return true;
+}
+
+/*######
+## npc_surristrasz
+######*/
+
+#define GOSSIP_ITEM_FREE_FLIGHT "I'd like passage to the Transitus Shield."
+#define GOSSIP_ITEM_FLIGHT "May I use a drake to fly elsewhere?"
+
+bool GossipHello_npc_surristrasz(Player *player, Creature *_Creature)
+{
+ if (_Creature->isQuestGiver())
+ player->PrepareQuestMenu(_Creature->GetGUID());
+
+ if (_Creature->isTaxi())
+ {
+ player->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_FREE_FLIGHT, GOSSIP_SENDER_MAIN, GOSSIP_OPTION_GOSSIP);
+ player->ADD_GOSSIP_ITEM(2, GOSSIP_ITEM_FLIGHT, GOSSIP_SENDER_MAIN, GOSSIP_OPTION_TAXIVENDOR);
+ }
+
+ player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_surristrasz(Player *player, Creature *_Creature, uint32 sender, uint32 action)
+{
+ if (action == GOSSIP_OPTION_GOSSIP)
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->CastSpell(player,46064,true); //TaxiPath 795 (amber to coldarra)
+ }
+ if (action == GOSSIP_OPTION_TAXIVENDOR)
+ {
+ player->GetSession()->SendTaxiMenu(_Creature);
+ }
+ return true;
+}
+
+void AddSC_borean_tundra()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_tiare";
+ newscript->pGossipHello = &GossipHello_npc_tiare;
+ newscript->pGossipSelect = &GossipSelect_npc_tiare;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_surristrasz";
+ newscript->pGossipHello = &GossipHello_npc_surristrasz;
+ newscript->pGossipSelect = &GossipSelect_npc_surristrasz;
+ 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 0458e495959..1bbe33ea415 100644
--- a/src/bindings/scripts/scripts/zone/burning_steppes/burning_steppes.cpp
+++ b/src/bindings/scripts/scripts/zone/burning_steppes/burning_steppes.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -52,7 +52,7 @@ struct TRINITY_DLL_DECL npc_ragged_johnAI : public ScriptedAI
void MoveInLineOfSight(Unit *who)
{
- if( who->HasAura(16468,0) )
+ if( who->HasAura(16468) )
{
if( who->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(who, 15) && who->isInAccessiblePlaceFor(m_creature) )
{
@@ -64,7 +64,7 @@ struct TRINITY_DLL_DECL npc_ragged_johnAI : public ScriptedAI
ScriptedAI::MoveInLineOfSight(who);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
};
CreatureAI* GetAI_npc_ragged_john(Creature *_Creature)
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/boss_epoch.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/boss_epoch.cpp
new file mode 100644
index 00000000000..4912f586309
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/boss_epoch.cpp
@@ -0,0 +1,86 @@
+/* Script Data Start
+SDName: Boss epoch
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_CURSE_OF_EXERTION 52772
+#define SPELL_TIME_WARP 52766 //Time slows down, reducing attack, casting and movement speed by 70% for 6 sec.
+#define SPELL_TIME_STOP 58848 //Stops time in a 50 yard sphere for 2 sec.
+#define SPELL_WOUNDING_STRIKE_N 52771 //Used only on the tank
+#define SPELL_WOUNDING_STRIKE_H 58830
+
+//Say
+#define SAY_INTRO -1595000 //"Prince Arthas Menethil, on this day, a powerful darkness has taken hold of your soul. The death you are destined to visit upon others will this day be your own."
+#define SAY_AGGRO -1595001 //"We'll see about that, young prince."
+#define SAY_TIME_WARP_1 -1595002 //"Tick tock, tick tock..."
+#define SAY_TIME_WARP_2 -1595003 //"Not quick enough!"
+#define SAY_TIME_WARP_3 -1595004 //"Let's get this over with. "
+#define SAY_SLAY_1 -1595005 //"There is no future for you."
+#define SAY_SLAY_2 -1595006 //"This is the hour of our greatest triumph!"
+#define SAY_SLAY_3 -1595007 //"You were destined to fail. "
+#define SAY_DEATH -1595008 //"*gurgles*"
+
+struct TRINITY_DLL_DECL boss_epochAI : public ScriptedAI
+{
+ boss_epochAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ switch(rand()%3)
+ {
+ case 0:DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1:DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2:DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_epoch(Creature *_Creature)
+{
+ return new boss_epochAI (_Creature);
+}
+
+void AddSC_boss_epoch()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_epoch";
+ newscript->GetAI = GetAI_boss_epoch;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/boss_mal_ganis.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/boss_mal_ganis.cpp
new file mode 100644
index 00000000000..bc2d69a6a73
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/boss_mal_ganis.cpp
@@ -0,0 +1,123 @@
+/* Script Data Start
+SDName: Boss mal_ganis
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_mal_ganis' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_CARRION_SWARM_N 52720 //A cresting wave of chaotic magic splashes over enemies in front of the caster, dealing 3230 to 3570 Shadow damage and 380 to 420 Shadow damage every 3 sec. for 15 sec.
+#define SPELL_CARRION_SWARM_H 58852
+#define SPELL_MIND_BLAST_N 52722 //Inflicts 4163 to 4837 Shadow damage to an enemy.
+#define SPELL_MIND_BLAST_H 58850
+#define SPELL_SLEEP 52721 //Puts an enemy to sleep for up to 10 sec. Any damage caused will awaken the target.
+#define SPELL_VAMPIRIC_TOUCH 52723 //Heals the caster for half the damage dealt by a melee attack.
+
+//Yell Mal'ganis
+#define SAY_INTRO_1 -1595009
+#define SAY_INTRO_2 -1595010
+#define SAY_OUTRO -1595011
+#define SAY_AGGRO -1595012
+#define SAY_KILL_1 -1595013
+#define SAY_KILL_2 -1595014
+#define SAY_KILL_3 -1595015
+#define SAY_SLAY_1 -1595016
+#define SAY_SLAY_2 -1595017
+#define SAY_SLAY_3 -1595018
+#define SAY_SLAY_4 -1595019
+#define SAY_SLEEP_1 -1595020
+#define SAY_SLEEP_2 -1595021
+#define SAY_30HEALTH -1595022
+#define SAY_15HEALTH -1595023
+#define SAY_ESCAPE_SPEECH_1 -1595024
+#define SAY_ESCAPE_SPEECH_2 -1595025
+
+struct TRINITY_DLL_DECL boss_mal_ganisAI : public ScriptedAI
+{
+ boss_mal_ganisAI(Creature *c) : ScriptedAI(c) {}
+
+ bool yelled,
+ yelled2,
+ yelled3;
+
+ void Reset()
+ {
+ yelled = false;
+ yelled2 = false;
+ yelled3 = false;
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ if(!yelled)
+ {
+ if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 30)
+ {
+ DoScriptText(SAY_30HEALTH, m_creature);
+ yelled = true;
+ }
+ }
+
+ if(!yelled2)
+ {
+ if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 15)
+ {
+ DoScriptText(SAY_15HEALTH, m_creature);
+ yelled2 = true;
+ }
+ }
+
+ if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 1)
+ {
+ //Handle Escape Event
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer) {}
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ switch(rand()%4)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ case 3: DoScriptText(SAY_SLAY_4, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_mal_ganis(Creature *_Creature)
+{
+ return new boss_mal_ganisAI (_Creature);
+}
+
+void AddSC_boss_mal_ganis()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_mal_ganis";
+ newscript->GetAI = GetAI_boss_mal_ganis;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/boss_meathook.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/boss_meathook.cpp
new file mode 100644
index 00000000000..7109560b915
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/boss_meathook.cpp
@@ -0,0 +1,138 @@
+/* Script Data Start
+SDName: Boss meathook
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_meathook' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spell
+#define SPELL_CONSTRICTING_CHAINS_N 52696 //Encases the targets in chains, dealing 1800 Physical damage every 1 sec. and stunning the target for 5 sec.
+#define SPELL_CONSTRICTING_CHAINS_H 58823
+#define SPELL_DISEASE_EXPULSION_N 52666 //Meathook belches out a cloud of disease, dealing 1710 to 1890 Nature damage and interrupting the spell casting of nearby enemy targets for 4 sec.
+#define SPELL_DISEASE_EXPULSION_H 58824
+#define SPELL_FRENZY 58841 //Increases the caster's Physical damage by 10% for 30 sec.
+
+//Yell
+#define SAY_AGGRO -1595026
+#define SAY_SLAY_1 -1595027
+#define SAY_SLAY_2 -1595028
+#define SAY_SLAY_3 -1595029
+#define SAY_SPAWN -1595030
+#define SAY_DEATH -1595031
+
+struct TRINITY_DLL_DECL boss_meathookAI : public ScriptedAI
+{
+ boss_meathookAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 Chain_Timer,
+ Disease_Timer,
+ Frenzy_Timer;
+
+ void Reset()
+ {
+ Chain_Timer = 12000 + rand()%5000; //seen on video 13, 17, 15, 12, 16
+ Disease_Timer = 2000 + rand()%1000; //approx 3s
+ Frenzy_Timer = 20000 + rand()%10000; //made it up
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+
+ void AttackStart(Unit* who) {}
+
+ std::list <Unit*>pList;
+ void MoveInLineOfSight(Unit* who, const uint32 diff)
+ {
+ /*if (m_creature->isHostileTo(who))
+ {
+ pList.append(who);
+ }*/
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ if(Disease_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_DISEASE_EXPULSION_N);
+ Disease_Timer = 1500 + rand()%2500;
+ }else Disease_Timer -= diff;
+
+ if(Frenzy_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_FRENZY);
+ Frenzy_Timer = 20000 + rand()%10000;
+ }else Frenzy_Timer -= diff;
+
+ if(Chain_Timer < diff)
+ {
+
+ /*
+ std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
+ std::list<HostilReference*>::iterator itr;
+
+ int st=0;
+ for(itr = m_threatlist.begin(); itr != m_threatlist.end(); ++itr)
+ {
+ //st++;
+ m_creature->getThreatManager().
+ }
+ Unit* targets[st];
+ int st2=0;
+ for(int i=1; i<=st; i++){
+ if(!IsWithinLOSInMap(targets[i])
+ st2++;
+ }
+ Unit* targets_out_of_LOS[st2];*/
+
+ DoCast(SelectUnit(SELECT_TARGET_RANDOM, 1), SPELL_CONSTRICTING_CHAINS_N); //anyone but the tank
+ Chain_Timer = 2000 + rand()%1000;
+ }else Chain_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_meathook(Creature *_Creature)
+{
+ return new boss_meathookAI (_Creature);
+}
+
+void AddSC_boss_meathook()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_meathook";
+ newscript->GetAI = GetAI_boss_meathook;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/boss_salramm.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/boss_salramm.cpp
new file mode 100644
index 00000000000..0b4e8d6641e
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/boss_salramm.cpp
@@ -0,0 +1,152 @@
+/* Script Data Start
+SDName: Boss salramm
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_salramm' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_CURSE_OF_TWISTED_FLESH 58845
+#define SPELL_EXPLODE_GHOUL_N 52480
+#define SPELL_EXPLODE_GHOUL_H 58825
+#define SPELL_SHADOW_BOLT_N 57725
+#define SPELL_SHADOW_BOLT_H 58828
+#define SPELL_STEAL_FLESH 52708
+#define SPELL_SUMMON_GHOULS 52451
+
+//Yell
+#define SAY_AGGRO -1595032
+#define SAY_SPAWN -1595033
+#define SAY_SLAY_1 -1595034
+#define SAY_SLAY_2 -1595035
+#define SAY_SLAY_3 -1595036
+#define SAY_DEATH -1595037
+#define SAY_EXPLODE_GHOUL_1 -1595038
+#define SAY_EXPLODE_GHOUL_2 -1595039
+#define SAY_STEAL_FLESH_1 -1595040
+#define SAY_STEAL_FLESH_2 -1595041
+#define SAY_STEAL_FLESH_3 -1595042
+#define SAY_SUMMON_GHOULS_1 -1595043
+#define SAY_SUMMON_GHOULS_2 -1595044
+
+struct TRINITY_DLL_DECL boss_salrammAI : public ScriptedAI
+{
+ boss_salrammAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 Curse_flesh_Timer,
+ Explode_ghoul_Timer,
+ Shadow_bolt_Timer,
+ Steal_flesh_Timer,
+ Summon_ghouls_Timer;
+
+ void Reset()
+ {
+ Curse_flesh_Timer = 30000; //30s DBM
+ Explode_ghoul_Timer = 25000 + rand()%3000; //approx 6 sec after summon ghouls
+ Shadow_bolt_Timer = 8000 + rand()%4000; // approx 10s
+ Steal_flesh_Timer = 12345;
+ Summon_ghouls_Timer = 19000 + rand()%5000; //on a video approx 24s after aggro
+ }
+
+ void EnterCombat(Unit* who)
+ {DoScriptText(SAY_AGGRO, m_creature);}
+
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ Unit* random_target = SelectUnit(SELECT_TARGET_RANDOM, 0);
+
+ //Curse of twisted flesh timer
+ if (Curse_flesh_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(),SPELL_CURSE_OF_TWISTED_FLESH);
+ Curse_flesh_Timer = 37000;
+ }else Curse_flesh_Timer -= diff;
+
+ //Shadow bolt timer
+ if (Shadow_bolt_Timer < diff)
+ {
+ DoCast(random_target,SPELL_SHADOW_BOLT_N);
+ Shadow_bolt_Timer = 8000 + rand()%4000;
+ }else Shadow_bolt_Timer -= diff;
+
+ //Steal Flesh timer
+ if (Steal_flesh_Timer < diff)
+ {
+ switch(rand()%3)
+ {
+ case 0:
+ DoScriptText(SAY_STEAL_FLESH_1, m_creature);
+ break;
+ case 1:
+ DoScriptText(SAY_STEAL_FLESH_2, m_creature);
+ break;
+ case 2:
+ DoScriptText(SAY_STEAL_FLESH_3, m_creature);
+ break;
+ }
+ DoCast(random_target,SPELL_STEAL_FLESH);
+ Steal_flesh_Timer = 10000;
+ }else Steal_flesh_Timer -= diff;
+
+ //Summon ghouls timer
+ if (Summon_ghouls_Timer < diff)
+ {
+ switch(rand()%2)
+ {
+ case 0:
+ DoScriptText(SAY_SUMMON_GHOULS_1, m_creature);
+ break;
+ case 1:
+ DoScriptText(SAY_SUMMON_GHOULS_2, m_creature);
+ break;
+ }
+ DoCast(random_target,SPELL_SUMMON_GHOULS);
+ Summon_ghouls_Timer = 10000;
+ }else Summon_ghouls_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* killer)
+ {DoScriptText(SAY_DEATH, m_creature);}
+
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_salramm(Creature *_Creature)
+{
+ return new boss_salrammAI (_Creature);
+}
+
+void AddSC_boss_salramm()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_salramm";
+ newscript->GetAI = GetAI_boss_salramm;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/def_culling_of_stratholme.h b/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/def_culling_of_stratholme.h
new file mode 100644
index 00000000000..849549e8f99
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/def_culling_of_stratholme.h
@@ -0,0 +1,4 @@
+#ifndef DEF_CULLING_OF_STRATHOLME_H
+#define DEF_CULLING_OF_STRATHOLME_H
+
+#endif
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp
new file mode 100644
index 00000000000..936f8365a35
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp
@@ -0,0 +1,21 @@
+#include "precompiled.h"
+#include "def_culling_of_stratholme.h"
+
+struct TRINITY_DLL_DECL instance_culling_of_stratholme : public ScriptedInstance
+{
+ instance_culling_of_stratholme(Map *Map) : ScriptedInstance(Map) {Initialize();};
+};
+
+InstanceData* GetInstanceData_instance_culling_of_stratholme(Map* map)
+{
+ return new instance_culling_of_stratholme(map);
+}
+
+void AddSC_instance_culling_of_stratholme()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_culling_of_stratholme";
+ newscript->GetInstanceData = GetInstanceData_instance_culling_of_stratholme;
+ 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 7a2e8239cac..872f7b2fcaf 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -60,7 +60,7 @@ struct TRINITY_DLL_DECL boss_aeonusAI : public ScriptedAI
Frenzy_Timer = 120000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
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 dc8723b7201..b4a4ffd04f8 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -58,7 +58,7 @@ struct TRINITY_DLL_DECL boss_chrono_lord_dejaAI : public ScriptedAI
TimeLapse_Timer = 15000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
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 1efa7c75a2c..56b434373bd 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -60,7 +60,7 @@ struct TRINITY_DLL_DECL boss_temporusAI : public ScriptedAI
SpellReflection_Timer = 40000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/dark_portal.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/dark_portal.cpp
index e64a867a641..e69973c5fa5 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/dark_portal.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/dark_portal.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -79,8 +79,8 @@ struct TRINITY_DLL_DECL npc_medivh_bmAI : public ScriptedAI
if (pInstance->GetData(TYPE_MEDIVH) == IN_PROGRESS)
m_creature->CastSpell(m_creature,SPELL_CHANNEL,true);
- else if (m_creature->HasAura(SPELL_CHANNEL,0))
- m_creature->RemoveAura(SPELL_CHANNEL,0);
+ else if (m_creature->HasAura(SPELL_CHANNEL))
+ m_creature->RemoveAura(SPELL_CHANNEL);
m_creature->CastSpell(m_creature,SPELL_PORTAL_RUNE,true);
}
@@ -92,7 +92,7 @@ struct TRINITY_DLL_DECL npc_medivh_bmAI : public ScriptedAI
if (who->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(who, 10.0f))
{
- if (pInstance->GetData(TYPE_MEDIVH) == IN_PROGRESS)
+ if (pInstance->GetData(TYPE_MEDIVH) == IN_PROGRESS || pInstance->GetData(TYPE_MEDIVH) == DONE)
return;
DoScriptText(SAY_INTRO, m_creature);
@@ -127,7 +127,7 @@ struct TRINITY_DLL_DECL npc_medivh_bmAI : public ScriptedAI
//ScriptedAI::AttackStart(who);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void SpellHit(Unit* caster, const SpellEntry* spell)
{
@@ -156,13 +156,13 @@ struct TRINITY_DLL_DECL npc_medivh_bmAI : public ScriptedAI
if (SpellCorrupt_Timer)
{
- if (SpellCorrupt_Timer < diff)
+ if (SpellCorrupt_Timer <= diff)
{
pInstance->SetData(TYPE_MEDIVH,SPECIAL);
- if (m_creature->HasAura(SPELL_CORRUPT_AEONUS,0))
+ if (m_creature->HasAura(SPELL_CORRUPT_AEONUS))
SpellCorrupt_Timer = 1000;
- else if (m_creature->HasAura(SPELL_CORRUPT,0))
+ else if (m_creature->HasAura(SPELL_CORRUPT))
SpellCorrupt_Timer = 3000;
else
SpellCorrupt_Timer = 0;
@@ -171,7 +171,7 @@ struct TRINITY_DLL_DECL npc_medivh_bmAI : public ScriptedAI
if (Check_Timer)
{
- if (Check_Timer < diff)
+ if (Check_Timer <= diff)
{
uint32 pct = pInstance->GetData(DATA_SHIELD);
@@ -181,7 +181,6 @@ struct TRINITY_DLL_DECL npc_medivh_bmAI : public ScriptedAI
{
DoScriptText(SAY_WEAK25, m_creature);
Life25 = false;
- Check_Timer = 0;
}
else if (Life50 && pct <= 50)
{
@@ -203,11 +202,16 @@ struct TRINITY_DLL_DECL npc_medivh_bmAI : public ScriptedAI
return;
}
- if (pInstance->GetData(TYPE_MEDIVH) == DONE)
+ if (pInstance->GetData(TYPE_RIFT) == DONE)
{
DoScriptText(SAY_WIN, m_creature);
Check_Timer = 0;
+
+ if (m_creature->HasAura(SPELL_CHANNEL))
+ m_creature->RemoveAura(SPELL_CHANNEL);
+
//TODO: start the post-event here
+ pInstance->SetData(TYPE_MEDIVH,DONE);
}
}else Check_Timer -= diff;
}
@@ -268,7 +272,7 @@ struct TRINITY_DLL_DECL npc_time_riftAI : public ScriptedAI
else mWaveId = 1;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void DoSummonAtRift(uint32 creature_entry)
{
@@ -334,7 +338,8 @@ struct TRINITY_DLL_DECL npc_time_riftAI : public ScriptedAI
debug_log("TSCR: npc_time_rift: not casting anylonger, i need to die.");
m_creature->setDeathState(JUST_DIED);
- pInstance->SetData(TYPE_RIFT,SPECIAL);
+ if (pInstance->GetData(TYPE_RIFT) == IN_PROGRESS)
+ pInstance->SetData(TYPE_RIFT,SPECIAL);
}
};
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/def_dark_portal.h b/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/def_dark_portal.h
index 61018f58118..7bfd8c917d7 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/def_dark_portal.h
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/def_dark_portal.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/instance_dark_portal.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/instance_dark_portal.cpp
index 830917a7ad1..697134cd82d 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/instance_dark_portal.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/instance_dark_portal.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -227,6 +227,7 @@ struct TRINITY_DLL_DECL instance_dark_portal : public ScriptedInstance
//this may be completed further out in the post-event
if (Unit *medivh = Unit::GetUnit(*player,MedivhGUID))
{
+ debug_log("TSCR: Instance Dark Portal: Event completed.");
player->GroupEventHappens(QUEST_OPENING_PORTAL,medivh);
player->GroupEventHappens(QUEST_MASTER_TOUCH,medivh);
}
@@ -302,11 +303,10 @@ struct TRINITY_DLL_DECL instance_dark_portal : public ScriptedInstance
if (Unit *medivh = Unit::GetUnit(*player,MedivhGUID))
{
- for(uint8 i = 0; i < 4; i++)
- {
- int tmp = rand()%4;
- if (tmp != CurrentRiftId)
- {
+ int tmp = rand()%(4-1);
+
+ if (tmp >= CurrentRiftId)
+ tmp++;
debug_log("TSCR: Instance Dark Portal: Creating Time Rift at locationId %i (old locationId was %u).",tmp,CurrentRiftId);
CurrentRiftId = tmp;
@@ -334,9 +334,6 @@ struct TRINITY_DLL_DECL instance_dark_portal : public ScriptedInstance
}
}
}
- break;
- }
- }
}
}
@@ -354,7 +351,7 @@ struct TRINITY_DLL_DECL instance_dark_portal : public ScriptedInstance
if (NextPortal_Timer)
{
- if (NextPortal_Timer < diff)
+ if (NextPortal_Timer <= diff)
{
++mRiftPortalCount;
UpdateBMWorldState(WORLD_STATE_BM_RIFT,mRiftPortalCount);
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp
index cae3a17ff02..de86ca23242 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp
@@ -70,7 +70,7 @@ struct TRINITY_DLL_DECL boss_anetheronAI : public hyjal_trashAI
pInstance->SetData(DATA_ANETHERONEVENT, NOT_STARTED);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance && IsEvent)
pInstance->SetData(DATA_ANETHERONEVENT, IN_PROGRESS);
@@ -242,7 +242,7 @@ struct TRINITY_DLL_DECL mob_towering_infernalAI : public ScriptedAI
CheckTimer = 5000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -259,11 +259,8 @@ struct TRINITY_DLL_DECL mob_towering_infernalAI : public ScriptedAI
void MoveInLineOfSight(Unit *who)
{
- if (m_creature->GetDistance(who) <= 50 && !InCombat && m_creature->IsHostileTo(who))
- {
- m_creature->AddThreat(who,0.0);
- m_creature->Attack(who,false);
- }
+ if (m_creature->GetDistance(who) <= 50 && !m_creature->isInCombat() && m_creature->IsHostileTo(who))
+ AttackStart(who);
}
void UpdateAI(const uint32 diff)
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 4476a47d04c..ca3d8296f35 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -6,12 +6,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
*/
/* ScriptData
@@ -40,9 +40,9 @@ EndScriptData */
#define SAY_SOUL_CHARGE1 -1534029
#define SAY_SOUL_CHARGE2 -1534030
-#define SPELL_DENOUEMENT_WISP 32124
-#define SPELL_ANCIENT_SPARK 39349
-#define SPELL_PROTECTION_OF_ELUNE 38528
+#define SPELL_DENOUEMENT_WISP 32124
+#define SPELL_ANCIENT_SPARK 39349
+#define SPELL_PROTECTION_OF_ELUNE 38528
#define SPELL_DRAIN_WORLD_TREE 39140
#define SPELL_DRAIN_WORLD_TREE_2 39141
@@ -53,8 +53,7 @@ EndScriptData */
#define SPELL_GRIP_OF_THE_LEGION 31972
#define SPELL_DOOMFIRE_STRIKE 31903 //summons two creatures
#define SPELL_DOOMFIRE_SPAWN 32074
-#define SPELL_DOOMFIRE_VISUAL 42344 // This is actually a Zul'Aman spell, but the proper Doomfire spell sometimes freezes the server if a player stands in it for too long
-#define SPELL_DOOMFIRE_DAMAGE 31944
+#define SPELL_DOOMFIRE 31945
#define SPELL_SOUL_CHARGE_YELLOW 32045
#define SPELL_SOUL_CHARGE_GREEN 32051
#define SPELL_SOUL_CHARGE_RED 32052
@@ -65,7 +64,7 @@ EndScriptData */
#define CREATURE_ARCHIMONDE 17968
#define CREATURE_DOOMFIRE 18095
-#define CREATURE_DOOMFIRE_TARGETING 18104
+#define CREATURE_DOOMFIRE_SPIRIT 18104
#define CREATURE_ANCIENT_WISP 17946
#define CREATURE_CHANNEL_TARGET 22418
@@ -92,26 +91,26 @@ struct mob_ancient_wispAI : public ScriptedAI
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void DamageTaken(Unit* done_by, uint32 &damage) { damage = 0; }
void UpdateAI(const uint32 diff)
{
- if(!ArchimondeGUID)
+ if (!ArchimondeGUID)
{
- if(pInstance)
+ if (pInstance)
ArchimondeGUID = pInstance->GetData64(DATA_ARCHIMONDE);
}
- if(CheckTimer < diff)
+ if (CheckTimer < diff)
{
- if(ArchimondeGUID)
+ if (ArchimondeGUID)
{
Unit* Archimonde = Unit::GetUnit((*m_creature), ArchimondeGUID);
- if(Archimonde)
+ if (Archimonde)
{
- if((((Archimonde->GetHealth()*100) / Archimonde->GetMaxHealth()) < 2) || !Archimonde->isAlive())
+ if ((((Archimonde->GetHealth()*100) / Archimonde->GetMaxHealth()) < 2) || !Archimonde->isAlive())
DoCast(m_creature, SPELL_DENOUEMENT_WISP);
else
DoCast(Archimonde, SPELL_ANCIENT_SPARK);
@@ -122,186 +121,65 @@ struct mob_ancient_wispAI : public ScriptedAI
}
};
-/* This script controls the Doomfire mob. Unlike the other Doomfire mob, this one does not stalk players.
- Instead, this doomfire will simply stand in one place after spawning and deal damage to any players that
- are within 3 yards. Another creature called Doomfire Targetting spawns this creature as well as stalks. */
+/* This script is merely a placeholder for the Doomfire that triggers Doomfire spell. It will
+ MoveChase the Doomfire Spirit always, until despawn (AttackStart is called upon it's spawn) */
struct TRINITY_DLL_DECL mob_doomfireAI : public ScriptedAI
{
mob_doomfireAI(Creature* c) : ScriptedAI(c) {}
- uint32 CheckTimer;
- uint32 RefreshTimer;
-
- bool TargetSelected;
-
- uint64 ArchimondeGUID;
- uint64 TargetGUID;
-
- void Reset()
- {
- CheckTimer = 5000;
- RefreshTimer = 0;
-
- TargetSelected = false;
-
- ArchimondeGUID = 0;
- TargetGUID = 0;
- }
+ void Reset() { }
+ void MoveInLineOfSight(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void DamageTaken(Unit *done_by, uint32 &damage) { damage = 0; }
-
- void Aggro(Unit* who) { }
-
- void MoveInLineOfSight(Unit* who)
- {
- // Do not do anything if who does not exist, or we are refreshing our timer, or who is Doomfire, Archimonde or Doomfire targetting
- if(!who || who == m_creature || RefreshTimer || who->GetEntry() == CREATURE_ANCIENT_WISP ||
- who->GetEntry() == CREATURE_ARCHIMONDE || who->GetEntry() == CREATURE_DOOMFIRE ||
- who->GetEntry() == CREATURE_DOOMFIRE_TARGETING || !who->isTargetableForAttack())
- return;
-
- if(m_creature->IsWithinDistInMap(who, 3))
- {
- TargetSelected = true;
- TargetGUID = who->GetGUID();
- RefreshTimer = 2000;
- }
- }
-
- void KilledUnit(Unit* victim)
- {
- bool suicide = true;
- if(ArchimondeGUID)
- {
- Creature* Archimonde = (Unit::GetCreature((*m_creature), ArchimondeGUID));
- if(Archimonde && Archimonde->isAlive())
- {
- suicide = false;
- Archimonde->AI()->KilledUnit(victim);
- }
- }
-
- if(suicide)
- m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- }
-
- void UpdateAI(const uint32 diff)
- {
- if(RefreshTimer < diff)
- RefreshTimer = 0;
- else RefreshTimer -= diff;
-
- if(TargetSelected && TargetGUID)
- {
- Unit* target = Unit::GetUnit((*m_creature), TargetGUID);
- if(target && target->isAlive())
- {
- target->CastSpell(target, SPELL_DOOMFIRE_DAMAGE, true);
- TargetGUID = 0;
- TargetSelected = false;
- }
- }
-
- if(CheckTimer < diff)
- {
- if(ArchimondeGUID)
- {
- Unit* Archimonde = Unit::GetUnit((*m_creature), ArchimondeGUID);
- if(!Archimonde || !Archimonde->isAlive())
- m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- CheckTimer = 5000;
- }
- else m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- }else CheckTimer -= diff;
- }
};
-/* This is the script for the Doomfire Targetting Mob. This mob simply follows players and/or travels in random directions and spawns the actual Doomfire which does damage to anyone that moves close. */
+/* This is the script for the Doomfire Spirit Mob. This mob simply follow players or
+ travels in random directions if target cannot be found. */
struct TRINITY_DLL_DECL mob_doomfire_targettingAI : public ScriptedAI
{
mob_doomfire_targettingAI(Creature* c) : ScriptedAI(c) {}
+ uint64 TargetGUID;
uint32 ChangeTargetTimer;
- uint32 SummonTimer; // This timer will serve as both a summon timer for the doomfire that does damage as well as to check on Archionde
-
- uint64 ArchimondeGUID;
void Reset()
{
+ TargetGUID = 0;
ChangeTargetTimer = 5000;
- SummonTimer = 1000;
-
- ArchimondeGUID = 0;
}
- void Aggro(Unit* who) {}
-
void MoveInLineOfSight(Unit* who)
{
- // Do not do anything if who does not exist, or who is Doomfire, Archimonde or Doomfire targetting
- if(!who || who == m_creature || who->GetEntry() == CREATURE_ARCHIMONDE
- || who->GetEntry() == CREATURE_DOOMFIRE || who->GetEntry() == CREATURE_DOOMFIRE_TARGETING || !who->isTargetableForAttack())
- return;
-
- m_creature->AddThreat(who, 0.0f);
+ //will update once TargetGUID is 0. In case noone actually moves(not likely) and this is 0
+ //when UpdateAI needs it, it will be forced to select randomPoint
+ if (!TargetGUID && who->GetTypeId() == TYPEID_PLAYER)
+ TargetGUID = who->GetGUID();
}
+ void EnterCombat(Unit* who) {}
+
void DamageTaken(Unit *done_by, uint32 &damage) { damage = 0; }
void UpdateAI(const uint32 diff)
{
- if(!UpdateVictim())
- return;
-
- if(SummonTimer < diff)
+ if (ChangeTargetTimer < diff)
{
- if(ArchimondeGUID)
+ if (Unit *temp = Unit::GetUnit(*m_creature,TargetGUID))
{
- Unit* Archimonde = Unit::GetUnit((*m_creature), ArchimondeGUID);
- if(Archimonde && Archimonde->isAlive())
- {
- Creature* Doomfire = DoSpawnCreature(CREATURE_DOOMFIRE, 0, 0, 2, 0, TEMPSUMMON_TIMED_DESPAWN, 30000);
- if(Doomfire)
- {
- Doomfire->CastSpell(Doomfire, SPELL_DOOMFIRE_VISUAL, true);
- ((mob_doomfireAI*)Doomfire->AI())->ArchimondeGUID = ArchimondeGUID;
- Doomfire->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- }
- SummonTimer = 500;
- }
- else
- m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ m_creature->GetMotionMaster()->MoveFollow(temp,0.0f,0.0f);
+ TargetGUID = 0;
}
else
- m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- }else SummonTimer -= diff;
-
- if(ChangeTargetTimer < diff)
- {
- Unit* target = NULL;
- switch(rand()%2)
{
- case 0: // stalk player
- target = SelectUnit(SELECT_TARGET_RANDOM, 1);
- if(target && target->isAlive())
- {
- m_creature->AddThreat(target, DoGetThreat(m_creature->getVictim()));
- m_creature->GetMotionMaster()->MoveChase(target);
- }
- break;
-
- case 1: // random location
- float x = 0;
- float y = 0;
- float z = 0;
- m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 40, x, y, z);
- m_creature->GetMotionMaster()->MovePoint(0, x, y, z);
- break;
+ float x,y,z = 0.0;
+ m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 40, x, y, z);
+ m_creature->GetMotionMaster()->MovePoint(0, x, y, z);
}
+
ChangeTargetTimer = 5000;
}else ChangeTargetTimer -= diff;
}
-
};
/* Finally, Archimonde's script. His script isn't extremely complex, most are simply spells on timers.
@@ -309,8 +187,8 @@ struct TRINITY_DLL_DECL mob_doomfire_targettingAI : public ScriptedAI
hardest bit to code. Finger of Death is simply a distance check - if no one is in melee range, then
select a random target and cast the spell on them. However, if someone IS in melee range, and this
is NOT the main tank (creature's victim), then we aggro that player and they become the new victim.
- For Doomfire, we summon a mob (Doomfire Targetting) that summons another mob (Doomfire every second)
- Doomfire Targetting 'stalks' players whilst Doomfire damages player that are within range. */
+ For Doomfire, we summon a mob (Doomfire Spirit) for the Doomfire mob to follow. It's spirit will
+ randomly select it's target to follow and then we create the random movement making it unpredictable. */
// This is used to sort by distance in order to see who is the closest target, when checking for Finger of Death
struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool>
@@ -333,6 +211,9 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public hyjal_trashAI
ScriptedInstance* pInstance;
+ uint64 DoomfireSpiritGUID;
+ uint64 WorldTreeGUID;
+
uint32 DrainNordrassilTimer;
uint32 FearTimer;
uint32 AirBurstTimer;
@@ -354,10 +235,13 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public hyjal_trashAI
void Reset()
{
- if(pInstance)
+ if (pInstance)
pInstance->SetData(DATA_ARCHIMONDEEVENT, NOT_STARTED);
+ DoomfireSpiritGUID = 0;
damageTaken = 0;
+ WorldTreeGUID = 0;
+
DrainNordrassilTimer = 0;
FearTimer = 42000;
AirBurstTimer = 30000;
@@ -378,13 +262,13 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public hyjal_trashAI
IsChanneling = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
m_creature->InterruptSpell(CURRENT_CHANNELED_SPELL);
DoScriptText(SAY_AGGRO, m_creature);
DoZoneInCombat();
- if(pInstance)
+ if (pInstance)
pInstance->SetData(DATA_ARCHIMONDEEVENT, IN_PROGRESS);
}
@@ -392,12 +276,12 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public hyjal_trashAI
{
switch(rand()%2)
{
- case 0: DoScriptText(SAY_SLAY1, m_creature); break;
- case 1: DoScriptText(SAY_SLAY2, m_creature); break;
- case 2: DoScriptText(SAY_SLAY3, m_creature); break;
+ case 0: DoScriptText(SAY_SLAY1, m_creature); break;
+ case 1: DoScriptText(SAY_SLAY2, m_creature); break;
+ case 2: DoScriptText(SAY_SLAY3, m_creature); break;
}
- if(victim && (victim->GetTypeId() == TYPEID_PLAYER))
+ if (victim && (victim->GetTypeId() == TYPEID_PLAYER))
GainSoulCharge(((Player*)victim));
}
@@ -431,7 +315,7 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public hyjal_trashAI
hyjal_trashAI::JustDied(victim);
DoScriptText(SAY_DEATH, m_creature);
- if(pInstance)
+ if (pInstance)
pInstance->SetData(DATA_ARCHIMONDEEVENT, DONE);
}
@@ -439,11 +323,11 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public hyjal_trashAI
{
// First we check if our current victim is in melee range or not.
Unit* victim = m_creature->getVictim();
- if(victim && m_creature->IsWithinDistInMap(victim, m_creature->GetAttackDistance(victim)))
+ if (victim && m_creature->IsWithinDistInMap(victim, m_creature->GetAttackDistance(victim)))
return false;
std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
- if(m_threatlist.empty())
+ if (m_threatlist.empty())
return false;
std::list<Unit*> targets;
@@ -451,56 +335,70 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public hyjal_trashAI
for( ; itr != m_threatlist.end(); ++itr)
{
Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid());
- if(pUnit && pUnit->isAlive())
+ if (pUnit && pUnit->isAlive())
targets.push_back(pUnit);
}
- if(targets.empty())
+ if (targets.empty())
return false;
targets.sort(TargetDistanceOrder(m_creature));
Unit* target = targets.front();
- if(target)
+ if (target)
{
- if(!m_creature->IsWithinDistInMap(target, m_creature->GetAttackDistance(target)))
+ if (!m_creature->IsWithinDistInMap(target, m_creature->GetAttackDistance(target)))
return true; // Cast Finger of Death
else // This target is closest, he is our new tank
- m_creature->AddThreat(target, DoGetThreat(m_creature->getVictim()));
+ m_creature->AddThreat(target, m_creature->getThreatManager().getThreat(m_creature->getVictim()));
}
return false;
}
- void SummonDoomfire(Unit* target)
+ void JustSummoned(Creature *summoned)
{
- Creature* Doomfire = DoSpawnCreature(CREATURE_DOOMFIRE_TARGETING, rand()%30, rand()%30, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 30000);
- if(Doomfire)
+ summoned->setFaction(m_creature->getFaction());
+ summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
+ if (summoned->GetEntry() == CREATURE_DOOMFIRE_SPIRIT)
{
- ((mob_doomfire_targettingAI*)Doomfire->AI())->ArchimondeGUID = m_creature->GetGUID();
- Doomfire->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- // Give Doomfire a taste of everyone in the threatlist = more targets to chase.
- std::list<HostilReference*>::iterator itr;
- for(itr = m_creature->getThreatManager().getThreatList().begin(); itr != m_creature->getThreatManager().getThreatList().end(); ++itr)
- Doomfire->AddThreat(Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()), 1.0f);
- Doomfire->setFaction(m_creature->getFaction());
- DoCast(Doomfire, SPELL_DOOMFIRE_SPAWN);
- Doomfire->CastSpell(Doomfire, SPELL_DOOMFIRE_VISUAL, true);
- if(target)
- Doomfire->AI()->AttackStart(target);
-
- if(rand()%2 == 0)
- DoScriptText(SAY_DOOMFIRE1, m_creature);
- else
- DoScriptText(SAY_DOOMFIRE2, m_creature);
+ DoomfireSpiritGUID = summoned->GetGUID();
+ }
+
+ if (summoned->GetEntry() == CREATURE_DOOMFIRE)
+ {
+ summoned->CastSpell(summoned,SPELL_DOOMFIRE_SPAWN,false);
+ summoned->CastSpell(summoned,SPELL_DOOMFIRE,true,0,0,m_creature->GetGUID());
+
+ if (Unit *DoomfireSpirit = Unit::GetUnit(*m_creature, DoomfireSpiritGUID))
+ {
+ summoned->GetMotionMaster()->MoveFollow(DoomfireSpirit,0.0f,0.0f);
+ DoomfireSpiritGUID = 0;
+ }
}
}
+ //this is code doing close to what the summoning spell would do (spell 31903)
+ void SummonDoomfire(Unit* target)
+ {
+ m_creature->SummonCreature(CREATURE_DOOMFIRE_SPIRIT,
+ target->GetPositionX()+15.0,target->GetPositionY()+15.0,target->GetPositionZ(),0,
+ TEMPSUMMON_TIMED_DESPAWN, 27000);
+
+ m_creature->SummonCreature(CREATURE_DOOMFIRE,
+ target->GetPositionX()-15.0,target->GetPositionY()-15.0,target->GetPositionZ(),0,
+ TEMPSUMMON_TIMED_DESPAWN, 27000);
+ }
+
void UnleashSoulCharge()
{
m_creature->InterruptNonMeleeSpells(false);
+
bool HasCast = false;
uint32 chargeSpell = 0;
uint32 unleashSpell = 0;
+
switch(rand()%3)
{
case 0:
@@ -516,42 +414,48 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public hyjal_trashAI
unleashSpell = SPELL_UNLEASH_SOUL_GREEN;
break;
}
- if(m_creature->HasAura(chargeSpell, 0))
+
+ if (m_creature->HasAura(chargeSpell))
{
- m_creature->RemoveSingleAuraFromStack(chargeSpell, 0);
+ m_creature->RemoveAuraFromStack(chargeSpell);
DoCast(m_creature->getVictim(), unleashSpell);
HasCast = true;
SoulChargeCount--;
}
- if(HasCast)
+
+ if (HasCast)
SoulChargeTimer = 2000 + rand()%28000;
}
void UpdateAI(const uint32 diff)
{
- if(!InCombat)
+ if (!m_creature->isInCombat())
{
- if(pInstance)
+ if (pInstance)
{
// Do not let the raid skip straight to Archimonde. Visible and hostile ONLY if Azagalor is finished.
- if((pInstance->GetData(DATA_AZGALOREVENT) < DONE) && ((m_creature->GetVisibility() != VISIBILITY_OFF) || (m_creature->getFaction() != 35)))
+ if ((pInstance->GetData(DATA_AZGALOREVENT) < DONE) && ((m_creature->GetVisibility() != VISIBILITY_OFF) || (m_creature->getFaction() != 35)))
{
m_creature->SetVisibility(VISIBILITY_OFF);
m_creature->setFaction(35);
}
- else if((pInstance->GetData(DATA_AZGALOREVENT) >= DONE) && ((m_creature->GetVisibility() != VISIBILITY_ON) || (m_creature->getFaction() == 35)))
+ else if ((pInstance->GetData(DATA_AZGALOREVENT) >= DONE) && ((m_creature->GetVisibility() != VISIBILITY_ON) || (m_creature->getFaction() == 35)))
{
m_creature->setFaction(1720);
m_creature->SetVisibility(VISIBILITY_ON);
}
}
- if(DrainNordrassilTimer < diff)
+ if (DrainNordrassilTimer < diff)
{
- if(!IsChanneling)
+ if (!IsChanneling)
{
- Creature* Nordrassil = m_creature->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 1200000);
- if(Nordrassil)
+ Creature *temp = m_creature->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 1200000);
+
+ if (temp)
+ WorldTreeGUID = temp->GetGUID();
+
+ if (Unit *Nordrassil = Unit::GetUnit(*m_creature, WorldTreeGUID))
{
Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
Nordrassil->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686);
@@ -559,26 +463,24 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public hyjal_trashAI
IsChanneling = true;
}
}
- Creature* Nordrassil = m_creature->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 5000);
- if(Nordrassil)
+
+ if (Unit *Nordrassil = Unit::GetUnit(*m_creature, WorldTreeGUID))
{
- Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- Nordrassil->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686);
Nordrassil->CastSpell(m_creature, SPELL_DRAIN_WORLD_TREE_2, true);
DrainNordrassilTimer = 1000;
}
}else DrainNordrassilTimer -= diff;
}
- if(!UpdateVictim())
+ if (!UpdateVictim() )
return;
- if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 10) && !BelowTenPercent && !Enraged)
+ if (((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 10) && !BelowTenPercent && !Enraged)
BelowTenPercent = true;
- if(!Enraged)
+ if (!Enraged)
{
- if(EnrageTimer < diff)
+ if (EnrageTimer < diff)
{
if((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) > 10)
{
@@ -589,14 +491,15 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public hyjal_trashAI
}
}else EnrageTimer -= diff;
- if(CheckDistanceTimer < diff)
+ if (CheckDistanceTimer < diff)
{
// To simplify the check, we simply summon a creature in the location and then check how far we are from the creature
Creature* Check = m_creature->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 2000);
- if(Check)
+ if (Check)
{
Check->SetVisibility(VISIBILITY_OFF);
- if(m_creature->IsWithinDistInMap(Check, 75))
+
+ if (m_creature->IsWithinDistInMap(Check, 75))
{
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveIdle();
@@ -608,22 +511,23 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public hyjal_trashAI
}else CheckDistanceTimer -= diff;
}
- if(BelowTenPercent)
+ if (BelowTenPercent)
{
- if(!HasProtected)
+ if (!HasProtected)
{
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveIdle();
+
//all members of raid must get this buff
DoCast(m_creature->getVictim(), SPELL_PROTECTION_OF_ELUNE);
HasProtected = true;
Enraged = true;
}
- if(SummonWispTimer < diff)
+ if (SummonWispTimer < diff)
{
Creature* Wisp = DoSpawnCreature(CREATURE_ANCIENT_WISP, rand()%40, rand()%40, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if(Wisp)
+ if (Wisp)
{
Wisp->AI()->AttackStart(m_creature);
((mob_ancient_wispAI*)Wisp->AI())->ArchimondeGUID = m_creature->GetGUID();
@@ -632,13 +536,13 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public hyjal_trashAI
++WispCount;
}else SummonWispTimer -= diff;
- if(WispCount >= 30)
+ if (WispCount >= 30)
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}
- if(Enraged)
+ if (Enraged)
{
- if(HandOfDeathTimer < diff)
+ if (HandOfDeathTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_HAND_OF_DEATH);
HandOfDeathTimer = 2000;
@@ -646,46 +550,57 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public hyjal_trashAI
return; // Don't do anything after this point.
}
- if(SoulChargeCount)
+ if (SoulChargeCount)
{
- if(SoulChargeTimer < diff)
+ if (SoulChargeTimer < diff)
UnleashSoulCharge();
else SoulChargeTimer -= diff;
}
- if(GripOfTheLegionTimer < diff)
+ if (GripOfTheLegionTimer < diff)
{
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_GRIP_OF_THE_LEGION);
GripOfTheLegionTimer = 5000 + rand()%20000;
}else GripOfTheLegionTimer -= diff;
- if(AirBurstTimer < diff)
+ if (AirBurstTimer < diff)
{
- if(rand()%2 == 0)
+ if (rand()%2 == 0)
DoScriptText(SAY_AIR_BURST1, m_creature);
else
DoScriptText(SAY_AIR_BURST2, m_creature);
-
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 1), SPELL_AIR_BURST);//not on tank
AirBurstTimer = 25000 + rand()%15000;
}else AirBurstTimer -= diff;
- if(FearTimer < diff)
+ if (FearTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_FEAR);
FearTimer = 42000;
}else FearTimer -= diff;
- if(DoomfireTimer < diff)
+ if (DoomfireTimer < diff)
{
- SummonDoomfire(SelectUnit(SELECT_TARGET_RANDOM, 1));
- DoomfireTimer = 40000;
+ if (rand()%2 == 0)
+ DoScriptText(SAY_DOOMFIRE1, m_creature);
+ else
+ DoScriptText(SAY_DOOMFIRE2, m_creature);
+
+ Unit *temp = SelectUnit(SELECT_TARGET_RANDOM, 1);
+ if (!temp)
+ temp = m_creature->getVictim();
+
+ //replace with spell cast 31903 once implicitTarget 73 implemented
+ SummonDoomfire(temp);
+
+ //supposedly three doomfire can be up at the same time
+ DoomfireTimer = 20000;
}else DoomfireTimer -= diff;
- if(MeleeRangeCheckTimer < diff)
+ if (MeleeRangeCheckTimer < diff)
{
- if(CanUseFingerOfDeath())
+ if (CanUseFingerOfDeath())
{
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH);
MeleeRangeCheckTimer = 1000;
@@ -723,7 +638,7 @@ void AddSC_boss_archimonde()
{
Script *newscript;
newscript = new Script;
- newscript->Name="boss_archimonde";
+ newscript->Name = "boss_archimonde";
newscript->GetAI = &GetAI_boss_archimonde;
newscript->RegisterSelf();
@@ -742,4 +657,3 @@ void AddSC_boss_archimonde()
newscript->GetAI = &GetAI_mob_ancient_wisp;
newscript->RegisterSelf();
}
-
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp
index 9bdee9887e5..44eebba1d5e 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp
@@ -63,7 +63,7 @@ struct TRINITY_DLL_DECL boss_azgalorAI : public hyjal_trashAI
pInstance->SetData(DATA_AZGALOREVENT, NOT_STARTED);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance && IsEvent)
pInstance->SetData(DATA_AZGALOREVENT, IN_PROGRESS);
@@ -206,7 +206,7 @@ struct TRINITY_DLL_DECL mob_lesser_doomguardAI : public hyjal_trashAI
CheckTimer = 5000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -222,11 +222,8 @@ struct TRINITY_DLL_DECL mob_lesser_doomguardAI : public hyjal_trashAI
void MoveInLineOfSight(Unit *who)
{
- if (m_creature->GetDistance(who) <= 50 && !InCombat && m_creature->IsHostileTo(who))
- {
- m_creature->AddThreat(who,0.0);
- m_creature->Attack(who,false);
- }
+ if (m_creature->GetDistance(who) <= 50 && !m_creature->isInCombat() && m_creature->IsHostileTo(who))
+ AttackStart(who);
}
void JustDied(Unit *victim)
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_kazrogal.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_kazrogal.cpp
index 33c6ec44cf9..7ab9000d05f 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_kazrogal.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_kazrogal.cpp
@@ -58,7 +58,7 @@ struct TRINITY_DLL_DECL boss_kazrogalAI : public hyjal_trashAI
pInstance->SetData(DATA_KAZROGALEVENT, NOT_STARTED);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance && IsEvent)
pInstance->SetData(DATA_KAZROGALEVENT, IN_PROGRESS);
@@ -145,7 +145,7 @@ struct TRINITY_DLL_DECL boss_kazrogalAI : public hyjal_trashAI
WarStompTimer = 60000;
}else WarStompTimer -= diff;
- if(m_creature->HasAura(SPELL_MARK,0))
+ if(m_creature->HasAura(SPELL_MARK))
m_creature->RemoveAurasDueToSpell(SPELL_MARK);
if(MarkTimer < diff)
{
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp
index ddf5e0ad715..f198ed483d1 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp
@@ -58,7 +58,7 @@ struct TRINITY_DLL_DECL boss_rage_winterchillAI : public hyjal_trashAI
pInstance->SetData(DATA_RAGEWINTERCHILLEVENT, NOT_STARTED);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance && IsEvent)
pInstance->SetData(DATA_RAGEWINTERCHILLEVENT, IN_PROGRESS);
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/def_hyjal.h b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/def_hyjal.h
index ed02258cd9f..7d81dbe4993 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/def_hyjal.h
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/def_hyjal.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
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 ad8206dce3e..5dc149b1b02 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
@@ -1,4 +1,4 @@
- /* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ /* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp
index 1c561140bec..d40d060dd88 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -354,6 +354,7 @@ void hyjalAI::Reset()
// Misc
WaveCount = 0;
+ EnemyCount = 0;
// Set faction properly based on creature entry
switch(m_creature->GetEntry())
@@ -419,14 +420,12 @@ void hyjalAI::EnterEvadeMode()
m_creature->GetMotionMaster()->MoveTargetedHome();
m_creature->SetLootRecipient(NULL);
-
- InCombat = false;
}
-void hyjalAI::Aggro(Unit *who)
+void hyjalAI::EnterCombat(Unit *who)
{
if(IsDummy)return;
- for(uint8 i = 0; i < 2; ++i)
+ for(uint8 i = 0; i < 3; ++i)
if(Spell[i].Cooldown)
SpellTimer[i] = Spell[i].Cooldown;
@@ -956,7 +955,7 @@ void hyjalAI::HideNearPos(float x, float y)
// First get all creatures.
std::list<Creature*> creatures;
Trinity::AllFriendlyCreaturesInGrid creature_check(m_creature);
- Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> creature_searcher(creatures, creature_check);
+ Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> creature_searcher(m_creature, creatures, creature_check);
TypeContainerVisitor
<Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid>,
GridTypeMapContainer> creature_visitor(creature_searcher);
@@ -982,7 +981,7 @@ void hyjalAI::RespawnNearPos(float x, float y)
cell.SetNoCreate();
Trinity::RespawnDo u_do;
- Trinity::WorldObjectWorker<Trinity::RespawnDo> worker(u_do);
+ Trinity::WorldObjectWorker<Trinity::RespawnDo> worker(m_creature, u_do);
TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, obj_worker, *m_creature->GetMap());
@@ -991,7 +990,7 @@ void hyjalAI::WaypointReached(uint32 i)
{
if(i == 1 || (i == 0 && m_creature->GetEntry() == THRALL))
{
- m_creature->Yell("Hurry, we don't have much time",0,0);
+ m_creature->MonsterYell("Hurry, we don't have much time",0,0);
WaitForTeleport = true;
TeleportTimer = 20000;
if(m_creature->GetEntry() == JAINA)
@@ -1016,7 +1015,7 @@ void hyjalAI::WaypointReached(uint32 i)
// First get all creatures.
std::list<Creature*> creatures;
Trinity::AllFriendlyCreaturesInGrid creature_check(m_creature);
- Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> creature_searcher(creatures, creature_check);
+ Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> creature_searcher(m_creature, creatures, creature_check);
TypeContainerVisitor
<Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid>,
GridTypeMapContainer> creature_visitor(creature_searcher);
@@ -1058,7 +1057,7 @@ void hyjalAI::DoOverrun(uint32 faction, const uint32 diff)
std::list<Creature*> creatures;
Trinity::AllFriendlyCreaturesInGrid creature_check(m_creature);
- Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> creature_searcher(creatures, creature_check);
+ Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> creature_searcher(m_creature, creatures, creature_check);
TypeContainerVisitor
<Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid>,
GridTypeMapContainer> creature_visitor(creature_searcher);
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.h b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.h
index 4a2fbd6494e..2eae91ad7c1 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.h
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
@@ -161,7 +161,7 @@ struct TRINITY_DLL_DECL hyjalAI : public npc_escortAI
void EnterEvadeMode(); // Send creature back to spawn location and evade.
- void Aggro(Unit *who); // Used to reset cooldowns for our spells and to inform the raid that we're under attack
+ void EnterCombat(Unit *who); // Used to reset cooldowns for our spells and to inform the raid that we're under attack
void UpdateAI(const uint32 diff); // Called to summon waves, check for boss deaths and to cast our spells.
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp
index 998db444cfb..d46b9f7a77e 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp
@@ -139,8 +139,6 @@ float HordeOverrunWP[21][3]=//waypoints in the horde base used in the end in the
{5429.91,-2718.44,1493.42}//20 end 2
};
-void hyjal_trashAI::Reset(){}
-
hyjal_trashAI::hyjal_trashAI(Creature *c) : npc_escortAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
@@ -166,8 +164,6 @@ void hyjal_trashAI::DamageTaken(Unit *done_by, uint32 &damage)
}
}
-void hyjal_trashAI::Aggro(Unit *who){}
-
void hyjal_trashAI::UpdateAI(const uint32 diff)
{
if(IsOverrun && !SetupOverrun)
@@ -407,7 +403,7 @@ struct mob_giant_infernalAI : public hyjal_trashAI
imol = false;
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void WaypointReached(uint32 i)
{
@@ -441,7 +437,7 @@ struct mob_giant_infernalAI : public hyjal_trashAI
{
trigger->SetVisibility(VISIBILITY_OFF);
trigger->setFaction(m_creature->getFaction());
- trigger->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ trigger->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
trigger->CastSpell(m_creature,SPELL_METEOR,true);
}
m_creature->GetMotionMaster()->Clear();
@@ -553,7 +549,7 @@ struct mob_abominationAI : public hyjal_trashAI
}
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void UpdateAI(const uint32 diff)
{
@@ -583,7 +579,7 @@ struct mob_abominationAI : public hyjal_trashAI
}
}
}
- if(!m_creature->HasAura(SPELL_DISEASE_CLOUD,0))
+ if(!m_creature->HasAura(SPELL_DISEASE_CLOUD))
DoCast(m_creature,SPELL_DISEASE_CLOUD);
if (!UpdateVictim())
return;
@@ -654,7 +650,7 @@ struct mob_ghoulAI : public hyjal_trashAI
}
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void UpdateAI(const uint32 diff)
{
@@ -773,7 +769,7 @@ struct mob_necromancerAI : public hyjal_trashAI
}
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void UpdateAI(const uint32 diff)
{
@@ -865,7 +861,7 @@ struct mob_bansheeAI : public hyjal_trashAI
}
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void UpdateAI(const uint32 diff)
{
@@ -960,7 +956,7 @@ struct mob_crypt_fiendAI : public hyjal_trashAI
}
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void UpdateAI(const uint32 diff)
{
@@ -1046,7 +1042,7 @@ struct mob_fel_stalkerAI : public hyjal_trashAI
}
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void UpdateAI(const uint32 diff)
{
@@ -1115,7 +1111,7 @@ struct mob_frost_wyrmAI : public hyjal_trashAI
{
FrostBreathTimer = 5000;
MoveTimer = 0;
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
}
void WaypointReached(uint32 i)
@@ -1144,7 +1140,7 @@ struct mob_frost_wyrmAI : public hyjal_trashAI
m_creature->Relocate(x,y,z,0);
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void UpdateAI(const uint32 diff)
{
@@ -1231,7 +1227,7 @@ struct mob_gargoyleAI : public hyjal_trashAI
Zpos = 10.0;
StrikeTimer = 2000+rand()%5000;
MoveTimer = 0;
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
}
void WaypointReached(uint32 i)
@@ -1374,7 +1370,7 @@ struct TRINITY_DLL_DECL alliance_riflemanAI : public Scripted_NoMovementAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.h b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.h
index 1113ce4c8a2..e5e90e571b2 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.h
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.h
@@ -11,12 +11,6 @@ struct TRINITY_DLL_DECL hyjal_trashAI : public npc_escortAI
{
hyjal_trashAI(Creature *c);
- void Reset();
-
- //void EnterEvadeMode();
-
- void Aggro(Unit *who);
-
void UpdateAI(const uint32 diff);
void JustDied(Unit* killer);
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 9ce778b3600..5e6e4d9a152 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
@@ -1,4 +1,4 @@
- /* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ /* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -39,6 +39,9 @@ struct TRINITY_DLL_DECL instance_mount_hyjal : public ScriptedInstance
{
instance_mount_hyjal(Map *map) : ScriptedInstance(map) {Initialize();};
+ uint32 Encounters[ENCOUNTERS];
+ std::string str_data;
+
uint64 RageWinterchill;
uint64 Anetheron;
uint64 Kazrogal;
@@ -51,7 +54,7 @@ struct TRINITY_DLL_DECL instance_mount_hyjal : public ScriptedInstance
uint64 ElfGate;
uint32 Trash;
- uint32 Encounters[ENCOUNTERS];
+
uint32 hordeRetreat;
uint32 allianceRetreat;
@@ -98,29 +101,28 @@ struct TRINITY_DLL_DECL instance_mount_hyjal : public ScriptedInstance
case 182060:
HordeGate = go->GetGUID();
if(allianceRetreat)
- go->SetGoState(0);
+ go->SetGoState(GO_STATE_ACTIVE);
else
- go->SetGoState(1);
+ go->SetGoState(GO_STATE_READY);
break;
case 182061:
ElfGate = go->GetGUID();
if(hordeRetreat)
- go->SetGoState(0);
+ go->SetGoState(GO_STATE_ACTIVE);
else
- go->SetGoState(1);
+ go->SetGoState(GO_STATE_READY);
break;
}
}
void OpenDoor(uint64 DoorGUID, bool open)
{
- if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID))
- Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1);
+ HandleGameObject(DoorGUID, open, NULL);
}
void OnCreatureCreate(Creature *creature, uint32 creature_entry)
{
- switch(creature_entry)
+ switch(creature->GetEntry())
{
case 17767: RageWinterchill = creature->GetGUID(); break;
case 17808: Anetheron = creature->GetGUID(); break;
@@ -167,7 +169,7 @@ struct TRINITY_DLL_DECL instance_mount_hyjal : public ScriptedInstance
if(ArchiYell)break;
ArchiYell = true;
- Creature* pCreature = instance->GetCreatureInMap(Azgalor);
+ Creature* pCreature = instance->GetCreature(Azgalor);
if(pCreature)
{
Creature* pUnit = pCreature->SummonCreature(21987,pCreature->GetPositionX(),pCreature->GetPositionY(),pCreature->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,10000);
@@ -229,7 +231,21 @@ struct TRINITY_DLL_DECL instance_mount_hyjal : public ScriptedInstance
debug_log("TSCR: Instance Hyjal: Instance data updated for event %u (Data=%u)",type,data);
if(data == DONE)
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << Encounters[0] << " " << Encounters[1] << " " << Encounters[2] << " "
+ << Encounters[3] << " " << Encounters[4]
+ << " " << allianceRetreat << " " << hordeRetreat
+ << " " << RaidDamage;
+
+ str_data = saveStream.str();
+
SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
+ }
+
}
uint32 GetData(uint32 type)
@@ -265,19 +281,7 @@ struct TRINITY_DLL_DECL instance_mount_hyjal : public ScriptedInstance
const char* Save()
{
- OUT_SAVE_INST_DATA;
- std::ostringstream stream;
- stream << Encounters[0] << " " << Encounters[1] << " " << Encounters[2] << " "
- << Encounters[3] << " " << Encounters[4] << " " << allianceRetreat << " " << hordeRetreat << " " << RaidDamage;
- char* out = new char[stream.str().length() + 1];
- strcpy(out, stream.str().c_str());
- if(out)
- {
- OUT_SAVE_INST_DATA_COMPLETE;
- return out;
- }
-
- return NULL;
+ return str_data.c_str();
}
void Load(const char* in)
@@ -289,8 +293,7 @@ struct TRINITY_DLL_DECL instance_mount_hyjal : public ScriptedInstance
}
OUT_LOAD_INST_DATA(in);
- std::istringstream loadStream;
- loadStream.str(in);
+ std::istringstream loadStream(in);
loadStream >> Encounters[0] >> Encounters[1] >> Encounters[2] >> Encounters[3] >> Encounters[4] >> allianceRetreat >> hordeRetreat >> RaidDamage;
for(uint8 i = 0; i < ENCOUNTERS; ++i)
if(Encounters[i] == IN_PROGRESS) // Do not load an encounter as IN_PROGRESS - reset it instead.
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 ab3a61ffe0b..3eda30963a5 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -56,15 +56,15 @@ struct TRINITY_DLL_DECL boss_captain_skarlocAI : public ScriptedAI
void Reset()
{
- Holy_Light_Timer = 30000;
+ Holy_Light_Timer = 20000 + rand()%10000;
Cleanse_Timer = 10000;
- HammerOfJustice_Timer = 60000;
+ HammerOfJustice_Timer = 20000 + rand()%15000;
HolyShield_Timer = 240000;
DevotionAura_Timer = 3000;
Consecration_Timer = 8000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
//This is not correct. Should taunt Thrall before engage in combat
DoScriptText(SAY_TAUNT1, m_creature);
@@ -126,14 +126,14 @@ struct TRINITY_DLL_DECL boss_captain_skarlocAI : public ScriptedAI
if (DevotionAura_Timer < diff)
{
DoCast(m_creature, SPELL_DEVOTION_AURA);
- DevotionAura_Timer = 60000;
+ DevotionAura_Timer = 45000 + rand()%10000;
}else DevotionAura_Timer -= diff;
//Consecration
if (Consecration_Timer < diff)
{
//DoCast(m_creature->getVictim(), SPELL_CONSECRATION);
- Consecration_Timer = 8000;
+ Consecration_Timer = 5000 + rand()%5000;
}else Consecration_Timer -= diff;
DoMeleeAttackIfReady();
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 39d42413c5f..c2451dce22d 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -56,13 +56,13 @@ struct TRINITY_DLL_DECL boss_epoch_hunterAI : public ScriptedAI
void Reset()
{
- SandBreath_Timer = 25000;
- ImpendingDeath_Timer = 30000;
+ SandBreath_Timer = 8000 + rand()%8000;
+ ImpendingDeath_Timer = 25000 + rand()%5000;
WingBuffet_Timer = 35000;
Mda_Timer = 40000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%2)
{
@@ -108,13 +108,13 @@ struct TRINITY_DLL_DECL boss_epoch_hunterAI : public ScriptedAI
case 1: DoScriptText(SAY_BREATH2, m_creature); break;
}
- SandBreath_Timer = 25000+rand()%5000;
+ SandBreath_Timer = 10000 + rand()%10000;
}else SandBreath_Timer -= diff;
if (ImpendingDeath_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_IMPENDING_DEATH);
- ImpendingDeath_Timer = 30000+rand()%5000;
+ ImpendingDeath_Timer = 25000+rand()%5000;
}else ImpendingDeath_Timer -= diff;
if (WingBuffet_Timer < diff)
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 67d0db45872..ddca1523597 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -115,7 +115,7 @@ struct TRINITY_DLL_DECL boss_lieutenant_drakeAI : public ScriptedAI
ExplodingShout_Timer = 25000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
@@ -159,7 +159,7 @@ struct TRINITY_DLL_DECL boss_lieutenant_drakeAI : public ScriptedAI
{
DoScriptText(SAY_SHOUT, m_creature);
DoCast(m_creature->getVictim(), SPELL_FRIGHTENING_SHOUT);
- Fear_Timer = 30000+rand()%10000;
+ Fear_Timer = 25000+rand()%10000;
}else Fear_Timer -= diff;
//Mortal Strike
@@ -167,7 +167,7 @@ struct TRINITY_DLL_DECL boss_lieutenant_drakeAI : public ScriptedAI
{
DoScriptText(SAY_MORTAL, m_creature);
DoCast(m_creature->getVictim(), SPELL_MORTAL_STRIKE);
- MortalStrike_Timer = 45000+rand()%5000;
+ MortalStrike_Timer = 20000+rand()%10000;
}else MortalStrike_Timer -= diff;
DoMeleeAttackIfReady();
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/def_old_hillsbrad.h b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/def_old_hillsbrad.h
index b60f8eee565..3253a384217 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/def_old_hillsbrad.h
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/def_old_hillsbrad.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
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 330d7d5c62a..3c34e42cee5 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -98,7 +98,7 @@ struct TRINITY_DLL_DECL instance_old_hillsbrad : public ScriptedInstance
void OnCreatureCreate(Creature *creature, uint32 creature_entry)
{
- switch(creature_entry)
+ switch(creature->GetEntry())
{
case THRALL_ENTRY:
ThrallGUID = creature->GetGUID();
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 ea85414a27e..6b4d37f4b63 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
@@ -1,4 +1,4 @@
- /* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ /* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -229,24 +229,23 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI
switch( i )
{
case 8:
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ SetRun(false);
m_creature->SummonCreature(18764,2181.87,112.46,89.45,0.26,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000);
break;
case 9:
DoScriptText(SAY_TH_ARMORY, m_creature);
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, THRALL_WEAPON_MODEL);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, THRALL_WEAPON_INFO);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 781);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, THRALL_SHIELD_MODEL);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, THRALL_SHIELD_INFO);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 1038);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, THRALL_WEAPON_MODEL);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, THRALL_WEAPON_INFO);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 781);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, THRALL_SHIELD_MODEL);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, THRALL_SHIELD_INFO);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 1038);
break;
case 10:
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, THRALL_MODEL_EQUIPPED);
break;
case 11:
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ SetRun();
break;
case 15:
m_creature->SummonCreature(MOB_ENTRY_RIFLE,2200.28,137.37,87.93,5.07,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000);
@@ -274,12 +273,12 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI
case 30:
IsOnHold = true;
m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ SetRun(false);
break;
case 31:
DoScriptText(SAY_TH_MOUNTS_UP, m_creature);
- m_creature->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
DoMount();
+ SetRun();
break;
case 37:
//possibly regular patrollers? If so, remove this and let database handle them
@@ -291,6 +290,7 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI
m_creature->SummonCreature(SKARLOC_MOUNT,2488.64,625.77,58.26,4.71,TEMPSUMMON_TIMED_DESPAWN,10000);
DoUnmount();
HadMount = false;
+ SetRun(false);
break;
case 60:
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
@@ -298,9 +298,10 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI
IsOnHold = true;
m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
pInstance->SetData(TYPE_THRALL_PART2, DONE);
+ SetRun();
break;
case 64:
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ SetRun(false);
break;
case 68:
m_creature->SummonCreature(MOB_ENTRY_BARN_PROTECTOR,2500.22,692.60,55.50,2.84,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000);
@@ -309,10 +310,10 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI
m_creature->SummonCreature(MOB_ENTRY_BARN_GUARDSMAN,2500.94,695.81,55.50,3.14,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000);
break;
case 71:
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ SetRun();
break;
case 81:
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ SetRun(false);
break;
case 83:
m_creature->SummonCreature(MOB_ENTRY_CHURCH_PROTECTOR,2627.33,646.82,56.03,4.28,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,5000);
@@ -322,9 +323,11 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI
break;
case 84:
DoScriptText(SAY_TH_CHURCH_END, m_creature);
+ SetRun();
break;
case 91:
m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ SetRun(false);
break;
case 93:
m_creature->SummonCreature(MOB_ENTRY_INN_PROTECTOR,2652.71,660.31,61.93,1.67,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000);
@@ -333,7 +336,6 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI
m_creature->SummonCreature(MOB_ENTRY_INN_GUARDSMAN,2656.39,659.77,61.93,2.61,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000);
break;
case 94:
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
if (uint64 TarethaGUID = pInstance->GetData64(DATA_TARETHA))
{
if (Unit* Taretha = Unit::GetUnit((*m_creature), TarethaGUID))
@@ -347,12 +349,10 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI
break;
case 96:
DoScriptText(SAY_TH_EPOCH_WONDER, m_creature);
- m_creature->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
break;
case 97:
DoScriptText(SAY_TH_EPOCH_KILL_TARETHA, m_creature);
- m_creature->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ SetRun();
break;
case 98:
//trigger epoch Yell("Thrall! Come outside and face your fate! ....")
@@ -386,11 +386,11 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI
//alot will happen here, thrall and taretha talk, erozion appear at spot to explain
m_creature->SummonCreature(EROZION_ENTRY,2646.47,680.416,55.38,4.16,TEMPSUMMON_TIMED_DESPAWN,120000);
}
- break;
+ break;
case 108:
- //last waypoint, just set Thrall invisible, respawn is turned off
+ //last waypoint, just set Thrall invisible, respawn is turned off
m_creature->SetVisibility(VISIBILITY_OFF);
- break;
+ break;
}
}
@@ -406,12 +406,8 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI
{
DoUnmount();
HadMount = false;
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, THRALL_MODEL_UNEQUIPPED);
}
if( IsBeingEscorted )
@@ -433,14 +429,13 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI
{
m_creature->Mount(SKARLOC_MOUNT_MODEL);
m_creature->SetSpeed(MOVE_RUN,SPEED_MOUNT);
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
}
void DoUnmount()
{
m_creature->Unmount();
m_creature->SetSpeed(MOVE_RUN,SPEED_RUN);
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
switch(rand()%4)
{
@@ -522,154 +517,7 @@ CreatureAI* GetAI_npc_thrall_old_hillsbrad(Creature *_Creature)
{
npc_thrall_old_hillsbradAI* thrall_walkAI = new npc_thrall_old_hillsbradAI(_Creature);
- thrall_walkAI->AddWaypoint(0, 2230.91, 118.765, 82.2947,5000);
- thrall_walkAI->AddWaypoint(1, 2230.33, 114.980, 82.2946);
- thrall_walkAI->AddWaypoint(2, 2233.36, 111.057, 82.2996);
- thrall_walkAI->AddWaypoint(3, 2231.17, 108.486, 82.6624);
- thrall_walkAI->AddWaypoint(4, 2220.22, 114.605, 89.4264);
- thrall_walkAI->AddWaypoint(5, 2215.23, 115.990, 89.4549);
- thrall_walkAI->AddWaypoint(6, 2210.00, 106.849, 89.4549);
- thrall_walkAI->AddWaypoint(7, 2205.66, 105.234, 89.4549);
- //spawn armorer
- thrall_walkAI->AddWaypoint(8, 2192.26, 112.618, 89.4549);
-
- //get weapon
- thrall_walkAI->AddWaypoint(9, 2181.28, 118.612, 89.4549,8000);
- //get armor
- thrall_walkAI->AddWaypoint(10, 2181.62, 120.385, 89.4549,5000);
-
- thrall_walkAI->AddWaypoint(11, 2189.44, 113.922, 89.4549);
- thrall_walkAI->AddWaypoint(12, 2195.63, 110.584, 89.4549);
- thrall_walkAI->AddWaypoint(13, 2201.09, 115.115, 89.4549);
- thrall_walkAI->AddWaypoint(14, 2204.34, 121.036, 89.4355);
- //first ambush
- thrall_walkAI->AddWaypoint(15, 2208.66, 129.127, 87.9560);
- thrall_walkAI->AddWaypoint(16, 2193.09, 137.940, 88.2164);
- thrall_walkAI->AddWaypoint(17, 2173.39, 149.064, 87.9227);
- thrall_walkAI->AddWaypoint(18, 2164.25, 137.965, 85.0595);
- thrall_walkAI->AddWaypoint(19, 2149.31, 125.645, 77.0858);
- thrall_walkAI->AddWaypoint(20, 2142.78, 127.173, 75.5954);
- //second ambush
- thrall_walkAI->AddWaypoint(21, 2139.28, 133.952, 73.6386);
- thrall_walkAI->AddWaypoint(22, 2139.54, 155.235, 67.1269);
- thrall_walkAI->AddWaypoint(23, 2145.38, 167.551, 64.8974);
- thrall_walkAI->AddWaypoint(24, 2134.28, 175.304, 67.9446);
- thrall_walkAI->AddWaypoint(25, 2118.08, 187.387, 68.8141);
- //third ambush
- thrall_walkAI->AddWaypoint(26, 2105.88, 195.461, 65.1854);
- thrall_walkAI->AddWaypoint(27, 2096.77, 196.939, 65.2117);
- thrall_walkAI->AddWaypoint(28, 2083.90, 209.395, 64.8736);
- //in front of keeps gate, meeting scarloc
- thrall_walkAI->AddWaypoint(29, 2067.84, 224.376, 64.8022,30000);
-
- //ref point after skarloc fight
- thrall_walkAI->AddWaypoint(30, 2055.40, 242.90, 63.3418);
-
- //mount up!
- thrall_walkAI->AddWaypoint(31, 2039.20, 266.460, 63.0182,10000);
- thrall_walkAI->AddWaypoint(32, 2011.77, 278.478, 65.3388);
- thrall_walkAI->AddWaypoint(33, 2005.08, 289.676, 66.1179);
- thrall_walkAI->AddWaypoint(34, 2033.11, 337.450, 66.0948);
- thrall_walkAI->AddWaypoint(35, 2070.30, 416.208, 66.0893);
- thrall_walkAI->AddWaypoint(36, 2086.76, 469.768, 65.9182);
- //possible road ambush
- thrall_walkAI->AddWaypoint(37, 2101.70, 497.955, 61.7881);
-
- thrall_walkAI->AddWaypoint(38, 2133.39, 530.933, 55.3700,5000);
- thrall_walkAI->AddWaypoint(39, 2157.91, 559.635, 48.5157);
- thrall_walkAI->AddWaypoint(40, 2167.34, 586.191, 42.4394);
- thrall_walkAI->AddWaypoint(41, 2174.17, 637.643, 33.9002);
- thrall_walkAI->AddWaypoint(42, 2179.31, 656.053, 34.723);
- thrall_walkAI->AddWaypoint(43, 2183.65, 670.941, 34.0318);
- thrall_walkAI->AddWaypoint(44, 2201.50, 668.616, 36.1236);
- thrall_walkAI->AddWaypoint(45, 2221.56, 652.747, 36.6153);
- thrall_walkAI->AddWaypoint(46, 2238.97, 640.125, 37.2214);
- thrall_walkAI->AddWaypoint(47, 2251.17, 620.574, 40.1473);
- thrall_walkAI->AddWaypoint(48, 2261.98, 595.303, 41.4117);
- thrall_walkAI->AddWaypoint(49, 2278.67, 560.172, 38.9090);
- thrall_walkAI->AddWaypoint(50, 2336.72, 528.327, 40.9369);
- thrall_walkAI->AddWaypoint(51, 2381.04, 519.612, 37.7312);
- thrall_walkAI->AddWaypoint(52, 2412.20, 515.425, 39.2068);
- thrall_walkAI->AddWaypoint(53, 2452.39, 516.174, 42.9387);
- thrall_walkAI->AddWaypoint(54, 2467.38, 539.389, 47.4992);
- thrall_walkAI->AddWaypoint(55, 2470.70, 554.333, 46.6668);
- thrall_walkAI->AddWaypoint(56, 2478.07, 575.321, 55.4549);
- thrall_walkAI->AddWaypoint(57, 2480.00, 585.408, 56.6921);
- thrall_walkAI->AddWaypoint(58, 2482.67, 608.817, 55.6643);
- //demount
- thrall_walkAI->AddWaypoint(59, 2485.62, 626.061, 58.0132,2000);
- //scare the shit out of horse, so it'll run off
- thrall_walkAI->AddWaypoint(60, 2486.91, 626.356, 58.0761);
-
- thrall_walkAI->AddWaypoint(61, 2488.58, 660.940, 57.3913);
- thrall_walkAI->AddWaypoint(62, 2502.56, 686.059, 55.6252);
- thrall_walkAI->AddWaypoint(63, 2502.08, 694.360, 55.5083);
- thrall_walkAI->AddWaypoint(64, 2491.46, 694.321, 55.7163);
- thrall_walkAI->AddWaypoint(65, 2491.10, 703.300, 55.7630);
- thrall_walkAI->AddWaypoint(66, 2485.64, 702.992, 55.7917);
-
- thrall_walkAI->AddWaypoint(67, 2479.10, 695.291, 55.7901,10000);
- //spawn mobs
- thrall_walkAI->AddWaypoint(68, 2476.75, 693.689, 55.7960);
- thrall_walkAI->AddWaypoint(69, 2475.39, 695.983, 55.8146);
- thrall_walkAI->AddWaypoint(70, 2477.75, 694.473, 55.7945);
- //meet mobs in doorway
- thrall_walkAI->AddWaypoint(71, 2481.27, 697.747, 55.7910);
-
- thrall_walkAI->AddWaypoint(72, 2486.31, 703.131, 55.7861,5000);
- thrall_walkAI->AddWaypoint(73, 2490.76, 703.511, 55.7662);
- thrall_walkAI->AddWaypoint(74, 2491.30, 694.792, 55.7195);
- thrall_walkAI->AddWaypoint(75, 2518.69, 693.876, 55.1383);
- thrall_walkAI->AddWaypoint(76, 2531.33, 681.914, 55.1383);
- thrall_walkAI->AddWaypoint(77, 2568.25, 682.654, 55.1778);
- thrall_walkAI->AddWaypoint(78, 2589.61, 689.981, 55.1421);
- thrall_walkAI->AddWaypoint(79, 2634.74, 679.833, 54.6613);
- thrall_walkAI->AddWaypoint(80, 2630.41, 661.464, 54.2761);
- thrall_walkAI->AddWaypoint(81, 2629.00, 656.982, 56.0651);
- //stop in church
- thrall_walkAI->AddWaypoint(82, 2620.84, 633.007, 56.0300,3000);
- //summon
- thrall_walkAI->AddWaypoint(83, 2622.99, 639.178, 56.0300);
-
- thrall_walkAI->AddWaypoint(84, 2628.73, 656.693, 56.0610,5000);
- thrall_walkAI->AddWaypoint(85, 2630.34, 661.135, 54.2738);
- thrall_walkAI->AddWaypoint(86, 2635.38, 672.243, 54.4508);
- thrall_walkAI->AddWaypoint(87, 2644.13, 668.158, 55.3797);
- thrall_walkAI->AddWaypoint(88, 2646.82, 666.740, 56.9898);
- thrall_walkAI->AddWaypoint(89, 2658.22, 665.432, 57.1725);
- thrall_walkAI->AddWaypoint(90, 2661.88, 674.849, 57.1725);
- thrall_walkAI->AddWaypoint(91, 2656.23, 677.208, 57.1725);
-
- thrall_walkAI->AddWaypoint(92, 2652.28, 670.270, 61.9353);
- //summon inn
- thrall_walkAI->AddWaypoint(93, 2650.79, 664.290, 61.9302);
- thrall_walkAI->AddWaypoint(94, 2658.19, 660.454, 61.9320,5000);
- //speak with Taretha
- thrall_walkAI->AddWaypoint(95, 2660.57, 659.173, 61.9370);
-
- //epoch calls
- thrall_walkAI->AddWaypoint(96, 2658.19, 660.454, 61.9320,5000);
- //taretha "dies"
- thrall_walkAI->AddWaypoint(97, 2659.84, 659.482, 61.9361,5000);
-
- thrall_walkAI->AddWaypoint(98, 2654.28, 662.722, 61.9313);
- thrall_walkAI->AddWaypoint(99, 2652.37, 670.561, 61.9368);
- thrall_walkAI->AddWaypoint(100, 2656.05, 676.761, 57.1727);
- thrall_walkAI->AddWaypoint(101, 2658.49, 677.166, 57.1727);
- thrall_walkAI->AddWaypoint(102, 2659.28, 667.117, 57.1727);
- thrall_walkAI->AddWaypoint(103, 2649.71, 665.387, 57.1727);
- //he's outside inn here
- thrall_walkAI->AddWaypoint(104, 2634.79, 672.964, 54.4577);
-
- //getting ready here, must start attack before 30secs up
- thrall_walkAI->AddWaypoint(105, 2635.06, 673.892, 54.4713,30000);
-
- //ref point, will move here when all dead and meet Taretha
- thrall_walkAI->AddWaypoint(106, 2634.79, 672.964, 54.4577,60000);
-
- //run off
- thrall_walkAI->AddWaypoint(107, 2631.72, 665.629, 54.2923);
- thrall_walkAI->AddWaypoint(108, 2647.40, 640.530, 55.7634);
+ thrall_walkAI->FillPointMovementListForCreature();
return (CreatureAI*)thrall_walkAI;
}
@@ -779,7 +627,7 @@ struct TRINITY_DLL_DECL npc_tarethaAI : public npc_escortAI
}
}
void Reset() {}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void UpdateAI(const uint32 diff)
{
@@ -790,14 +638,7 @@ CreatureAI* GetAI_npc_taretha(Creature *_Creature)
{
npc_tarethaAI* taretha_walkAI = new npc_tarethaAI(_Creature);
- taretha_walkAI->AddWaypoint(0, 2650.06, 665.473, 61.9305);
- taretha_walkAI->AddWaypoint(1, 2652.44, 670.761, 61.9370);
- taretha_walkAI->AddWaypoint(2, 2655.96, 676.913, 57.1725);
- taretha_walkAI->AddWaypoint(3, 2659.40, 677.317, 57.1725);
- taretha_walkAI->AddWaypoint(4, 2651.75, 664.482, 57.1725);
- taretha_walkAI->AddWaypoint(5, 2647.49, 666.595, 57.0824);
- taretha_walkAI->AddWaypoint(6, 2644.37, 668.167, 55.4182);
- taretha_walkAI->AddWaypoint(7, 2640.96, 669.890, 54.7567,60000);
+ taretha_walkAI->FillPointMovementListForCreature();
return (CreatureAI*)taretha_walkAI;
}
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 134dac56ca0..deb3f995216 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -211,7 +211,7 @@ struct TRINITY_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI
m_creature->SummonCreature(SEER_OLUM, OLUM_X, OLUM_Y, OLUM_Z, OLUM_O, TEMPSUMMON_TIMED_DESPAWN, 3600000);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
StartEvent(who);
}
@@ -219,7 +219,7 @@ struct TRINITY_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
//Only if not incombat check if the event is started
- if (!InCombat && pInstance && pInstance->GetData(DATA_KARATHRESSEVENT))
+ if (!m_creature->isInCombat() && pInstance && pInstance->GetData(DATA_KARATHRESSEVENT))
{
Unit* target = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KARATHRESSEVENT_STARTER));
@@ -331,7 +331,7 @@ struct TRINITY_DLL_DECL boss_fathomguard_sharkkisAI : public ScriptedAI
pet = false;
- Creature *Pet = (Creature*) Unit::GetUnit(*m_creature, SummonedPet);
+ Creature *Pet = Unit::GetCreature(*m_creature, SummonedPet);
if( Pet && Pet->isAlive() )
{
Pet->DealDamage( Pet, Pet->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false );
@@ -348,7 +348,7 @@ struct TRINITY_DLL_DECL boss_fathomguard_sharkkisAI : public ScriptedAI
if (pInstance)
{
Creature *Karathress = NULL;
- Karathress = (Creature*)(Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KARATHRESS)));
+ Karathress = (Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_KARATHRESS)));
if (Karathress)
((boss_fathomlord_karathressAI*)Karathress->AI())->EventSharkkisDeath();
@@ -356,7 +356,7 @@ struct TRINITY_DLL_DECL boss_fathomguard_sharkkisAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if (pInstance)
{
@@ -368,7 +368,7 @@ struct TRINITY_DLL_DECL boss_fathomguard_sharkkisAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
//Only if not incombat check if the event is started
- if (!InCombat && pInstance && pInstance->GetData(DATA_KARATHRESSEVENT))
+ if (!m_creature->isInCombat() && pInstance && pInstance->GetData(DATA_KARATHRESSEVENT))
{
Unit* target = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KARATHRESSEVENT_STARTER));
@@ -407,7 +407,7 @@ struct TRINITY_DLL_DECL boss_fathomguard_sharkkisAI : public ScriptedAI
if(TheBeastWithin_Timer < diff)
{
DoCast(m_creature, SPELL_THE_BEAST_WITHIN);
- Creature *Pet = (Creature*) Unit::GetUnit(*m_creature, SummonedPet);
+ Creature *Pet = Unit::GetCreature(*m_creature, SummonedPet);
if( Pet && Pet->isAlive() )
{
Pet->CastSpell( Pet, SPELL_PET_ENRAGE, true );
@@ -477,7 +477,7 @@ struct TRINITY_DLL_DECL boss_fathomguard_tidalvessAI : public ScriptedAI
if (pInstance)
{
Creature *Karathress = NULL;
- Karathress = (Creature*)(Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KARATHRESS)));
+ Karathress = (Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_KARATHRESS)));
if (Karathress)
if(!m_creature->isAlive() && Karathress)
@@ -485,7 +485,7 @@ struct TRINITY_DLL_DECL boss_fathomguard_tidalvessAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if (pInstance)
{
@@ -498,7 +498,7 @@ struct TRINITY_DLL_DECL boss_fathomguard_tidalvessAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
//Only if not incombat check if the event is started
- if (!InCombat && pInstance && pInstance->GetData(DATA_KARATHRESSEVENT))
+ if (!m_creature->isInCombat() && pInstance && pInstance->GetData(DATA_KARATHRESSEVENT))
{
Unit* target = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KARATHRESSEVENT_STARTER));
@@ -519,7 +519,7 @@ struct TRINITY_DLL_DECL boss_fathomguard_tidalvessAI : public ScriptedAI
return;
}
- if( !m_creature->HasAura(SPELL_WINDFURY_WEAPON, 0) )
+ if( !m_creature->HasAura(SPELL_WINDFURY_WEAPON) )
{
DoCast(m_creature, SPELL_WINDFURY_WEAPON);
}
@@ -592,7 +592,7 @@ struct TRINITY_DLL_DECL boss_fathomguard_caribdisAI : public ScriptedAI
if (pInstance)
{
Creature *Karathress = NULL;
- Karathress = (Creature*)(Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KARATHRESS)));
+ Karathress = (Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_KARATHRESS)));
if (Karathress)
if(!m_creature->isAlive() && Karathress)
@@ -600,7 +600,7 @@ struct TRINITY_DLL_DECL boss_fathomguard_caribdisAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if (pInstance)
{
@@ -612,7 +612,7 @@ struct TRINITY_DLL_DECL boss_fathomguard_caribdisAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
//Only if not incombat check if the event is started
- if (!InCombat && pInstance && pInstance->GetData(DATA_KARATHRESSEVENT))
+ if (!m_creature->isInCombat() && pInstance && pInstance->GetData(DATA_KARATHRESSEVENT))
{
Unit* target = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KARATHRESSEVENT_STARTER));
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 e28fc77acd2..cb91f063d9f 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -153,7 +153,7 @@ struct TRINITY_DLL_DECL boss_hydross_the_unstableAI : public ScriptedAI
}
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
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 1a82ee38900..beebbc631c0 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -248,7 +248,7 @@ struct TRINITY_DLL_DECL boss_lady_vashjAI : public ScriptedAI
pInstance->SetData(DATA_LADYVASHJEVENT, IN_PROGRESS);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if (pInstance)
{
@@ -370,7 +370,7 @@ struct TRINITY_DLL_DECL boss_lady_vashjAI : public ScriptedAI
Unit *target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM, 0);
- if(target && !target->HasAura(SPELL_STATIC_CHARGE_TRIGGER, 0))
+ if(target && !target->HasAura(SPELL_STATIC_CHARGE_TRIGGER))
//cast Static Charge every 2 seconds for 20 seconds
DoCast(target, SPELL_STATIC_CHARGE_TRIGGER);
@@ -576,12 +576,7 @@ struct TRINITY_DLL_DECL boss_lady_vashjAI : public ScriptedAI
}
}
};
-class TRINITY_DLL_DECL VashjSurgeAura : public Aura
-{
- public:
- VashjSurgeAura(SpellEntry *spell, uint32 eff, int32 *bp, Unit *target, Unit *caster) : Aura(spell, eff, bp, target, caster, NULL)
- {}
-};
+
//Enchanted Elemental
//If one of them reaches Vashj he will increase her damage done by 5%.
struct TRINITY_DLL_DECL mob_enchanted_elementalAI : public ScriptedAI
@@ -627,7 +622,7 @@ struct TRINITY_DLL_DECL mob_enchanted_elementalAI : public ScriptedAI
Vashj = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_LADYVASHJ));
}
- void Aggro(Unit *who) { return; }
+ void EnterCombat(Unit *who) { return; }
void MoveInLineOfSight(Unit *who){return;}
@@ -665,13 +660,14 @@ struct TRINITY_DLL_DECL mob_enchanted_elementalAI : public ScriptedAI
SpellEntry *spell = (SpellEntry *)GetSpellStore()->LookupEntry(SPELL_SURGE);
if( spell )
{
- for(uint32 i = 0;i<3;i++)
+ uint8 eff_mask=0;
+ for (int i=0; i<3; i++)
{
if (!spell->Effect[i])
continue;
-
- Vashj->AddAura(new VashjSurgeAura(spell, i, NULL, Vashj, Vashj));
+ eff_mask|=1<<i;
}
+ Vashj->AddAura(new Aura(spell, eff_mask, NULL, Vashj, Vashj));
}
m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}
@@ -711,14 +707,14 @@ struct TRINITY_DLL_DECL mob_tainted_elementalAI : public ScriptedAI
if(pInstance)
{
Creature *Vashj = NULL;
- Vashj = (Creature*)(Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_LADYVASHJ)));
+ Vashj = (Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_LADYVASHJ)));
if(Vashj)
((boss_lady_vashjAI*)Vashj->AI())->EventTaintedElementalDeath();
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
m_creature->AddThreat(who, 0.1f);
}
@@ -768,7 +764,7 @@ struct TRINITY_DLL_DECL mob_toxic_sporebatAI : public ScriptedAI
void Reset()
{
- m_creature->AddUnitMovementFlag(/*MOVEMENTFLAG_ONTRANSPORT + */MOVEMENTFLAG_LEVITATING);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->setFaction(14);
movement_timer = 0;
ToxicSpore_Timer = 5000;
@@ -776,7 +772,7 @@ struct TRINITY_DLL_DECL mob_toxic_sporebatAI : public ScriptedAI
Check_Timer = 1000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -797,10 +793,6 @@ struct TRINITY_DLL_DECL mob_toxic_sporebatAI : public ScriptedAI
void UpdateAI (const uint32 diff)
{
-
- /*if(!m_creature->isInCombat())
- m_creature->SetInCombatState(false);*/
-
//Random movement
if (movement_timer < diff)
{
@@ -906,7 +898,7 @@ struct TRINITY_DLL_DECL mob_shield_generator_channelAI : public ScriptedAI
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
- void Aggro(Unit *who) { return; }
+ void EnterCombat(Unit *who) { return; }
void MoveInLineOfSight(Unit *who) { return; }
@@ -923,7 +915,7 @@ struct TRINITY_DLL_DECL mob_shield_generator_channelAI : public ScriptedAI
if(Vashj && Vashj->isAlive())
{
//start visual channel
- if (!Casted || !Vashj->HasAura(SPELL_MAGIC_BARRIER,0))
+ if (!Casted || !Vashj->HasAura(SPELL_MAGIC_BARRIER))
{
m_creature->CastSpell(Vashj,SPELL_MAGIC_BARRIER,true);
Casted = true;
@@ -945,7 +937,7 @@ bool ItemUse_item_tainted_core(Player *player, Item* _Item, SpellCastTargets con
}
Creature *Vashj = NULL;
- Vashj = (Creature*)(Unit::GetUnit((*player), pInstance->GetData64(DATA_LADYVASHJ)));
+ Vashj = (Unit::GetCreature((*player), pInstance->GetData64(DATA_LADYVASHJ)));
if(Vashj && ((boss_lady_vashjAI*)Vashj->AI())->Phase == 2)
{
if(targets.getGOTarget() && targets.getGOTarget()->GetTypeId()==TYPEID_GAMEOBJECT)
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 6c2588671e6..15ce224454f 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -65,12 +65,6 @@ EndScriptData */
#define SAY_FREE -1548019
#define SAY_DEATH -1548020
-class TRINITY_DLL_DECL InsidiousAura : public Aura {
-public:
- InsidiousAura(SpellEntry *spell, uint32 eff, int32 *bp, Unit *target, Unit *caster) : Aura(spell, eff, bp, target, caster, NULL)
- {}
-};
-
struct TRINITY_DLL_DECL mob_inner_demonAI : public ScriptedAI
{
mob_inner_demonAI(Creature *c) : ScriptedAI(c)
@@ -91,7 +85,7 @@ struct TRINITY_DLL_DECL mob_inner_demonAI : public ScriptedAI
void JustDied(Unit *victim)
{
Unit* pUnit = Unit::GetUnit((*m_creature),victimGUID);
- if (pUnit && pUnit->HasAura(SPELL_INSIDIOUS_WHISPER,0))
+ if (pUnit && pUnit->HasAura(SPELL_INSIDIOUS_WHISPER))
pUnit->RemoveAurasDueToSpell(SPELL_INSIDIOUS_WHISPER);
}
@@ -104,7 +98,7 @@ struct TRINITY_DLL_DECL mob_inner_demonAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if (!victimGUID) return;
}
@@ -128,7 +122,7 @@ struct TRINITY_DLL_DECL mob_inner_demonAI : public ScriptedAI
}else Link_Timer -= diff;
- if(!m_creature->HasAura(AURA_DEMONIC_ALIGNMENT, 0))
+ if(!m_creature->HasAura(AURA_DEMONIC_ALIGNMENT))
DoCast(m_creature, AURA_DEMONIC_ALIGNMENT,true);
if(ShadowBolt_Timer < diff)
@@ -194,8 +188,8 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
InnderDemon_Count = 0;
m_creature->SetSpeed( MOVE_RUN, 2.0f, true);
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY , 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID , 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true);
m_creature->SetCorpseDelay(1000*60*60);
if(pInstance)
@@ -229,7 +223,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
}
void MoveInLineOfSight(Unit *who)
{
- if(m_creature->HasAura(AURA_BANISH, 0))
+ if(m_creature->HasAura(AURA_BANISH))
return;
if( !m_creature->getVictim() && who->isTargetableForAttack() && ( m_creature->IsHostileTo( who )) && who->isInAccessiblePlaceFor(m_creature) )
@@ -267,7 +261,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
}
// channelers == 0 remove banish aura
- if(AliveChannelers == 0 && m_creature->HasAura(AURA_BANISH, 0))
+ if(AliveChannelers == 0 && m_creature->HasAura(AURA_BANISH))
{
// removing banish aura
m_creature->RemoveAurasDueToSpell(AURA_BANISH);
@@ -290,7 +284,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
StartEvent();
}
}
- else if(AliveChannelers != 0 && !m_creature->HasAura(AURA_BANISH, 0))
+ else if(AliveChannelers != 0 && !m_creature->HasAura(AURA_BANISH))
{
// channelers != 0 apply banish aura
// removing Leotheras banish immune to apply AURA_BANISH
@@ -301,8 +295,8 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_DEMON);
// and removing weapons
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY , 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID , 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
}
}
@@ -388,9 +382,9 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
pInstance->SetData(DATA_LEOTHERASTHEBLINDEVENT, DONE);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
- if(m_creature->HasAura(AURA_BANISH, 0))
+ if(m_creature->HasAura(AURA_BANISH))
return;
m_creature->LoadEquipment(m_creature->GetEquipmentId());
@@ -399,7 +393,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
//Return since we have no target
- if (m_creature->HasAura(AURA_BANISH, 0) || !UpdateVictim())
+ if (m_creature->HasAura(AURA_BANISH) || !UpdateVictim())
{
if(BanishTimer<diff)
{
@@ -408,7 +402,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
}else BanishTimer -= diff;
return;
}
- if(m_creature->HasAura(SPELL_WHIRLWIND, 0))
+ if(m_creature->HasAura(SPELL_WHIRLWIND))
if(Whirlwind_Timer < diff)
{
Unit *newTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
@@ -422,7 +416,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
}else Whirlwind_Timer -= diff;
// reseting after changing forms and after ending whirlwind
- if(NeedThreatReset && !m_creature->HasAura(SPELL_WHIRLWIND, 0))
+ if(NeedThreatReset && !m_creature->HasAura(SPELL_WHIRLWIND))
{
// when changing forms seting timers (or when ending whirlwind - to avoid adding new variable i use Whirlwind_Timer to countdown 2s while whirlwinding)
if(DemonForm)
@@ -446,7 +440,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
if(!DemonForm)
{
//Whirldind Timer
- if(!m_creature->HasAura(SPELL_WHIRLWIND, 0))
+ if(!m_creature->HasAura(SPELL_WHIRLWIND))
{
if(Whirlwind_Timer < diff)
{
@@ -465,8 +459,8 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
m_creature->RemoveAurasDueToSpell(SPELL_WHIRLWIND,0);
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_DEMON);
DoScriptText(SAY_SWITCH_TO_DEMON, m_creature);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY , 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID , 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
DemonForm = true;
NeedThreatReset = true;
SwitchToDemon_Timer = 45000;
@@ -513,12 +507,14 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
((ScriptedAI *)demon->AI())->AttackStart( (*itr) );
((mob_inner_demonAI *)demon->AI())->victimGUID = (*itr)->GetGUID();
+ uint8 eff_mask=0;
for (int i=0; i<3; i++)
{
if (!spell->Effect[i])
continue;
- (*itr)->AddAura(new InsidiousAura(spell, i, NULL, (*itr), (*itr)));
+ eff_mask|=1<<i;
}
+ (*itr)->AddAura(new Aura(spell, eff_mask, NULL, (*itr), (*itr)));
if( InnderDemon_Count > 4 ) InnderDemon_Count = 0;
//Safe storing of creatures
@@ -611,7 +607,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blind_demonformAI : public ScriptedAI
m_creature->CastSpell(m_creature, 8149, true);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
StartEvent();
}
@@ -672,7 +668,7 @@ struct TRINITY_DLL_DECL mob_greyheart_spellbinderAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
m_creature->InterruptNonMeleeSpells(false);
if(pInstance)
@@ -681,14 +677,13 @@ struct TRINITY_DLL_DECL mob_greyheart_spellbinderAI : public ScriptedAI
void JustRespawned()
{
- InCombat = false;
AddedBanish = false;
Reset();
}
void CastChanneling()
{
- if(!InCombat && !m_creature->m_currentSpells[CURRENT_CHANNELED_SPELL])
+ if(!m_creature->isInCombat() && !m_creature->m_currentSpells[CURRENT_CHANNELED_SPELL])
{
if(leotherasGUID)
{
@@ -706,7 +701,7 @@ struct TRINITY_DLL_DECL mob_greyheart_spellbinderAI : public ScriptedAI
if(!leotherasGUID)
leotherasGUID = pInstance->GetData64(DATA_LEOTHERAS);
- if(!InCombat && pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER))
+ if(!m_creature->isInCombat() && pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER))
{
Unit *victim = NULL;
victim = Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER));
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 02125f5fd38..1de9f1debbd 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -151,7 +151,7 @@ struct TRINITY_DLL_DECL boss_the_lurker_belowAI : public Scripted_NoMovementAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
pInstance->SetData(DATA_THELURKERBELOWEVENT, IN_PROGRESS);
@@ -266,7 +266,7 @@ struct TRINITY_DLL_DECL boss_the_lurker_belowAI : public Scripted_NoMovementAI
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
{
- if (i->getSource()->isAlive() && i->getSource()->IsInWater() && !i->getSource()->HasAura(SPELL_SCALDINGWATER, 0))
+ if (i->getSource()->isAlive() && i->getSource()->IsInWater() && !i->getSource()->HasAura(SPELL_SCALDINGWATER))
i->getSource()->CastSpell(i->getSource(), SPELL_SCALDINGWATER, true);
else if(!i->getSource()->IsInWater())
i->getSource()->RemoveAurasDueToSpell(SPELL_SCALDINGWATER);
@@ -357,7 +357,7 @@ struct TRINITY_DLL_DECL boss_the_lurker_belowAI : public Scripted_NoMovementAI
}else PhaseTimer-=diff;
if(!m_creature->isInCombat())
- m_creature->SetInCombatState(false);
+ DoZoneInCombat();
if(!Spawned)
{
@@ -416,7 +416,7 @@ struct TRINITY_DLL_DECL mob_coilfang_ambusherAI : public Scripted_NoMovementAI
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 7d56bbf6d2a..859c9d27943 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -161,7 +161,7 @@ struct TRINITY_DLL_DECL boss_morogrim_tidewalkerAI : public ScriptedAI
pInstance->SetData(DATA_MOROGRIMTIDEWALKEREVENT, DONE);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
PlayerList = &((InstanceMap*)m_creature->GetMap())->GetPlayers();
Playercount = PlayerList->getSize();
@@ -307,7 +307,7 @@ struct TRINITY_DLL_DECL mob_water_globuleAI : public ScriptedAI
m_creature->setFaction(14);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void MoveInLineOfSight(Unit *who)
{
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/def_serpent_shrine.h b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/def_serpent_shrine.h
index aceabea4b5c..13144bc93c0 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/def_serpent_shrine.h
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/def_serpent_shrine.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
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 0aceef32714..6c4ae72aec1 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -136,13 +136,13 @@ struct TRINITY_DLL_DECL instance_serpentshrine_cavern : public ScriptedInstance
void OpenDoor(uint64 DoorGUID, bool open)
{
- if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID))
- Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1);
+ if(GameObject *Door = instance->GetGameObject(DoorGUID))
+ Door->SetGoState(open ? GO_STATE_ACTIVE : GO_STATE_READY);
}
void OnCreatureCreate(Creature *creature, uint32 creature_entry)
{
- switch(creature_entry)
+ switch(creature->GetEntry())
{
case 21212: LadyVashj = creature->GetGUID(); break;
case 21214: Karathress = creature->GetGUID(); break;
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 cafbf8e3f4f..648781f6606 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -83,7 +83,7 @@ struct TRINITY_DLL_DECL boss_thespiaAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
@@ -153,7 +153,7 @@ struct TRINITY_DLL_DECL mob_coilfang_waterelementalAI : public ScriptedAI
WaterBoltVolley_Timer = 3000+rand()%3000;
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void UpdateAI(const uint32 diff)
{
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 1515b14e3a2..14dae22fdc2 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -96,7 +96,7 @@ struct TRINITY_DLL_DECL boss_mekgineer_steamriggerAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
@@ -219,7 +219,7 @@ struct TRINITY_DLL_DECL mob_steamrigger_mechanicAI : public ScriptedAI
return;
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void UpdateAI(const uint32 diff)
{
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 7090d678768..fb8a00865ed 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -65,7 +65,7 @@ struct TRINITY_DLL_DECL mob_naga_distillerAI : public ScriptedAI
}
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void StartRageGen(Unit *caster)
{
@@ -111,7 +111,7 @@ struct TRINITY_DLL_DECL boss_warlord_kalithreshAI : public ScriptedAI
pInstance->SetData(TYPE_WARLORD_KALITHRESH, NOT_STARTED);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
@@ -143,7 +143,7 @@ struct TRINITY_DLL_DECL boss_warlord_kalithreshAI : public ScriptedAI
cell.SetNoCreate();
Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck creature_check(*m_creature, entry, true, range);
- Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(pCreature, creature_check);
+ Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(m_creature, pCreature, creature_check);
TypeContainerVisitor<Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer> creature_searcher(searcher);
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/def_steam_vault.h b/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/def_steam_vault.h
index 09a76d482b7..4b407ac4816 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/def_steam_vault.h
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/def_steam_vault.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
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 e268ca97112..6d01da7f625 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -141,12 +141,12 @@ struct TRINITY_DLL_DECL instance_steam_vault : public ScriptedInstance
if (data == SPECIAL)
{
if (GameObject *_go = GameObject::GetGameObject(*player,AccessPanelHydro))
- _go->SetGoState(0);
+ _go->SetGoState(GO_STATE_ACTIVE);
if (GetData(TYPE_MEKGINEER_STEAMRIGGER) == SPECIAL)
{
if (GameObject *_go = GameObject::GetGameObject(*player,MainChambersDoor))
- _go->SetGoState(0);
+ _go->SetGoState(GO_STATE_ACTIVE);
}
debug_log("TSCR: Instance Steamvault: Access panel used.");
}
@@ -156,12 +156,12 @@ struct TRINITY_DLL_DECL instance_steam_vault : public ScriptedInstance
if (data == SPECIAL)
{
if (GameObject *_go = GameObject::GetGameObject(*player,AccessPanelMek))
- _go->SetGoState(0);
+ _go->SetGoState(GO_STATE_ACTIVE);
if (GetData(TYPE_HYDROMANCER_THESPIA) == SPECIAL)
{
if (GameObject *_go = GameObject::GetGameObject(*player,MainChambersDoor))
- _go->SetGoState(0);
+ _go->SetGoState(GO_STATE_ACTIVE);
}
debug_log("TSCR: Instance Steamvault: Access panel used.");
}
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 328bd8ee1ce..a0a0b2a2cd1 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -45,7 +45,7 @@ struct TRINITY_DLL_DECL boss_hungarfenAI : public ScriptedAI
AcidGeyser_Timer = 10000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -114,7 +114,7 @@ struct TRINITY_DLL_DECL mob_underbog_mushroomAI : public ScriptedAI
void AttackStart(Unit* who) { return; }
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void UpdateAI(const uint32 diff)
{
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_the_black_stalker.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_the_black_stalker.cpp
index 5153edb5e62..370b07c8adc 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_the_black_stalker.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_the_black_stalker.cpp
@@ -63,7 +63,7 @@ struct TRINITY_DLL_DECL boss_the_black_stalkerAI : public ScriptedAI
Striders.clear();
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void JustSummoned(Creature *summon)
{
@@ -121,7 +121,7 @@ struct TRINITY_DLL_DECL boss_the_black_stalkerAI : public ScriptedAI
{
if(Unit* target = (Unit*)Unit::GetUnit(*m_creature, LevitatedTarget))
{
- if(!target->HasAura(SPELL_LEVITATE,0))
+ if(!target->HasAura(SPELL_LEVITATE))
{
LevitatedTarget = 0;
return;
@@ -131,7 +131,7 @@ struct TRINITY_DLL_DECL boss_the_black_stalkerAI : public ScriptedAI
target->AddAura(SPELL_SUSPENSION, target);
LevitatedTarget = 0;
}
- else
+ else
{
target->CastSpell(target, SPELL_MAGNETIC_PULL, true);
InAir = true;
diff --git a/src/bindings/scripts/scripts/zone/darkshore/darkshore.cpp b/src/bindings/scripts/scripts/zone/darkshore/darkshore.cpp
index aea0e52e4f7..fcb13e9f479 100644
--- a/src/bindings/scripts/scripts/zone/darkshore/darkshore.cpp
+++ b/src/bindings/scripts/scripts/zone/darkshore/darkshore.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
diff --git a/src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp b/src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp
index 3f71dc9041b..fa6bdd61386 100644
--- a/src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp
+++ b/src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -69,7 +69,7 @@ struct TRINITY_DLL_DECL instance_deadmines : public ScriptedInstance
CannonBlast_Timer = CANNON_BLAST_TIMER;
// it's a hack - Mr. Smite should do that but his too far away
IronCladDoor->SetName("Mr. Smite");
- IronCladDoor->Yell(SAY_MR_SMITE_ALARM1, LANG_UNIVERSAL, 0);
+ IronCladDoor->MonsterYell(SAY_MR_SMITE_ALARM1, LANG_UNIVERSAL, 0);
DoPlaySound(IronCladDoor, SOUND_MR_SMITE_ALARM1);
State=CANNON_BLAST_INITIATED;
break;
@@ -81,7 +81,7 @@ struct TRINITY_DLL_DECL instance_deadmines : public ScriptedInstance
ShootCannon();
BlastOutDoor();
LeverStucked();
- IronCladDoor->Yell(SAY_MR_SMITE_ALARM2, LANG_UNIVERSAL, 0);
+ IronCladDoor->MonsterYell(SAY_MR_SMITE_ALARM2, LANG_UNIVERSAL, 0);
DoPlaySound(IronCladDoor, SOUND_MR_SMITE_ALARM2);
State = PIRATES_ATTACK;
}else
@@ -120,13 +120,13 @@ struct TRINITY_DLL_DECL instance_deadmines : public ScriptedInstance
void ShootCannon()
{
- DefiasCannon->SetUInt32Value(GAMEOBJECT_STATE, 0);
+ DefiasCannon->SetGoState(GO_STATE_ACTIVE);
DoPlaySound(DefiasCannon, SOUND_CANNONFIRE);
}
void BlastOutDoor()
{
- IronCladDoor->SetUInt32Value(GAMEOBJECT_STATE, 2);
+ IronCladDoor->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
DoPlaySound(IronCladDoor, SOUND_DESTROYDOOR);
}
diff --git a/src/bindings/scripts/scripts/zone/draktharon_keep/boss_dred.cpp b/src/bindings/scripts/scripts/zone/draktharon_keep/boss_dred.cpp
new file mode 100644
index 00000000000..c4b05ef8001
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/draktharon_keep/boss_dred.cpp
@@ -0,0 +1,56 @@
+/* Script Data Start
+SDName: Boss dred
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_BELLOWING_ROAR 44863 // fears the group, can be resisted/dispelled
+#define SPELL_GRIEVOUS_BITE 48920
+#define SPELL_MANGLING_SLASH 48873 //casted on the current tank, adds debuf
+#define SPELL_FEARSOME_ROAR_N 48849
+#define SPELL_FEARSOME_ROAR_H 48849 //Not stacking, debuff
+#define SPELL_PIERCING_SLASH 48878 //debuff -->Armor reduced by 75%
+#define SPELL_RAPTOR_CALL 59416 //dummy
+
+
+struct TRINITY_DLL_DECL boss_dredAI : public ScriptedAI
+{
+ boss_dredAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who) {}
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer) {}
+};
+
+CreatureAI* GetAI_boss_dred(Creature *_Creature)
+{
+ return new boss_dredAI (_Creature);
+}
+
+void AddSC_boss_dred()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_dred";
+ newscript->GetAI = GetAI_boss_dred;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/draktharon_keep/boss_novos.cpp b/src/bindings/scripts/scripts/zone/draktharon_keep/boss_novos.cpp
new file mode 100644
index 00000000000..e4b4278151e
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/draktharon_keep/boss_novos.cpp
@@ -0,0 +1,75 @@
+/* Script Data Start
+SDName: Boss novos
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_novos' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_ARCANE_BLAST_N 49198
+#define SPELL_ARCANE_BLAST_H 59909
+#define SPELL_ARCANE_FIELD 47346
+#define SPELL_BLIZZARD_N 49034
+#define SPELL_BLIZZARD_H 59854
+#define SPELL_FROSTBOLT_N 49037
+#define SPELL_FROSTBOLT_H 59855
+#define SPELL_WRATH_OF_MISERY_N 50089
+#define SPELL_WRATH_OF_MISERY_H 59856
+#define SPELL_SUMMON_MINIONS 59910 //Summons an army of Fetid Troll Corpses to assist the caster.
+
+//Yell
+#define SAY_AGGRO -1600000
+#define SAY_KILL -1600001
+#define SAY_DEATH -1600002
+#define SAY_NECRO_ADD -1600003
+#define SAY_REUBBLE_1 -1600004
+#define SAY_REUBBLE_2 -1600005
+
+struct TRINITY_DLL_DECL boss_novosAI : public ScriptedAI
+{
+ boss_novosAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer) {}
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+ DoScriptText(SAY_KILL, m_creature);
+ }
+};
+
+CreatureAI* GetAI_boss_novos(Creature *_Creature)
+{
+ return new boss_novosAI (_Creature);
+}
+
+void AddSC_boss_novos()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_novos";
+ newscript->GetAI = GetAI_boss_novos;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/draktharon_keep/boss_tharon_ja.cpp b/src/bindings/scripts/scripts/zone/draktharon_keep/boss_tharon_ja.cpp
new file mode 100644
index 00000000000..086ef509ff7
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/draktharon_keep/boss_tharon_ja.cpp
@@ -0,0 +1,88 @@
+/* Script Data Start
+SDName: Boss tharon_ja
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_tharon_ja' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_COURSE_OF_LIFE 49527
+#define SPELL_DECAY_FLESH 49356 //casted at end of pahase 1, starts phase 2
+#define SPELL_EYE_BEAM_N 49544
+#define SPELL_LIGHTNING_BREATH_N 49537
+#define SPELL_POISON_CLOUD_N 49548
+#define SPELL_RAIN_OF_FIRE_N 49518
+#define SPELL_RETURN_FLESH 53463 //Channeled spell ending phase two and returning to phase 1. This ability will stun the party for 6 seconds.
+#define SPELL_SHADOW_VOLLEY_N 49528
+
+//Spells Heroic
+#define SPELL_COURSE_OF_LIFE_H 59972
+#define SPELL_EYE_BEAM_H 59965
+#define SPELL_LIGHTNING_BREATH_H 59963
+#define SPELL_POISON_CLOUD_H 59969
+#define SPELL_RAIN_OF_FIRE_H 59971
+#define SPELL_SHADOW_VOLLEY_H 59973
+
+//Players skills durring Phase2
+#define PLAYER_PHASE2_SLAYING_STRIKE 50799
+#define PLAYER_PHASE2_TAUNT 49613
+#define PLAYER_PHASE2_BONE_ARMOR 49609
+#define PLAYER_PHASE2_TOUCH_OF_LIFE 49617
+//Phase 1 all abilities except Eye beam
+//Phase 2 turns players to skeletons with new abilities, boss grows skin
+
+//Yell
+#define SAY_AGGRO 1600011
+#define SAY_KILL_1 1600012
+#define SAY_KILL_2 1600013
+#define SAY_FLESH_1 1600014
+#define SAY_FLESH_2 1600015
+#define SAY_SKELETON_1 1600016
+#define SAY_SKELETON_2 1600017
+#define SAY_DEATH 1600018
+
+struct TRINITY_DLL_DECL boss_tharon_jaAI : public ScriptedAI
+{
+ boss_tharon_jaAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH,m_creature);
+ }
+};
+
+CreatureAI* GetAI_boss_tharon_ja(Creature *_Creature)
+{
+ return new boss_tharon_jaAI (_Creature);
+}
+
+void AddSC_boss_tharon_ja()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_tharon_ja";
+ newscript->GetAI = GetAI_boss_tharon_ja;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/draktharon_keep/boss_trollgore.cpp b/src/bindings/scripts/scripts/zone/draktharon_keep/boss_trollgore.cpp
new file mode 100644
index 00000000000..94993e7b3ec
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/draktharon_keep/boss_trollgore.cpp
@@ -0,0 +1,75 @@
+/* Script Data Start
+SDName: Boss trollgore
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_trollgore' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spell
+#define SPELL_INFECTED_WOUND 49637
+#define SPELL_CRUSH 49639
+#define SPELL_CORPSE_EXPLODE_N 49555
+#define SPELL_CONSUME_N 49380
+
+//Spell Heroic
+#define SPELL_CORPSE_EXPLODE_H 59807
+#define SPELL_CONSUME_H 59803
+
+//Yell
+#define SAY_AGGRO -1600006
+#define SAY_KILL -1600007
+#define SAY_CONSUME -1600008
+#define SAY_EXPLODE -1600009
+#define SAY_DEATH -1600010
+
+struct TRINITY_DLL_DECL boss_trollgoreAI : public ScriptedAI
+{
+ boss_trollgoreAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+ DoScriptText(SAY_KILL, m_creature);
+ }
+};
+
+CreatureAI* GetAI_boss_trollgore(Creature *_Creature)
+{
+ return new boss_trollgoreAI (_Creature);
+}
+
+void AddSC_boss_trollgore()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_trollgore";
+ newscript->GetAI = GetAI_boss_trollgore;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/draktharon_keep/def_drak_tharon_keep.h b/src/bindings/scripts/scripts/zone/draktharon_keep/def_drak_tharon_keep.h
new file mode 100644
index 00000000000..321d77a9c27
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/draktharon_keep/def_drak_tharon_keep.h
@@ -0,0 +1,4 @@
+#ifndef DEF_DRAK_THARON_H
+#define DEF_DRAK_THARON_H
+
+#endif
diff --git a/src/bindings/scripts/scripts/zone/draktharon_keep/instance_drak_tharon_keep.cpp b/src/bindings/scripts/scripts/zone/draktharon_keep/instance_drak_tharon_keep.cpp
new file mode 100644
index 00000000000..3f3cd32e764
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/draktharon_keep/instance_drak_tharon_keep.cpp
@@ -0,0 +1,21 @@
+#include "precompiled.h"
+#include "def_drak_tharon_keep.h"
+
+struct TRINITY_DLL_DECL instance_drak_tharon : public ScriptedInstance
+{
+ instance_drak_tharon(Map *Map) : ScriptedInstance(Map) {Initialize();};
+};
+
+InstanceData* GetInstanceData_instance_drak_tharon(Map* map)
+{
+ return new instance_drak_tharon(map);
+}
+
+void AddSC_instance_drak_tharon()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_drak_tharon";
+ newscript->GetInstanceData = GetInstanceData_instance_drak_tharon;
+ 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 abba40ffe2a..c4e405477c2 100644
--- a/src/bindings/scripts/scripts/zone/dun_morogh/dun_morogh.cpp
+++ b/src/bindings/scripts/scripts/zone/dun_morogh/dun_morogh.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -44,11 +44,11 @@ struct TRINITY_DLL_DECL npc_narm_faulkAI : public ScriptedAI
{
lifeTimer = 120000;
m_creature->SetUInt32Value(UNIT_DYNAMIC_FLAGS, 32);
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,7); // lay down
+ m_creature->SetStandState(UNIT_STAND_STATE_DEAD);
spellHit = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -59,7 +59,7 @@ struct TRINITY_DLL_DECL npc_narm_faulkAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
- if (!m_creature->GetUInt32Value(UNIT_FIELD_BYTES_1))
+ if (m_creature->IsStandState())
{
if(lifeTimer < diff)
m_creature->AI()->EnterEvadeMode();
@@ -73,7 +73,7 @@ struct TRINITY_DLL_DECL npc_narm_faulkAI : public ScriptedAI
if(Spellkind->Id == 8593 && !spellHit)
{
DoCast(m_creature,32343);
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
m_creature->SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0);
//m_creature->RemoveAllAuras();
DoScriptText(SAY_HEAL, m_creature);
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 6e3e0fbb6d7..6fc6a53651b 100644
--- a/src/bindings/scripts/scripts/zone/dustwallow_marsh/dustwallow_marsh.cpp
+++ b/src/bindings/scripts/scripts/zone/dustwallow_marsh/dustwallow_marsh.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -52,7 +52,7 @@ struct TRINITY_DLL_DECL mobs_risen_husk_spiritAI : public ScriptedAI
IntangiblePresence_Timer = 5000;
}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void DamageTaken(Unit *done_by, uint32 &damage)
{
@@ -115,7 +115,7 @@ struct TRINITY_DLL_DECL npc_deserter_agitatorAI : public ScriptedAI
m_creature->setFaction(894);
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
};
CreatureAI* GetAI_npc_deserter_agitator(Creature *_Creature)
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 6d068ec1543..be1a2258dda 100644
--- a/src/bindings/scripts/scripts/zone/eastern_plaguelands/eastern_plaguelands.cpp
+++ b/src/bindings/scripts/scripts/zone/eastern_plaguelands/eastern_plaguelands.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -40,7 +40,7 @@ struct TRINITY_DLL_DECL mobs_ghoul_flayerAI : public ScriptedAI
void Reset() { }
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void JustDied(Unit* Killer)
{
@@ -93,7 +93,7 @@ struct TRINITY_DLL_DECL npc_darrowshire_spiritAI : public ScriptedAI
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
};
CreatureAI* GetAI_npc_darrowshire_spirit(Creature *_Creature)
@@ -118,7 +118,7 @@ bool GossipHello_npc_tirion_fordring(Player *player, Creature *_Creature)
if (_Creature->isQuestGiver())
player->PrepareQuestMenu( _Creature->GetGUID() );
- if (player->GetQuestStatus(5742) == QUEST_STATUS_INCOMPLETE && player->getStandState() == PLAYER_STATE_SIT )
+ if (player->GetQuestStatus(5742) == QUEST_STATUS_INCOMPLETE && player->getStandState() == UNIT_STAND_STATE_SIT )
player->ADD_GOSSIP_ITEM( 0, "I am ready to hear your tale, Tirion.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
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 2e07f91984c..7dbe22e8a25 100644
--- a/src/bindings/scripts/scripts/zone/elwynn_forest/elwynn_forest.cpp
+++ b/src/bindings/scripts/scripts/zone/elwynn_forest/elwynn_forest.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -44,11 +44,11 @@ struct TRINITY_DLL_DECL npc_henze_faulkAI : public ScriptedAI
{
lifeTimer = 120000;
m_creature->SetUInt32Value(UNIT_DYNAMIC_FLAGS, 32);
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,7); // lay down
+ m_creature->SetStandState(UNIT_STAND_STATE_DEAD); // lay down
spellHit = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -59,7 +59,7 @@ struct TRINITY_DLL_DECL npc_henze_faulkAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
- if (!m_creature->GetUInt32Value(UNIT_FIELD_BYTES_1))
+ if (m_creature->IsStandState())
{
if(lifeTimer < diff)
m_creature->AI()->EnterEvadeMode();
@@ -73,7 +73,7 @@ struct TRINITY_DLL_DECL npc_henze_faulkAI : public ScriptedAI
if(Spellkind->Id == 8593 && !spellHit)
{
DoCast(m_creature,32343);
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
m_creature->SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0);
//m_creature->RemoveAllAuras();
DoScriptText(SAY_HEAL, m_creature);
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 7340ac5c073..85c094dada0 100644
--- a/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp
+++ b/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -17,12 +17,11 @@
/* ScriptData
SDName: Eversong_Woods
SD%Complete: 100
-SDComment: Quest support: 8346, 8483, 8488, 8490
+SDComment: Quest support: 8483, 8488, 8490
SDCategory: Eversong Woods
EndScriptData */
/* ContentData
-mobs_mana_tapped
npc_prospector_anvilward
npc_apprentice_mirveda
npc_infused_crystal
@@ -32,31 +31,6 @@ EndContentData */
#include "../../npc/npc_escortAI.h"
/*######
-## mobs_mana_tapped
-######*/
-
-struct TRINITY_DLL_DECL mobs_mana_tappedAI : public ScriptedAI
-{
- mobs_mana_tappedAI(Creature *c) : ScriptedAI(c) {}
-
- void Reset() { }
-
- void Aggro(Unit *who) { }
-
- void SpellHit(Unit *caster, const SpellEntry *spell)
- {
- if( caster->GetTypeId() == TYPEID_PLAYER)
- if( ((Player*)caster)->GetQuestStatus(8346) == QUEST_STATUS_INCOMPLETE && !((Player*)caster)->GetReqKillOrCastCurrentCount(8346, m_creature->GetEntry()) && spell->Id == 28734)
- ((Player*)caster)->CastedCreatureOrGO(15468, m_creature->GetGUID(), spell->Id);
- return;
- }
-};
-CreatureAI* GetAI_mobs_mana_tapped(Creature *_Creature)
-{
- return new mobs_mana_tappedAI (_Creature);
-}
-
-/*######
## npc_prospector_anvilward
######*/
@@ -89,7 +63,7 @@ struct TRINITY_DLL_DECL npc_prospector_anvilwardAI : public npc_escortAI
}
}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void Reset()
{
@@ -107,18 +81,11 @@ struct TRINITY_DLL_DECL npc_prospector_anvilwardAI : public npc_escortAI
}
};
-CreatureAI* GetAI_npc_prospector_anvilward(Creature *_Creature)
+CreatureAI* GetAI_npc_prospector_anvilward(Creature* pCreature)
{
- npc_prospector_anvilwardAI* thisAI = new npc_prospector_anvilwardAI(_Creature);
+ npc_prospector_anvilwardAI* thisAI = new npc_prospector_anvilwardAI(pCreature);
- thisAI->AddWaypoint(0, 9294.78, -6682.51, 22.42);
- thisAI->AddWaypoint(1, 9298.27, -6667.99, 22.42);
- thisAI->AddWaypoint(2, 9309.63, -6658.84, 22.43);
- thisAI->AddWaypoint(3, 9304.43, -6649.31, 26.46);
- thisAI->AddWaypoint(4, 9298.83, -6648.00, 28.61);
- thisAI->AddWaypoint(5, 9291.06, -6653.46, 31.83, 2500);
- thisAI->AddWaypoint(6, 9289.08, -6660.17, 31.85, 5000);
- thisAI->AddWaypoint(7, 9291.06, -6653.46, 31.83);
+ thisAI->FillPointMovementListForCreature();
return (CreatureAI*)thisAI;
}
@@ -229,7 +196,7 @@ struct TRINITY_DLL_DECL npc_secondTrialAI : public ScriptedAI
questPhase = 0;
summonerGuid = 0;
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_KNEEL);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_KNEEL);
m_creature->setFaction(FACTION_FRIENDLY);
spellFlashLight = false;
@@ -261,14 +228,14 @@ struct TRINITY_DLL_DECL npc_secondTrialAI : public ScriptedAI
}
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void UpdateAI(const uint32 diff)
{
if ( questPhase == 1 ) {
if ( timer < diff ) {
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_NONE);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND);
m_creature->setFaction(FACTION_HOSTILE);
questPhase = 0;
@@ -357,7 +324,7 @@ struct TRINITY_DLL_DECL master_kelerun_bloodmournAI : public ScriptedAI
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void UpdateAI(const uint32 diff)
{
@@ -539,7 +506,7 @@ bool GOHello_go_second_trial(Player *player, GameObject* _GO)
Creature* event_controller = NULL;
Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*_GO, MASTER_KELERUN_BLOODMOURN, true, 30);
- Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(event_controller, u_check);
+ Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(player, event_controller, u_check);
TypeContainerVisitor<Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
//cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(_GO->GetMap(), _GO));
cell_lock->Visit(cell_lock, grid_unit_searcher, *(_GO->GetMap()));
@@ -575,7 +542,7 @@ struct TRINITY_DLL_DECL npc_apprentice_mirvedaAI : public ScriptedAI
Summon = false;
}
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void JustSummoned(Creature *summoned)
{
@@ -680,7 +647,7 @@ struct TRINITY_DLL_DECL npc_infused_crystalAI : public Scripted_NoMovementAI
WaveTimer = 0;
}
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void MoveInLineOfSight(Unit* who)
{
@@ -754,11 +721,6 @@ void AddSC_eversong_woods()
Script *newscript;
newscript = new Script;
- newscript->Name="mobs_mana_tapped";
- newscript->GetAI = &GetAI_mobs_mana_tapped;
- newscript->RegisterSelf();
-
- newscript = new Script;
newscript->Name= "npc_prospector_anvilward";
newscript->GetAI = &GetAI_npc_prospector_anvilward;
newscript->pGossipHello = &GossipHello_npc_prospector_anvilward;
diff --git a/src/bindings/scripts/scripts/zone/felwood/felwood.cpp b/src/bindings/scripts/scripts/zone/felwood/felwood.cpp
index b7a4bc03c59..4103283be43 100644
--- a/src/bindings/scripts/scripts/zone/felwood/felwood.cpp
+++ b/src/bindings/scripts/scripts/zone/felwood/felwood.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
diff --git a/src/bindings/scripts/scripts/zone/feralas/feralas.cpp b/src/bindings/scripts/scripts/zone/feralas/feralas.cpp
index f3822bcdb7a..ff30fc3f90c 100644
--- a/src/bindings/scripts/scripts/zone/feralas/feralas.cpp
+++ b/src/bindings/scripts/scripts/zone/feralas/feralas.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
diff --git a/src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp b/src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp
index bdd36dba074..c74f11d14a9 100644
--- a/src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp
+++ b/src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -135,17 +135,21 @@ bool GOHello_gilded_brazier(Player *player, GameObject* _GO)
## npc_ranger_lilatha
######*/
-#define SAY_START -1000140
-#define SAY_PROGRESS1 -1000141
-#define SAY_PROGRESS2 -1000142
-#define SAY_PROGRESS3 -1000143
-#define SAY_END1 -1000144
-#define SAY_END2 -1000145
-#define SAY_CAPTAIN_ANSWER -1000146
-
-#define QUEST_ESCAPE_FROM_THE_CATACOMBS 9212
-#define GO_CAGE 181152
-#define NPC_CAPTAIN_HELIOS 16220
+enum
+{
+ SAY_START = -1000140,
+ SAY_PROGRESS1 = -1000141,
+ SAY_PROGRESS2 = -1000142,
+ SAY_PROGRESS3 = -1000143,
+ SAY_END1 = -1000144,
+ SAY_END2 = -1000145,
+ SAY_CAPTAIN_ANSWER = -1000146,
+
+ QUEST_ESCAPE_FROM_THE_CATACOMBS = 9212,
+ GO_CAGE = 181152,
+ NPC_CAPTAIN_HELIOS = 16220,
+ FACTION_SMOON_E = 1603,
+};
struct TRINITY_DLL_DECL npc_ranger_lilathaAI : public npc_escortAI
{
@@ -167,7 +171,7 @@ struct TRINITY_DLL_DECL npc_ranger_lilathaAI : public npc_escortAI
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
GameObject* Cage = FindGameObject(GO_CAGE, 20, m_creature);
if(Cage)
- Cage->SetGoState(0);
+ Cage->SetGoState(GO_STATE_ACTIVE);
DoScriptText(SAY_START, m_creature, player);
break;
}
@@ -207,7 +211,7 @@ struct TRINITY_DLL_DECL npc_ranger_lilathaAI : public npc_escortAI
}
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void Reset()
{
@@ -216,7 +220,7 @@ struct TRINITY_DLL_DECL npc_ranger_lilathaAI : public npc_escortAI
GameObject* Cage = FindGameObject(GO_CAGE, 20, m_creature);
if(Cage)
- Cage->SetGoState(1);
+ Cage->SetGoState(GO_STATE_READY);
}
void JustDied(Unit* killer)
@@ -249,41 +253,7 @@ CreatureAI* GetAI_npc_ranger_lilathaAI(Creature *_Creature)
{
npc_ranger_lilathaAI* ranger_lilathaAI = new npc_ranger_lilathaAI(_Creature);
- ranger_lilathaAI->AddWaypoint(0, 7545.07, -7359.87, 162.354, 4000); // Say0
- ranger_lilathaAI->AddWaypoint(1, 7550.048340, -7362.237793, 162.235657);
- ranger_lilathaAI->AddWaypoint(2, 7566.976074, -7364.315430, 161.738770);
- ranger_lilathaAI->AddWaypoint(3, 7578.830566, -7361.677734, 161.738770);
- ranger_lilathaAI->AddWaypoint(4, 7590.969238, -7359.053711, 162.257660);
- ranger_lilathaAI->AddWaypoint(5, 7598.354004, -7362.815430, 162.256683, 4000); // Say1
- ranger_lilathaAI->AddWaypoint(6, 7605.861328, -7380.424316, 161.937073);
- ranger_lilathaAI->AddWaypoint(7, 7605.295410, -7387.382813, 157.253998);
- ranger_lilathaAI->AddWaypoint(8, 7606.131836, -7393.893555, 156.941925);
- ranger_lilathaAI->AddWaypoint(9, 7615.207520, -7400.187012, 157.142639);
- ranger_lilathaAI->AddWaypoint(10, 7618.956543, -7402.652832, 158.202042);
- ranger_lilathaAI->AddWaypoint(11, 7636.850586, -7401.756836, 162.144791);
- ranger_lilathaAI->AddWaypoint(12, 7637.058105, -7404.944824, 162.206970, 4000);// Say2
- ranger_lilathaAI->AddWaypoint(13, 7636.910645, -7412.585449, 162.366425);
- ranger_lilathaAI->AddWaypoint(14, 7637.607910, -7425.591797, 162.630661);
- ranger_lilathaAI->AddWaypoint(15, 7637.816895, -7459.057129, 163.302704);
- ranger_lilathaAI->AddWaypoint(16, 7638.859863, -7470.902344, 162.517059);
- ranger_lilathaAI->AddWaypoint(17, 7641.395996, -7488.217285, 157.381287);
- ranger_lilathaAI->AddWaypoint(18, 7634.455566, -7505.451660, 154.682159);
- ranger_lilathaAI->AddWaypoint(19, 7631.906738, -7516.948730, 153.597382); // say3
- ranger_lilathaAI->AddWaypoint(20, 7622.231445, -7537.037598, 151.587112);
- ranger_lilathaAI->AddWaypoint(21, 7610.921875, -7550.670410, 149.639374);
- ranger_lilathaAI->AddWaypoint(22, 7598.229004, -7562.551758, 145.953888);
- ranger_lilathaAI->AddWaypoint(23, 7588.509277, -7577.755371, 148.294479);
- ranger_lilathaAI->AddWaypoint(24, 7567.339355, -7608.456055, 146.006485);
- ranger_lilathaAI->AddWaypoint(25, 7562.547852, -7617.417969, 148.097504);
- ranger_lilathaAI->AddWaypoint(26, 7561.508789, -7645.064453, 151.245163);
- ranger_lilathaAI->AddWaypoint(27, 7563.337402, -7654.652344, 151.227158);
- ranger_lilathaAI->AddWaypoint(28, 7565.533691, -7658.296387, 151.248886);
- ranger_lilathaAI->AddWaypoint(29, 7571.155762, -7659.118652, 151.244568);
- ranger_lilathaAI->AddWaypoint(30, 7579.119629, -7662.213867, 151.651505);
- ranger_lilathaAI->AddWaypoint(31, 7603.768066, -7667.000488, 153.997726);
- ranger_lilathaAI->AddWaypoint(32, 7603.768066, -7667.000488, 153.997726, 4000); // Say4 & Set orientation
- ranger_lilathaAI->AddWaypoint(33, 7603.768066, -7667.000488, 153.997726, 8000); // Say5 & Set orientation
- ranger_lilathaAI->AddWaypoint(34, 7603.768066, -7667.000488, 153.997726);
+ ranger_lilathaAI->FillPointMovementListForCreature();
return (CreatureAI*)ranger_lilathaAI;
}
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 a651c117d7a..34400549822 100644
--- a/src/bindings/scripts/scripts/zone/gruuls_lair/boss_gruul.cpp
+++ b/src/bindings/scripts/scripts/zone/gruuls_lair/boss_gruul.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -6,12 +6,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
*/
/* ScriptData
@@ -24,7 +24,6 @@ EndScriptData */
#include "precompiled.h"
#include "def_gruuls_lair.h"
-/* Yells & Quotes */
#define SAY_AGGRO -1565010
#define SAY_SLAM1 -1565011
#define SAY_SLAM2 -1565012
@@ -36,17 +35,18 @@ EndScriptData */
#define SAY_DEATH -1565018
#define EMOTE_GROW -1565019
-/* Spells */
-#define SPELL_GROWTH 36300
-#define SPELL_CAVE_IN 36240
-#define SPELL_GROUND_SLAM 33525 // AoE Ground Slam applying Ground Slam to everyone with a script effect (most likely the knock back, we can code it to a set knockback)
-#define SPELL_REVERBERATION 36297 //AoE Silence
-#define SPELL_SHATTER 33654
-#define SPELL_MAGNETIC_PULL 28337
-#define SPELL_KNOCK_BACK 24199 //Knockback spell until correct implementation is made
+#define SPELL_GROWTH 36300
+#define SPELL_CAVE_IN 36240
+#define SPELL_GROUND_SLAM 33525 //AoE Ground Slam applying Ground Slam to everyone with a script effect (most likely the knock back, we can code it to a set knockback)
+#define SPELL_REVERBERATION 36297 //AoE Silence
+#define SPELL_SHATTER 33654
+
#define SPELL_SHATTER_EFFECT 33671
#define SPELL_HURTFUL_STRIKE 33813
#define SPELL_STONED 33652 //Spell is self cast
+#define SPELL_MAGNETIC_PULL 28337
+#define SPELL_KNOCK_BACK 24199 //Knockback spell until correct implementation is made
+
#define SPELL_GRONN_LORDS_GRASP 33572 //Triggered by Ground Slam
struct TRINITY_DLL_DECL boss_gruulAI : public ScriptedAI
@@ -60,6 +60,7 @@ struct TRINITY_DLL_DECL boss_gruulAI : public ScriptedAI
uint32 Growth_Timer;
uint32 CaveIn_Timer;
+ uint32 CaveIn_StaticTimer;
uint32 GroundSlamTimer;
uint32 GroundSlamStage;
uint32 PerformingGroundSlam;
@@ -69,31 +70,26 @@ struct TRINITY_DLL_DECL boss_gruulAI : public ScriptedAI
void Reset()
{
Growth_Timer= 30000;
- CaveIn_Timer= 40000;
+ CaveIn_Timer= 27000;
+ CaveIn_StaticTimer = 30000;
GroundSlamTimer= 35000;
GroundSlamStage= 0;
PerformingGroundSlam= false;
HurtfulStrike_Timer= 8000;
Reverberation_Timer= 60000+45000;
- if(pInstance)
+ if (pInstance)
pInstance->SetData(DATA_GRUULEVENT, NOT_STARTED);
- }
-
- void JustDied(Unit* Killer)
- {
- DoScriptText(SAY_DEATH, m_creature);
- if(pInstance)
- pInstance->SetData(DATA_GRUULEVENT, DONE);
+ m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
+ m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
- DoZoneInCombat();
- if(pInstance)
+ if (pInstance)
pInstance->SetData(DATA_GRUULEVENT, IN_PROGRESS);
}
@@ -101,9 +97,23 @@ struct TRINITY_DLL_DECL boss_gruulAI : public ScriptedAI
{
switch(rand()%3)
{
- case 0: DoScriptText(SAY_SLAY1, m_creature); break;
- case 1: DoScriptText(SAY_SLAY2, m_creature); break;
- case 2: DoScriptText(SAY_SLAY3, m_creature); break;
+ case 0: DoScriptText(SAY_SLAY1, m_creature); break;
+ case 1: DoScriptText(SAY_SLAY2, m_creature); break;
+ case 2: DoScriptText(SAY_SLAY3, m_creature); break;
+ }
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+
+ if(pInstance)
+ {
+ pInstance->SetData(DATA_GRUULEVENT, DONE);
+
+ GameObject* EncounterDoor = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GRUULDOOR));
+ if (EncounterDoor)
+ EncounterDoor->SetGoState(GO_STATE_ACTIVE); // Open the encounter door
}
}
@@ -117,14 +127,14 @@ struct TRINITY_DLL_DECL boss_gruulAI : public ScriptedAI
// Gruul can cast this spell up to 30 times
if (Growth_Timer < diff)
{
- DoCast(m_creature,SPELL_GROWTH);
DoScriptText(EMOTE_GROW, m_creature);
+ DoCast(m_creature,SPELL_GROWTH);
Growth_Timer = 30000;
}else Growth_Timer -= diff;
- if(PerformingGroundSlam)
+ if (PerformingGroundSlam)
{
- if(GroundSlamTimer < diff)
+ if (GroundSlamTimer < diff)
{
switch(GroundSlamStage)
{
@@ -140,7 +150,7 @@ struct TRINITY_DLL_DECL boss_gruulAI : public ScriptedAI
{
Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
- if(target && target->GetTypeId() == TYPEID_PLAYER)
+ if (target && target->GetTypeId() == TYPEID_PLAYER)
knockback_targets.push_back(target);
}
@@ -150,7 +160,7 @@ struct TRINITY_DLL_DECL boss_gruulAI : public ScriptedAI
Unit *target = *itr;
Unit *target2 = *(knockback_targets.begin() + rand()%knockback_targets.size());
- if(target && target2)
+ if (target && target2)
{
switch(rand()%2)
{
@@ -161,7 +171,7 @@ struct TRINITY_DLL_DECL boss_gruulAI : public ScriptedAI
}
GroundSlamTimer = 7000;
- break;
+ break;
}
case 1:
@@ -181,18 +191,15 @@ struct TRINITY_DLL_DECL boss_gruulAI : public ScriptedAI
}
GroundSlamTimer = 5000;
-
- break;
+ break;
}
case 2:
{
//The dummy shatter spell is cast
DoCast(m_creature, SPELL_SHATTER);
-
GroundSlamTimer = 1000;
-
- break;
+ break;
}
case 3:
@@ -217,20 +224,20 @@ struct TRINITY_DLL_DECL boss_gruulAI : public ScriptedAI
m_creature->GetMotionMaster()->Clear();
Unit *victim = m_creature->getVictim();
- if(victim)
+ if (victim)
{
m_creature->GetMotionMaster()->MoveChase(victim);
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID());
}
PerformingGroundSlam = false;
-
GroundSlamTimer =120000;
HurtfulStrike_Timer= 8000;
- if(Reverberation_Timer < 10000) //Give a little time to the players to undo the damage from shatter
+
+ if (Reverberation_Timer < 10000) //Give a little time to the players to undo the damage from shatter
Reverberation_Timer += 10000;
- break;
+ break;
}
}
@@ -259,7 +266,7 @@ struct TRINITY_DLL_DECL boss_gruulAI : public ScriptedAI
if (Reverberation_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_REVERBERATION, true);
- Reverberation_Timer = 30000;
+ Reverberation_Timer = 15000 + rand()%10000;
}else Reverberation_Timer -= diff;
// Cave In
@@ -268,7 +275,11 @@ struct TRINITY_DLL_DECL boss_gruulAI : public ScriptedAI
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0))
DoCast(target,SPELL_CAVE_IN);
- CaveIn_Timer = 20000;
+ if(CaveIn_StaticTimer >= 4000)
+ CaveIn_StaticTimer -= 2000;
+
+ CaveIn_Timer = CaveIn_StaticTimer;
+
}else CaveIn_Timer -= diff;
// Ground Slam, Gronn Lord's Grasp, Stoned, Shatter
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 0131d39dc48..6a22e58bbc6 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -88,11 +88,11 @@ bool CheckAllBossDied(ScriptedInstance* pInstance, Creature* m_creature)
OlmGUID = pInstance->GetData64(DATA_OLMTHESUMMONER);
KroshGUID = pInstance->GetData64(DATA_KROSHFIREHAND);
- Maulgar = ((Creature*)Unit::GetUnit((*m_creature), MaulgarGUID));
- Kiggler = ((Creature*)Unit::GetUnit((*m_creature), KigglerGUID));
- Blindeye = ((Creature*)Unit::GetUnit((*m_creature), BlindeyeGUID));
- Olm = ((Creature*)Unit::GetUnit((*m_creature), OlmGUID));
- Krosh = ((Creature*)Unit::GetUnit((*m_creature), KroshGUID));
+ Maulgar = (Unit::GetCreature((*m_creature), MaulgarGUID));
+ Kiggler = (Unit::GetCreature((*m_creature), KigglerGUID));
+ Blindeye = (Unit::GetCreature((*m_creature), BlindeyeGUID));
+ Olm = (Unit::GetCreature((*m_creature), OlmGUID));
+ Krosh = (Unit::GetCreature((*m_creature), KroshGUID));
if(!Maulgar || !Kiggler || !Blindeye || !Olm || !Krosh)
return false;
@@ -142,7 +142,7 @@ struct TRINITY_DLL_DECL boss_high_king_maulgarAI : public ScriptedAI
{
if(Council[i])
{
- pCreature = (Creature*)(Unit::GetUnit((*m_creature), Council[i]));
+ pCreature = (Unit::GetCreature((*m_creature), Council[i]));
if(pCreature && !pCreature->isAlive())
{
pCreature->Respawn();
@@ -186,7 +186,7 @@ struct TRINITY_DLL_DECL boss_high_king_maulgarAI : public ScriptedAI
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
StartEvent(who);
}
@@ -218,7 +218,7 @@ struct TRINITY_DLL_DECL boss_high_king_maulgarAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
//Only if not incombat check if the event is started
- if(!InCombat && pInstance && pInstance->GetData(DATA_MAULGAREVENT))
+ if(!m_creature->isInCombat() && pInstance && pInstance->GetData(DATA_MAULGAREVENT))
{
Unit* target = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_MAULGAREVENT_TANK));
@@ -268,8 +268,8 @@ struct TRINITY_DLL_DECL boss_high_king_maulgarAI : public ScriptedAI
DoScriptText(SAY_ENRAGE, m_creature);
m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
}
if(Phase2)
@@ -323,7 +323,7 @@ struct TRINITY_DLL_DECL boss_olm_the_summonerAI : public ScriptedAI
pInstance->SetData(DATA_MAULGAREVENT, NOT_STARTED);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
{
@@ -337,7 +337,7 @@ struct TRINITY_DLL_DECL boss_olm_the_summonerAI : public ScriptedAI
if(pInstance)
{
Creature *Maulgar = NULL;
- Maulgar = (Creature*)(Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_MAULGAR)));
+ Maulgar = (Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_MAULGAR)));
if(Maulgar)
((boss_high_king_maulgarAI*)Maulgar->AI())->AddDeath();
@@ -350,7 +350,7 @@ struct TRINITY_DLL_DECL boss_olm_the_summonerAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
//Only if not incombat check if the event is started
- if(!InCombat && pInstance && pInstance->GetData(DATA_MAULGAREVENT))
+ if(!m_creature->isInCombat() && pInstance && pInstance->GetData(DATA_MAULGAREVENT))
{
Unit* target = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_MAULGAREVENT_TANK));
@@ -427,7 +427,7 @@ struct TRINITY_DLL_DECL boss_kiggler_the_crazedAI : public ScriptedAI
pInstance->SetData(DATA_MAULGAREVENT, NOT_STARTED);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
{
@@ -441,7 +441,7 @@ struct TRINITY_DLL_DECL boss_kiggler_the_crazedAI : public ScriptedAI
if(pInstance)
{
Creature *Maulgar = NULL;
- Maulgar = (Creature*)(Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_MAULGAR)));
+ Maulgar = (Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_MAULGAR)));
if(Maulgar)
((boss_high_king_maulgarAI*)Maulgar->AI())->AddDeath();
@@ -454,7 +454,7 @@ struct TRINITY_DLL_DECL boss_kiggler_the_crazedAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
//Only if not incombat check if the event is started
- if(!InCombat && pInstance && pInstance->GetData(DATA_MAULGAREVENT))
+ if(!m_creature->isInCombat() && pInstance && pInstance->GetData(DATA_MAULGAREVENT))
{
Unit* target = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_MAULGAREVENT_TANK));
@@ -482,7 +482,7 @@ struct TRINITY_DLL_DECL boss_kiggler_the_crazedAI : public ScriptedAI
if(target)
DoCast(target, SPELL_GREATER_POLYMORPH);
- GreaterPolymorph_Timer = 20000;
+ GreaterPolymorph_Timer = 15000 + rand()%5000;
}else GreaterPolymorph_Timer -= diff;
//LightningBolt_Timer
@@ -520,20 +520,22 @@ struct TRINITY_DLL_DECL boss_blindeye_the_seerAI : public ScriptedAI
uint32 GreaterPowerWordShield_Timer;
uint32 Heal_Timer;
+ uint32 PrayerofHealing_Timer;
ScriptedInstance* pInstance;
void Reset()
{
GreaterPowerWordShield_Timer = 5000;
- Heal_Timer = 30000;
+ Heal_Timer = 25000 + rand()%15000;
+ PrayerofHealing_Timer = 45000 + rand()%10000;
//reset encounter
if (pInstance)
pInstance->SetData(DATA_MAULGAREVENT, NOT_STARTED);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
{
@@ -547,7 +549,7 @@ struct TRINITY_DLL_DECL boss_blindeye_the_seerAI : public ScriptedAI
if(pInstance)
{
Creature *Maulgar = NULL;
- Maulgar = (Creature*)(Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_MAULGAR)));
+ Maulgar = (Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_MAULGAR)));
if(Maulgar)
((boss_high_king_maulgarAI*)Maulgar->AI())->AddDeath();
@@ -560,7 +562,7 @@ struct TRINITY_DLL_DECL boss_blindeye_the_seerAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
//Only if not incombat check if the event is started
- if(!InCombat && pInstance && pInstance->GetData(DATA_MAULGAREVENT))
+ if(!m_creature->isInCombat() && pInstance && pInstance->GetData(DATA_MAULGAREVENT))
{
Unit* target = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_MAULGAREVENT_TANK));
@@ -592,9 +594,16 @@ struct TRINITY_DLL_DECL boss_blindeye_the_seerAI : public ScriptedAI
if(Heal_Timer < diff)
{
DoCast(m_creature, SPELL_HEAL);
- Heal_Timer = 60000;
+ Heal_Timer = 15000 + rand()%25000;
}else Heal_Timer -= diff;
+ //PrayerofHealing_Timer
+ if (PrayerofHealing_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_PRAYER_OH);
+ PrayerofHealing_Timer = 35000 + rand()%15000;
+ }else PrayerofHealing_Timer -= diff;
+
DoMeleeAttackIfReady();
}
};
@@ -624,7 +633,7 @@ struct TRINITY_DLL_DECL boss_krosh_firehandAI : public ScriptedAI
pInstance->SetData(DATA_MAULGAREVENT, NOT_STARTED);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
{
@@ -638,7 +647,7 @@ struct TRINITY_DLL_DECL boss_krosh_firehandAI : public ScriptedAI
if(pInstance)
{
Creature *Maulgar = NULL;
- Maulgar = (Creature*)(Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_MAULGAR)));
+ Maulgar = (Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_MAULGAR)));
if(Maulgar)
((boss_high_king_maulgarAI*)Maulgar->AI())->AddDeath();
@@ -651,7 +660,7 @@ struct TRINITY_DLL_DECL boss_krosh_firehandAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
//Only if not incombat check if the event is started
- if(!InCombat && pInstance && pInstance->GetData(DATA_MAULGAREVENT))
+ if(!m_creature->isInCombat() && pInstance && pInstance->GetData(DATA_MAULGAREVENT))
{
Unit* target = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_MAULGAREVENT_TANK));
diff --git a/src/bindings/scripts/scripts/zone/gruuls_lair/def_gruuls_lair.h b/src/bindings/scripts/scripts/zone/gruuls_lair/def_gruuls_lair.h
index 145e573f02a..7003dcb1e26 100644
--- a/src/bindings/scripts/scripts/zone/gruuls_lair/def_gruuls_lair.h
+++ b/src/bindings/scripts/scripts/zone/gruuls_lair/def_gruuls_lair.h
@@ -1,19 +1,21 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef DEF_GRUULS_LAIR_H
#define DEF_GRUULS_LAIR_H
-#define DATA_BLINDEYETHESEER 1
-#define DATA_GRUULEVENT 2
-#define DATA_KIGGLERTHECRAZED 3
-#define DATA_KROSHFIREHAND 4
-#define DATA_MAULGAREVENT 5
-#define DATA_MAULGAREVENT_TANK 6
-#define DATA_OLMTHESUMMONER 7
-#define DATA_MAULGARDOOR 8
-#define DATA_GRUULDOOR 9
-#define DATA_MAULGAR 10
+#define DATA_BLINDEYETHESEER 1
+#define DATA_GRUULEVENT 2
+#define DATA_KIGGLERTHECRAZED 3
+#define DATA_KROSHFIREHAND 4
+#define DATA_MAULGAREVENT 5
+#define DATA_MAULGAREVENT_TANK 6
+#define DATA_OLMTHESUMMONER 7
+#define DATA_MAULGARDOOR 8
+#define DATA_GRUULDOOR 9
+#define DATA_MAULGAR 10
+
+#define ERROR_INST_DATA "TSCR Error: Instance Data not set properly for Gruul's Lair instance (map 565). Encounters will be buggy."
#endif
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 5c026ab1860..34943449b1e 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -73,7 +73,7 @@ struct TRINITY_DLL_DECL instance_gruuls_lair : public ScriptedInstance
void OnCreatureCreate(Creature *creature, uint32 creature_entry)
{
- switch(creature_entry)
+ switch(creature->GetEntry())
{
case 18835: KigglerTheCrazed = creature->GetGUID(); break;
case 18836: BlindeyeTheSeer = creature->GetGUID(); break;
diff --git a/src/bindings/scripts/scripts/zone/gundrak/boss_drakkari_colossus.cpp b/src/bindings/scripts/scripts/zone/gundrak/boss_drakkari_colossus.cpp
new file mode 100644
index 00000000000..ee0e99d46ec
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/gundrak/boss_drakkari_colossus.cpp
@@ -0,0 +1,55 @@
+/* Script Data Start
+SDName: Boss Drakkari Colossus
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_EMERGE 54850 //to phase2, Colossus unatackable, Elemental emerges
+#define SPELL_EMERGE_2 54851
+#define SPELL_MIGHTY_BLOW 54719
+
+struct TRINITY_DLL_DECL boss_drakkari_colossusAI : public ScriptedAI
+{
+ boss_drakkari_colossusAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 phase;
+
+ void Reset() {}
+ void EnterCombat(Unit* who) {}
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ phase =1;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer) {}
+};
+
+CreatureAI* GetAI_boss_drakkari_colossus(Creature *_Creature)
+{
+ return new boss_drakkari_colossusAI (_Creature);
+}
+
+void AddSC_boss_drakkari_colossus()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_drakkari_colossus";
+ newscript->GetAI = GetAI_boss_drakkari_colossus;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/gundrak/boss_eck.cpp b/src/bindings/scripts/scripts/zone/gundrak/boss_eck.cpp
new file mode 100644
index 00000000000..3c283e17271
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/gundrak/boss_eck.cpp
@@ -0,0 +1,65 @@
+/* Script Data Start
+SDName: Boss Eck the Ferocious
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment: Only appears in Heroic mode
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+#define SPELL_ECK_BERSERK 55816 //Eck goes berserk, increasing his attack speed by 150% and all damage he deals by 500%.
+#define SPELL_ECK_BITE 55813 //Eck bites down hard, inflicting 150% of his normal damage to an enemy.
+#define SPELL_ECK_SPIT 55814 //Eck spits toxic bile at enemies in a cone in front of him, inflicting 2970 Nature damage and draining 220 mana every 1 sec for 3 sec.
+#define SPELL_ECK_SPRING_1 55815 //Eck leaps at a distant target. --> Drops aggro and charges a random player. Tank can simply taunt him back.
+#define SPELL_ECK_SPRING_2 55837 //Eck leaps at a distant target.
+
+struct TRINITY_DLL_DECL boss_eckAI : public ScriptedAI
+{
+ boss_eckAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 berserk;
+
+ void Reset()
+ {
+ //Source Deadly Boss Mod
+ berserk = 120000; //2min
+ }
+
+ void EnterCombat(Unit* who) {}
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ if(berserk < diff)
+ {
+ DoCast(m_creature,SPELL_ECK_BERSERK);
+ berserk = 120000;
+ }else berserk -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer) {}
+};
+
+CreatureAI* GetAI_boss_eck(Creature *_Creature)
+{
+ return new boss_eckAI (_Creature);
+}
+
+void AddSC_boss_eck()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_eck";
+ newscript->GetAI = GetAI_boss_eck;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/gundrak/boss_gal_darah.cpp b/src/bindings/scripts/scripts/zone/gundrak/boss_gal_darah.cpp
new file mode 100644
index 00000000000..a369df3abb6
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/gundrak/boss_gal_darah.cpp
@@ -0,0 +1,85 @@
+/* Script Data Start
+SDName: Boss gal_darah
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_ENRAGE 55285
+#define SPELL_IMPALING_CHARGE 54956
+#define SPELL_STOMP 55292
+
+#define SPELL_PUNCTURE 55276
+#define SPELL_STAMPEDE 55218
+#define SPELL_WHIRLING_SLASH 55285
+
+//Yells
+#define SAY_AGGRO -1604000
+#define SAY_SLAY_1 -1604001
+#define SAY_SLAY_2 -1604002
+#define SAY_SLAY_3 -1604003
+#define SAY_DEATH -1604004
+#define SAY_SUMMON_RHINO_1 -1604005
+#define SAY_SUMMON_RHINO_2 -1604006
+#define SAY_SUMMON_RHINO_3 -1604007
+#define SAY_TRANSFORM_1 -1604008 //Phase change
+#define SAY_TRANSFORM_2 -1604009
+
+struct TRINITY_DLL_DECL boss_gal_darahAI : public ScriptedAI
+{
+ boss_gal_darahAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_gal_darah(Creature *_Creature)
+{
+ return new boss_gal_darahAI (_Creature);
+}
+
+void AddSC_boss_gal_darah()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_gal_darah";
+ newscript->GetAI = GetAI_boss_gal_darah;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/gundrak/boss_moorabi.cpp b/src/bindings/scripts/scripts/zone/gundrak/boss_moorabi.cpp
new file mode 100644
index 00000000000..edfc8e7a26a
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/gundrak/boss_moorabi.cpp
@@ -0,0 +1,88 @@
+/* Script Data Start
+SDName: Boss moorabi
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_moorabi' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_DETERMINED_GORE 55102
+#define SPELL_DETERMINED_STAB_2 59444
+#define SPELL_DETERMINED_STAB_3 55104
+
+#define SPELL_GROUND_TREMOR 55142
+#define SPELL_MOJO_FRENZY 55163
+#define SPELL_NUMBING_ROAR_1 55100
+#define SPELL_NUMBING_ROAR_2 55106
+#define SPELL_TRANSFORMATION 55098 //Periodic, The caster transforms into a powerful mammoth, increasing Physical damage done by 25% and granting immunity to Stun effects.
+#define SPELL_QUAKE 55101
+
+//Yell
+#define SAY_AGGRO -1604010
+#define SAY_SLAY_1 -1604011
+#define SAY_SLAY_2 -1604012
+#define SAY_SLAY_3 -1604013
+#define SAY_DEATH -1604014
+#define SAY_TRANSFORM -1604015
+#define SAY_QUAKE -1604016
+
+struct TRINITY_DLL_DECL boss_moorabiAI : public ScriptedAI
+{
+ boss_moorabiAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 phase;
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ phase =1;
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_moorabi(Creature *_Creature)
+{
+ return new boss_moorabiAI (_Creature);
+}
+
+void AddSC_boss_moorabi()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_moorabi";
+ newscript->GetAI = GetAI_boss_moorabi;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/gundrak/boss_slad_ran.cpp b/src/bindings/scripts/scripts/zone/gundrak/boss_slad_ran.cpp
new file mode 100644
index 00000000000..ba813a69f8d
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/gundrak/boss_slad_ran.cpp
@@ -0,0 +1,95 @@
+/* Script Data Start
+SDName: Boss slad_ran
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_slad_ran' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_POISON_NOVA 55081
+#define SPELL_POISON_NOVA_2 59842
+//--
+#define SPELL_POWERFUL_BITE 48287
+#define SPELL_POWERFUL_BITE_2 59840
+//--
+#define SPELL_VENOM_BOLT 54970
+#define SPELL_VENOM_BOLT_2 59839
+//At 30% HPStart summoning small serpents
+
+//Yell
+#define SAY_AGGRO -1604017
+#define SAY_SLAY_1 -1604018
+#define SAY_SLAY_2 -1604019
+#define SAY_SLAY_3 -1604020
+#define SAY_DEATH -1604021
+#define SAY_SUMMON_SNAKES -1604022 //npc 29680
+#define SAY_SUMMON_CONSTRICTORS -1604023 //npc 29713, can cast Grip of Slad'ran (spell 55093)
+
+struct TRINITY_DLL_DECL boss_slad_ranAI : public ScriptedAI
+{
+ boss_slad_ranAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 30)
+ {
+ //Summon 3 snakes --> npc 29680
+ DoScriptText(SAY_SUMMON_SNAKES,m_creature);
+ }
+ if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 25)
+ {
+ //Summon 3 constrictors --> npc 29713
+ DoScriptText(SAY_SUMMON_CONSTRICTORS,m_creature);
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ switch(rand()%3)
+ {
+ case 0:DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1:DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2:DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_slad_ran(Creature *_Creature)
+{
+ return new boss_slad_ranAI (_Creature);
+}
+
+void AddSC_boss_slad_ran()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_slad_ran";
+ newscript->GetAI = GetAI_boss_slad_ran;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/gundrak/def_gundrak.h b/src/bindings/scripts/scripts/zone/gundrak/def_gundrak.h
new file mode 100644
index 00000000000..5f015610312
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/gundrak/def_gundrak.h
@@ -0,0 +1,4 @@
+#ifndef DEF_GUNDRAK_H
+#define DEF_GUNDRAK_H
+
+#endif
diff --git a/src/bindings/scripts/scripts/zone/gundrak/instance_gundrak.cpp b/src/bindings/scripts/scripts/zone/gundrak/instance_gundrak.cpp
new file mode 100644
index 00000000000..88df9e1b73c
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/gundrak/instance_gundrak.cpp
@@ -0,0 +1,21 @@
+#include "precompiled.h"
+#include "def_gundrak.h"
+
+struct TRINITY_DLL_DECL instance_gundrak : public ScriptedInstance
+{
+ instance_gundrak(Map *Map) : ScriptedInstance(Map) {Initialize();};
+};
+
+InstanceData* GetInstanceData_instance_gundrak(Map* map)
+{
+ return new instance_gundrak(map);
+}
+
+void AddSC_instance_gundrak()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_gundrak";
+ newscript->GetInstanceData = GetInstanceData_instance_gundrak;
+ 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 92971bf16cf..a4c873eabcd 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -6,18 +6,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
*/
/* ScriptData
SDName: Boss_Broggok
-SD%Complete: 100
-SDComment:
+SD%Complete: 70
+SDComment: pre-event not made
SDCategory: Hellfire Citadel, Blood Furnace
EndScriptData */
@@ -46,30 +46,37 @@ struct TRINITY_DLL_DECL boss_broggokAI : public ScriptedAI
PoisonBolt_Timer = 7000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
- void UpdateAI(const uint32 diff)
+ void JustSummoned(Creature *summoned)
{
+ summoned->setFaction(16);
+ summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ summoned->CastSpell(summoned,SPELL_POISON,false,0,0,m_creature->GetGUID());
+ }
- if (!UpdateVictim())
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim() )
return;
- if(AcidSpray_Timer < diff)
+ if (AcidSpray_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_SLIME_SPRAY);
AcidSpray_Timer = 4000+rand()%8000;
}else AcidSpray_Timer -=diff;
- if(PoisonBolt_Timer < diff)
+ if (PoisonBolt_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_POISON_BOLT);
PoisonBolt_Timer = 4000+rand()%8000;
}else PoisonBolt_Timer -=diff;
- if(PoisonSpawn_Timer < diff)
+ if (PoisonSpawn_Timer < diff)
{
DoCast(m_creature,SPELL_POISON_CLOUD);
PoisonSpawn_Timer = 20000;
@@ -79,17 +86,36 @@ struct TRINITY_DLL_DECL boss_broggokAI : public ScriptedAI
}
};
-CreatureAI* GetAI_boss_broggokAI(Creature *_Creature)
+struct TRINITY_DLL_DECL mob_broggok_poisoncloudAI : public ScriptedAI
+{
+ mob_broggok_poisoncloudAI(Creature *c) : ScriptedAI(c) {Reset();}
+
+ void Reset() { }
+ void MoveInLineOfSight(Unit *who) { }
+ void AttackStart(Unit *who) { }
+ void EnterCombat(Unit* who) { }
+};
+
+CreatureAI* GetAI_boss_broggok(Creature *_Creature)
{
return new boss_broggokAI (_Creature);
}
+CreatureAI* GetAI_mob_broggok_poisoncloud(Creature *_Creature)
+{
+ return new mob_broggok_poisoncloudAI (_Creature);
+}
+
void AddSC_boss_broggok()
{
Script *newscript;
newscript = new Script;
- newscript->Name="boss_broggok";
- newscript->GetAI = &GetAI_boss_broggokAI;
+ newscript->Name = "boss_broggok";
+ newscript->GetAI = &GetAI_boss_broggok;
newscript->RegisterSelf();
-}
+ newscript = new Script;
+ newscript->Name = "mob_broggok_poisoncloud";
+ newscript->GetAI = &GetAI_mob_broggok_poisoncloud;
+ 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 64bd8e04de1..e1365a05a77 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -62,12 +62,6 @@ const float ShadowmoonChannelers[5][4]=
{316,-109,-24.6,1.257}
};
-class TRINITY_DLL_DECL BurningNovaAura : public Aura
-{
- public:
- BurningNovaAura(SpellEntry *spell, uint32 eff, Unit *target, Unit *caster) : Aura(spell, eff, NULL, target, caster, NULL){}
-};
-
struct TRINITY_DLL_DECL boss_kelidan_the_breakerAI : public ScriptedAI
{
boss_kelidan_the_breakerAI(Creature *c) : ScriptedAI(c)
@@ -100,7 +94,7 @@ struct TRINITY_DLL_DECL boss_kelidan_the_breakerAI : public ScriptedAI
SummonChannelers();
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_WAKE, m_creature);
if (m_creature->IsNonMeleeSpellCasted(false))
@@ -234,12 +228,14 @@ struct TRINITY_DLL_DECL boss_kelidan_the_breakerAI : public ScriptedAI
if(SpellEntry *nova = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_BURNING_NOVA))
{
- for(uint32 i = 0; i < 3; ++i)
- if(nova->Effect[i] == SPELL_EFFECT_APPLY_AURA)
- {
- Aura *Aur = new BurningNovaAura(nova, i, m_creature, m_creature);
- m_creature->AddAura(Aur);
- }
+ uint8 eff_mask=0;
+ for (int i=0; i<3; i++)
+ {
+ if (!nova->Effect[i])
+ continue;
+ eff_mask|=1<<i;
+ }
+ m_creature->AddAura(new Aura(nova, eff_mask, NULL, m_creature, m_creature));
}
if (HeroicMode)
@@ -293,7 +289,7 @@ struct TRINITY_DLL_DECL mob_shadowmoon_channelerAI : public ScriptedAI
m_creature->InterruptNonMeleeSpells(true);
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
if(Creature *Kelidan = (Creature *)FindCreature(ENTRY_KELIDAN, 100, m_creature))
((boss_kelidan_the_breakerAI*)Kelidan->AI())->ChannelerEngaged(who);
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 65c98d5ef8d..02bfef63ea1 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -52,7 +52,7 @@ struct TRINITY_DLL_DECL boss_the_makerAI : public ScriptedAI
Knockdown_Timer = 10000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp b/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp
index caf29b1f213..035bd8aadfe 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp
@@ -68,20 +68,6 @@ struct TRINITY_DLL_DECL instance_blood_furnace : public ScriptedInstance
return NULL;
}
- void HandleGameObject(uint64 guid, uint32 state)
- {
- Player *player = GetPlayerInMap();
-
- if (!player || !guid)
- {
- debug_log("TSCR: Blood Furnace: HandleGameObject fail");
- return;
- }
-
- if (GameObject *go = GameObject::GetGameObject(*player,guid))
- go->SetGoState(state);
- }
-
void SetData(uint32 type, uint32 data)
{
switch(type)
@@ -89,8 +75,8 @@ struct TRINITY_DLL_DECL instance_blood_furnace : public ScriptedInstance
case DATA_KELIDANEVENT:
if( data == DONE )
{
- HandleGameObject(Sewer1GUID,0);
- HandleGameObject(Sewer2GUID,0);
+ HandleGameObject(Sewer1GUID, true);
+ HandleGameObject(Sewer2GUID, true);
}
break;
}
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 0dce1fe51d9..99130528eb8 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -75,7 +75,7 @@ struct TRINITY_DLL_DECL boss_omor_the_unscarredAI : public Scripted_NoMovementAI
CanPullBack = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_vazruden_the_herald.cpp b/src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_vazruden_the_herald.cpp
index 86d76952b45..0e99aea9350 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_vazruden_the_herald.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_vazruden_the_herald.cpp
@@ -85,7 +85,7 @@ struct TRINITY_DLL_DECL boss_nazanAI : public ScriptedAI
UnsummonCheck = 5000;
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void JustSummoned(Creature *summoned)
{
@@ -133,7 +133,7 @@ struct TRINITY_DLL_DECL boss_nazanAI : public ScriptedAI
flight = false;
BellowingRoar_Timer = 6000;
ConeOfFire_Timer = 12000;
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
m_creature->GetMotionMaster()->Clear();
if(Unit *victim = SelectUnit(SELECT_TARGET_NEAREST,0))
@@ -190,7 +190,7 @@ struct TRINITY_DLL_DECL boss_vazrudenAI : public ScriptedAI
WipeSaid = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
@@ -317,7 +317,7 @@ struct TRINITY_DLL_DECL boss_vazruden_the_heraldAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(phase==0)
{
@@ -334,7 +334,7 @@ struct TRINITY_DLL_DECL boss_vazruden_the_heraldAI : public ScriptedAI
if(summoned->GetEntry() == ENTRY_NAZAN)
{
((boss_nazanAI *)summoned->AI())->VazrudenGUID = VazrudenGUID;
- summoned->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ summoned->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
summoned->SetSpeed(MOVE_FLIGHT, 2.5);
if(victim)
((ScriptedAI*)summoned->AI())->AttackStart(victim,false);
@@ -416,7 +416,7 @@ struct TRINITY_DLL_DECL mob_hellfire_sentryAI : public ScriptedAI
KidneyShot_Timer = 3000+rand()%4000;
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void JustDied(Unit* who)
{
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 042291b330a..c36f963555c 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -64,7 +64,7 @@ struct TRINITY_DLL_DECL boss_watchkeeper_gargolmarAI : public ScriptedAI
YelledForHeal = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
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 3e001888752..96956790019 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
@@ -128,7 +128,7 @@ struct TRINITY_DLL_DECL mob_abyssalAI : public ScriptedAI
}
}
- void Aggro(Unit*) {DoZoneInCombat();}
+ void EnterCombat(Unit*) {DoZoneInCombat();}
void AttackStart(Unit *who) {if(!trigger) ScriptedAI::AttackStart(who);}
void MoveInLineOfSight(Unit *who) {if(!trigger) ScriptedAI::MoveInLineOfSight(who);}
@@ -257,7 +257,7 @@ struct TRINITY_DLL_DECL boss_magtheridonAI : public ScriptedAI
for(CubeMap::iterator i = Cube.begin(); i != Cube.end(); ++i)
{
Unit *clicker = Unit::GetUnit(*m_creature, (*i).second);
- if(!clicker || !clicker->HasAura(SPELL_SHADOW_GRASP, 1))
+ if(!clicker || !clicker->HasAura(SPELL_SHADOW_GRASP))
{
DebuffClicker(clicker);
(*i).second = 0;
@@ -265,12 +265,12 @@ struct TRINITY_DLL_DECL boss_magtheridonAI : public ScriptedAI
}
// if 5 clickers from other cubes apply shadow cage
- if(ClickerNum >= CLICKERS_COUNT && !m_creature->HasAura(SPELL_SHADOW_CAGE, 0))
+ if(ClickerNum >= CLICKERS_COUNT && !m_creature->HasAura(SPELL_SHADOW_CAGE))
{
DoScriptText(SAY_BANISH, m_creature);
m_creature->CastSpell(m_creature, SPELL_SHADOW_CAGE, true);
}
- else if(ClickerNum < CLICKERS_COUNT && m_creature->HasAura(SPELL_SHADOW_CAGE, 0))
+ else if(ClickerNum < CLICKERS_COUNT && m_creature->HasAura(SPELL_SHADOW_CAGE))
m_creature->RemoveAurasDueToSpell(SPELL_SHADOW_CAGE);
if(!ClickerNum) NeedCheckCube = false;
@@ -297,7 +297,7 @@ struct TRINITY_DLL_DECL boss_magtheridonAI : public ScriptedAI
ScriptedAI::AttackStart(who);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
pInstance->SetData(DATA_MAGTHERIDON_EVENT, IN_PROGRESS);
@@ -311,7 +311,7 @@ struct TRINITY_DLL_DECL boss_magtheridonAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
- if (!InCombat)
+ if (!m_creature->isInCombat())
{
if (RandChat_Timer < diff)
{
@@ -439,7 +439,7 @@ struct TRINITY_DLL_DECL mob_hellfire_channelerAI : public ScriptedAI
m_creature->CastSpell(m_creature, SPELL_SHADOW_GRASP_C, false);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
pInstance->SetData(DATA_CHANNELER_EVENT, IN_PROGRESS);
@@ -510,7 +510,7 @@ bool GOHello_go_Manticron_Cube(Player *player, GameObject* _GO)
if(!Magtheridon || !Magtheridon->isAlive()) return true;
// if exhausted or already channeling return
- if(player->HasAura(SPELL_MIND_EXHAUSTION, 0) || player->HasAura(SPELL_SHADOW_GRASP, 1))
+ if(player->HasAura(SPELL_MIND_EXHAUSTION) || player->HasAura(SPELL_SHADOW_GRASP))
return true;
player->InterruptNonMeleeSpells(false);
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/def_magtheridons_lair.h b/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/def_magtheridons_lair.h
index 3c0012ce447..c5469acaea0 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/def_magtheridons_lair.h
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/def_magtheridons_lair.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
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 ea51e575824..8f3a28e02a3 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -126,8 +126,8 @@ struct TRINITY_DLL_DECL instance_magtheridons_lair : public ScriptedInstance
RespawnTimer = 10000;
if(data != IN_PROGRESS)
{
- if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID))
- Door->SetGoState(0);
+ if(GameObject *Door = instance->GetGameObject(DoorGUID))
+ Door->SetGoState(GO_STATE_ACTIVE);
}
break;
case DATA_CHANNELER_EVENT:
@@ -139,7 +139,7 @@ struct TRINITY_DLL_DECL instance_magtheridons_lair : public ScriptedInstance
Encounters[1] = NOT_STARTED;
for(std::set<uint64>::iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i)
{
- if(Creature *Channeler = instance->GetCreatureInMap(*i))
+ if(Creature *Channeler = instance->GetCreature(*i))
{
if(Channeler->isAlive())
Channeler->AI()->EnterEvadeMode();
@@ -148,8 +148,8 @@ struct TRINITY_DLL_DECL instance_magtheridons_lair : public ScriptedInstance
}
}
CageTimer = 0;
- if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID))
- Door->SetGoState(0);
+ if(GameObject *Door = instance->GetGameObject(DoorGUID))
+ Door->SetGoState(GO_STATE_ACTIVE);
}break;
case IN_PROGRESS: // Event start.
if(Encounters[1] != IN_PROGRESS)
@@ -158,24 +158,24 @@ struct TRINITY_DLL_DECL instance_magtheridons_lair : public ScriptedInstance
// Let all five channelers aggro.
for(std::set<uint64>::iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i)
{
- Creature *Channeler = instance->GetCreatureInMap(*i);
+ Creature *Channeler = instance->GetCreature(*i);
if(Channeler && Channeler->isAlive())
Channeler->AI()->AttackStart(Channeler->SelectNearestTarget(999));
}
// Release Magtheridon after two minutes.
- Creature *Magtheridon = instance->GetCreatureInMap(MagtheridonGUID);
+ Creature *Magtheridon = instance->GetCreature(MagtheridonGUID);
if(Magtheridon && Magtheridon->isAlive())
{
- Magtheridon->TextEmote("'s bonds begin to weaken!", 0);
+ Magtheridon->MonsterTextEmote("'s bonds begin to weaken!", 0);
CageTimer = 120000;
}
- if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID))
- Door->SetGoState(1);
+ if(GameObject *Door = instance->GetGameObject(DoorGUID))
+ Door->SetGoState(GO_STATE_READY);
}break;
case DONE: // Add buff and check if all channelers are dead.
for(std::set<uint64>::iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i)
{
- Creature *Channeler = instance->GetCreatureInMap(*i);
+ Creature *Channeler = instance->GetCreature(*i);
if(Channeler && Channeler->isAlive())
{
//Channeler->CastSpell(Channeler, SPELL_SOUL_TRANSFER, true);
@@ -189,10 +189,7 @@ struct TRINITY_DLL_DECL instance_magtheridons_lair : public ScriptedInstance
case DATA_COLLAPSE:
// true - collapse / false - reset
for(std::set<uint64>::iterator i = ColumnGUID.begin(); i != ColumnGUID.end(); ++i)
- {
- if(GameObject *Column = instance->GetGameObjectInMap(*i))
- Column->SetGoState(!data);
- }
+ HandleGameObject(*i, data);
break;
default:
break;
@@ -212,7 +209,7 @@ struct TRINITY_DLL_DECL instance_magtheridons_lair : public ScriptedInstance
{
if(CageTimer <= diff)
{
- Creature *Magtheridon = instance->GetCreatureInMap(MagtheridonGUID);
+ Creature *Magtheridon = instance->GetCreature(MagtheridonGUID);
if(Magtheridon && Magtheridon->isAlive())
{
Magtheridon->clearUnitState(UNIT_STAT_STUNNED);
@@ -228,7 +225,7 @@ struct TRINITY_DLL_DECL instance_magtheridons_lair : public ScriptedInstance
{
for(std::set<uint64>::iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i)
{
- if(Creature *Channeler = instance->GetCreatureInMap(*i))
+ if(Creature *Channeler = instance->GetCreature(*i))
{
if(Channeler->isAlive())
Channeler->AI()->EnterEvadeMode();
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 320c6a0b0a4..2506d2a56aa 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -168,14 +168,6 @@ struct TRINITY_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI
if (m_creature->Attack(who, true))
{
- m_creature->AddThreat(who, 0.0f);
-
- if (!InCombat)
- {
- InCombat = true;
- Aggro(who);
- }
-
if (Phase) DoStartNoMovement(who);
else DoStartMovement(who);
}
@@ -183,10 +175,11 @@ struct TRINITY_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI
void MoveInLineOfSight(Unit *who)
{
- if (!m_creature->getVictim() && who->isTargetableForAttack() && ( m_creature->IsHostileTo( who )) && who->isInAccessiblePlaceFor(m_creature) )
- {
- if (!IntroOnce && m_creature->IsWithinDistInMap(who, 75))
+ if (!IntroOnce && m_creature->IsWithinDistInMap(who, 50.0f))
{
+ if (who->GetTypeId() != TYPEID_PLAYER)
+ return;
+
DoScriptText(SAY_INTRO, m_creature);
IntroOnce = true;
IsIntroEvent = true;
@@ -195,22 +188,13 @@ struct TRINITY_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI
pInstance->SetData(TYPE_NETHEKURSE,IN_PROGRESS);
}
- if (!m_creature->canFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE )
- return;
-
if (IsIntroEvent || !IsMainEvent)
return;
- float attackRadius = m_creature->GetAttackDistance(who);
- if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who) )
- {
- //who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
- AttackStart(who);
- }
- }
+ ScriptedAI::MoveInLineOfSight(who);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
@@ -222,9 +206,13 @@ struct TRINITY_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI
void JustSummoned(Creature *summoned)
{
- summoned->setFaction(14);
+ summoned->setFaction(16);
summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
+ //triggered spell of consumption does not properly show it's SpellVisual, wrong spellid?
+ summoned->CastSpell(summoned,SPELL_TEMPORARY_VISUAL,true);
+ summoned->CastSpell(summoned,SPELL_CONSUMPTION,false,0,0,m_creature->GetGUID());
}
void KilledUnit(Unit* victim)
@@ -248,7 +236,7 @@ struct TRINITY_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI
if (pInstance->GetData64(DATA_NETHEKURSE_DOOR))
{
if (GameObject *Door = GameObject::GetGameObject(*m_creature,pInstance->GetData64(DATA_NETHEKURSE_DOOR)))
- Door->SetGoState(0);
+ Door->SetGoState(GO_STATE_ACTIVE);
}
}
@@ -333,27 +321,31 @@ struct TRINITY_DLL_DECL mob_fel_orc_convertAI : public ScriptedAI
return;
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
if (pInstance)
{
if (pInstance->GetData64(DATA_NETHEKURSE))
{
Creature *pKurse = Unit::GetCreature(*m_creature,pInstance->GetData64(DATA_NETHEKURSE));
- if (pKurse)
+ if (pKurse && m_creature->GetDistance(pKurse) < 45.0f)
+ {
((boss_grand_warlock_nethekurseAI*)pKurse->AI())->DoYellForPeonAggro();
- }
- if (pInstance->GetData(TYPE_NETHEKURSE) == IN_PROGRESS )
- return;
- else pInstance->SetData(TYPE_NETHEKURSE,IN_PROGRESS);
- }
+ if (pInstance->GetData(TYPE_NETHEKURSE) == IN_PROGRESS )
+ return;
+ else pInstance->SetData(TYPE_NETHEKURSE,IN_PROGRESS);
+ }
+ }
+ }
}
void JustDied(Unit* Killer)
{
if (pInstance)
{
+ if (pInstance->GetData(TYPE_NETHEKURSE) != IN_PROGRESS)
+ return;
if (pInstance->GetData64(DATA_NETHEKURSE))
{
Creature *pKurse = Unit::GetCreature(*m_creature,pInstance->GetData64(DATA_NETHEKURSE));
@@ -383,39 +375,10 @@ struct TRINITY_DLL_DECL mob_lesser_shadow_fissureAI : public ScriptedAI
{
mob_lesser_shadow_fissureAI(Creature *c) : ScriptedAI(c) {}
- bool Start;
- uint32 Stop_Timer;
-
- void Reset()
- {
- Start = false;
- Stop_Timer = 30000;
- }
-
- void Aggro(Unit* who) { }
-
- void MoveInLineOfSight(Unit *who) { return; }
-
- void AttackStart(Unit* who) { return; }
-
- void UpdateAI(const uint32 diff)
- {
- if (!Start)
- {
- //triggered spell of consumption does not properly show it's SpellVisual, hack it a bit
- m_creature->CastSpell(m_creature,SPELL_TEMPORARY_VISUAL,true);
- m_creature->CastSpell(m_creature,SPELL_CONSUMPTION,false);
- Start = true;
- }
-
- if (Stop_Timer < diff)
- {
- m_creature->setDeathState(JUST_DIED);
- m_creature->SetHealth(0);
- m_creature->CombatStop();
- m_creature->DeleteThreatList();
- }else Stop_Timer -= diff;
- }
+ void Reset() { }
+ void MoveInLineOfSight(Unit *who) { }
+ void AttackStart(Unit* who) { }
+ void EnterCombat(Unit* who) { }
};
CreatureAI* GetAI_boss_grand_warlock_nethekurse(Creature *_Creature)
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 b5caede6f7d..a225293a48e 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -103,7 +103,7 @@ struct TRINITY_DLL_DECL mob_omrogg_headsAI : public ScriptedAI
uint32 Death_Timer;
void Reset() {}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void DoDeathYell()
{
@@ -156,8 +156,6 @@ struct TRINITY_DLL_DECL boss_warbringer_omroggAI : public ScriptedAI
void Reset()
{
- m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
- m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
LeftHead = 0;
RightHead = 0;
@@ -175,6 +173,9 @@ struct TRINITY_DLL_DECL boss_warbringer_omroggAI : public ScriptedAI
ThunderClap_Timer = 15000;
ResetThreat_Timer = 30000;
+ m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
+ m_creature->ApplySpellImmune(1, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
+
if (pInstance)
pInstance->SetData(TYPE_OMROGG, NOT_STARTED); //End boss can use this later. O'mrogg must be defeated(DONE) or he will come to aid.
}
@@ -200,10 +201,10 @@ struct TRINITY_DLL_DECL boss_warbringer_omroggAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
- DoSpawnCreature(ENTRY_LEFT_HEAD,0,0,0,0,TEMPSUMMON_TIMED_DESPAWN,1800000);
- DoSpawnCreature(ENTRY_RIGHT_HEAD,0,0,0,0,TEMPSUMMON_TIMED_DESPAWN,1800000);
+ DoSpawnCreature(ENTRY_LEFT_HEAD,0,0,0,0,TEMPSUMMON_TIMED_DESPAWN,90000);
+ DoSpawnCreature(ENTRY_RIGHT_HEAD,0,0,0,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,90000);
if (Unit *Left = Unit::GetUnit(*m_creature,LeftHead))
{
@@ -357,19 +358,19 @@ struct TRINITY_DLL_DECL boss_warbringer_omroggAI : public ScriptedAI
DoResetThreat();
m_creature->AddThreat(target, 0.0f);
}
- ResetThreat_Timer = 35000+rand()%10000;
+ ResetThreat_Timer = 25000+rand()%15000;
}else ResetThreat_Timer -= diff;
if (Fear_Timer < diff)
{
DoCast(m_creature,SPELL_FEAR);
- Fear_Timer = 15000+rand()%25000;
+ Fear_Timer = 15000+rand()%20000;
}else Fear_Timer -= diff;
if (ThunderClap_Timer < diff)
{
DoCast(m_creature,SPELL_THUNDERCLAP);
- ThunderClap_Timer = 25000+rand()%15000;
+ ThunderClap_Timer = 15000+rand()%15000;
}else ThunderClap_Timer -= diff;
DoMeleeAttackIfReady();
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp b/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp
index 8c4b24421c6..33e6468c3e7 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp
@@ -1,6 +1,39 @@
-/* Copyright (C) 2008 - 2009 BroodWyrm */
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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
+ */
+
+/* ScriptData
+SDName: Boss_Warchief_Kargath_Bladefist
+SD%Complete: 90
+SDComment:
+SDCategory: Hellfire Citadel, Shattered Halls
+EndScriptData */
+
+/* ContentData
+boss_warchief_kargath_bladefist
+EndContentData */
+
#include "precompiled.h"
+#define SAY_AGGRO1 -1540042
+#define SAY_AGGRO2 -1540043
+#define SAY_AGGRO3 -1540044
+#define SAY_SLAY1 -1540045
+#define SAY_SLAY2 -1540046
+#define SAY_DEATH -1540047
+
#define SPELL_BLADE_DANCE 30739
#define H_SPELL_CHARGE 25821
@@ -11,23 +44,10 @@
#define MOB_SHARPSHOOTER_GUARD 17622
#define MOB_REAVER_GUARD 17623
-float AssassEntrance[3] = {275.136,-84.29,2.3}; // y +-8
-float AssassExit[3] = {184.233,-84.29,2.3}; // y +-8
+float AssassEntrance[3] = {275.136,-84.29,2.3}; // y -8
+float AssassExit[3] = {184.233,-84.29,2.3}; // y -8
float AddsEntrance[3] = {306.036,-84.29,1.93};
-#define SOUND_AGGRO1 10323
-#define SAY_AGGRO1 "Ours is the true Horde! The only Horde!"
-#define SOUND_AGGRO2 10324
-#define SAY_AGGRO2 "I'll carve the meat from your bones!"
-#define SOUND_AGGRO3 10325
-#define SAY_AGGRO3 "I am called Bladefist for a reason, as you will see!"
-#define SOUND_SLAY1 10326
-#define SAY_SLAY1 "For the real Horde!"
-#define SOUND_SLAY2 10327
-#define SAY_SLAY2 "I am the only Warchief!"
-#define SOUND_DEATH 10328
-#define SAY_DEATH "The true Horde... will.. prevail.."
-
struct TRINITY_DLL_DECL boss_warchief_kargath_bladefistAI : public ScriptedAI
{
boss_warchief_kargath_bladefistAI(Creature *c) : ScriptedAI(c)
@@ -67,28 +87,19 @@ struct TRINITY_DLL_DECL boss_warchief_kargath_bladefistAI : public ScriptedAI
Wait_Timer = 0;
Charge_timer = 0;
- Blade_Dance_Timer = 30000;
- Summon_Assistant_Timer = 15000;
+ Blade_Dance_Timer = 45000;
+ Summon_Assistant_Timer = 30000;
Assassins_Timer = 5000;
resetcheck_timer = 5000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch (rand()%3)
{
- case 0:
- DoPlaySoundToSet(m_creature,SOUND_AGGRO1);
- DoYell(SAY_AGGRO1,LANG_UNIVERSAL,NULL);
- break;
- case 1:
- DoPlaySoundToSet(m_creature,SOUND_AGGRO2);
- DoYell(SAY_AGGRO2,LANG_UNIVERSAL,NULL);
- break;
- case 2:
- DoPlaySoundToSet(m_creature,SOUND_AGGRO3);
- DoYell(SAY_AGGRO3,LANG_UNIVERSAL,NULL);
- break;
+ case 0:DoScriptText(SAY_AGGRO1, m_creature);break;
+ case 1:DoScriptText(SAY_AGGRO2, m_creature);break;
+ case 2:DoScriptText(SAY_AGGRO3, m_creature);break;
}
}
@@ -114,22 +125,15 @@ struct TRINITY_DLL_DECL boss_warchief_kargath_bladefistAI : public ScriptedAI
{
switch(rand()%2)
{
- case 0:
- DoPlaySoundToSet(m_creature, SOUND_SLAY1);
- DoYell(SAY_SLAY1,LANG_UNIVERSAL,NULL);
- break;
- case 1:
- DoPlaySoundToSet(m_creature, SOUND_SLAY2);
- DoYell(SAY_SLAY2,LANG_UNIVERSAL,NULL);
- break;
+ case 0: DoScriptText(SAY_SLAY1, m_creature); break;
+ case 1: DoScriptText(SAY_SLAY2, m_creature); break;
}
}
}
void JustDied(Unit* Killer)
{
- DoPlaySoundToSet(m_creature, SOUND_DEATH);
- DoYell(SAY_DEATH,LANG_UNIVERSAL,NULL);
+ DoScriptText(SAY_DEATH, m_creature);
removeAdds();
}
@@ -180,15 +184,16 @@ struct TRINITY_DLL_DECL boss_warchief_kargath_bladefistAI : public ScriptedAI
}
void SpawnAssassin()
{
- m_creature->SummonCreature(MOB_SHATTERED_ASSASSIN,AssassEntrance[0],AssassEntrance[1]+8, AssassEntrance[2], 0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,10000);
- m_creature->SummonCreature(MOB_SHATTERED_ASSASSIN,AssassEntrance[0],AssassEntrance[1]-8, AssassEntrance[2], 0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,10000);
- m_creature->SummonCreature(MOB_SHATTERED_ASSASSIN,AssassExit[0],AssassExit[1]+8, AssassExit[2], 0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,10000);
- m_creature->SummonCreature(MOB_SHATTERED_ASSASSIN,AssassExit[0],AssassExit[1]-8, AssassExit[2], 0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,10000);
+ m_creature->SummonCreature(MOB_SHATTERED_ASSASSIN,AssassEntrance[0],AssassEntrance[1]+8, AssassEntrance[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000);
+ m_creature->SummonCreature(MOB_SHATTERED_ASSASSIN,AssassEntrance[0],AssassEntrance[1]-8, AssassEntrance[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000);
+ m_creature->SummonCreature(MOB_SHATTERED_ASSASSIN,AssassExit[0],AssassExit[1]+8, AssassExit[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000);
+ m_creature->SummonCreature(MOB_SHATTERED_ASSASSIN,AssassExit[0],AssassExit[1]-8, AssassExit[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000);
}
void UpdateAI(const uint32 diff)
{
- if (!UpdateVictim() )
+ //Return since we have no target
+ if (!UpdateVictim())
return;
if(Assassins_Timer)
@@ -250,30 +255,29 @@ struct TRINITY_DLL_DECL boss_warchief_kargath_bladefistAI : public ScriptedAI
if (Summon_Assistant_Timer < diff)
{
Unit* target = NULL;
- Creature* Summoned;
for(int i = 0; i < summoned; i++)
{
switch(rand()%3)
{
- case 0: Summoned = m_creature->SummonCreature(MOB_HEARTHEN_GUARD,AddsEntrance[0],AddsEntrance[1], AddsEntrance[2], 0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,10000); break;
- case 1: Summoned = m_creature->SummonCreature(MOB_SHARPSHOOTER_GUARD,AddsEntrance[0],AddsEntrance[1], AddsEntrance[2], 0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,10000); break;
- case 2: Summoned = m_creature->SummonCreature(MOB_REAVER_GUARD,AddsEntrance[0],AddsEntrance[1], AddsEntrance[2], 0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,10000); break;
+ case 0: m_creature->SummonCreature(MOB_HEARTHEN_GUARD,AddsEntrance[0],AddsEntrance[1], AddsEntrance[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); break;
+ case 1: m_creature->SummonCreature(MOB_SHARPSHOOTER_GUARD,AddsEntrance[0],AddsEntrance[1], AddsEntrance[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); break;
+ case 2: m_creature->SummonCreature(MOB_REAVER_GUARD,AddsEntrance[0],AddsEntrance[1], AddsEntrance[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); break;
}
}
if(rand()%100 < 20) summoned++;
- Summon_Assistant_Timer = 15000 + (rand()%5000) ;
+ Summon_Assistant_Timer = 25000 + (rand()%10000) ;
}else Summon_Assistant_Timer -= diff;
DoMeleeAttackIfReady();
}
- if(resetcheck_timer < diff)
+ if (resetcheck_timer < diff)
{
uint32 tempx,tempy;
- tempx = m_creature->GetPositionX();
- tempy = m_creature->GetPositionY();
- if ( tempx > 255 || tempx < 205)
+ tempx = uint32(m_creature->GetPositionX());
+ tempy = uint32(m_creature->GetPositionY());
+ if (tempx > 255 || tempx < 205)
{
EnterEvadeMode();
}
@@ -292,7 +296,7 @@ void AddSC_boss_warchief_kargath_bladefist()
Script *newscript;
newscript = new Script;
newscript->Name="boss_warchief_kargath_bladefist";
- newscript->GetAI = &GetAI_boss_warchief_kargath_bladefist;
+ newscript->GetAI = GetAI_boss_warchief_kargath_bladefist;
newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/def_shattered_halls.h b/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/def_shattered_halls.h
index cb3a06055cb..cbfa23ec4e0 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/def_shattered_halls.h
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/def_shattered_halls.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
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 aa2817ca994..b606ff0f97e 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
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 b9e3b9d752f..27e673f7f29 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -73,7 +73,7 @@ struct TRINITY_DLL_DECL boss_doomlordkazzakAI : public ScriptedAI
DoScriptText(SAY_INTRO, m_creature);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%2)
{
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 cba3a107af6..54d4e4803f4 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -68,7 +68,7 @@ struct TRINITY_DLL_DECL npc_aeranasAI : public ScriptedAI
DoScriptText(SAY_SUMMON, m_creature);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void UpdateAI(const uint32 diff)
{
@@ -293,8 +293,6 @@ struct TRINITY_DLL_DECL npc_wounded_blood_elfAI : public npc_escortAI
break;
case 13:
DoScriptText(SAY_ELF_RESTING, m_creature, player);
- // make the NPC kneel
- m_creature->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL);
break;
case 14:
DoScriptText(SAY_ELF_SUMMON2, m_creature, player);
@@ -318,7 +316,7 @@ struct TRINITY_DLL_DECL npc_wounded_blood_elfAI : public npc_escortAI
m_creature->setFaction(1604);
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
if (IsBeingEscorted)
DoScriptText(SAY_ELF_AGGRO, m_creature);
@@ -349,38 +347,11 @@ struct TRINITY_DLL_DECL npc_wounded_blood_elfAI : public npc_escortAI
}
};
-CreatureAI* GetAI_npc_wounded_blood_elf(Creature *_Creature)
+CreatureAI* GetAI_npc_wounded_blood_elf(Creature* pCreature)
{
- npc_wounded_blood_elfAI* welfAI = new npc_wounded_blood_elfAI(_Creature);
-
- welfAI->AddWaypoint(0, -1137.72, 4272.10, 14.04, 5000);
- welfAI->AddWaypoint(1, -1141.34, 4232.42, 14.63);
- welfAI->AddWaypoint(2, -1133.47, 4220.88, 11.78);
- welfAI->AddWaypoint(3, -1126.18, 4213.26, 13.51);
- welfAI->AddWaypoint(4, -1100.12, 4204.32, 16.41);
- welfAI->AddWaypoint(5, -1063.68, 4197.92, 15.51);
- welfAI->AddWaypoint(6, -1027.28, 4194.36, 15.52);
- welfAI->AddWaypoint(7, -995.68, 4189.59, 19.84);
- welfAI->AddWaypoint(8, -970.90, 4188.60, 24.61);
- welfAI->AddWaypoint(9, -961.93, 4193.34, 26.11, 15000); // Summon 1
- welfAI->AddWaypoint(10, -935.52, 4210.99, 31.98);
- welfAI->AddWaypoint(11, -913.42, 4218.27, 37.29);
- welfAI->AddWaypoint(12, -896.53, 4207.73, 43.23);
- welfAI->AddWaypoint(13, -868.49, 4194.77, 46.75, 30000);// Kneel and Rest Here
- welfAI->AddWaypoint(14, -852.83, 4198.29, 47.28, 15000);// Summon 2
- welfAI->AddWaypoint(15, -819.85, 4200.50, 46.37);
- welfAI->AddWaypoint(16, -791.92, 4201.96, 44.19);
- welfAI->AddWaypoint(17, -774.42, 4202.46, 47.41);
- welfAI->AddWaypoint(18, -762.90, 4202.17, 48.81);
- welfAI->AddWaypoint(19, -728.25, 4195.35, 50.68);
- welfAI->AddWaypoint(20, -713.58, 4192.07, 53.98);
- welfAI->AddWaypoint(21, -703.09, 4189.74, 56.96);
- welfAI->AddWaypoint(22, -693.70, 4185.43, 57.06);
- welfAI->AddWaypoint(23, -686.38, 4159.81, 60.26);
- welfAI->AddWaypoint(24, -679.88, 4147.04, 64.20);
- welfAI->AddWaypoint(25, -656.74, 4147.72, 64.11);
- welfAI->AddWaypoint(26, -652.22, 4137.50, 64.58);
- welfAI->AddWaypoint(27, -649.99, 4136.38, 64.63, 30000);// Award Quest Credit
+ npc_wounded_blood_elfAI* welfAI = new npc_wounded_blood_elfAI(pCreature);
+
+ welfAI->FillPointMovementListForCreature();
return (CreatureAI*)welfAI;
}
diff --git a/src/bindings/scripts/scripts/zone/ironforge/ironforge.cpp b/src/bindings/scripts/scripts/zone/ironforge/ironforge.cpp
index 674bf56bb26..b17a280391a 100644
--- a/src/bindings/scripts/scripts/zone/ironforge/ironforge.cpp
+++ b/src/bindings/scripts/scripts/zone/ironforge/ironforge.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
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 900a5ae3d5b..a5d1fcd3c37 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -87,7 +87,7 @@ struct TRINITY_DLL_DECL npc_converted_sentryAI : public ScriptedAI
void MoveInLineOfSight(Unit *who)
{ return; }
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{ }
void UpdateAI(const uint32 diff)
@@ -153,7 +153,7 @@ struct TRINITY_DLL_DECL npc_greengill_slaveAI : public ScriptedAI
uint64 PlayerGUID;
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void Reset()
{
@@ -165,7 +165,7 @@ struct TRINITY_DLL_DECL npc_greengill_slaveAI : public ScriptedAI
if(!caster)
return;
- if(caster->GetTypeId() == TYPEID_PLAYER && spell->Id == ORB && !m_creature->HasAura(ENRAGE, 0))
+ if(caster->GetTypeId() == TYPEID_PLAYER && spell->Id == ORB && !m_creature->HasAura(ENRAGE))
{
PlayerGUID = caster->GetGUID();
if(PlayerGUID)
diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_curator.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_curator.cpp
index 9c5563e8ac8..f95ff8ead5a 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_curator.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_curator.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -6,18 +6,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
*/
/* ScriptData
SDName: Boss_Curator
SD%Complete: 100
-SDComment: Evocation may cause client crash (Core related)
+SDComment:
SDCategory: Karazhan
EndScriptData */
@@ -34,10 +34,6 @@ EndScriptData */
//Flare spell info
#define SPELL_ASTRAL_FLARE_PASSIVE 30234 //Visual effect + Flare damage
-#define SPELL_ASTRAL_FLARE_NE 30236
-#define SPELL_ASTRAL_FLARE_NW 30239
-#define SPELL_ASTRAL_FLARE_SE 30240
-#define SPELL_ASTRAL_FLARE_SW 30241
//Curator spell info
#define SPELL_HATEFUL_BOLT 30383
@@ -45,7 +41,7 @@ EndScriptData */
#define SPELL_ENRAGE 30403 //Arcane Infusion: Transforms Curator and adds damage.
#define SPELL_BERSERK 26662
-struct TRINITY_DLL_DECL boss_curatorAI : public ScriptedAI
+struct TRINITY_DLL_DECL boss_curatorAI : public ScriptedAI
{
boss_curatorAI(Creature *c) : ScriptedAI(c) {}
@@ -69,8 +65,8 @@ struct TRINITY_DLL_DECL boss_curatorAI : public ScriptedAI
{
switch(rand()%2)
{
- case 0: DoScriptText(SAY_KILL1, m_creature); break;
- case 1: DoScriptText(SAY_KILL2, m_creature); break;
+ case 0: DoScriptText(SAY_KILL1, m_creature); break;
+ case 1: DoScriptText(SAY_KILL2, m_creature); break;
}
}
@@ -79,7 +75,7 @@ struct TRINITY_DLL_DECL boss_curatorAI : public ScriptedAI
DoScriptText(SAY_DEATH, m_creature);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
@@ -89,18 +85,38 @@ struct TRINITY_DLL_DECL boss_curatorAI : public ScriptedAI
if (!UpdateVictim() )
return;
- if (Evocating && !m_creature->HasAura(SPELL_EVOCATION, 0))
- Evocating = false;
+ //always decrease BerserkTimer
+ if (BerserkTimer < diff)
+ {
+ //if evocate, then break evocate
+ if (Evocating)
+ {
+ if (m_creature->HasAura(SPELL_EVOCATION))
+ m_creature->RemoveAurasDueToSpell(SPELL_EVOCATION);
+
+ Evocating = false;
+ }
+
+ //may not be correct SAY (generic hard enrage)
+ DoScriptText(SAY_ENRAGE, m_creature);
- if (m_creature->GetPower(POWER_MANA) <= 1000 && !Evocating)
+ m_creature->InterruptNonMeleeSpells(true);
+ DoCast(m_creature, SPELL_BERSERK);
+
+ //don't know if he's supposed to do summon/evocate after hard enrage (probably not)
+ Enraged = true;
+ }else BerserkTimer -= diff;
+
+ if (Evocating)
{
- DoScriptText(SAY_EVOCATE, m_creature);
- m_creature->InterruptNonMeleeSpells(false);
- DoCast(m_creature, SPELL_EVOCATION);
- Evocating = true;
+ //not supposed to do anything while evocate
+ if (m_creature->HasAura(SPELL_EVOCATION))
+ return;
+ else
+ Evocating = false;
}
- if (!Enraged && !Evocating)
+ if (!Enraged)
{
if (AddTimer < diff)
{
@@ -113,29 +129,40 @@ struct TRINITY_DLL_DECL boss_curatorAI : public ScriptedAI
{
AstralFlare->CastSpell(AstralFlare, SPELL_ASTRAL_FLARE_PASSIVE, false);
AstralFlare->AI()->AttackStart(target);
+ AstralFlare->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
+ AstralFlare->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
}
- //Reduce Mana by 10%
- int32 mana = (int32)(0.1f*(m_creature->GetMaxPower(POWER_MANA)));
- m_creature->ModifyPower(POWER_MANA, -mana);
- switch(rand()%4)
+ //Reduce Mana by 10% of max health
+ if (int32 mana = m_creature->GetMaxPower(POWER_MANA))
{
- case 0: DoScriptText(SAY_SUMMON1, m_creature);break;
- case 1: DoScriptText(SAY_SUMMON2, m_creature);break;
+ mana /= 10;
+ m_creature->ModifyPower(POWER_MANA, -mana);
+
+ //if this get's us below 10%, then we evocate (the 10th should be summoned now)
+ if (m_creature->GetPower(POWER_MANA)*100 / m_creature->GetMaxPower(POWER_MANA) < 10)
+ {
+ DoScriptText(SAY_EVOCATE, m_creature);
+ m_creature->InterruptNonMeleeSpells(false);
+ DoCast(m_creature, SPELL_EVOCATION);
+ Evocating = true;
+ //no AddTimer cooldown, this will make first flare appear instantly after evocate end, like expected
+ return;
+ }
+ else
+ {
+ switch(rand()%4)
+ {
+ case 0: DoScriptText(SAY_SUMMON1, m_creature); break;
+ case 1: DoScriptText(SAY_SUMMON2, m_creature); break;
+ }
+ }
}
+
AddTimer = 10000;
}else AddTimer -= diff;
- if (HatefulBoltTimer < diff)
- {
- Unit* target = NULL;
- target = SelectUnit(SELECT_TARGET_TOPAGGRO, 1);
- DoCast(target, SPELL_HATEFUL_BOLT);
-
- HatefulBoltTimer = 15000;
- }else HatefulBoltTimer -= diff;
-
- if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 15)
+ if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 15)
{
Enraged = true;
DoCast(m_creature, SPELL_ENRAGE);
@@ -143,11 +170,17 @@ struct TRINITY_DLL_DECL boss_curatorAI : public ScriptedAI
}
}
- if (BerserkTimer < diff)
+ if (HatefulBoltTimer < diff)
{
- DoCast(m_creature, SPELL_BERSERK);
- DoScriptText(SAY_ENRAGE, m_creature);
- }else BerserkTimer -= diff;
+ if (Enraged)
+ HatefulBoltTimer = 7000;
+ else
+ HatefulBoltTimer = 15000;
+
+ if (Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 1))
+ DoCast(target, SPELL_HATEFUL_BOLT);
+
+ }else HatefulBoltTimer -= diff;
DoMeleeAttackIfReady();
}
@@ -162,8 +195,7 @@ void AddSC_boss_curator()
{
Script *newscript;
newscript = new Script;
- newscript->Name="boss_curator";
+ newscript->Name = "boss_curator";
newscript->GetAI = &GetAI_boss_curator;
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 230b31c69bb..69fae7d4f72 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -51,9 +51,9 @@ struct TRINITY_DLL_DECL boss_maiden_of_virtueAI : public ScriptedAI
void Reset()
{
- Repentance_Timer = 30000+(rand()%15000);
+ Repentance_Timer = 25000+(rand()%15000);
Holyfire_Timer = 8000+(rand()%17000);
- Holywrath_Timer = 20000+(rand()%10000);
+ Holywrath_Timer = 15000+(rand()%10000);
Holyground_Timer = 3000;
Enrage_Timer = 600000;
@@ -78,7 +78,7 @@ struct TRINITY_DLL_DECL boss_maiden_of_virtueAI : public ScriptedAI
DoScriptText(SAY_DEATH, m_creature);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
@@ -109,7 +109,7 @@ struct TRINITY_DLL_DECL boss_maiden_of_virtueAI : public ScriptedAI
case 0: DoScriptText(SAY_REPENTANCE1, m_creature);break;
case 1: DoScriptText(SAY_REPENTANCE2, m_creature);break;
}
- Repentance_Timer = 30000 + rand()%15000; //A little randomness on that spell
+ Repentance_Timer = 25000 + rand()%10000; //A little randomness on that spell
}else Repentance_Timer -= diff;
if (Holyfire_Timer < diff)
@@ -117,7 +117,7 @@ struct TRINITY_DLL_DECL boss_maiden_of_virtueAI : public ScriptedAI
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0))
DoCast(target,SPELL_HOLYFIRE);
- Holyfire_Timer = 8000 + rand()%17000; //Anywhere from 8 to 25 seconds, good luck having several of those in a row!
+ Holyfire_Timer = 8000 + rand()%15000; //Anywhere from 8 to 23 seconds, good luck having several of those in a row!
}else Holyfire_Timer -= diff;
if (Holywrath_Timer < diff)
@@ -125,7 +125,7 @@ struct TRINITY_DLL_DECL boss_maiden_of_virtueAI : public ScriptedAI
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0))
DoCast(target,SPELL_HOLYWRATH);
- Holywrath_Timer = 20000+(rand()%10000); //20-30 secs sounds nice
+ Holywrath_Timer = 20000+(rand()%5000); //20-30 secs sounds nice
}else Holywrath_Timer -= diff;
diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_midnight.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_midnight.cpp
index 8bb8a5edbcd..d60e057c296 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_midnight.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_midnight.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -62,7 +62,7 @@ struct TRINITY_DLL_DECL boss_midnightAI : public ScriptedAI
m_creature->SetVisibility(VISIBILITY_ON);
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void KilledUnit(Unit *victim)
{
@@ -185,9 +185,12 @@ struct TRINITY_DLL_DECL boss_attumenAI : public ScriptedAI
void Reset()
{
ResetTimer = 2000;
+
+ m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
+ m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void KilledUnit(Unit *victim)
{
@@ -283,6 +286,7 @@ struct TRINITY_DLL_DECL boss_attumenAI : public ScriptedAI
{
((boss_midnightAI*)(pMidnight->AI()))->Mount(m_creature);
m_creature->SetHealth(pMidnight->GetHealth());
+ DoResetThreat();
}
}
}
diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp
index 0d3f6f010c6..a96b2043df6 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -111,7 +111,7 @@ struct TRINITY_DLL_DECL boss_moroesAI : public ScriptedAI
pInstance->SetData(DATA_MOROES_EVENT, IN_PROGRESS);
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
StartEvent();
@@ -150,7 +150,7 @@ struct TRINITY_DLL_DECL boss_moroesAI : public ScriptedAI
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
{
- if (i->getSource()->isAlive() && i->getSource()->HasAura(SPELL_GARROTE,0))
+ if (i->getSource()->isAlive() && i->getSource()->HasAura(SPELL_GARROTE))
i->getSource()->RemoveAurasDueToSpell(SPELL_GARROTE);
}
}
@@ -246,13 +246,13 @@ struct TRINITY_DLL_DECL boss_moroesAI : public ScriptedAI
{
for(uint8 i = 0; i < 4; ++i)
{
- Unit* Temp = NULL;
+ Creature* Temp = NULL;
if (AddGUID[i])
{
- Temp = Unit::GetUnit((*m_creature),AddGUID[i]);
+ Temp = Unit::GetCreature(*m_creature, AddGUID[i]);
if (Temp && Temp->isAlive())
{
- ((Creature*)Temp)->AI()->AttackStart(m_creature->getVictim());
+ Temp->AI()->AttackStart(m_creature->getVictim());
DoZoneInCombat(Temp);
}else
EnterEvadeMode();
@@ -320,6 +320,8 @@ struct TRINITY_DLL_DECL boss_moroesAI : public ScriptedAI
m_creature->setFaction(16);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
+ m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
m_creature->AI()->AttackStart(m_creature->getVictim());
InVanish = false;
}else Wait_Timer -= diff;
@@ -382,7 +384,7 @@ struct TRINITY_DLL_DECL boss_moroes_guestAI : public ScriptedAI
pInstance->SetData(DATA_MOROES_EVENT, NOT_STARTED);
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void AcquireGUID()
{
@@ -540,7 +542,7 @@ struct TRINITY_DLL_DECL boss_baron_rafe_dreugerAI : public boss_moroes_guestAI
struct TRINITY_DLL_DECL boss_lady_catriona_von_indiAI : public boss_moroes_guestAI
{
//Holy Priest
- boss_lady_catriona_von_indiAI(Creature *c) : boss_moroes_guestAI(c) {}
+ boss_lady_catriona_von_indiAI(Creature *c) : boss_moroes_guestAI(c) {Reset();}
uint32 DispelMagic_Timer;
uint32 GreaterHeal_Timer;
@@ -610,7 +612,7 @@ struct TRINITY_DLL_DECL boss_lady_catriona_von_indiAI : public boss_moroes_guest
struct TRINITY_DLL_DECL boss_lady_keira_berrybuckAI : public boss_moroes_guestAI
{
//Holy Pally
- boss_lady_keira_berrybuckAI(Creature *c) : boss_moroes_guestAI(c) {}
+ boss_lady_keira_berrybuckAI(Creature *c) : boss_moroes_guestAI(c) {Reset();}
uint32 Cleanse_Timer;
uint32 GreaterBless_Timer;
@@ -727,7 +729,7 @@ struct TRINITY_DLL_DECL boss_lord_robin_darisAI : public boss_moroes_guestAI
struct TRINITY_DLL_DECL boss_lord_crispin_ferenceAI : public boss_moroes_guestAI
{
//Arms Warr
- boss_lord_crispin_ferenceAI(Creature *c) : boss_moroes_guestAI(c) {}
+ boss_lord_crispin_ferenceAI(Creature *c) : boss_moroes_guestAI(c) {Reset();}
uint32 Disarm_Timer;
uint32 HeroicStrike_Timer;
diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_netherspite.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_netherspite.cpp
index b074dc920c1..6db1b193234 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_netherspite.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_netherspite.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_nightbane.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_nightbane.cpp
index 96f58bd3a3c..b3226c7a038 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_nightbane.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_nightbane.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -109,7 +109,7 @@ struct TRINITY_DLL_DECL boss_nightbaneAI : public ScriptedAI
MovePhase = 0;
m_creature->SetSpeed(MOVE_RUN, 2.0f);
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
m_creature->setActive(true);
@@ -134,12 +134,12 @@ struct TRINITY_DLL_DECL boss_nightbaneAI : public ScriptedAI
void HandleTerraceDoors(bool open)
{
if(GameObject *Door = GameObject::GetGameObject((*m_creature),pInstance->GetData64(DATA_MASTERS_TERRACE_DOOR_1)))
- Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1);
+ Door->SetGoState(open ? GO_STATE_ACTIVE : GO_STATE_READY);
if(GameObject *Door = GameObject::GetGameObject((*m_creature),pInstance->GetData64(DATA_MASTERS_TERRACE_DOOR_2)))
- Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1);
+ Door->SetGoState(open ? GO_STATE_ACTIVE : GO_STATE_READY);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
pInstance->SetData(DATA_NIGHTBANE_EVENT, IN_PROGRESS);
@@ -228,7 +228,7 @@ struct TRINITY_DLL_DECL boss_nightbaneAI : public ScriptedAI
m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
(*m_creature).GetMotionMaster()->Clear(false);
(*m_creature).GetMotionMaster()->MovePoint(0,IntroWay[2][0],IntroWay[2][1],IntroWay[2][2]);
@@ -251,7 +251,7 @@ struct TRINITY_DLL_DECL boss_nightbaneAI : public ScriptedAI
{
if(MovePhase >= 7)
{
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
m_creature->GetMotionMaster()->MovePoint(8,IntroWay[7][0],IntroWay[7][1],IntroWay[7][2]);
}
@@ -266,7 +266,7 @@ struct TRINITY_DLL_DECL boss_nightbaneAI : public ScriptedAI
{
if(MovePhase >= 7)
{
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
m_creature->GetMotionMaster()->MovePoint(8,IntroWay[7][0],IntroWay[7][1],IntroWay[7][2]);
}
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 3de8e352ded..0d24d4002dd 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -37,7 +37,7 @@ EndScriptData */
#define SAY_SUMMON2 -1532101
#define SAY_DEATH -1532102
-// 19 Coordinates for Infernal spawns
+// 18 Coordinates for Infernal spawns
struct InfernalPoint
{
float x,y;
@@ -64,11 +64,10 @@ static InfernalPoint InfernalPoints[] =
{-10948.8, -2005.1},
{-10984.0, -2019.3},
{-10932.8, -1979.6},
- {-10932.8, -1979.6},
{-10935.7, -1996.0}
};
-#define TOTAL_INFERNAL_POINTS 19
+#define TOTAL_INFERNAL_POINTS 18
//Enfeeble is supposed to reduce hp to 1 and then heal player back to full when it ends
//Along with reducing healing and regen while enfeebled to 0%
@@ -81,9 +80,10 @@ static InfernalPoint InfernalPoints[] =
#define SPELL_SW_PAIN 30854 //Shadow word pain during phase 1 and 3 (different targeting rules though)
#define SPELL_THRASH_PASSIVE 12787 //Extra attack chance during phase 2
#define SPELL_SUNDER_ARMOR 30901 //Sunder armor during phase 2
-#define SPELL_THRASH_AURA 3417 //Passive proc chance for thrash
+#define SPELL_THRASH_AURA 12787 //Passive proc chance for thrash
#define SPELL_EQUIP_AXES 30857 //Visual for axe equiping
-#define SPELL_AMPLIFY_DAMAGE 12738 //Amplifiy during phase 3
+#define SPELL_AMPLIFY_DAMAGE 39095 //Amplifiy during phase 3
+#define SPELL_CLEAVE 30131 //Same as Nightbane.
#define SPELL_HELLFIRE 30859 //Infenals' hellfire aura
#define NETHERSPITE_INFERNAL 17646 //The netherspite infernal creature
#define MALCHEZARS_AXE 17650 //Malchezar's axes (creatures), summoned during phase 3
@@ -106,7 +106,7 @@ struct TRINITY_DLL_DECL netherspite_infernalAI : public ScriptedAI
InfernalPoint *point;
void Reset() {}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void MoveInLineOfSight(Unit *who) {}
void UpdateAI(const uint32 diff)
@@ -168,6 +168,7 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI
uint32 SWPainTimer;
uint32 SunderArmorTimer;
uint32 AmplifyDamageTimer;
+ uint32 Cleave_Timer;
uint32 InfernalTimer;
uint32 AxesTargetSwitchTimer;
uint32 InfernalCleanupTimer;
@@ -196,12 +197,14 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI
EnfeebleTimer = 30000;
EnfeebleResetTimer = 38000;
- ShadowNovaTimer = 35000;
+ ShadowNovaTimer = 35500;
SWPainTimer = 20000;
- AmplifyDamageTimer = 10000;
+ AmplifyDamageTimer = 5000;
+ Cleave_Timer = 8000;
InfernalTimer = 45000;
InfernalCleanupTimer = 47000;
AxesTargetSwitchTimer = 7500 + rand()%12500;
+ SunderArmorTimer = 5000 + rand()%5000;
phase = 1;
if(pInstance)
@@ -209,7 +212,7 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI
GameObject* Door = GameObject::GetGameObject((*m_creature),pInstance->GetData64(DATA_GAMEOBJECT_NETHER_DOOR));
if(Door)
{
- Door->SetGoState(0);
+ Door->SetGoState(GO_STATE_ACTIVE);
}
}
}
@@ -241,12 +244,12 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI
GameObject* Door = GameObject::GetGameObject((*m_creature),pInstance->GetData64(DATA_GAMEOBJECT_NETHER_DOOR));
if(Door)
{
- Door->SetGoState(0);
+ Door->SetGoState(GO_STATE_ACTIVE);
}
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
@@ -255,7 +258,7 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI
GameObject* Door = GameObject::GetGameObject((*m_creature),pInstance->GetData64(DATA_GAMEOBJECT_NETHER_DOOR));
if(Door)
{
- Door->SetGoState(1);
+ Door->SetGoState(GO_STATE_READY);
}
}
}
@@ -288,11 +291,11 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI
void ClearWeapons()
{
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, 0);
//damage
const CreatureInfo *cinfo = m_creature->GetCreatureInfo();
@@ -432,11 +435,11 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI
m_creature->CastSpell(m_creature, SPELL_THRASH_AURA, true);
//models
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, AXE_EQUIP_MODEL);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, AXE_EQUIP_INFO);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, AXE_EQUIP_MODEL);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, AXE_EQUIP_INFO);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, AXE_EQUIP_MODEL);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, AXE_EQUIP_INFO);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, AXE_EQUIP_MODEL);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, AXE_EQUIP_INFO);
//damage
const CreatureInfo *cinfo = m_creature->GetCreatureInfo();
@@ -474,8 +477,8 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI
Creature *axe = m_creature->SummonCreature(MALCHEZARS_AXE, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000);
if(axe)
{
- axe->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, AXE_EQUIP_MODEL);
- axe->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, AXE_EQUIP_INFO);
+ axe->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, AXE_EQUIP_MODEL);
+ //axe->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, AXE_EQUIP_INFO);
axe->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
axe->setFaction(m_creature->getFaction());
@@ -499,9 +502,16 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI
if(SunderArmorTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_SUNDER_ARMOR);
- SunderArmorTimer = 15000;
+ SunderArmorTimer = 10000 + rand()%8000;
}else SunderArmorTimer -= diff;
+
+ if (Cleave_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_CLEAVE);
+ Cleave_Timer = 6000 + rand()%6000;
+
+ }else Cleave_Timer -= diff;
}
else
{
@@ -543,13 +553,13 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI
if(InfernalTimer < diff)
{
SummonInfernal(diff);
- InfernalTimer = phase == 3 ? 15000 : 45000; //15 secs in phase 3, 45 otherwise
+ InfernalTimer = phase == 3 ? 14500 : 44500; //15 secs in phase 3, 45 otherwise
}else InfernalTimer -= diff;
if(ShadowNovaTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_SHADOWNOVA);
- ShadowNovaTimer = phase == 3 ? 35000 : -1;
+ ShadowNovaTimer = phase == 3 ? 31000 : -1;
}else ShadowNovaTimer -= diff;
if(phase != 2)
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 02480d14d66..d358f9585c1 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -143,7 +143,7 @@ struct TRINITY_DLL_DECL boss_aranAI : public ScriptedAI
pInstance->SetData(DATA_SHADEOFARAN_EVENT, NOT_STARTED);
if(GameObject* Door = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_GAMEOBJECT_LIBRARY_DOOR)))
- Door->SetGoState(0);
+ Door->SetGoState(GO_STATE_ACTIVE);
}
}
@@ -165,11 +165,11 @@ struct TRINITY_DLL_DECL boss_aranAI : public ScriptedAI
pInstance->SetData(DATA_SHADEOFARAN_EVENT, DONE);
if(GameObject* Door = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_GAMEOBJECT_LIBRARY_DOOR)))
- Door->SetGoState(0);
+ Door->SetGoState(GO_STATE_ACTIVE);
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
@@ -182,7 +182,7 @@ struct TRINITY_DLL_DECL boss_aranAI : public ScriptedAI
{
pInstance->SetData(DATA_SHADEOFARAN_EVENT, IN_PROGRESS);
if(GameObject* Door = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_GAMEOBJECT_LIBRARY_DOOR)))
- Door->SetGoState(1);
+ Door->SetGoState(GO_STATE_READY);
}
}
@@ -233,7 +233,7 @@ struct TRINITY_DLL_DECL boss_aranAI : public ScriptedAI
if(pInstance)
{
if(GameObject* Door = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_GAMEOBJECT_LIBRARY_DOOR)))
- Door->SetGoState(1);
+ Door->SetGoState(GO_STATE_READY);
CloseDoorTimer = 0;
}
}else CloseDoorTimer -= diff;
@@ -273,8 +273,7 @@ struct TRINITY_DLL_DECL boss_aranAI : public ScriptedAI
m_creature->CastSpell(m_creature, SPELL_MASS_POLY, true);
m_creature->CastSpell(m_creature, SPELL_CONJURE, false);
m_creature->CastSpell(m_creature, SPELL_DRINK, false);
- //Sitting down
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 1);
+ m_creature->SetStandState(UNIT_STAND_STATE_SIT);
DrinkInturruptTimer = 10000;
}
}
@@ -284,7 +283,7 @@ struct TRINITY_DLL_DECL boss_aranAI : public ScriptedAI
{
Drinking = false;
m_creature->RemoveAurasDueToSpell(SPELL_DRINK);
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
m_creature->SetPower(POWER_MANA, m_creature->GetMaxPower(POWER_MANA)-32000);
m_creature->CastSpell(m_creature, SPELL_POTION, false);
}
@@ -295,7 +294,7 @@ struct TRINITY_DLL_DECL boss_aranAI : public ScriptedAI
DrinkInturruptTimer -= diff;
else
{
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
m_creature->CastSpell(m_creature, SPELL_POTION, true);
m_creature->CastSpell(m_creature, SPELL_AOE_PYROBLAST, false);
DrinkInturrupted = true;
@@ -539,7 +538,7 @@ struct TRINITY_DLL_DECL water_elementalAI : public ScriptedAI
CastTimer = 2000 + (rand()%3000);
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void UpdateAI(const uint32 diff)
{
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 4cbe59aabb5..b504844d924 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_terestian_illhoof.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_terestian_illhoof.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -45,11 +45,10 @@ EndScriptData */
#define SPELL_FIENDISH_PORTAL 30171 // Opens portal and summons Fiendish Portal, 2 sec cast
#define SPELL_FIENDISH_PORTAL_1 30179 // Opens portal and summons Fiendish Portal, instant cast
-#define SPELL_FIREBOLT 18086 // Blasts a target for 150 Fire damage.
+#define SPELL_FIREBOLT 30050 // Blasts a target for 150 Fire damage.
#define SPELL_BROKEN_PACT 30065 // All damage taken increased by 25%.
#define SPELL_AMPLIFY_FLAMES 30053 // Increases the Fire damage taken by an enemy by 500 for 25 sec.
-#define SPELL_FIREBOLT 18086 // Blasts a target for 150 Fire damage.
#define CREATURE_DEMONCHAINS 17248
#define CREATURE_FIENDISHIMP 17267
@@ -79,11 +78,10 @@ struct TRINITY_DLL_DECL mob_kilrekAI : public ScriptedAI
void Reset()
{
TerestianGUID = 0;
-
- AmplifyTimer = 0;
+ AmplifyTimer = 2000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(!pInstance)
{
@@ -121,13 +119,10 @@ struct TRINITY_DLL_DECL mob_kilrekAI : public ScriptedAI
m_creature->InterruptNonMeleeSpells(false);
DoCast(m_creature->getVictim(),SPELL_AMPLIFY_FLAMES);
- AmplifyTimer = 20000;
+ AmplifyTimer = 10000 + rand()%10000;
}else AmplifyTimer -= diff;
- //Chain cast
- if (!m_creature->IsNonMeleeSpellCasted(false) && m_creature->IsWithinDistInMap(m_creature->getVictim(), 30))
- DoCast(m_creature->getVictim(),SPELL_FIREBOLT);
- else DoMeleeAttackIfReady();
+ DoMeleeAttackIfReady();
}
};
@@ -142,7 +137,7 @@ struct TRINITY_DLL_DECL mob_demon_chainAI : public ScriptedAI
SacrificeGUID = 0;
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
@@ -161,6 +156,8 @@ struct TRINITY_DLL_DECL boss_terestianAI : public ScriptedAI
{
boss_terestianAI(Creature *c) : ScriptedAI(c)
{
+ for(uint8 i = 0; i < 2; ++i)
+ PortalGUID[i] = 0;
pInstance = ((ScriptedInstance*)c->GetInstanceData());
}
@@ -175,6 +172,7 @@ struct TRINITY_DLL_DECL boss_terestianAI : public ScriptedAI
uint32 SummonTimer;
uint32 BerserkTimer;
+ bool ReSummon;
bool SummonKilrek;
bool SummonedPortals;
bool Berserk;
@@ -201,19 +199,26 @@ struct TRINITY_DLL_DECL boss_terestianAI : public ScriptedAI
SummonedPortals = false;
Berserk = false;
+ ReSummon = false;
if(pInstance)
pInstance->SetData(DATA_TERESTIAN_EVENT, NOT_STARTED);
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
if(pInstance)
{
- // Put Kil'rek in combat against our target so players don't skip him
Creature* Kilrek = (Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_KILREK)));
+ // Respawn Kil'rek on aggro if Kil'rek is dead.
+ if (Kilrek && !Kilrek->isAlive())
+ {
+ Kilrek->Respawn();
+ }
+
+ // Put Kil'rek in combat against our target so players don't skip him
if(Kilrek && !Kilrek->getVictim())
Kilrek->AddThreat(who, 1.0f);
@@ -257,18 +262,22 @@ struct TRINITY_DLL_DECL boss_terestianAI : public ScriptedAI
if(CheckKilrekTimer < diff)
{
+
CheckKilrekTimer = 5000;
if(pInstance)
uint64 KilrekGUID = pInstance->GetData64(DATA_KILREK);
else ERROR_INST_DATA(m_creature);
- Creature* Kilrek = (Unit::GetCreature((*m_creature), KilrekGUID));
+ Creature* Kilrek = (Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_KILREK)));
if(SummonKilrek && Kilrek)
{
Kilrek->Respawn();
if(Kilrek->AI())
+ {
Kilrek->AI()->AttackStart(m_creature->getVictim());
+ m_creature->RemoveAurasDueToSpell(SPELL_BROKEN_PACT);
+ }
SummonKilrek = false;
}
@@ -355,10 +364,12 @@ struct TRINITY_DLL_DECL mob_karazhan_impAI : public ScriptedAI
void Reset()
{
- FireboltTimer = 3000;
+ FireboltTimer = 2000;
+
+ m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void UpdateAI(const uint32 diff)
{
@@ -369,7 +380,7 @@ struct TRINITY_DLL_DECL mob_karazhan_impAI : public ScriptedAI
if(FireboltTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_FIREBOLT);
- FireboltTimer = 1500;
+ FireboltTimer = 2200;
}else FireboltTimer -= diff;
DoMeleeAttackIfReady();
diff --git a/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp b/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp
index cd404e2ff15..67dd35b46a0 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -91,7 +91,7 @@ void SummonCroneIfReady(ScriptedInstance* pInstance, Creature *_Creature)
pInstance->SetData(DATA_OPERA_OZ_DEATHCOUNT, 0); // Increment DeathCount
if(pInstance->GetData(DATA_OPERA_OZ_DEATHCOUNT) == 4)
{
- Creature* Crone = _Creature->SummonCreature(CREATURE_CRONE, -10891.96, -1755.95, _Creature->GetPositionZ(), 4.64, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30000);
+ Creature* Crone = _Creature->SummonCreature(CREATURE_CRONE, -10891.96, -1755.95, _Creature->GetPositionZ(), 4.64, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
if(Crone)
{
if(_Creature->getVictim())
@@ -117,7 +117,6 @@ struct TRINITY_DLL_DECL boss_dorotheeAI : public ScriptedAI
bool SummonedTito;
bool TitoDied;
- bool InCombat;
void Reset()
{
@@ -129,10 +128,9 @@ struct TRINITY_DLL_DECL boss_dorotheeAI : public ScriptedAI
SummonedTito = false;
TitoDied = false;
- InCombat = false;
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
DoScriptText(SAY_DOROTHEE_AGGRO, m_creature);
}
@@ -205,17 +203,15 @@ struct TRINITY_DLL_DECL mob_titoAI : public ScriptedAI
mob_titoAI(Creature* c) : ScriptedAI(c) {}
uint64 DorotheeGUID;
-
uint32 YipTimer;
void Reset()
{
DorotheeGUID = 0;
-
YipTimer = 10000;
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void JustDied(Unit* killer)
{
@@ -247,7 +243,7 @@ struct TRINITY_DLL_DECL mob_titoAI : public ScriptedAI
void boss_dorotheeAI::SummonTito()
{
- Creature* Tito = DoSpawnCreature(CREATURE_TITO, 0, 0, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);
+ Creature* Tito = DoSpawnCreature(CREATURE_TITO, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
if(Tito)
{
DoScriptText(SAY_DOROTHEE_SUMMON, m_creature);
@@ -294,15 +290,22 @@ struct TRINITY_DLL_DECL boss_strawmanAI : public ScriptedAI
ScriptedAI::MoveInLineOfSight(who);
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
DoScriptText(SAY_STRAWMAN_AGGRO, m_creature);
}
void SpellHit(Unit* caster, const SpellEntry *Spell)
{
- if((Spell->SchoolMask == SPELL_SCHOOL_MASK_FIRE) && (!(rand()%10)))
+ if ((Spell->SchoolMask == SPELL_SCHOOL_MASK_FIRE) && (!(rand()%10)))
+ {
+ /*
+ if (not direct damage(aoe,dot))
+ return;
+ */
+
DoCast(m_creature, SPELL_BURNING_STRAW, true);
+ }
}
void JustDied(Unit* killer)
@@ -372,7 +375,7 @@ struct TRINITY_DLL_DECL boss_tinheadAI : public ScriptedAI
RustCount = 0;
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
DoScriptText(SAY_TINHEAD_AGGRO, m_creature);
}
@@ -479,7 +482,7 @@ struct TRINITY_DLL_DECL boss_roarAI : public ScriptedAI
ScriptedAI::AttackStart(who);
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
DoScriptText(SAY_ROAR_AGGRO, m_creature);
}
@@ -551,7 +554,7 @@ struct TRINITY_DLL_DECL boss_croneAI : public ScriptedAI
ChainLightningTimer = 10000;
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
switch(rand()%2)
{
@@ -569,9 +572,13 @@ struct TRINITY_DLL_DECL boss_croneAI : public ScriptedAI
if(pInstance)
{
pInstance->SetData(DATA_OPERA_EVENT, DONE);
- GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_STAGEDOORRIGHT));
- if(Door)
- Door->UseDoorOrButton();
+
+ if (GameObject* lDoor = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_STAGEDOORLEFT)))
+ lDoor->SetGoState(GO_STATE_ACTIVE);
+ if (GameObject* rDoor = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_STAGEDOORRIGHT)))
+ rDoor->SetGoState(GO_STATE_ACTIVE);
+ if (GameObject* pSideEntrance = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GO_SIDE_ENTRANCE_DOOR)))
+ pSideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
}
}
@@ -612,7 +619,7 @@ struct TRINITY_DLL_DECL mob_cycloneAI : public ScriptedAI
MoveTimer = 1000;
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void MoveInLineOfSight(Unit* who)
{
@@ -620,7 +627,7 @@ struct TRINITY_DLL_DECL mob_cycloneAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
- if(!m_creature->HasAura(SPELL_KNOCKBACK, 0))
+ if(!m_creature->HasAura(SPELL_KNOCKBACK))
DoCast(m_creature, SPELL_KNOCKBACK, true);
if(MoveTimer < diff)
@@ -705,7 +712,7 @@ bool GossipSelect_npc_grandmother(Player* player, Creature* _Creature, uint32 se
_Creature->SetVisibility(VISIBILITY_OFF);
float x,y,z;
_Creature->GetPosition(x,y,z);
- Creature* BigBadWolf = _Creature->SummonCreature(CREATURE_BIG_BAD_WOLF, x, y, z, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30000);
+ Creature* BigBadWolf = _Creature->SummonCreature(CREATURE_BIG_BAD_WOLF, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
if(BigBadWolf)
{
BigBadWolf->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
@@ -748,7 +755,7 @@ struct TRINITY_DLL_DECL boss_bigbadwolfAI : public ScriptedAI
IsChasing = false;
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
DoScriptText(SAY_WOLF_AGGRO, m_creature);
}
@@ -760,9 +767,13 @@ struct TRINITY_DLL_DECL boss_bigbadwolfAI : public ScriptedAI
if(pInstance)
{
pInstance->SetData(DATA_OPERA_EVENT, DONE);
- GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_STAGEDOORRIGHT));
- if(Door)
- Door->UseDoorOrButton();
+
+ if (GameObject* lDoor = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_STAGEDOORLEFT)))
+ lDoor->SetGoState(GO_STATE_ACTIVE);
+ if (GameObject* rDoor = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_STAGEDOORRIGHT)))
+ rDoor->SetGoState(GO_STATE_ACTIVE);
+ if (GameObject* pSideEntrance = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GO_SIDE_ENTRANCE_DOOR)))
+ pSideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
}
}
@@ -795,8 +806,8 @@ struct TRINITY_DLL_DECL boss_bigbadwolfAI : public ScriptedAI
else
{
IsChasing = false;
- Unit* target = Unit::GetUnit((*m_creature), HoodGUID);
- if(target)
+
+ if (Unit* target = Unit::GetUnit((*m_creature), HoodGUID))
{
HoodGUID = 0;
if(DoGetThreat(target))
@@ -868,9 +879,9 @@ CreatureAI* GetAI_boss_bigbadwolf(Creature* _Creature)
#define SPELL_RES_VISUAL 24171
/*** Misc. Information ****/
-#define CREATURE_ROMULO 17533
-#define ROMULO_X -10900
-#define ROMULO_Y -1758
+#define CREATURE_ROMULO 17533
+#define ROMULO_X -10900
+#define ROMULO_Y -1758
enum RAJPhase
{
@@ -881,32 +892,28 @@ enum RAJPhase
void PretendToDie(Creature* _Creature)
{
- _Creature->InterruptNonMeleeSpells(false);
+ _Creature->InterruptNonMeleeSpells(true);
+ _Creature->RemoveAllAuras();
_Creature->SetHealth(0);
- _Creature->ClearComboPointHolders();
- _Creature->RemoveAllAurasOnDeath();
- _Creature->ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false);
- _Creature->ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, false);
_Creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- _Creature->ClearAllReactives();
- _Creature->SetUInt64Value(UNIT_FIELD_TARGET,0);
- _Creature->GetMotionMaster()->Clear();
+ _Creature->GetMotionMaster()->MovementExpired(false);
_Creature->GetMotionMaster()->MoveIdle();
- _Creature->SetUInt32Value(UNIT_FIELD_BYTES_1,PLAYER_STATE_DEAD);
+ _Creature->SetStandState(UNIT_STAND_STATE_DEAD);
};
void Resurrect(Creature* target)
{
target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
target->SetHealth(target->GetMaxHealth());
- target->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ target->SetStandState(UNIT_STAND_STATE_STAND);
target->CastSpell(target, SPELL_RES_VISUAL, true);
if(target->getVictim())
{
- target->SetUInt64Value(UNIT_FIELD_TARGET, target->getVictim()->GetGUID());
target->GetMotionMaster()->MoveChase(target->getVictim());
target->AI()->AttackStart(target->getVictim());
}
+ else
+ target->GetMotionMaster()->Initialize();
};
struct TRINITY_DLL_DECL boss_julianneAI : public ScriptedAI
@@ -920,18 +927,21 @@ struct TRINITY_DLL_DECL boss_julianneAI : public ScriptedAI
ScriptedInstance* pInstance;
+ uint32 EntryYellTimer;
+ uint32 AggroYellTimer;
+
uint64 RomuloGUID;
uint32 Phase;
- uint32 EntryYellTimer;
- uint32 AggroYellTimer;
uint32 BlindingPassionTimer;
uint32 DevotionTimer;
uint32 EternalAffectionTimer;
uint32 PowerfulAttractionTimer;
uint32 SummonRomuloTimer;
uint32 ResurrectTimer;
+ uint32 DrinkPoisonTimer;
+ uint32 ResurrectSelfTimer;
bool IsFakingDeath;
bool SummonedRomulo;
@@ -947,15 +957,18 @@ struct TRINITY_DLL_DECL boss_julianneAI : public ScriptedAI
Romulo->DealDamage(Romulo, Romulo->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}
- RomuloGUID = 0;
}
+ RomuloGUID = 0;
Phase = PHASE_JULIANNE;
BlindingPassionTimer = 30000;
DevotionTimer = 15000;
EternalAffectionTimer = 25000;
PowerfulAttractionTimer = 5000;
+ SummonRomuloTimer = 10000;
+ DrinkPoisonTimer = 0;
+ ResurrectSelfTimer = 0;
if(IsFakingDeath)
Resurrect(m_creature);
@@ -965,7 +978,7 @@ struct TRINITY_DLL_DECL boss_julianneAI : public ScriptedAI
RomuloDead = false;
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void AttackStart(Unit* who)
{
@@ -983,6 +996,15 @@ struct TRINITY_DLL_DECL boss_julianneAI : public ScriptedAI
ScriptedAI::MoveInLineOfSight(who);
}
+ void SpellHit(Unit* caster, const SpellEntry *Spell)
+ {
+ if (Spell->Id == SPELL_DRINK_POISON)
+ {
+ DoScriptText(SAY_JULIANNE_DEATH01, m_creature);
+ DrinkPoisonTimer = 2500;
+ }
+ }
+
void DamageTaken(Unit* done_by, uint32 &damage);
void JustDied(Unit* killer)
@@ -992,9 +1014,13 @@ struct TRINITY_DLL_DECL boss_julianneAI : public ScriptedAI
if(pInstance)
{
pInstance->SetData(DATA_OPERA_EVENT, DONE);
- GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_STAGEDOORRIGHT));
- if(Door)
- Door->UseDoorOrButton();
+
+ if (GameObject* lDoor = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_STAGEDOORLEFT)))
+ lDoor->SetGoState(GO_STATE_ACTIVE);
+ if (GameObject* rDoor = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_STAGEDOORRIGHT)))
+ rDoor->SetGoState(GO_STATE_ACTIVE);
+ if (GameObject* pSideEntrance = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GO_SIDE_ENTRANCE_DOOR)))
+ pSideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
}
}
@@ -1010,12 +1036,14 @@ struct TRINITY_DLL_DECL boss_romuloAI : public ScriptedAI
{
boss_romuloAI(Creature* c) : ScriptedAI(c)
{
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
EntryYellTimer = 8000;
AggroYellTimer = 15000;
}
+
+ ScriptedInstance* pInstance;
uint64 JulianneGUID;
-
uint32 Phase;
uint32 EntryYellTimer;
@@ -1026,22 +1054,19 @@ struct TRINITY_DLL_DECL boss_romuloAI : public ScriptedAI
uint32 PoisonThrustTimer;
uint32 ResurrectTimer;
- bool JulianneDead;
bool IsFakingDeath;
+ bool JulianneDead;
void Reset()
{
JulianneGUID = 0;
-
Phase = PHASE_ROMULO;
BackwardLungeTimer = 15000;
DaringTimer = 20000;
DeadlySwatheTimer = 25000;
PoisonThrustTimer = 10000;
-
- if(IsFakingDeath)
- Resurrect(m_creature);
+ ResurrectTimer = 10000;
IsFakingDeath = false;
JulianneDead = false;
@@ -1049,7 +1074,7 @@ struct TRINITY_DLL_DECL boss_romuloAI : public ScriptedAI
void DamageTaken(Unit* done_by, uint32 &damage);
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
DoScriptText(SAY_ROMULO_AGGRO, m_creature);
if(JulianneGUID)
@@ -1074,6 +1099,18 @@ struct TRINITY_DLL_DECL boss_romuloAI : public ScriptedAI
void JustDied(Unit* killer)
{
DoScriptText(SAY_ROMULO_DEATH, m_creature);
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_OPERA_EVENT, DONE);
+
+ if (GameObject* lDoor = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_STAGEDOORLEFT)))
+ lDoor->SetGoState(GO_STATE_ACTIVE);
+ if (GameObject* rDoor = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_STAGEDOORRIGHT)))
+ rDoor->SetGoState(GO_STATE_ACTIVE);
+ if (GameObject* pSideEntrance = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GO_SIDE_ENTRANCE_DOOR)))
+ pSideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
+ }
}
void KilledUnit(Unit* victim)
@@ -1086,137 +1123,169 @@ struct TRINITY_DLL_DECL boss_romuloAI : public ScriptedAI
void boss_julianneAI::DamageTaken(Unit* done_by, uint32 &damage)
{
- if(damage < m_creature->GetHealth() || done_by == m_creature || done_by->GetGUID() == RomuloGUID)
+ if (damage < m_creature->GetHealth())
return;
+ //anything below only used if incoming damage will kill
+
if(Phase == PHASE_JULIANNE)
{
- DoScriptText(SAY_JULIANNE_DEATH01, m_creature);
+ damage = 0;
+
+ //this means already drinking, so return
+ if (IsFakingDeath)
+ return;
+
m_creature->InterruptNonMeleeSpells(true);
DoCast(m_creature, SPELL_DRINK_POISON);
- PretendToDie(m_creature);
- Phase = PHASE_ROMULO;
- damage = 0;
+
IsFakingDeath = true;
- SummonRomuloTimer = 10000;
+ //IS THIS USEFULL? Creature* Julianne = (Unit::GetCreature((*m_creature), JulianneGUID));
return;
}
- if(!IsFakingDeath)
+ if (Phase == PHASE_ROMULO)
{
- Creature* Romulo = (Unit::GetCreature((*m_creature), RomuloGUID));
- if(Romulo && Romulo->isAlive() && !((boss_romuloAI*)Romulo->AI())->IsFakingDeath)
- {
- ((boss_romuloAI*)Romulo->AI())->ResurrectTimer = 10000;
- ((boss_romuloAI*)Romulo->AI())->JulianneDead = true;
- }
- else
+ error_log("TSCR: boss_julianneAI: cannot take damage in PHASE_ROMULO, why was i here?");
+ damage = 0;
+ return;
+ }
+
+ if (Phase == PHASE_BOTH)
+ {
+ //if this is true then we have to kill romulo too
+ if (RomuloDead)
{
- m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- if(Romulo)
+ if (Creature* Romulo = (Unit::GetCreature((*m_creature), RomuloGUID)))
{
- Romulo->DealDamage(Romulo, Romulo->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
Romulo->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ Romulo->GetMotionMaster()->Clear();
+ Romulo->setDeathState(JUST_DIED);
+ Romulo->CombatStop();
+ Romulo->DeleteThreatList();
+ Romulo->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
}
- JustDied(done_by);
+ return;
}
- IsFakingDeath = true;
- PretendToDie(m_creature);
- damage = 0;
+ //if not already returned, then romulo is alive and we can pretend die
+ if (Creature* Romulo = (Unit::GetCreature((*m_creature), RomuloGUID)))
+ {
+ PretendToDie(m_creature);
+ IsFakingDeath = true;
+ ((boss_romuloAI*)Romulo->AI())->ResurrectTimer = 10000;
+ ((boss_romuloAI*)Romulo->AI())->JulianneDead = true;
+ damage = 0;
+ return;
+ }
}
- else
- damage = 0;
+ error_log("TSCR: boss_julianneAI: DamageTaken reach end of code, that should not happen.");
}
void boss_romuloAI::DamageTaken(Unit* done_by, uint32 &damage)
{
- if(damage < m_creature->GetHealth() || done_by == m_creature || done_by->GetGUID() == JulianneGUID)
+ if (damage < m_creature->GetHealth())
return;
- if(!IsFakingDeath)
+ //anything below only used if incoming damage will kill
+
+ if (Phase == PHASE_ROMULO)
{
- IsFakingDeath = true;
+ DoScriptText(SAY_ROMULO_DEATH, m_creature);
PretendToDie(m_creature);
+ IsFakingDeath = true;
+ Phase = PHASE_BOTH;
- if(Phase == PHASE_BOTH)
+ if (Creature* Julianne = (Unit::GetCreature((*m_creature), JulianneGUID)))
{
- Creature* Julianne = (Unit::GetCreature((*m_creature), JulianneGUID));
- if(Julianne && Julianne->isAlive() && !((boss_julianneAI*)Julianne->AI())->IsFakingDeath)
- {
- ((boss_julianneAI*)Julianne->AI())->ResurrectTimer = 10000;
- ((boss_julianneAI*)Julianne->AI())->RomuloDead = true;
- }
- else
- {
- m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- if(Julianne)
- {
- Julianne->DealDamage(Julianne, Julianne->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- Julianne->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- }
- JustDied(done_by);
- }
+ ((boss_julianneAI*)Julianne->AI())->RomuloDead = true;
+ ((boss_julianneAI*)Julianne->AI())->ResurrectSelfTimer = 10000;
}
- else
+
+ damage = 0;
+ return;
+ }
+
+ if (Phase == PHASE_BOTH)
+ {
+ if (JulianneDead)
{
- Creature* Julianne = (Unit::GetCreature((*m_creature), JulianneGUID));
- if(Julianne)
+ if (Creature* Julianne = (Unit::GetCreature((*m_creature), JulianneGUID)))
{
- Resurrect(Julianne);
- m_creature->SetHealth(m_creature->GetMaxHealth());
- ((boss_julianneAI*)Julianne->AI())->ResurrectTimer = 4000;
- ((boss_julianneAI*)Julianne->AI())->RomuloDead = true;
- ((boss_julianneAI*)Julianne->AI())->Phase = PHASE_BOTH;
- ((boss_julianneAI*)Julianne->AI())->IsFakingDeath = false;
+ Julianne->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ Julianne->GetMotionMaster()->Clear();
+ Julianne->setDeathState(JUST_DIED);
+ Julianne->CombatStop();
+ Julianne->DeleteThreatList();
+ Julianne->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
}
- Phase = PHASE_BOTH;
+ return;
}
- damage = 0;
+ if (Creature* Julianne = (Unit::GetCreature((*m_creature), JulianneGUID)))
+ {
+ PretendToDie(m_creature);
+ IsFakingDeath = true;
+ ((boss_julianneAI*)Julianne->AI())->ResurrectTimer = 10000;
+ ((boss_julianneAI*)Julianne->AI())->RomuloDead = true;
+ damage = 0;
+ return;
+ }
}
- if(IsFakingDeath) damage = 0;
+ error_log("TSCR: boss_romuloAI: DamageTaken reach end of code, that should not happen.");
}
void boss_julianneAI::UpdateAI(const uint32 diff)
{
if(EntryYellTimer)
{
- if(EntryYellTimer < diff)
+ if (EntryYellTimer <= diff)
{
DoScriptText(SAY_JULIANNE_ENTER, m_creature);
- m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
EntryYellTimer = 0;
}else EntryYellTimer -= diff;
}
if(AggroYellTimer)
{
- if(AggroYellTimer < diff)
+ if (AggroYellTimer <= diff)
{
DoScriptText(SAY_JULIANNE_AGGRO, m_creature);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->setFaction(16);
AggroYellTimer = 0;
}else AggroYellTimer -= diff;
}
- if(Phase == PHASE_ROMULO && !SummonedRomulo)
+ if (DrinkPoisonTimer)
+ {
+ //will do this 2secs after spell hit. this is time to display visual as expected
+ if (DrinkPoisonTimer <= diff)
+ {
+ PretendToDie(m_creature);
+ Phase = PHASE_ROMULO;
+ SummonRomuloTimer = 10000;
+ DrinkPoisonTimer = 0;
+ }else DrinkPoisonTimer -= diff;
+ }
+
+ if (Phase == PHASE_ROMULO && !SummonedRomulo)
{
if(SummonRomuloTimer < diff)
{
- Creature* Romulo = m_creature->SummonCreature(CREATURE_ROMULO, ROMULO_X, ROMULO_Y, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 45000);
+ Creature* Romulo = m_creature->SummonCreature(CREATURE_ROMULO, ROMULO_X, ROMULO_Y, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
if(Romulo)
{
RomuloGUID = Romulo->GetGUID();
((boss_romuloAI*)Romulo->AI())->JulianneGUID = m_creature->GetGUID();
((boss_romuloAI*)Romulo->AI())->Phase = PHASE_ROMULO;
+ Romulo->setFaction(16);
+
if(m_creature->getVictim())
{
- Romulo->AI()->AttackStart(m_creature->getVictim());
- Romulo->AddThreat(m_creature->getVictim(), 50.0f);
+ Romulo->AddThreat(m_creature->getVictim(), 0.0f);
}
DoZoneInCombat(Romulo);
}
@@ -1224,7 +1293,23 @@ void boss_julianneAI::UpdateAI(const uint32 diff)
}else SummonRomuloTimer -= diff;
}
- if(!UpdateVictim() ||IsFakingDeath)
+ if (ResurrectSelfTimer)
+ {
+ if (ResurrectSelfTimer <= diff)
+ {
+ Resurrect(m_creature);
+ Phase = PHASE_BOTH;
+ IsFakingDeath = false;
+
+ if (m_creature->getVictim())
+ AttackStart(m_creature->getVictim());
+
+ ResurrectSelfTimer = 0;
+ ResurrectTimer = 1000;
+ }else ResurrectSelfTimer -= diff;
+ }
+
+ if(!UpdateVictim() || IsFakingDeath)
return;
if(RomuloDead)
@@ -1237,9 +1322,9 @@ void boss_julianneAI::UpdateAI(const uint32 diff)
DoScriptText(SAY_JULIANNE_RESURRECT, m_creature);
Resurrect(Romulo);
((boss_romuloAI*)Romulo->AI())->IsFakingDeath = false;
+ RomuloDead = false;
ResurrectTimer = 10000;
}
- RomuloDead = false;
}else ResurrectTimer -= diff;
}
@@ -1266,10 +1351,8 @@ void boss_julianneAI::UpdateAI(const uint32 diff)
if(rand()%2 == 1 && SummonedRomulo)
{
Creature* Romulo = (Unit::GetCreature((*m_creature), RomuloGUID));
- if(Romulo && Romulo->isAlive() && !((boss_romuloAI*)Romulo->AI())->IsFakingDeath)
+ if (Romulo && Romulo->isAlive() && !RomuloDead)
DoCast(Romulo, SPELL_ETERNAL_AFFECTION);
- else
- return;
}else DoCast(m_creature, SPELL_ETERNAL_AFFECTION);
EternalAffectionTimer = 45000 + rand()%15000;
@@ -1293,9 +1376,9 @@ void boss_romuloAI::UpdateAI(const uint32 diff)
DoScriptText(SAY_ROMULO_RESURRECT, m_creature);
Resurrect(Julianne);
((boss_julianneAI*)Julianne->AI())->IsFakingDeath = false;
+ JulianneDead = false;
ResurrectTimer = 10000;
}
- JulianneDead = false;
}else ResurrectTimer -= diff;
}
diff --git a/src/bindings/scripts/scripts/zone/karazhan/def_karazhan.h b/src/bindings/scripts/scripts/zone/karazhan/def_karazhan.h
index be007134fe4..47162ec2599 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/def_karazhan.h
+++ b/src/bindings/scripts/scripts/zone/karazhan/def_karazhan.h
@@ -1,44 +1,51 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
+
#ifndef DEF_KARAZHAN_H
#define DEF_KARAZHAN_H
-#define DATA_ATTUMEN_EVENT 1
-#define DATA_MOROES_EVENT 2
-#define DATA_MAIDENOFVIRTUE_EVENT 3
-#define DATA_OPTIONAL_BOSS_EVENT 4
-#define DATA_OPERA_EVENT 5
-#define DATA_CURATOR_EVENT 6
-#define DATA_SHADEOFARAN_EVENT 7
-#define DATA_TERESTIAN_EVENT 8
-#define DATA_NETHERSPITE_EVENT 9
-#define DATA_CHESS_EVENT 10
-#define DATA_MALCHEZZAR_EVENT 11
-#define DATA_NIGHTBANE_EVENT 12
-#define DATA_OPERA_PERFORMANCE 13
-#define DATA_OPERA_OZ_DEATHCOUNT 14
-#define DATA_KILREK 15
-#define DATA_TERESTIAN 16
-#define DATA_MOROES 17
-#define DATA_GAMEOBJECT_CURTAINS 18
-#define DATA_GAMEOBJECT_STAGEDOORLEFT 19
-#define DATA_GAMEOBJECT_STAGEDOORRIGHT 20
-#define DATA_GAMEOBJECT_LIBRARY_DOOR 21
-#define DATA_GAMEOBJECT_MASSIVE_DOOR 22
-#define DATA_GAMEOBJECT_NETHER_DOOR 23
-#define DATA_GAMEOBJECT_GAME_DOOR 24
-#define DATA_GAMEOBJECT_GAME_EXIT_DOOR 25
-#define DATA_IMAGE_OF_MEDIVH 26
-#define DATA_MASTERS_TERRACE_DOOR_1 27
-#define DATA_MASTERS_TERRACE_DOOR_2 28
+enum
+{
+ DATA_ATTUMEN_EVENT = 1,
+ DATA_MOROES_EVENT = 2,
+ DATA_MAIDENOFVIRTUE_EVENT = 3,
+ DATA_OPTIONAL_BOSS_EVENT = 4,
+ DATA_OPERA_EVENT = 5,
+ DATA_CURATOR_EVENT = 6,
+ DATA_SHADEOFARAN_EVENT = 7,
+ DATA_TERESTIAN_EVENT = 8,
+ DATA_NETHERSPITE_EVENT = 9,
+ DATA_CHESS_EVENT = 10,
+ DATA_MALCHEZZAR_EVENT = 11,
+ DATA_NIGHTBANE_EVENT = 12,
+ DATA_OPERA_PERFORMANCE = 13,
+ DATA_OPERA_OZ_DEATHCOUNT = 14,
+ DATA_KILREK = 15,
+ DATA_TERESTIAN = 16,
+ DATA_MOROES = 17,
+ DATA_GAMEOBJECT_CURTAINS = 18,
+ DATA_GAMEOBJECT_STAGEDOORLEFT = 19,
+ DATA_GAMEOBJECT_STAGEDOORRIGHT = 20,
+ DATA_GAMEOBJECT_LIBRARY_DOOR = 21,
+ DATA_GAMEOBJECT_MASSIVE_DOOR = 22,
+ DATA_GAMEOBJECT_NETHER_DOOR = 23,
+ DATA_GAMEOBJECT_GAME_DOOR = 24,
+ DATA_GAMEOBJECT_GAME_EXIT_DOOR = 25,
+ DATA_IMAGE_OF_MEDIVH = 26,
+ DATA_MASTERS_TERRACE_DOOR_1 = 27,
+ DATA_MASTERS_TERRACE_DOOR_2 = 28,
+ DATA_GO_SIDE_ENTRANCE_DOOR = 29
+};
-// Opera Performances
-#define EVENT_OZ 1
-#define EVENT_HOOD 2
-#define EVENT_RAJ 3
+enum OperaEvents
+{
+ EVENT_OZ = 1,
+ EVENT_HOOD = 2,
+ EVENT_RAJ = 3
+};
-#define ERROR_INST_DATA(a) error_log("TSCR: Instance Data for Karazhan not set properly. Encounter for Creature Entry %u may not work properly.", a->GetEntry());
+#define ERROR_INST_DATA(a) error_log("TSCR: Instance Data for Karazhan not set properly. Encounter for Creature Entry %u may not work properly.", a->GetEntry());
#endif
diff --git a/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp b/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp
index 3952c0da167..e8dccdd62a4 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -46,6 +46,7 @@ struct TRINITY_DLL_DECL instance_karazhan : public ScriptedInstance
instance_karazhan(Map* map) : ScriptedInstance(map) {Initialize();}
uint32 Encounters[ENCOUNTERS];
+ std::string str_data;
uint32 OperaEvent;
uint32 OzDeathCount;
@@ -58,6 +59,7 @@ struct TRINITY_DLL_DECL instance_karazhan : public ScriptedInstance
uint64 MoroesGUID;
uint64 LibraryDoor; // Door at Shade of Aran
uint64 MassiveDoor; // Door at Netherspite
+ uint64 SideEntranceDoor; // Side Entrance
uint64 GamesmansDoor; // Door before Chess
uint64 GamesmansExitDoor; // Door after Chess
uint64 NetherspaceDoor; // Door at Malchezaar
@@ -82,6 +84,7 @@ struct TRINITY_DLL_DECL instance_karazhan : public ScriptedInstance
LibraryDoor = 0;
MassiveDoor = 0;
+ SideEntranceDoor = 0;
GamesmansDoor = 0;
GamesmansExitDoor = 0;
NetherspaceDoor = 0;
@@ -145,6 +148,7 @@ struct TRINITY_DLL_DECL instance_karazhan : public ScriptedInstance
case DATA_GAMEOBJECT_CURTAINS: return CurtainGUID;
case DATA_GAMEOBJECT_LIBRARY_DOOR: return LibraryDoor;
case DATA_GAMEOBJECT_MASSIVE_DOOR: return MassiveDoor;
+ case DATA_GO_SIDE_ENTRANCE_DOOR: return SideEntranceDoor;
case DATA_GAMEOBJECT_GAME_DOOR: return GamesmansDoor;
case DATA_GAMEOBJECT_GAME_EXIT_DOOR: return GamesmansExitDoor;
case DATA_GAMEOBJECT_NETHER_DOOR: return NetherspaceDoor;
@@ -183,7 +187,19 @@ struct TRINITY_DLL_DECL instance_karazhan : public ScriptedInstance
}
if(data == DONE)
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << Encounters[0] << " " << Encounters[1] << " " << Encounters[2] << " "
+ << Encounters[3] << " " << Encounters[4] << " " << Encounters[5] << " " << Encounters[6] << " "
+ << Encounters[7] << " " << Encounters[8] << " " << Encounters[9] << " " << Encounters[10];
+
+ str_data = saveStream.str();
+
SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
+ }
}
void SetData64(uint32 identifier, uint64 data)
@@ -208,6 +224,13 @@ struct TRINITY_DLL_DECL instance_karazhan : public ScriptedInstance
case 185134: NetherspaceDoor = go->GetGUID(); break;
case 184274: MastersTerraceDoor[0] = go->GetGUID(); break;
case 184280: MastersTerraceDoor[1] = go->GetGUID(); break;
+ case 184275:
+ SideEntranceDoor = go->GetGUID();
+ if (GetData(DATA_OPERA_EVENT) != DONE)
+ go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
+ else
+ go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
+ break;
}
switch(OperaEvent)
@@ -226,20 +249,7 @@ struct TRINITY_DLL_DECL instance_karazhan : public ScriptedInstance
const char* Save()
{
- OUT_SAVE_INST_DATA;
- std::ostringstream stream;
- stream << Encounters[0] << " " << Encounters[1] << " " << Encounters[2] << " " << Encounters[3] << " "
- << Encounters[4] << " " << Encounters[5] << " " << Encounters[6] << " " << Encounters[7] << " "
- << Encounters[8] << " " << Encounters[9] << " " << Encounters[10] << " " << Encounters[11];
- char* out = new char[stream.str().length() + 1];
- strcpy(out, stream.str().c_str());
- if(out)
- {
- OUT_SAVE_INST_DATA_COMPLETE;
- return out;
- }
-
- return NULL;
+ return str_data.c_str();
}
void Load(const char* in)
@@ -251,8 +261,8 @@ struct TRINITY_DLL_DECL instance_karazhan : public ScriptedInstance
}
OUT_LOAD_INST_DATA(in);
- std::istringstream stream(in);
- stream >> Encounters[0] >> Encounters[1] >> Encounters[2] >> Encounters[3]
+ std::istringstream loadStream(in);
+ loadStream >> Encounters[0] >> Encounters[1] >> Encounters[2] >> Encounters[3]
>> Encounters[4] >> Encounters[5] >> Encounters[6] >> Encounters[7]
>> Encounters[8] >> Encounters[9] >> Encounters[10] >> Encounters[11];
for(uint8 i = 0; i < ENCOUNTERS; ++i)
diff --git a/src/bindings/scripts/scripts/zone/karazhan/karazhan.cpp b/src/bindings/scripts/scripts/zone/karazhan/karazhan.cpp
index e3babcf89df..384ac20822b 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/karazhan.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/karazhan.cpp
@@ -1,4 +1,4 @@
- /* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ /* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -46,6 +46,10 @@ EndContentData */
#define SAY_RAJ_INTRO1 "The romantic plays are really tough, but you'll do better this time. You have TALENT. Ready?"
#define RAJ_GOSSIP1 "I've never been more ready."
+#define OZ_GM_GOSSIP1 "[GM] Change event to EVENT_OZ"
+#define OZ_GM_GOSSIP2 "[GM] Change event to EVENT_HOOD"
+#define OZ_GM_GOSSIP3 "[GM] Change event to EVENT_RAJ"
+
struct Dialogue
{
int32 textid;
@@ -145,14 +149,14 @@ struct TRINITY_DLL_DECL npc_barnesAI : public npc_escortAI
Event = pInstance->GetData(DATA_OPERA_PERFORMANCE);
if (GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_STAGEDOORLEFT)))
- Door->SetGoState(1);
+ Door->SetGoState(GO_STATE_READY);
if (GameObject* Curtain = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_CURTAINS)))
- Curtain->SetGoState(1);
+ Curtain->SetGoState(GO_STATE_READY);
}
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void WaypointReached(uint32 i)
{
@@ -177,10 +181,11 @@ struct TRINITY_DLL_DECL npc_barnesAI : public npc_escortAI
if(pInstance)
{
if (GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_STAGEDOORLEFT)))
- Door->SetGoState(1);
+ Door->SetGoState(GO_STATE_READY);
}
IsBeingEscorted = false;
PerformanceReady = true;
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
break;
}
}
@@ -257,7 +262,7 @@ struct TRINITY_DLL_DECL npc_barnesAI : public npc_escortAI
return;
if (GameObject* Curtain = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_CURTAINS)))
- Curtain->SetGoState(0);
+ Curtain->SetGoState(GO_STATE_ACTIVE);
CurtainTimer = 0;
}else CurtainTimer -= diff;
@@ -310,7 +315,7 @@ struct TRINITY_DLL_DECL npc_barnesAI : public npc_escortAI
pInstance->SetData(DATA_OPERA_EVENT, IN_PROGRESS);
if (GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_STAGEDOORLEFT)))
- Door->SetGoState(0);
+ Door->SetGoState(GO_STATE_ACTIVE);
m_creature->CastSpell(m_creature, SPELL_TUXEDO, true);
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
@@ -377,6 +382,13 @@ bool GossipHello_npc_barnes(Player* player, Creature* _Creature)
{
player->ADD_GOSSIP_ITEM(0, OZ_GOSSIP1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ if (player->isGameMaster())
+ {
+ player->ADD_GOSSIP_ITEM(5, OZ_GM_GOSSIP1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ player->ADD_GOSSIP_ITEM(5, OZ_GM_GOSSIP2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
+ player->ADD_GOSSIP_ITEM(5, OZ_GM_GOSSIP3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
+ }
+
if(!((npc_barnesAI*)_Creature->AI())->RaidWiped)
player->SEND_GOSSIP_MENU(8970, _Creature->GetGUID());
else
@@ -394,11 +406,25 @@ bool GossipSelect_npc_barnes(Player *player, Creature *_Creature, uint32 sender,
player->ADD_GOSSIP_ITEM(0, OZ_GOSSIP2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
player->SEND_GOSSIP_MENU(8971, _Creature->GetGUID());
break;
-
case GOSSIP_ACTION_INFO_DEF+2:
player->CLOSE_GOSSIP_MENU();
((npc_barnesAI*)_Creature->AI())->StartEvent();
break;
+ case GOSSIP_ACTION_INFO_DEF+3:
+ player->CLOSE_GOSSIP_MENU();
+ ((npc_barnesAI*)_Creature->AI())->Event = EVENT_OZ;
+ outstring_log("TSCR: player (GUID %i) manually set Opera event to EVENT_OZ",player->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+4:
+ player->CLOSE_GOSSIP_MENU();
+ ((npc_barnesAI*)_Creature->AI())->Event = EVENT_HOOD;
+ outstring_log("TSCR: player (GUID %i) manually set Opera event to EVENT_HOOD",player->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+5:
+ player->CLOSE_GOSSIP_MENU();
+ ((npc_barnesAI*)_Creature->AI())->Event = EVENT_RAJ;
+ outstring_log("TSCR: player (GUID %i) manually set Opera event to EVENT_RAJ",player->GetGUID());
+ break;
}
return true;
@@ -488,7 +514,7 @@ struct TRINITY_DLL_DECL npc_image_of_medivhAI : public ScriptedAI
m_creature->RemoveCorpse();
}
}
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void MovementInform(uint32 type, uint32 id)
{
@@ -508,7 +534,7 @@ struct TRINITY_DLL_DECL npc_image_of_medivhAI : public ScriptedAI
EventStarted = true;
Creature* Arcanagos = m_creature->SummonCreature(MOB_ARCANAGOS,ArcanagosPos[0],ArcanagosPos[1],ArcanagosPos[2],0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,20000);
ArcanagosGUID = Arcanagos->GetGUID();
- Arcanagos->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ Arcanagos->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
(*Arcanagos).GetMotionMaster()->MovePoint(0,ArcanagosPos[0],ArcanagosPos[1],ArcanagosPos[2]);
Arcanagos->SetOrientation(ArcanagosPos[3]);
m_creature->SetOrientation(MedivPos[3]);
@@ -524,25 +550,25 @@ struct TRINITY_DLL_DECL npc_image_of_medivhAI : public ScriptedAI
{
case 0: return 9999999;
case 1:
- m_creature->Yell(SAY_DIALOG_MEDIVH_1,LANG_UNIVERSAL,NULL);
+ m_creature->MonsterYell(SAY_DIALOG_MEDIVH_1,LANG_UNIVERSAL,NULL);
return 10000;
case 2:
if(arca)
- ((Creature*)arca)->Yell(SAY_DIALOG_ARCANAGOS_2,LANG_UNIVERSAL,NULL);
+ ((Creature*)arca)->MonsterYell(SAY_DIALOG_ARCANAGOS_2,LANG_UNIVERSAL,NULL);
return 20000;
case 3:
- m_creature->Yell(SAY_DIALOG_MEDIVH_3,LANG_UNIVERSAL,NULL);
+ m_creature->MonsterYell(SAY_DIALOG_MEDIVH_3,LANG_UNIVERSAL,NULL);
return 10000;
case 4:
if(arca)
- ((Creature*)arca)->Yell(SAY_DIALOG_ARCANAGOS_4, LANG_UNIVERSAL, NULL);
+ ((Creature*)arca)->MonsterYell(SAY_DIALOG_ARCANAGOS_4, LANG_UNIVERSAL, NULL);
return 20000;
case 5:
- m_creature->Yell(SAY_DIALOG_MEDIVH_5, LANG_UNIVERSAL, NULL);
+ m_creature->MonsterYell(SAY_DIALOG_MEDIVH_5, LANG_UNIVERSAL, NULL);
return 20000;
case 6:
if(arca)
- ((Creature*)arca)->Yell(SAY_DIALOG_ARCANAGOS_6, LANG_UNIVERSAL, NULL);
+ ((Creature*)arca)->MonsterYell(SAY_DIALOG_ARCANAGOS_6, LANG_UNIVERSAL, NULL);
return 10000;
case 7:
FireArcanagosTimer = 500;
@@ -552,7 +578,7 @@ struct TRINITY_DLL_DECL npc_image_of_medivhAI : public ScriptedAI
DoCast(m_creature, SPELL_MANA_SHIELD);
return 10000;
case 9:
- m_creature->TextEmote(EMOTE_DIALOG_MEDIVH_7, 0, false);
+ m_creature->MonsterTextEmote(EMOTE_DIALOG_MEDIVH_7, 0, false);
return 10000;
case 10:
if(arca)
@@ -560,7 +586,7 @@ struct TRINITY_DLL_DECL npc_image_of_medivhAI : public ScriptedAI
return 1000;
case 11:
if(arca)
- ((Creature*)arca)->Yell(SAY_DIALOG_ARCANAGOS_8, LANG_UNIVERSAL, NULL);
+ ((Creature*)arca)->MonsterYell(SAY_DIALOG_ARCANAGOS_8, LANG_UNIVERSAL, NULL);
return 5000;
case 12:
arca->GetMotionMaster()->MovePoint(0, -11010.82,-1761.18, 156.47);
@@ -569,7 +595,7 @@ struct TRINITY_DLL_DECL npc_image_of_medivhAI : public ScriptedAI
arca->SetSpeed(MOVE_FLIGHT, 2.0f);
return 10000;
case 13:
- m_creature->Yell(SAY_DIALOG_MEDIVH_9, LANG_UNIVERSAL, NULL);
+ m_creature->MonsterYell(SAY_DIALOG_MEDIVH_9, LANG_UNIVERSAL, NULL);
return 10000;
case 14:
m_creature->SetVisibility(VISIBILITY_OFF);
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 d79f581d1c8..b838fc97aab 100644
--- a/src/bindings/scripts/scripts/zone/loch_modan/loch_modan.cpp
+++ b/src/bindings/scripts/scripts/zone/loch_modan/loch_modan.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
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 cbc1013da17..1d27ddd6e2d 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -6,18 +6,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
*/
/* ScriptData
SDName: Boss_Felblood_Kaelthas
SD%Complete: 80
-SDComment: Normal and Heroic Support. Issues: Arcane Spheres do not initially follow targets. TODO: Convert Phoenix to ACID.
+SDComment: Normal and Heroic Support. Issues: Arcane Spheres do not initially follow targets.
SDCategory: Magisters' Terrace
EndScriptData */
@@ -25,7 +25,7 @@ EndScriptData */
#include "def_magisters_terrace.h"
#include "WorldPacket.h"
-#define SAY_AGGRO -1585023 //This yell should be done when the room is cleared. For now, set it as aggro yell.
+#define SAY_AGGRO -1585023 //This yell should be done when the room is cleared. For now, set it as a movelineofsight yell.
#define SAY_PHOENIX -1585024
#define SAY_FLAMESTRIKE -1585025
#define SAY_GRAVITY_LAPSE -1585026
@@ -36,13 +36,12 @@ EndScriptData */
/*** Spells ***/
// Phase 1 spells
-
#define SPELL_FIREBALL_NORMAL 44189 // Deals 2700-3300 damage at current target
#define SPELL_FIREBALL_HEROIC 46164 // 4950-6050
#define SPELL_PHOENIX 44194 // Summons a phoenix (Doesn't work?)
-#define SPELL_PHOENIX_BURN 44198 // A spell Phoenix uses to damage everything around
-#define SPELL_PHOENIX_FIREBALL 44202 // Phoenix casts this in phase 2 and stops moving
+#define SPELL_PHOENIX_BURN 44197 // A spell Phoenix uses to damage everything around
+#define SPELL_REBIRTH_DMG 44196 // DMG if a Phoenix rebirth happen
#define SPELL_FLAMESTRIKE1_NORMAL 44190 // Damage part
#define SPELL_FLAMESTRIKE1_HEROIC 46163 // Heroic damage part
@@ -53,7 +52,6 @@ EndScriptData */
#define SPELL_PYROBLAST 36819 // Heroic only; 45-55k fire damage
// Phase 2 spells
-
#define SPELL_GRAVITY_LAPSE_INITIAL 44224 // Cast at the beginning of every Gravity Lapse
#define SPELL_GRAVITY_LAPSE_CHANNEL 44251 // Channeled; blue beam animation to every enemy in range
#define SPELL_TELEPORT_CENTER 44218 // Should teleport people to the center. Requires DB entry in spell_target_position.
@@ -68,16 +66,14 @@ EndScriptData */
#define CREATURE_ARCANE_SPHERE 24708
/** Locations **/
-float KaelLocations[6][2]=
+float KaelLocations[3][2]=
{
- {148.744659, 181.377426},//center
- {140.823883, 195.403046},//phoenixpos1
- {156.574188, 195.650482},//phoenixpos2
- {149.813, 160.917},//spherepos1
- {167.223, 173.594},//spherepos2
- {130.68, 173.007},//spherepos3
+ {148.744659, 181.377426},
+ {140.823883, 195.403046},
+ {156.574188, 195.650482},
};
-#define LOCATION_Z -16.727455
+
+#define LOCATION_Z -16.727455
struct TRINITY_DLL_DECL boss_felblood_kaelthasAI : public ScriptedAI
{
@@ -106,6 +102,7 @@ struct TRINITY_DLL_DECL boss_felblood_kaelthasAI : public ScriptedAI
bool FirstGravityLapse;
bool Heroic;
+ bool HasTaunted;
uint8 Phase;
// 0 = Not started
@@ -116,7 +113,7 @@ struct TRINITY_DLL_DECL boss_felblood_kaelthasAI : public ScriptedAI
{
// TODO: Timers
FireballTimer = 0;
- PhoenixTimer = 30000;
+ PhoenixTimer = 10000;
FlameStrikeTimer = 25000;
CombatPulseTimer = 0;
@@ -126,55 +123,57 @@ struct TRINITY_DLL_DECL boss_felblood_kaelthasAI : public ScriptedAI
GravityLapsePhase = 0;
FirstGravityLapse = true;
+ HasTaunted = false;
Phase = 0;
- if(pInstance)
- {
- if(m_creature->isDead())
- pInstance->SetData(DATA_KAELTHAS_EVENT, DONE);
- else
- pInstance->SetData(DATA_KAELTHAS_EVENT, NOT_STARTED);
- }
- }
+ if (pInstance)
+ pInstance->SetData(DATA_KAELTHAS_EVENT, 0);
- void KilledUnit(Unit* victim)
- {
- if(victim && (victim->GetTypeId() == TYPEID_PLAYER))
- {
- victim->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY);
- victim->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT);
- WorldPacket data(12);
- data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
- data.append(victim->GetPackGUID());
- data << uint32(0);
- victim->SendMessageToSet(&data, true);
- }
+ GameObject* Door = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_KAEL_DOOR));
+ if (Door)
+ Door->SetGoState(GO_STATE_ACTIVE); // Open the big encounter door. Close it in Aggro and open it only in JustDied(and here)
+ // Small door opened after event are expected to be closed by default
}
+
void JustDied(Unit *killer)
{
- RemoveGravityLapse();
DoScriptText(SAY_DEATH, m_creature);
- if(pInstance)
- pInstance->SetData(DATA_KAELTHAS_EVENT, DONE);
+ GameObject* EncounterDoor = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_KAEL_DOOR));
+ if (EncounterDoor)
+ EncounterDoor->SetGoState(GO_STATE_ACTIVE); // Open the encounter door
}
void DamageTaken(Unit* done_by, uint32 &damage)
{
- if(damage > m_creature->GetHealth())
+ if (damage > m_creature->GetHealth())
RemoveGravityLapse(); // Remove Gravity Lapse so that players fall to ground if they kill him when in air.
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
+ {
+ if (pInstance)
+ {
+ GameObject* EncounterDoor = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_KAEL_DOOR));
+ if (EncounterDoor)
+ EncounterDoor->SetGoState(GO_STATE_READY); //Close the encounter door, open it in JustDied/Reset
+ }
+ }
+
+ void MoveInLineOfSight(Unit *who)
{
- DoScriptText(SAY_AGGRO, m_creature);
- if(pInstance)
- pInstance->SetData(DATA_KAELTHAS_EVENT, IN_PROGRESS);
+ if (!HasTaunted && m_creature->IsWithinDistInMap(who, 40.0))
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ HasTaunted = true;
+ }
+
+ ScriptedAI::MoveInLineOfSight(who);
}
void SetThreatList(Creature* SummonedUnit)
{
- if(!SummonedUnit)
+ if (!SummonedUnit)
return;
std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
@@ -182,114 +181,86 @@ struct TRINITY_DLL_DECL boss_felblood_kaelthasAI : public ScriptedAI
for(i = m_threatlist.begin(); i != m_threatlist.end(); i++)
{
Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
- if(pUnit && pUnit->isAlive())
+ if (pUnit && pUnit->isAlive())
{
- float threat = DoGetThreat(pUnit);
- SummonedUnit->AddThreat(pUnit, 0.1f);
+ float threat = m_creature->getThreatManager().getThreat(pUnit);
+ SummonedUnit->AddThreat(pUnit, threat);
}
}
}
- void EnterEvadeMode()
- {
- RemoveGravityLapse();
- m_creature->InterruptNonMeleeSpells(true);
- m_creature->RemoveAllAuras();
- m_creature->DeleteThreatList();
- m_creature->CombatStop();
- m_creature->LoadCreaturesAddon();
-
- if( m_creature->isAlive() )
- m_creature->GetMotionMaster()->MoveTargetedHome();
-
- m_creature->SetLootRecipient(NULL);
-
- InCombat = false;
- Reset();
- }
-
void TeleportPlayersToSelf()
{
- float x,y,z;
- m_creature->Relocate(KaelLocations[0][0], KaelLocations[0][1], LOCATION_Z, 0);
- Map *map = m_creature->GetMap();
- Map::PlayerList const &PlayerList = map->GetPlayers();
- Map::PlayerList::const_iterator i;
- for (i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ float x = KaelLocations[0][0];
+ float y = KaelLocations[0][1];
+ m_creature->Relocate(x, y, LOCATION_Z, 0);
+ //m_creature->SendMonsterMove(x, y, LOCATION_Z, 0, 0, 0); // causes some issues...
+ std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
+ for (i = m_creature->getThreatManager().getThreatList().begin(); i!= m_creature->getThreatManager().getThreatList().end();++i)
{
- if (Player* i_pl = i->getSource())
- if(i_pl->isAlive())
- {
- i_pl->CastSpell(i_pl, SPELL_TELEPORT_CENTER, true);
- m_creature->GetNearPoint(m_creature,x,y,z,5,5,0);
- i_pl->TeleportTo(m_creature->GetMapId(),x,y,LOCATION_Z,i_pl->GetOrientation());
- }
+ Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
+ if (pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER))
+ pUnit->CastSpell(pUnit, SPELL_TELEPORT_CENTER, true);
}
DoCast(m_creature, SPELL_TELEPORT_CENTER, true);
}
void CastGravityLapseKnockUp()
{
- Map *map = m_creature->GetMap();
- Map::PlayerList const &PlayerList = map->GetPlayers();
- Map::PlayerList::const_iterator i;
- for (i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
+ for (i = m_creature->getThreatManager().getThreatList().begin(); i!= m_creature->getThreatManager().getThreatList().end();++i)
{
- if (Player* i_pl = i->getSource())
- if(i_pl->isAlive())
+ Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
+ if (pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER))
// Knockback into the air
- i_pl->CastSpell(i_pl, SPELL_GRAVITY_LAPSE_DOT, true, 0, 0, m_creature->GetGUID());
+ pUnit->CastSpell(pUnit, SPELL_GRAVITY_LAPSE_DOT, true, 0, 0, m_creature->GetGUID());
}
}
void CastGravityLapseFly() // Use Fly Packet hack for now as players can't cast "fly" spells unless in map 530. Has to be done a while after they get knocked into the air...
{
- Map *map = m_creature->GetMap();
- Map::PlayerList const &PlayerList = map->GetPlayers();
- Map::PlayerList::const_iterator i;
- for (i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
+ for (i = m_creature->getThreatManager().getThreatList().begin(); i!= m_creature->getThreatManager().getThreatList().end();++i)
{
- if (Player* i_pl = i->getSource())
+ Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
+ if (pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER))
{
- if(i_pl->isAlive())
- {
- // Also needs an exception in spell system.
- i_pl->CastSpell(i_pl, SPELL_GRAVITY_LAPSE_FLY, true, 0, 0, m_creature->GetGUID());
- // Use packet hack
- WorldPacket data(12);
- data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
- data.append(i_pl->GetPackGUID());
- data << uint32(0);
- i_pl->SendMessageToSet(&data, true);
- i_pl->SetSpeed(MOVE_FLIGHT, 2.0f);
- }
+ // Also needs an exception in spell system.
+ pUnit->CastSpell(pUnit, SPELL_GRAVITY_LAPSE_FLY, true, 0, 0, m_creature->GetGUID());
+ // Use packet hack
+ WorldPacket data(12);
+ data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
+ data.append(pUnit->GetPackGUID());
+ data << uint32(0);
+ pUnit->SendMessageToSet(&data, true);
}
}
}
void RemoveGravityLapse()
{
- Map *map = m_creature->GetMap();
- Map::PlayerList const &PlayerList = map->GetPlayers();
- Map::PlayerList::const_iterator i;
- for (i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
+ for (i = m_creature->getThreatManager().getThreatList().begin(); i!= m_creature->getThreatManager().getThreatList().end();++i)
{
- if(Player* i_pl = i->getSource())
+ Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
+ if (pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER))
{
- i_pl->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY);
- i_pl->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT);
+ pUnit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY);
+ pUnit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT);
+
WorldPacket data(12);
data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
- data.append(i_pl->GetPackGUID());
+ data.append(pUnit->GetPackGUID());
data << uint32(0);
- i_pl->SendMessageToSet(&data, true);
+ pUnit->SendMessageToSet(&data, true);
}
}
}
void UpdateAI(const uint32 diff)
{
- if(!UpdateVictim())
+ //Return since we have no target
+ if (!UpdateVictim())
return;
switch(Phase)
@@ -297,9 +268,9 @@ struct TRINITY_DLL_DECL boss_felblood_kaelthasAI : public ScriptedAI
case 0:
{
// *Heroic mode only:
- if(Heroic)
+ if (Heroic)
{
- if(PyroblastTimer < diff)
+ if (PyroblastTimer < diff)
{
DoCast(m_creature, SPELL_SHOCK_BARRIER, true);
DoCast(m_creature->getVictim(), SPELL_PYROBLAST);
@@ -307,56 +278,47 @@ struct TRINITY_DLL_DECL boss_felblood_kaelthasAI : public ScriptedAI
}else PyroblastTimer -= diff;
}
- if(FireballTimer < diff)
+ if (FireballTimer < diff)
{
DoCast(m_creature->getVictim(), Heroic ? SPELL_FIREBALL_HEROIC : SPELL_FIREBALL_NORMAL);
FireballTimer = 2000 + rand()%4000;
}else FireballTimer -= diff;
- if(PhoenixTimer < diff)
+ if (PhoenixTimer < diff)
{
+
+ Unit* target = NULL;
+ target = SelectUnit(SELECT_TARGET_RANDOM,1);
+
uint32 random = rand()%2 + 1;
float x = KaelLocations[random][0];
float y = KaelLocations[random][1];
- Creature* Phoenix = m_creature->SummonCreature(CREATURE_PHOENIX, x, y, LOCATION_Z, 0, TEMPSUMMON_CORPSE_DESPAWN, 60000);
- if(Phoenix)
+
+ Creature* Phoenix = m_creature->SummonCreature(CREATURE_PHOENIX, x, y, LOCATION_Z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
+ if (Phoenix)
{
Phoenix->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
SetThreatList(Phoenix);
- Unit *target = SelectUnit(SELECT_TARGET_RANDOM,1);
- if(target)
- {
- Phoenix->AddThreat(target,1000);
- Phoenix->Attack(target,true);
- Phoenix->GetMotionMaster()->MoveChase(target);
- }
- else
- {
- Phoenix->AddThreat(m_creature->getVictim(),1000);
- Phoenix->Attack(m_creature->getVictim(),true);
- Phoenix->GetMotionMaster()->MoveChase(m_creature->getVictim());
- }
+ Phoenix->AI()->AttackStart(target);
}
DoScriptText(SAY_PHOENIX, m_creature);
- PhoenixTimer = 40000;
+ PhoenixTimer = 60000;
}else PhoenixTimer -= diff;
- if(FlameStrikeTimer < diff)
+ if (FlameStrikeTimer < diff)
{
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
- m_creature->InterruptNonMeleeSpells(false);
DoCast(target, SPELL_FLAMESTRIKE3, true);
DoScriptText(SAY_FLAMESTRIKE, m_creature);
-
- FlameStrikeTimer = 20000 + rand()%5000;
}
+ FlameStrikeTimer = 15000 + rand()%10000;
}else FlameStrikeTimer -= diff;
// Below 50%
- if(m_creature->GetMaxHealth() * 0.5 > m_creature->GetHealth())
+ if (m_creature->GetMaxHealth() * 0.5 > m_creature->GetHealth())
{
m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);
m_creature->StopMoving();
@@ -366,34 +328,35 @@ struct TRINITY_DLL_DECL boss_felblood_kaelthasAI : public ScriptedAI
GravityLapsePhase = 0;
Phase = 1;
}
+
DoMeleeAttackIfReady();
}
break;
case 1:
{
- m_creature->StopMoving();
- if(GravityLapseTimer < diff)
+ if (GravityLapseTimer < diff)
{
switch(GravityLapsePhase)
{
case 0:
- if(FirstGravityLapse) // Different yells at 50%, and at every following Gravity Lapse
+ if (FirstGravityLapse) // Different yells at 50%, and at every following Gravity Lapse
{
DoScriptText(SAY_GRAVITY_LAPSE, m_creature);
FirstGravityLapse = false;
- if(pInstance)
+
+ if (pInstance)
{
GameObject* KaelLeft = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_KAEL_STATUE_LEFT));
- if(KaelLeft) KaelLeft->SetGoState(0);
+ if (KaelLeft) KaelLeft->SetGoState(GO_STATE_ACTIVE);
GameObject* KaelRight = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_KAEL_STATUE_RIGHT));
- if(KaelRight) KaelRight->SetGoState(0);
+ if (KaelRight) KaelRight->SetGoState(GO_STATE_ACTIVE);
}
}else
{
DoScriptText(SAY_RECAST_GRAVITY, m_creature);
}
- m_creature->StopMoving();
+
DoCast(m_creature, SPELL_GRAVITY_LAPSE_INITIAL);
GravityLapseTimer = 2000 + diff;// Don't interrupt the visual spell
GravityLapsePhase = 1;
@@ -415,31 +378,23 @@ struct TRINITY_DLL_DECL boss_felblood_kaelthasAI : public ScriptedAI
CastGravityLapseFly();
GravityLapseTimer = 30000;
GravityLapsePhase = 4;
+
+
for(uint8 i = 0; i < 3; ++i)
{
- Creature* Orb = m_creature->SummonCreature(CREATURE_ARCANE_SPHERE,KaelLocations[3+i][0],KaelLocations[3+i][1],LOCATION_Z,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,30000);
- if(Orb)
+ Unit* target = NULL;
+ target = SelectUnit(SELECT_TARGET_RANDOM,0);
+
+ Creature* Orb = DoSpawnCreature(CREATURE_ARCANE_SPHERE, 5, 5, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000);
+ if (Orb && target)
{
- SetThreatList(Orb);
- Unit *target = SelectUnit(SELECT_TARGET_BOTTOMAGGRO,i);
- if(target)
- {
- Orb->AddThreat(target,1000);
- Orb->Attack(target,true);
- Orb->GetMotionMaster()->MoveChase(target);
- }
- else
- {
- Unit *ntarget = SelectUnit(SELECT_TARGET_RANDOM,0);
- if(ntarget)
- {
- Orb->AddThreat(ntarget,1000);
- Orb->Attack(ntarget,true);
- Orb->GetMotionMaster()->MoveChase(ntarget);
- }
- }
+ //SetThreatList(Orb);
+ Orb->AddThreat(target, 1.0f);
+ Orb->AI()->AttackStart(target);
}
+
}
+
DoCast(m_creature, SPELL_GRAVITY_LAPSE_CHANNEL);
break;
@@ -479,11 +434,11 @@ struct TRINITY_DLL_DECL mob_felkael_flamestrikeAI : public ScriptedAI
DoCast(m_creature, SPELL_FLAMESTRIKE2, true);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void MoveInLineOfSight(Unit *who) {}
void UpdateAI(const uint32 diff)
{
- if(FlameStrikeTimer < diff)
+ if (FlameStrikeTimer < diff)
{
DoCast(m_creature, Heroic ? SPELL_FLAMESTRIKE1_HEROIC : SPELL_FLAMESTRIKE1_NORMAL, true);
m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
@@ -493,211 +448,187 @@ struct TRINITY_DLL_DECL mob_felkael_flamestrikeAI : public ScriptedAI
struct TRINITY_DLL_DECL mob_felkael_phoenixAI : public ScriptedAI
{
- mob_felkael_phoenixAI(Creature *c) : ScriptedAI(c)
+ mob_felkael_phoenixAI(Creature* c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
}
- uint32 BurnTimer;
- uint32 CheckTimer;
- uint8 phase;
+
ScriptedInstance* pInstance;
- bool end;
+ uint32 BurnTimer;
+ uint32 Death_Timer;
+ bool Rebirth;
+ bool FakeDeath;
void Reset()
{
- m_creature->SetSpeed(MOVE_RUN, 0.5f);
- m_creature->SetSpeed(MOVE_WALK, 0.5f);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ m_creature->CastSpell(m_creature,SPELL_PHOENIX_BURN,true);
BurnTimer = 2000;
- CheckTimer = 1000;
- phase = 0;
- end = false;
+ Death_Timer = 2700;
+ Rebirth = false;
+ FakeDeath = false;
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
- void JustDied(Unit* slayer)
+ void DamageTaken(Unit* pKiller, uint32 &damage)
{
- if (end)
+ if (damage < m_creature->GetHealth())
+ return;
+
+ //Prevent glitch if in fake death
+ if (FakeDeath)
+ {
+ damage = 0;
return;
- DoSpawnCreature(CREATURE_PHOENIX_EGG, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 45000);
+
+ }
+ //Don't really die in all phases of Kael'Thas
+ if (pInstance && pInstance->GetData(DATA_KAELTHAS_EVENT) == 0)
+ {
+ //prevent death
+ damage = 0;
+ FakeDeath = true;
+
+ m_creature->InterruptNonMeleeSpells(false);
+ m_creature->SetHealth(0);
+ m_creature->StopMoving();
+ m_creature->ClearComboPointHolders();
+ m_creature->RemoveAllAurasOnDeath();
+ m_creature->ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false);
+ m_creature->ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, false);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->ClearAllReactives();
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET,0);
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveIdle();
+ m_creature->SetStandState(UNIT_STAND_STATE_DEAD);
+
+ }
+
+ }
+
+ void JustDied(Unit* slayer)
+ {
+ DoSpawnCreature(CREATURE_PHOENIX_EGG, 0, 0, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);
}
void UpdateAI(const uint32 diff)
{
- if(CheckTimer < diff)
+
+ //If we are fake death, we cast revbirth and after that we kill the phoenix to spawn the egg.
+ if (FakeDeath)
{
- if (pInstance)
+ if (!Rebirth)
+ {
+ DoCast(m_creature, SPELL_REBIRTH_DMG);
+ Rebirth = true;
+ }
+
+ if (Rebirth)
{
- Creature *boss = (Unit::GetCreature((*m_creature),pInstance->GetData64(DATA_KAEL)));
- if (boss)
+
+ if (Death_Timer < diff)
{
- phase = ((boss_felblood_kaelthasAI*)boss->AI())->Phase;
- if(boss->isDead() || !boss->isInCombat())
- {
- end = true;
- m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_FIRE, NULL, false);//temphack, hellfire is not damaging self
- }
- }
+ DoSpawnCreature(CREATURE_PHOENIX_EGG, 0, 0, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);
+ m_creature->setDeathState(JUST_DIED);
+ m_creature->RemoveCorpse();
+ Rebirth = false;
+ }else Death_Timer -= diff;
}
- CheckTimer = 1000;
- }else CheckTimer -= diff;
+
+
+ }
if (!UpdateVictim())
return;
if (BurnTimer < diff)
{
- if(!phase)
- {
- DoCast(m_creature, SPELL_PHOENIX_BURN);
- m_creature->DealDamage(m_creature, 1500, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_FIRE, NULL, false);//temphack, hellfire is not damaging self
- }
- else
- {
- m_creature->StopMoving();
- DoCast(m_creature->getVictim(), SPELL_PHOENIX_FIREBALL);
- }
- BurnTimer = 2000;
- }else BurnTimer -= diff;
+ //spell Burn should possible do this, but it doesn't, so do this for now.
+ uint32 dmg = urand(1650,2050);
+ m_creature->DealDamage(m_creature, dmg, 0, DOT, SPELL_SCHOOL_MASK_FIRE, NULL, false);
+ BurnTimer += 2000;
+ } BurnTimer -= diff;
- //DoMeleeAttackIfReady();
+
+ DoMeleeAttackIfReady();
}
};
-struct TRINITY_DLL_DECL mob_felkael_phoenix_eggAI : public Scripted_NoMovementAI
+struct TRINITY_DLL_DECL mob_felkael_phoenix_eggAI : public ScriptedAI
{
- mob_felkael_phoenix_eggAI(Creature *c) : Scripted_NoMovementAI(c)
- {
- pInstance = ((ScriptedInstance*)c->GetInstanceData());
- }
+ mob_felkael_phoenix_eggAI(Creature *c) : ScriptedAI(c) {}
uint32 HatchTimer;
- ScriptedInstance* pInstance;
- void Reset() { HatchTimer = 15000; }
- void Aggro(Unit* who) {}
+ void Reset()
+ {
+ HatchTimer = 10000;
+
+ }
+
+ void EnterCombat(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
+
void UpdateAI(const uint32 diff)
{
-
- if(HatchTimer < diff)
+ if (HatchTimer < diff)
{
- Creature *bird = DoSpawnCreature(CREATURE_PHOENIX, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 60000);
- if (bird)
- {
- Unit *boss = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_KAEL));
- if (boss && boss->getVictim())
- {
- bird->AddThreat(boss->getVictim(),100);
- bird->Attack(boss->getVictim(),true);
- bird->GetMotionMaster()->MoveChase(boss->getVictim());
- }
- }
+ DoSpawnCreature(CREATURE_PHOENIX, 0, 0, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}else HatchTimer -= diff;
+
}
};
struct TRINITY_DLL_DECL mob_arcane_sphereAI : public ScriptedAI
{
- mob_arcane_sphereAI(Creature *c) : ScriptedAI(c)
- {
- pInstance = ((ScriptedInstance*)c->GetInstanceData());
- }
+ mob_arcane_sphereAI(Creature *c) : ScriptedAI(c) {Reset();}
+
uint32 DespawnTimer;
uint32 ChangeTargetTimer;
- uint32 CheckTimer;
-
- ScriptedInstance* pInstance;
void Reset()
{
- m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING);
DespawnTimer = 30000;
- ChangeTargetTimer = 5000;
- CheckTimer = 1000;
- m_creature->SetSpeed(MOVE_RUN, 0.5f);
- m_creature->SetSpeed(MOVE_WALK, 0.5f);
+ ChangeTargetTimer = 6000 + rand()%6000;
+
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->setFaction(14);
DoCast(m_creature, SPELL_ARCANE_SPHERE_PASSIVE, true);
}
- void Aggro(Unit* who) {}
- void StalkTarget(Unit* target)
- {
- if(!target)
- return;
- m_creature->AddThreat(target,100000);
- m_creature->GetMotionMaster()->MoveChase(target);
- m_creature->Attack(target,true);
- }
+ void EnterCombat(Unit* who) {}
+
void UpdateAI(const uint32 diff)
{
- if(DespawnTimer < diff)
+ if (DespawnTimer < diff)
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
else DespawnTimer -= diff;
- if(!UpdateVictim())
- ChangeTargetTimer = 0;
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
- if(ChangeTargetTimer < diff)
+ if (ChangeTargetTimer < diff)
{
- DoResetThreat();
- Unit *ntarget = SelectUnit(SELECT_TARGET_RANDOM,0);
- if (ntarget)
- StalkTarget(ntarget);
- ChangeTargetTimer = 10000;
- }else ChangeTargetTimer -= diff;
- if(CheckTimer < diff)
- {
- if (pInstance)
- {
- Creature *boss = Unit::GetCreature((*m_creature),pInstance->GetData64(DATA_KAEL));
- if(boss)
- {
- if(!((boss_felblood_kaelthasAI*)boss->AI())->Phase || boss->isDead())
- DespawnTimer = 0;
- }else DespawnTimer = 0;
- }
- CheckTimer = 1000;
- }else CheckTimer -= diff;
- }
-};
+ Unit* target = NULL;
+ target = SelectUnit(SELECT_TARGET_RANDOM,0);
+ if (target)
+ m_creature->AddThreat(target, 1.0f);
+ m_creature->TauntApply(target);
+ AttackStart(target);
-bool GOHello_go_kael_orb(Player *player, GameObject* _GO)
-{
- ScriptedInstance* pInst = (ScriptedInstance*)_GO->GetInstanceData();
- if (pInst && player)
- {
- Unit *kael = Unit::GetUnit((*_GO),pInst->GetData64(DATA_KAEL));
- if (kael && kael->isDead())
- player->TeleportTo(530, 12888, -6876, 9, 0.3);
- }
- return true;
-}
-
-bool GOHello_go_movie_orb(Player *player, GameObject* _GO)
-{
- if (player)
- {
- WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4);
- data << (uint32)164;
- player->GetSession()->SendPacket(&data);
-
- if (player->GetQuestStatus(11490) == QUEST_STATUS_INCOMPLETE)
- {
- Unit *qUnit = player->SummonCreature(25042,player->GetPositionX(),player->GetPositionY(),player->GetPositionZ()-10,0,TEMPSUMMON_CORPSE_DESPAWN,0);
- if(qUnit)
- player->DealDamage(qUnit, qUnit->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- }
+ ChangeTargetTimer = 5000 + rand()%10000;
+ }else ChangeTargetTimer -= diff;
}
- return true;
-}
+};
CreatureAI* GetAI_boss_felblood_kaelthas(Creature* c)
{
@@ -739,28 +670,18 @@ void AddSC_boss_felblood_kaelthas()
newscript->RegisterSelf();
newscript = new Script;
- newscript->Name="mob_felkael_phoenix";
+ newscript->Name = "mob_felkael_phoenix";
newscript->GetAI = &GetAI_mob_felkael_phoenix;
newscript->RegisterSelf();
newscript = new Script;
- newscript->Name="mob_felkael_phoenix_egg";
+ newscript->Name = "mob_felkael_phoenix_egg";
newscript->GetAI = &GetAI_mob_felkael_phoenix_egg;
newscript->RegisterSelf();
newscript = new Script;
- newscript->Name="mob_felkael_flamestrike";
+ newscript->Name = "mob_felkael_flamestrike";
newscript->GetAI = &GetAI_mob_felkael_flamestrike;
newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name="go_kael_orb";
- newscript->pGOHello = &GOHello_go_kael_orb;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name="go_movie_orb";
- newscript->pGOHello = &GOHello_go_movie_orb;
- 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 36ec57a4e25..ead9e36eed6 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -97,8 +97,6 @@ struct TRINITY_DLL_DECL boss_priestess_delrissaAI : public ScriptedAI
boss_priestess_delrissaAI(Creature* c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
- Adds.clear();
- //SummonAdds();
Heroic = c->GetMap()->IsHeroic();
}
@@ -122,7 +120,6 @@ struct TRINITY_DLL_DECL boss_priestess_delrissaAI : public ScriptedAI
void Reset()
{
- m_creature->SetCorpseDelay(60*60*1000);
LackeysKilled = 0;
PlayersKilled = 0;
@@ -135,18 +132,17 @@ struct TRINITY_DLL_DECL boss_priestess_delrissaAI : public ScriptedAI
CombatPulseTimer = 5000;
+ SummonAdds();
CheckAdds();
- if(pInstance)
+ if (pInstance)
{
+ pInstance->SetData(DATA_DELRISSA_EVENT, NOT_STARTED);
pInstance->SetData(DATA_DELRISSA_DEATH_COUNT, 0);
- if (m_creature->isDead())
- pInstance->SetData(DATA_DELRISSA_EVENT, DONE);
- else pInstance->SetData(DATA_DELRISSA_EVENT, NOT_STARTED);
- }else error_log(ERROR_INST_DATA);
+ } else error_log(ERROR_INST_DATA);
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
@@ -157,8 +153,9 @@ struct TRINITY_DLL_DECL boss_priestess_delrissaAI : public ScriptedAI
void SummonAdds()
{
- /*if (m_creature->isDead())
- return;*/
+ if(!Adds.empty())
+ return;
+
std::vector<uint32> AddList;
for(uint8 i = 0; i < 8; ++i)
AddList.push_back(AddEntry[i]);
@@ -169,7 +166,7 @@ struct TRINITY_DLL_DECL boss_priestess_delrissaAI : public ScriptedAI
for(uint8 i = 0; i < AddList.size(); ++i)
{
Creature* pAdd = m_creature->SummonCreature(AddList[i], LackeyLocations[i][0], LackeyLocations[i][1], POS_Z, ORIENT, TEMPSUMMON_DEAD_DESPAWN, 0);
- if(pAdd)
+ if (pAdd)
{
Add* nAdd = new Add(AddList[i], pAdd->GetGUID());
Adds.push_back(nAdd);
@@ -179,51 +176,45 @@ struct TRINITY_DLL_DECL boss_priestess_delrissaAI : public ScriptedAI
void CheckAdds()
{
- //if (m_creature->isDead())
- // return;
- if(Adds.empty())
- {
- SummonAdds();
+ if (Adds.empty())
return;
- }
- for(uint8 i = 0; i < Adds.size(); ++i)
+
+ uint32 n = 0;
+ for(std::vector<Add*>::iterator i = Adds.begin(); i != Adds.end(); ++i, ++n)
{
- Creature* pAdd = (Unit::GetCreature(*m_creature, Adds[i]->guid));
+ Creature* pAdd = (Unit::GetCreature(*m_creature, (*i)->guid));
if(pAdd && pAdd->isAlive())
{
- pAdd->AI()->EnterEvadeMode();
- pAdd->GetMotionMaster()->MovePoint(0,LackeyLocations[i][0], LackeyLocations[i][1], POS_Z);
+ pAdd->AI()->EnterEvadeMode(); // Force them out of combat and reset if they are in combat.
}
- if(!pAdd || (pAdd && pAdd->isDead()))
+ else
{
+ pAdd = m_creature->SummonCreature((*i)->entry, LackeyLocations[n][0], LackeyLocations[n][1], POS_Z, ORIENT, TEMPSUMMON_DEAD_DESPAWN, 0);
if(pAdd)
- pAdd->RemoveCorpse();//looks stupid if mob is alive but has a dead corpse in front of him :)
- Creature* pAdd = m_creature->SummonCreature(Adds[i]->entry, LackeyLocations[i][0], LackeyLocations[i][1], POS_Z, ORIENT, TEMPSUMMON_DEAD_DESPAWN, 0);
- if(pAdd)
- Adds[i]->guid = pAdd->GetGUID();
+ (*i)->guid = pAdd->GetGUID();
+ else
+ (*i)->guid = 0;
}
}
}
void KilledUnit(Unit* victim)
{
- if(victim->GetTypeId() != TYPEID_PLAYER || m_creature->isDead())
+ if (victim->GetTypeId() != TYPEID_PLAYER)
return;
DoScriptText(PlayerDeath[PlayersKilled].id, m_creature);
- if( PlayersKilled < 4 )
+
+ if (PlayersKilled < 4)
++PlayersKilled;
}
void KilledLackey()
{
- if(m_creature->isDead())//no sense to talk if dead..
- return;
DoScriptText(LackeyDeath[LackeysKilled].id, m_creature);
- if( LackeysKilled < 3 )
- ++LackeysKilled;
- CheckLootable();
+ if (LackeysKilled < 3)
+ ++LackeysKilled;
}
void JustDied(Unit* killer)
@@ -232,21 +223,21 @@ struct TRINITY_DLL_DECL boss_priestess_delrissaAI : public ScriptedAI
CheckLootable();
- if(!pInstance)
+ if (!pInstance)
{
error_log(ERROR_INST_DATA);
return;
}
- pInstance->SetData(DATA_DELRISSA_DEATH_COUNT, 1);
pInstance->SetData(DATA_DELRISSA_EVENT, DONE);
- if(GameObject* Door = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_DELRISSA_DOOR)))
- Door->SetGoState(0);
+
+ if (GameObject* Door = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_DELRISSA_DOOR)))
+ Door->SetGoState(GO_STATE_ACTIVE);
}
void CheckLootable()
{
- if(pInstance && pInstance->GetData(DATA_DELRISSA_DEATH_COUNT) >= 4)
+ if (LackeysKilled > 3)
m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
else
m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
@@ -254,7 +245,7 @@ struct TRINITY_DLL_DECL boss_priestess_delrissaAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
- if(!UpdateVictim())
+ if (!UpdateVictim())
return;
if(ResetTimer < diff)
@@ -269,27 +260,27 @@ struct TRINITY_DLL_DECL boss_priestess_delrissaAI : public ScriptedAI
ResetTimer = 5000;
}else ResetTimer -= diff;
- if(HealTimer < diff)
+ if (HealTimer < diff)
{
uint32 health = m_creature->GetHealth();
Unit* target = m_creature;
for(uint8 i = 0; i < Adds.size(); ++i)
- if(Unit* pAdd = Unit::GetUnit(*m_creature, Adds[i]->guid))
- if(pAdd->isAlive() && pAdd->GetHealth() < health)
+ if (Unit* pAdd = Unit::GetUnit(*m_creature, Adds[i]->guid))
+ if (pAdd->isAlive() && pAdd->GetHealth() < health)
target = pAdd;
DoCast(target, SPELL_FLASH_HEAL);
HealTimer = 15000;
}else HealTimer -= diff;
- if(RenewTimer < diff)
+ if (RenewTimer < diff)
{
Unit* target = m_creature;
- if(rand()%2 == 1)
+ if (rand()%2 == 1)
{
std::vector<Add*>::iterator itr = Adds.begin() + rand()%Adds.size();
Unit* pAdd = Unit::GetUnit(*m_creature, (*itr)->guid);
- if(pAdd && pAdd->isAlive())
+ if (pAdd && pAdd->isAlive())
target = pAdd;
}
DoCast(target,Heroic ? SPELL_RENEW_HEROIC : SPELL_RENEW_NORMAL);
@@ -299,44 +290,44 @@ struct TRINITY_DLL_DECL boss_priestess_delrissaAI : public ScriptedAI
if(ShieldTimer < diff)
{
Unit* target = m_creature;
- if(rand()%2 == 1)
+ if (rand()%2 == 1)
{
std::vector<Add*>::iterator itr = Adds.begin() + rand()%Adds.size();
- if(Unit* pAdd = Unit::GetUnit(*m_creature, (*itr)->guid))
- if(!pAdd->HasAura(SPELL_SHIELD, 0) && pAdd->isAlive())
+ if (Unit* pAdd = Unit::GetUnit(*m_creature, (*itr)->guid))
+ if (!pAdd->HasAura(SPELL_SHIELD) && pAdd->isAlive())
target = pAdd;
}
DoCast(target, SPELL_SHIELD);
ShieldTimer = 7500;
}else ShieldTimer -= diff;
- if(DispelTimer < diff)
+ if (DispelTimer < diff)
{
Unit* target = NULL;
bool friendly = false;
- if(rand()%2 == 1)
+ if (rand()%2 == 1)
target = SelectUnit(SELECT_TARGET_RANDOM, 0);
else
{
friendly = true;
- if(rand()%2 == 1)
+ if (rand()%2 == 1)
target = m_creature;
else
{
std::vector<Add*>::iterator itr = Adds.begin() + rand()%Adds.size();
Unit* pAdd = Unit::GetUnit(*m_creature, (*itr)->guid);
- if(pAdd && pAdd->isAlive())
+ if (pAdd && pAdd->isAlive())
target = pAdd;
}
}
- if(target)
+ if (target)
{
DoCast(target, SPELL_DISPEL_MAGIC);
DispelTimer = 12000;
}
}else DispelTimer -= diff;
- if(SWPainTimer < diff)
+ if (SWPainTimer < diff)
{
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0),Heroic ? SPELL_SW_PAIN_HEROIC : SPELL_SW_PAIN_NORMAL);
SWPainTimer = 10000;
@@ -382,59 +373,55 @@ struct TRINITY_DLL_DECL boss_priestess_guestAI : public ScriptedAI
void Reset()
{
UsedPotion = false;
- if(pInstance)
- {
- Creature *boss = (Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_DELRISSA)));
- if (boss && boss->isDead())
- boss->Respawn();
- }
+
ResetThreatTimer = 5000 + rand()%15000; // These guys like to switch targets often, and are not meant to be tanked.
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void JustDied(Unit* killer)
{
- if(!pInstance)
+ if (!pInstance)
{
error_log(ERROR_INST_DATA);
return;
}
Creature* Delrissa = (Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_DELRISSA)));
- if(Delrissa)
+ if (Delrissa)
{
+ pInstance->SetData(DATA_DELRISSA_DEATH_COUNT, 1);
+
((boss_priestess_delrissaAI*)Delrissa->AI())->KilledLackey();
- if(!Delrissa->isAlive() && pInstance->GetData(DATA_DELRISSA_DEATH_COUNT) > 3)
- ((boss_priestess_delrissaAI*)Delrissa->AI())->CheckLootable();
- pInstance->SetData(DATA_DELRISSA_DEATH_COUNT, 1);
+ if (!Delrissa->isAlive() && pInstance->GetData(DATA_DELRISSA_DEATH_COUNT) > 3)
+ Delrissa->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
}
}
void KilledUnit(Unit* victim)
{
- if(!pInstance)
+ if (!pInstance)
{
error_log(ERROR_INST_DATA);
return;
}
Creature* Delrissa = (Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_DELRISSA)));
- if(Delrissa)
+ if (Delrissa)
Delrissa->AI()->KilledUnit(victim);
}
void AcquireGUIDs()
{
- if(!pInstance)
+ if (!pInstance)
{
error_log(ERROR_INST_DATA);
return;
}
Creature* Delrissa = (Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_DELRISSA)));
- if(Delrissa)
+ if (Delrissa)
{
Group = ((boss_priestess_delrissaAI*)Delrissa->AI())->Adds;
Add* dAdd = new Add(Delrissa->GetEntry(), Delrissa->GetGUID());
@@ -444,13 +431,13 @@ struct TRINITY_DLL_DECL boss_priestess_guestAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
- if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 25) && !UsedPotion)
+ if (((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 25) && !UsedPotion)
{
DoCast(m_creature, SPELL_HEALING_POTION, true);
UsedPotion = true;
}
- if(ResetThreatTimer < diff)
+ if (ResetThreatTimer < diff)
{
DoResetThreat();
ResetThreatTimer = 5000 + rand()%15000;
@@ -492,12 +479,12 @@ struct TRINITY_DLL_DECL boss_kagani_nightstrikeAI : public boss_priestess_guestA
void UpdateAI(const uint32 diff)
{
- if(!UpdateVictim() )
+ if (!UpdateVictim())
return;
boss_priestess_guestAI::UpdateAI(diff);
- if(Vanish_Timer < diff)
+ if (Vanish_Timer < diff)
{
m_creature->SetVisibility(VISIBILITY_OFF); // ...? Hacklike
DoCast(m_creature, SPELL_VANISH);
@@ -508,35 +495,36 @@ struct TRINITY_DLL_DECL boss_kagani_nightstrikeAI : public boss_priestess_guestA
m_creature->AddThreat(SelectUnit(SELECT_TARGET_RANDOM, 0), 1000.0f);
}else Vanish_Timer -= diff;
- if(InVanish)
- if(Wait_Timer < diff)
+ if (InVanish)
{
- DoCast(m_creature->getVictim(), SPELL_BACKSTAB, true);
- DoCast(m_creature->getVictim(), SPELL_KIDNEY_SHOT, true);
- m_creature->SetVisibility(VISIBILITY_ON); // ...? Hacklike
- InVanish = false;
- }else Wait_Timer -= diff;
+ if (Wait_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_BACKSTAB, true);
+ DoCast(m_creature->getVictim(), SPELL_KIDNEY_SHOT, true);
+ m_creature->SetVisibility(VISIBILITY_ON); // ...? Hacklike
+ InVanish = false;
+ }else Wait_Timer -= diff;
+ }
- if(Gouge_Timer < diff)
+ if (Gouge_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_GOUGE);
- DoModifyThreatPercent(m_creature->getVictim(),-100);
Gouge_Timer = 5500;
}else Gouge_Timer -= diff;
- if(Kick_Timer < diff)
+ if (Kick_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_KICK);
Kick_Timer = 7000;
}else Kick_Timer -= diff;
- if(Eviscerate_Timer < diff)
+ if (Eviscerate_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_EVISCERATE);
Eviscerate_Timer = 4000;
}else Eviscerate_Timer -= diff;
- if(!InVanish)
+ if (!InVanish)
DoMeleeAttackIfReady();
}
};
@@ -564,11 +552,12 @@ struct TRINITY_DLL_DECL boss_kagani_nightstrikeAI : public boss_priestess_guestA
void KilledUnit(Unit* victim);
void JustDied(Unit* killer);
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void UpdateAI(const uint32 diff)
{
- if (!UpdateVictim() )
+ //Return since we have no target
+ if (!UpdateVictim())
return;
//Chain cast
@@ -581,9 +570,7 @@ struct TRINITY_DLL_DECL boss_kagani_nightstrikeAI : public boss_priestess_guestA
struct TRINITY_DLL_DECL boss_ellris_duskhallowAI : public boss_priestess_guestAI
{
//Warlock
- boss_ellris_duskhallowAI(Creature *c) : boss_priestess_guestAI(c)
- {
- }
+ boss_ellris_duskhallowAI(Creature *c) : boss_priestess_guestAI(c) {}
bool HasSummonedImp;
@@ -595,7 +582,7 @@ struct TRINITY_DLL_DECL boss_ellris_duskhallowAI : public boss_priestess_guestAI
void Reset()
{
- //HasSummonedImp = false;
+ HasSummonedImp = false;
Immolate_Timer = 6000;
Shadow_Bolt_Timer = 3000;
@@ -613,51 +600,49 @@ struct TRINITY_DLL_DECL boss_ellris_duskhallowAI : public boss_priestess_guestAI
void UpdateAI(const uint32 diff)
{
- if(!HasSummonedImp)
+ if (!HasSummonedImp)
{
//Imp will not despawn unless it's killed, even if owner dies, this is correct way.
DoCast(m_creature,SPELL_SUMMON_IMP);
HasSummonedImp = true;
}
- if(!UpdateVictim() )
+ if (!UpdateVictim())
return;
boss_priestess_guestAI::UpdateAI(diff);
- if(Immolate_Timer < diff)
+ if (Immolate_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_IMMOLATE);
Immolate_Timer = 6000;
}else Immolate_Timer -= diff;
- if(Shadow_Bolt_Timer < diff)
+ if (Shadow_Bolt_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_SHADOW_BOLT);
Shadow_Bolt_Timer = 5000;
}else Shadow_Bolt_Timer -= diff;
- if(Seed_of_Corruption_Timer < diff)
+ if (Seed_of_Corruption_Timer < diff)
{
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_SEED_OF_CORRUPTION);
Seed_of_Corruption_Timer = 10000;
}else Seed_of_Corruption_Timer -= diff;
- if(Curse_of_Agony_Timer < diff)
+ if (Curse_of_Agony_Timer < diff)
{
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_CURSE_OF_AGONY);
Curse_of_Agony_Timer = 13000;
}else Curse_of_Agony_Timer -= diff;
- if(Fear_Timer < diff)
+ if (Fear_Timer < diff)
{
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FEAR);
Fear_Timer = 10000;
}else Fear_Timer -= diff;
- if (m_creature->GetDistance(m_creature->getVictim()) <= 10)
- m_creature->StopMoving();
- //DoMeleeAttackIfReady();//should not melee, she's a warlock
+ DoMeleeAttackIfReady();
}
};
@@ -694,18 +679,18 @@ struct TRINITY_DLL_DECL boss_eramas_brightblazeAI : public boss_priestess_guestA
void UpdateAI(const uint32 diff)
{
- if(!UpdateVictim() )
+ if (!UpdateVictim())
return;
boss_priestess_guestAI::UpdateAI(diff);
- if(Knockdown_Timer < diff)
+ if (Knockdown_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_KNOCKDOWN);
Knockdown_Timer = 6000;
}else Knockdown_Timer -= diff;
- if(Snap_Kick_Timer < diff)
+ if (Snap_Kick_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_SNAP_KICK);
Snap_Kick_Timer = 4500;
@@ -726,7 +711,7 @@ struct TRINITY_DLL_DECL boss_eramas_brightblazeAI : public boss_priestess_guestA
struct TRINITY_DLL_DECL boss_yazzaiAI : public boss_priestess_guestAI
{
//Mage
- boss_yazzaiAI(Creature *c) : boss_priestess_guestAI(c) {}
+ boss_yazzaiAI(Creature *c) : boss_priestess_guestAI(c) {}
bool HasIceBlocked;
@@ -757,82 +742,75 @@ struct TRINITY_DLL_DECL boss_yazzaiAI : public boss_priestess_guestAI
void UpdateAI(const uint32 diff)
{
- if(!UpdateVictim() )
+ if (!UpdateVictim())
return;
boss_priestess_guestAI::UpdateAI(diff);
- if(Polymorph_Timer < diff)
+ if (Polymorph_Timer < diff)
{
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
DoCast(target, SPELL_POLYMORPH);
- DoModifyThreatPercent(target,-100);
Polymorph_Timer = 20000;
}
}else Polymorph_Timer -= diff;
- if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 35) && !HasIceBlocked)
+ if (((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 35) && !HasIceBlocked)
{
DoCast(m_creature, SPELL_ICE_BLOCK);
HasIceBlocked = true;
}
- if(Blizzard_Timer < diff)
+ if (Blizzard_Timer < diff)
{
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_BLIZZARD);
Blizzard_Timer = 8000;
}else Blizzard_Timer -= diff;
- if(Ice_Lance_Timer < diff)
+ if (Ice_Lance_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_ICE_LANCE);
Ice_Lance_Timer = 12000;
}else Ice_Lance_Timer -= diff;
- if(Cone_of_Cold_Timer < diff)
+ if (Cone_of_Cold_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_CONE_OF_COLD);
Cone_of_Cold_Timer = 10000;
}else Cone_of_Cold_Timer -= diff;
- if(Frostbolt_Timer < diff)
+ if (Frostbolt_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_FROSTBOLT);
Frostbolt_Timer = 8000;
}else Frostbolt_Timer -= diff;
- if(Blink_Timer < diff)
+ if (Blink_Timer < diff)
{
bool InMeleeRange = false;
std::list<HostilReference*>& t_list = m_creature->getThreatManager().getThreatList();
for(std::list<HostilReference*>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
{
- if(Unit* target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()))
+ if (Unit* target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()))
+ {
//if in melee range
if (target->IsWithinDistInMap(m_creature, 5))
{
InMeleeRange = true;
break;
}
+ }
}
+
//if anybody is in melee range than escape by blink
- if(InMeleeRange)
- {
- //DoCast(m_creature, SPELL_BLINK); //blink does not work on npcs
- float x,y,z;
- m_creature->GetPosition(x,y,z);
- x = rand()%2 ? x+10+rand()%10 : x-10-rand()%10;
- y = rand()%2 ? y+10+rand()%10 : y-10-rand()%10;
- DoTeleportTo(x, y, z);
- }
+ if (InMeleeRange)
+ DoCast(m_creature, SPELL_BLINK);
+
Blink_Timer = 8000;
}else Blink_Timer -= diff;
- if (m_creature->getVictim() && m_creature->GetDistance(m_creature->getVictim()) <= 10)
- m_creature->StopMoving();
-
- //DoMeleeAttackIfReady(); //mage type, no melee needed
+ DoMeleeAttackIfReady();
}
};
@@ -865,66 +843,71 @@ struct TRINITY_DLL_DECL boss_warlord_salarisAI : public boss_priestess_guestAI
Hamstring_Timer = 4500;
Mortal_Strike_Timer = 8000;
DoCast(m_creature, SPELL_BATTLE_SHOUT);
+
boss_priestess_guestAI::Reset();
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
DoCast(m_creature, SPELL_BATTLE_SHOUT);
}
void UpdateAI(const uint32 diff)
{
- if(!UpdateVictim() )
+ if (!UpdateVictim())
return;
boss_priestess_guestAI::UpdateAI(diff);
- if(Intercept_Stun_Timer < diff)
+ if (Intercept_Stun_Timer < diff)
{
bool InMeleeRange = false;
std::list<HostilReference*>& t_list = m_creature->getThreatManager().getThreatList();
for(std::list<HostilReference*>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
{
- if(Unit* target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()))
- //if in melee range
- if (target->IsWithinDistInMap(m_creature, 5))
+ if (Unit* target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()))
{
- InMeleeRange = true;
- break;
+ //if in melee range
+ if (target->IsWithinDistInMap(m_creature, 5))
+ {
+ InMeleeRange = true;
+ break;
+ }
}
}
+
//if nobody is in melee range than try to use Intercept
- if(!InMeleeRange)
+ if (!InMeleeRange)
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_INTERCEPT_STUN);
+
Intercept_Stun_Timer = 10000;
}else Intercept_Stun_Timer -= diff;
- if(Disarm_Timer < diff)
+ if (Disarm_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_DISARM);
Disarm_Timer = 6000;
}else Disarm_Timer -= diff;
- if(Hamstring_Timer < diff)
+ if (Hamstring_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_HAMSTRING);
Hamstring_Timer = 4500;
}else Hamstring_Timer -= diff;
- if(Mortal_Strike_Timer < diff)
+ if (Mortal_Strike_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_MORTAL_STRIKE);
Mortal_Strike_Timer = 4500;
}else Mortal_Strike_Timer -= diff;
- if(Piercing_Howl_Timer < diff)
+ if (Piercing_Howl_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_PIERCING_HOWL);
Piercing_Howl_Timer = 10000;
}else Piercing_Howl_Timer -= diff;
- if(Frightening_Shout_Timer < diff)
+ if (Frightening_Shout_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_FRIGHTENING_SHOUT);
Frightening_Shout_Timer = 18000;
@@ -955,7 +938,7 @@ struct TRINITY_DLL_DECL boss_warlord_salarisAI : public boss_priestess_guestAI
void KilledUnit(Unit* victim);
void JustDied(Unit* killer);
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
};*/
@@ -973,13 +956,11 @@ struct TRINITY_DLL_DECL boss_garaxxasAI : public boss_priestess_guestAI
uint32 Multi_Shot_Timer;
uint32 Wing_Clip_Timer;
uint32 Freezing_Trap_Timer;
- uint32 StopMoving;
- bool Stopped;
void Reset()
{
//SliverGUID = 0;
- //HasSummonedSliver = false;
+ HasSummonedSliver = false;
Aimed_Shot_Timer = 6000;
Shoot_Timer = 2500;
@@ -987,8 +968,6 @@ struct TRINITY_DLL_DECL boss_garaxxasAI : public boss_priestess_guestAI
Multi_Shot_Timer = 10000;
Wing_Clip_Timer = 4000;
Freezing_Trap_Timer = 15000;
- StopMoving = 2000;
- Stopped = false;
boss_priestess_guestAI::Reset();
}
@@ -1000,10 +979,10 @@ struct TRINITY_DLL_DECL boss_garaxxasAI : public boss_priestess_guestAI
void UpdateAI(const uint32 diff)
{
- if(!HasSummonedSliver)
+ if (!HasSummonedSliver)
{
Creature* Sliver = m_creature->SummonCreature(CREATURE_SLIVER, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
- if(Sliver)
+ if (Sliver)
{
//((mob_sliverAI*)Sliver->AI())->GaraxxasGUID = m_creature->GetGUID();
//SliverGUID = Sliver->GetGUID();
@@ -1011,64 +990,53 @@ struct TRINITY_DLL_DECL boss_garaxxasAI : public boss_priestess_guestAI
}
}
- if(!UpdateVictim() )
+ if (!UpdateVictim())
return;
boss_priestess_guestAI::UpdateAI(diff);
- if(m_creature->IsWithinDistInMap(m_creature->getVictim(), 5))
+ if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 5.0f))
{
- if(Wing_Clip_Timer < diff)
+ if (Wing_Clip_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_WING_CLIP);
Wing_Clip_Timer = 4000;
}else Wing_Clip_Timer -= diff;
- if(Freezing_Trap_Timer < diff)
+ if (Freezing_Trap_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_FREEZING_TRAP);
- DoModifyThreatPercent(m_creature->getVictim(),-100);
Freezing_Trap_Timer = 30000;
}else Freezing_Trap_Timer -= diff;
- if(!m_creature->getVictim()->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT | UNIT_STAT_CONFUSED | UNIT_STAT_DISTRACTED))
- DoMeleeAttackIfReady();
- }else
+ DoMeleeAttackIfReady();
+ }
+ else
{
- if(Concussive_Shot_Timer < diff)
+ if (Concussive_Shot_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_CONCUSSIVE_SHOT);
Concussive_Shot_Timer = 8000;
}else Concussive_Shot_Timer -= diff;
- if(Multi_Shot_Timer < diff)
+ if (Multi_Shot_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_MULTI_SHOT);
Multi_Shot_Timer = 10000;
}else Multi_Shot_Timer -= diff;
- if(Aimed_Shot_Timer < diff)
+ if (Aimed_Shot_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_AIMED_SHOT);
Aimed_Shot_Timer = 6000;
}else Aimed_Shot_Timer -= diff;
- if(Shoot_Timer < diff)
+ if (Shoot_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_SHOOT);
Shoot_Timer = 2500;
}else Shoot_Timer -= diff;
}
- if(StopMoving < diff)
- {
- if(Stopped)
- Stopped = false;
- else
- Stopped = true;
- StopMoving = 2000+rand()%5000;
- }else StopMoving -= diff;
- if (Stopped)
- m_creature->StopMoving();
}
};
@@ -1118,12 +1086,12 @@ struct TRINITY_DLL_DECL boss_apokoAI : public boss_priestess_guestAI
void UpdateAI(const uint32 diff)
{
- if(!UpdateVictim() )
+ if (!UpdateVictim())
return;
boss_priestess_guestAI::UpdateAI(diff);
- if(Totem_Timer < diff)
+ if (Totem_Timer < diff)
{
switch(rand()%3)
{
@@ -1135,25 +1103,25 @@ struct TRINITY_DLL_DECL boss_apokoAI : public boss_priestess_guestAI
Totem_Timer = Totem_Amount*2000;
}else Totem_Timer -= diff;
- if(War_Stomp_Timer < diff)
+ if (War_Stomp_Timer < diff)
{
DoCast(m_creature, SPELL_WAR_STOMP);
War_Stomp_Timer = 10000;
}else War_Stomp_Timer -= diff;
- if(Purge_Timer < diff)
+ if (Purge_Timer < diff)
{
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_PURGE);
Purge_Timer = 15000;
}else Purge_Timer -= diff;
- if(Frost_Shock_Timer < diff)
+ if (Frost_Shock_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_FROST_SHOCK);
Frost_Shock_Timer = 7000;
}else Frost_Shock_Timer -= diff;
- if(Healing_Wave_Timer < diff)
+ if (Healing_Wave_Timer < diff)
{
// std::vector<Add*>::iterator itr = Group.begin() + rand()%Group.size();
// uint64 guid = (*itr)->guid;
@@ -1205,44 +1173,45 @@ struct TRINITY_DLL_DECL boss_zelfanAI : public boss_priestess_guestAI
void UpdateAI(const uint32 diff)
{
- if(!UpdateVictim() )
+ if (!UpdateVictim())
return;
boss_priestess_guestAI::UpdateAI(diff);
- if(Goblin_Dragon_Gun_Timer < diff)
+ if (Goblin_Dragon_Gun_Timer < diff)
{
- if (m_creature->GetDistance(m_creature->getVictim()) <= 5)
- {
- Goblin_Dragon_Gun_Timer = 10000;
- DoCast(m_creature->getVictim(), SPELL_GOBLIN_DRAGON_GUN);
- }else Goblin_Dragon_Gun_Timer = 2000;
+ DoCast(m_creature->getVictim(), SPELL_GOBLIN_DRAGON_GUN);
+ Goblin_Dragon_Gun_Timer = 10000;
}else Goblin_Dragon_Gun_Timer -= diff;
- if(Rocket_Launch_Timer < diff)
+ if (Rocket_Launch_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_ROCKET_LAUNCH);
Rocket_Launch_Timer = 9000;
}else Rocket_Launch_Timer -= diff;
- if(Fel_Iron_Bomb_Timer < diff)
+ if (Fel_Iron_Bomb_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_FEL_IRON_BOMB);
Fel_Iron_Bomb_Timer = 15000;
}else Fel_Iron_Bomb_Timer -= diff;
- if(Recombobulate_Timer < diff)
+ if (Recombobulate_Timer < diff)
{
for(uint8 i = 0; i < Group.size(); ++i)
- if(Unit* pAdd = Unit::GetUnit(*m_creature, Group[i]->guid))
- if(pAdd->IsPolymorphed())
+ {
+ if (Unit* pAdd = Unit::GetUnit(*m_creature, Group[i]->guid))
+ {
+ if (pAdd->IsPolymorphed())
{
DoCast(pAdd, SPELL_RECOMBOBULATE);
break;
}
+ }
+ }
}else Recombobulate_Timer -= diff;
- if(High_Explosive_Sheep_Timer < diff)
+ if (High_Explosive_Sheep_Timer < diff)
{
DoCast(m_creature, SPELL_HIGH_EXPLOSIVE_SHEEP);
High_Explosive_Sheep_Timer = 65000;
@@ -1265,7 +1234,7 @@ struct TRINITY_DLL_DECL boss_zelfanAI : public boss_priestess_guestAI
//
// void JustDied(Unit *Killer){}
//
-// void Aggro(Unit *who){}
+// void EnterCombat(Unit *who){}
//
// void UpdateAI(const uint32 diff)
// {
@@ -1342,62 +1311,62 @@ void AddSC_boss_priestess_delrissa()
Script *newscript;
newscript = new Script;
- newscript->Name="boss_priestess_delrissa";
+ newscript->Name = "boss_priestess_delrissa";
newscript->GetAI = &GetAI_boss_priestess_delrissa;
newscript->RegisterSelf();
newscript = new Script;
- newscript->Name="boss_kagani_nightstrike";
+ newscript->Name = "boss_kagani_nightstrike";
newscript->GetAI = &GetAI_boss_kagani_nightstrike;
newscript->RegisterSelf();
newscript = new Script;
- newscript->Name="boss_ellris_duskhallow";
+ newscript->Name = "boss_ellris_duskhallow";
newscript->GetAI = &GetAI_ellris_duskhallow;
newscript->RegisterSelf();
newscript = new Script;
- newscript->Name="boss_eramas_brightblaze";
+ newscript->Name = "boss_eramas_brightblaze";
newscript->GetAI = &GetAI_eramas_brightblaze;
newscript->RegisterSelf();
newscript = new Script;
- newscript->Name="boss_yazzai";
+ newscript->Name = "boss_yazzai";
newscript->GetAI = &GetAI_yazzai;
newscript->RegisterSelf();
newscript = new Script;
- newscript->Name="boss_warlord_salaris";
+ newscript->Name = "boss_warlord_salaris";
newscript->GetAI = &GetAI_warlord_salaris;
newscript->RegisterSelf();
newscript = new Script;
- newscript->Name="boss_garaxxas";
+ newscript->Name = "boss_garaxxas";
newscript->GetAI = &GetAI_garaxxas;
newscript->RegisterSelf();
newscript = new Script;
- newscript->Name="boss_apoko";
+ newscript->Name = "boss_apoko";
newscript->GetAI = &GetAI_apoko;
newscript->RegisterSelf();
newscript = new Script;
- newscript->Name="boss_zelfan";
+ newscript->Name = "boss_zelfan";
newscript->GetAI = &GetAI_zelfan;
newscript->RegisterSelf();
/*newscript = new Script;
- newscript->Name="mob_high_explosive_sheep";
+ newscript->Name = "mob_high_explosive_sheep";
newscript->GetAI = &GetAI_mob_high_explosive_sheep;
newscript->RegisterSelf();*/
/*newscript = new Script;
- newscript->Name="mob_fizzle";
+ newscript->Name = "mob_fizzle";
newscript->GetAI = &GetAI_mob_fizzle;
newscript->RegisterSelf();*/
/*newscript = new Script;
- newscript->Name="mob_sliver";
+ newscript->Name = "mob_sliver";
newscript->GetAI = &GetAI_mob_sliver;
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 a56d6a4dd3d..d057f0d8932 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -6,12 +6,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
*/
/* ScriptData
@@ -32,7 +32,7 @@ EndScriptData */
#define SAY_DEATH -1585005
#define EMOTE_CRYSTAL -1585006
-//Crystal efect spells
+//Crystal effect spells
#define SPELL_FEL_CRYSTAL_COSMETIC 44374
#define SPELL_FEL_CRYSTAL_DUMMY 44329
#define SPELL_FEL_CRYSTAL_VISUAL 44355
@@ -56,8 +56,8 @@ struct TRINITY_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
pInstance = ((ScriptedInstance*)c->GetInstanceData());
Crystals.clear();
- // GUIDs per instance is static, so we only need to load them once.
- if(pInstance)
+ //GUIDs per instance is static, so we only need to load them once.
+ if (pInstance)
{
uint32 size = pInstance->GetData(DATA_FEL_CRYSTAL_SIZE);
for(uint8 i = 0; i < size; ++i)
@@ -71,6 +71,7 @@ struct TRINITY_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
}
ScriptedInstance* pInstance;
+ bool Heroic;
std::list<uint64> Crystals;
@@ -78,23 +79,23 @@ struct TRINITY_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
uint32 DrainManaTimer;
uint32 FelExplosionTimer;
uint32 DrainCrystalTimer;
- uint32 CheckTimer;
+ uint32 EmpowerTimer;
bool IsDraining;
bool DrainingCrystal;
- bool Heroic;
+
uint64 CrystalGUID; // This will help us create a pointer to the crystal we are draining. We store GUIDs, never units in case unit is deleted/offline (offline if player of course).
void Reset()
{
- if(pInstance)
+ if (pInstance)
{
//for(uint8 i = 0; i < CRYSTALS_NUMBER; ++i)
for(std::list<uint64>::iterator itr = Crystals.begin(); itr != Crystals.end(); ++itr)
{
//Unit* pUnit = Unit::GetUnit(*m_creature, FelCrystals[i]);
Unit* pUnit = Unit::GetUnit(*m_creature, *itr);
- if(pUnit)
+ if (pUnit)
{
if(!pUnit->isAlive())
((Creature*)pUnit)->Respawn(); // Let MaNGOS handle setting death state, etc.
@@ -103,14 +104,13 @@ struct TRINITY_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
pUnit->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
}
+
GameObject* Door = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_SELIN_ENCOUNTER_DOOR));
- if( Door )
- Door->SetGoState(0); // Open the big encounter door. Close it in Aggro and open it only in JustDied(and here)
+ if (Door)
+ Door->SetGoState(GO_STATE_ACTIVE); // Open the big encounter door. Close it in Aggro and open it only in JustDied(and here)
// Small door opened after event are expected to be closed by default
// Set Inst data for encounter
- if (m_creature->isDead())
- pInstance->SetData(DATA_SELIN_EVENT, DONE);
- else pInstance->SetData(DATA_SELIN_EVENT, NOT_STARTED);
+ pInstance->SetData(DATA_SELIN_EVENT, NOT_STARTED);
}else error_log(ERROR_INST_DATA);
DrainLifeTimer = 3000 + rand()%4000;
@@ -118,7 +118,7 @@ struct TRINITY_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
FelExplosionTimer = 2100;
DrainCrystalTimer = 10000 + rand()%5000;
DrainCrystalTimer = 20000 + rand()%5000;
- CheckTimer = 1000;
+ EmpowerTimer = 10000;
IsDraining = false;
DrainingCrystal = false;
@@ -127,7 +127,7 @@ struct TRINITY_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
void SelectNearestCrystal()
{
- if(Crystals.empty())
+ if (Crystals.empty())
return;
float ShortestDistance = 0;
@@ -140,9 +140,9 @@ struct TRINITY_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
pCrystal = NULL;
//pCrystal = Unit::GetUnit(*m_creature, FelCrystals[i]);
pCrystal = Unit::GetUnit(*m_creature, *itr);
- if(pCrystal && pCrystal->isAlive())
+ if (pCrystal && pCrystal->isAlive())
{
- if(!ShortestDistance || (ShortestDistance > m_creature->GetDistance2d(pCrystal)))
+ if (!ShortestDistance || (ShortestDistance > m_creature->GetDistance2d(pCrystal)))
{
ShortestDistance = m_creature->GetDistance2d(pCrystal);
CrystalGUID = pCrystal->GetGUID();
@@ -150,7 +150,7 @@ struct TRINITY_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
}
}
}
- if( CrystalChosen )
+ if (CrystalChosen)
{
DoScriptText(SAY_ENERGY, m_creature);
DoScriptText(EMOTE_CRYSTAL, m_creature);
@@ -168,7 +168,7 @@ struct TRINITY_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
void ShatterRemainingCrystals()
{
- if(Crystals.empty())
+ if (Crystals.empty())
return;
//for(uint8 i = 0; i < CRYSTALS_NUMBER; ++i)
@@ -176,21 +176,20 @@ struct TRINITY_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
{
//Creature* pCrystal = (Unit::GetCreature(*m_creature, FelCrystals[i]));
Creature* pCrystal = (Unit::GetCreature(*m_creature, *itr));
- if( pCrystal && pCrystal->isAlive())
+ if (pCrystal && pCrystal->isAlive())
pCrystal->DealDamage(pCrystal, pCrystal->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
- m_creature->SetPower(POWER_MANA, 0);
DoScriptText(SAY_AGGRO, m_creature);
- if( pInstance )
+ if (pInstance)
{
GameObject* EncounterDoor = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_SELIN_ENCOUNTER_DOOR));
- if( EncounterDoor )
- EncounterDoor->SetGoState(1); //Close the encounter door, open it in JustDied/Reset
+ if (EncounterDoor)
+ EncounterDoor->SetGoState(GO_STATE_READY); //Close the encounter door, open it in JustDied/Reset
}
}
@@ -198,17 +197,17 @@ struct TRINITY_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
{
switch(rand()%2)
{
- case 0: DoScriptText(SAY_KILL_1, m_creature); break;
- case 1: DoScriptText(SAY_KILL_2, m_creature); break;
+ case 0: DoScriptText(SAY_KILL_1, m_creature); break;
+ case 1: DoScriptText(SAY_KILL_2, m_creature); break;
}
}
void MovementInform(uint32 type, uint32 id)
{
- if(type == POINT_MOTION_TYPE && id == 1)
+ if (type == POINT_MOTION_TYPE && id == 1)
{
Unit* CrystalChosen = Unit::GetUnit(*m_creature, CrystalGUID);
- if(CrystalChosen && CrystalChosen->isAlive())
+ if (CrystalChosen && CrystalChosen->isAlive())
{
// Make the crystal attackable
// We also remove NON_ATTACKABLE in case the database has it set.
@@ -229,7 +228,7 @@ struct TRINITY_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
{
DoScriptText(SAY_DEATH, m_creature);
- if(!pInstance)
+ if (!pInstance)
{
error_log(ERROR_INST_DATA);
return;
@@ -238,35 +237,36 @@ struct TRINITY_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
pInstance->SetData(DATA_SELIN_EVENT, DONE); // Encounter complete!
GameObject* EncounterDoor = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_SELIN_ENCOUNTER_DOOR));
- if( EncounterDoor )
- EncounterDoor->SetGoState(0); // Open the encounter door
+ if (EncounterDoor)
+ EncounterDoor->SetGoState(GO_STATE_ACTIVE); // Open the encounter door
GameObject* ContinueDoor = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_SELIN_DOOR));
- if( ContinueDoor )
- ContinueDoor->SetGoState(0); // Open the door leading further in
+ if (ContinueDoor)
+ ContinueDoor->SetGoState(GO_STATE_ACTIVE); // Open the door leading further in
+ ShatterRemainingCrystals();
}
void UpdateAI(const uint32 diff)
{
- if(!UpdateVictim())
+ if (!UpdateVictim())
return;
- if(!DrainingCrystal)
+ if (!DrainingCrystal)
{
uint32 maxPowerMana = m_creature->GetMaxPower(POWER_MANA);
- if( maxPowerMana && ((m_creature->GetPower(POWER_MANA)*100 / maxPowerMana) < 10) )
+ if (maxPowerMana && ((m_creature->GetPower(POWER_MANA)*100 / maxPowerMana) < 10))
{
- if( DrainLifeTimer < diff )
+ if (DrainLifeTimer < diff)
{
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DRAIN_LIFE);
DrainLifeTimer = 10000;
}else DrainLifeTimer -= diff;
// Heroic only
- if( Heroic )
+ if (Heroic)
{
- if( DrainManaTimer < diff )
+ if (DrainManaTimer < diff)
{
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DRAIN_MANA);
DrainManaTimer = 10000;
@@ -274,9 +274,9 @@ struct TRINITY_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
}
}
- if( FelExplosionTimer < diff )
+ if (FelExplosionTimer < diff)
{
- if(!m_creature->IsNonMeleeSpellCasted(false))
+ if (!m_creature->IsNonMeleeSpellCasted(false))
{
DoCast(m_creature, SPELL_FEL_EXPLOSION);
FelExplosionTimer = 2000;
@@ -285,48 +285,40 @@ struct TRINITY_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
// If below 10% mana, start recharging
maxPowerMana = m_creature->GetMaxPower(POWER_MANA);
- if( maxPowerMana && ((m_creature->GetPower(POWER_MANA)*100 / maxPowerMana) < 10) )
+ if (maxPowerMana && ((m_creature->GetPower(POWER_MANA)*100 / maxPowerMana) < 10))
{
- if(DrainCrystalTimer < diff)
+ if (DrainCrystalTimer < diff)
{
SelectNearestCrystal();
- if(Heroic) DrainCrystalTimer = 10000 + rand()%5000;
- else DrainCrystalTimer = 20000 + rand()%5000;
+ if (Heroic) DrainCrystalTimer = 10000 + rand()%5000;
+ else DrainCrystalTimer = 20000 + rand()%5000;
}else DrainCrystalTimer -= diff;
}
}else
{
- if( IsDraining )
+ if (IsDraining)
{
- if (CheckTimer < diff)
+ if (EmpowerTimer < diff)
{
+ IsDraining = false;
+ DrainingCrystal = false;
+
+ DoScriptText(SAY_EMPOWERED, m_creature);
+
Unit* CrystalChosen = Unit::GetUnit(*m_creature, CrystalGUID);
- if(CrystalChosen)
- {
- if(CrystalChosen->GetUInt32Value(UNIT_CHANNEL_SPELL) == SPELL_MANA_RAGE)
- {
- m_creature->StopMoving();
- }else{
- IsDraining = false;
- DrainingCrystal = false;
-
- DoScriptText(SAY_EMPOWERED, m_creature);
-
- Unit* CrystalChosen = Unit::GetUnit(*m_creature, CrystalGUID);
- if( CrystalChosen && CrystalChosen->isAlive() )
- // Use Deal Damage to kill it, not setDeathState.
- CrystalChosen->DealDamage(CrystalChosen, CrystalChosen->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- CrystalGUID = 0;
-
- m_creature->GetMotionMaster()->Clear();
- m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
- }
- }
- CheckTimer = 1000;
- }else CheckTimer -= diff;
+ if (CrystalChosen && CrystalChosen->isAlive())
+ // Use Deal Damage to kill it, not setDeathState.
+ CrystalChosen->DealDamage(CrystalChosen, CrystalChosen->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+
+ CrystalGUID = 0;
+
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ }else EmpowerTimer -= diff;
}
}
+
DoMeleeAttackIfReady(); // No need to check if we are draining crystal here, as the spell has a stun.
}
};
@@ -341,26 +333,25 @@ struct TRINITY_DLL_DECL mob_fel_crystalAI : public ScriptedAI
mob_fel_crystalAI(Creature *c) : ScriptedAI(c) {}
void Reset() {}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff) {}
void JustDied(Unit* killer)
{
- m_creature->RemoveAurasDueToSpell(SPELL_MANA_RAGE);
- if(ScriptedInstance* pInstance = ((ScriptedInstance*)m_creature->GetInstanceData()))
+ if (ScriptedInstance* pInstance = ((ScriptedInstance*)m_creature->GetInstanceData()))
{
Creature* Selin = (Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_SELIN)));
- if(Selin && Selin->isAlive())
+ if (Selin && Selin->isAlive())
{
- if(((boss_selin_fireheartAI*)Selin->AI())->CrystalGUID == m_creature->GetGUID())
+ if (((boss_selin_fireheartAI*)Selin->AI())->CrystalGUID == m_creature->GetGUID())
{
// Set this to false if we are the creature that Selin is draining so his AI flows properly
((boss_selin_fireheartAI*)Selin->AI())->DrainingCrystal = false;
((boss_selin_fireheartAI*)Selin->AI())->IsDraining = false;
- Selin->RemoveAurasDueToSpell(SPELL_MANA_RAGE);
- if(Selin->getVictim())
+ ((boss_selin_fireheartAI*)Selin->AI())->EmpowerTimer = 10000;
+ if (Selin->getVictim())
{
Selin->AI()->AttackStart(Selin->getVictim());
Selin->GetMotionMaster()->MoveChase(Selin->getVictim());
@@ -381,12 +372,12 @@ void AddSC_boss_selin_fireheart()
Script *newscript;
newscript = new Script;
- newscript->Name="boss_selin_fireheart";
+ newscript->Name = "boss_selin_fireheart";
newscript->GetAI = &GetAI_boss_selin_fireheart;
newscript->RegisterSelf();
newscript = new Script;
- newscript->Name="mob_fel_crystal";
+ newscript->Name = "mob_fel_crystal";
newscript->GetAI = &GetAI_mob_fel_crystal;
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 3743423f0e0..6d8bea0a24c 100644
--- a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_vexallus.cpp
+++ b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_vexallus.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -6,12 +6,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
*/
/* ScriptData
@@ -29,31 +29,36 @@ EndScriptData */
#define SAY_OVERLOAD -1585009
#define SAY_KILL -1585010
#define EMOTE_DISCHARGE_ENERGY -1585011
+
//is this text for real?
-#define SAY_DEATH "What...happen...ed."
+//#define SAY_DEATH "What...happen...ed."
//Pure energy spell info
-#define SPELL_ENERGY_BOLT 44342
+#define SPELL_ENERGY_BOLT 46156
#define SPELL_ENERGY_FEEDBACK 44335
//Vexallus spell info
#define SPELL_CHAIN_LIGHTNING 44318
-#define SPELL_SUMMON_PURE_ENERGY 44322 //not-working, this script summon this creatures without this spell
#define SPELL_OVERLOAD 44353
#define SPELL_ARCANE_SHOCK 44319
-#define ASTRAL_FLARE_VISUAL 30237
+
+#define SPELL_SUMMON_PURE_ENERGY 44322 //mod scale -10
+#define H_SPELL_SUMMON_PURE_ENERGY1 46154 //mod scale -5
+#define H_SPELL_SUMMON_PURE_ENERGY2 46159 //mod scale -5
//Creatures
#define CREATURE_PURE_ENERGY 24745
-struct TRINITY_DLL_DECL boss_vexallusAI : public ScriptedAI
+struct TRINITY_DLL_DECL boss_vexallusAI : public ScriptedAI
{
boss_vexallusAI(Creature *c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData()); Heroic = c->GetMap()->IsHeroic();
+ Heroic = c->GetMap()->IsHeroic();
}
ScriptedInstance* pInstance;
+ bool Heroic;
uint32 ChainLightningTimer;
uint32 ArcaneShockTimer;
@@ -61,7 +66,6 @@ struct TRINITY_DLL_DECL boss_vexallusAI : public ScriptedAI
uint32 SpawnAddInterval;
uint32 AlreadySpawnedAmount;
bool Enraged;
- bool Heroic;
void Reset()
{
@@ -70,15 +74,10 @@ struct TRINITY_DLL_DECL boss_vexallusAI : public ScriptedAI
OverloadTimer = 2200;
SpawnAddInterval = 15;
AlreadySpawnedAmount = 0;
-
Enraged = false;
- if(pInstance)
- {
- if (m_creature->isDead())
- pInstance->SetData(DATA_VEXALLUS_EVENT, DONE);
- else pInstance->SetData(DATA_VEXALLUS_EVENT, NOT_STARTED);
- }
+ if (pInstance)
+ pInstance->SetData(DATA_VEXALLUS_EVENT, NOT_STARTED);
}
void KilledUnit(Unit *victim)
@@ -88,83 +87,94 @@ struct TRINITY_DLL_DECL boss_vexallusAI : public ScriptedAI
void JustDied(Unit *victim)
{
- DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
if (pInstance)
{
pInstance->SetData(DATA_VEXALLUS_EVENT, DONE);
- GameObject* Door = NULL;
- Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_VEXALLUS_DOOR));
- if(Door)
- Door->SetGoState(0);
+ if (GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_VEXALLUS_DOOR)))
+ Door->SetGoState(GO_STATE_ACTIVE);
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
+
if (pInstance)
pInstance->SetData(DATA_VEXALLUS_EVENT, IN_PROGRESS);
}
+ void JustSummoned(Creature *summoned)
+ {
+ if (Unit *temp = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ summoned->GetMotionMaster()->MoveFollow(temp,0,0);
+
+ //spells are SUMMON_TYPE_GUARDIAN, so using setOwner should be ok
+ summoned->CastSpell(summoned,SPELL_ENERGY_BOLT,false,0,0,m_creature->GetGUID());
+ }
+
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim() )
return;
- if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 11)
+ if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 10)
{
Enraged = true;
}
- if(!Enraged)
+ if (!Enraged)
{
//used for check, when Vexallus cast adds 85%, 70%, 55%, 40%, 25%
if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < (100-(SpawnAddInterval*(AlreadySpawnedAmount+1))))
{
DoScriptText(SAY_ENERGY, m_creature);
DoScriptText(EMOTE_DISCHARGE_ENERGY, m_creature);
- Creature* PureEnergyCreature = NULL;
- PureEnergyCreature = DoSpawnCreature(CREATURE_PURE_ENERGY, 10, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
- Unit* target = NULL;
- target = SelectUnit(SELECT_TARGET_RANDOM, 0);
- if (PureEnergyCreature && target)
- PureEnergyCreature->AI()->AttackStart(target);
-
- if(Heroic) // *Heroic mode only - he summons two instead of one.
+
+ if (Heroic)
{
- PureEnergyCreature = DoSpawnCreature(CREATURE_PURE_ENERGY, -10, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
- target = SelectUnit(SELECT_TARGET_RANDOM, 0);
- if (PureEnergyCreature && target)
- PureEnergyCreature->AI()->AttackStart(target);
+ m_creature->CastSpell(m_creature,H_SPELL_SUMMON_PURE_ENERGY1,false);
+ m_creature->CastSpell(m_creature,H_SPELL_SUMMON_PURE_ENERGY2,false);
}
+ else
+ m_creature->CastSpell(m_creature,SPELL_SUMMON_PURE_ENERGY,false);
+
+ //below are workaround summons, remove when summoning spells w/implicitTarget 73 implemented in Mangos
+ DoSpawnCreature(CREATURE_PURE_ENERGY, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+
+ if (Heroic)
+ DoSpawnCreature(CREATURE_PURE_ENERGY, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
++AlreadySpawnedAmount;
- };
+ }
- if(ChainLightningTimer < diff)
+ if (ChainLightningTimer < diff)
{
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_CHAIN_LIGHTNING);
+ DoCast(target, SPELL_CHAIN_LIGHTNING);
+
ChainLightningTimer = 10000;
}else ChainLightningTimer -= diff;
- if(ArcaneShockTimer < diff)
+ if (ArcaneShockTimer < diff)
{
- Unit* target = NULL;
- target = SelectUnit(SELECT_TARGET_RANDOM, 0);
- DoCast(target, SPELL_ARCANE_SHOCK);
+ if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_ARCANE_SHOCK);
+
ArcaneShockTimer = 8000;
}else ArcaneShockTimer -= diff;
- }else
+ }
+ else
{
- if(OverloadTimer < diff)
+ if (OverloadTimer < diff)
{
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_OVERLOAD);
+ DoCast(target, SPELL_OVERLOAD);
+
OverloadTimer = 2200;
}else OverloadTimer -= diff;
}
+
DoMeleeAttackIfReady();
}
};
@@ -174,44 +184,24 @@ CreatureAI* GetAI_boss_vexallus(Creature *_Creature)
return new boss_vexallusAI (_Creature);
};
-struct TRINITY_DLL_DECL mob_pure_energyAI : public ScriptedAI
+struct TRINITY_DLL_DECL mob_pure_energyAI : public ScriptedAI
{
mob_pure_energyAI(Creature *c) : ScriptedAI(c) {}
- uint32 EnergyBoltTimer;
- uint32 VisualTimer;
-
- void Reset()
- {
- EnergyBoltTimer = 1700;
- VisualTimer = 1000;
- m_creature->SetSpeed(MOVE_RUN, 0.5f);
- m_creature->SetSpeed(MOVE_WALK, 0.5f);
- }
+ void Reset() { }
void JustDied(Unit* slayer)
{
- slayer->CastSpell(slayer, SPELL_ENERGY_FEEDBACK, true, 0, 0, m_creature->GetGUID());
- }
-
- void Aggro(Unit *who){}
-
- void UpdateAI(const uint32 diff)
- {
- if(!UpdateVictim())
- return;
-
- if(EnergyBoltTimer < diff)
+ if (Unit *temp = m_creature->GetOwner())
{
- DoCast(m_creature->getVictim(), SPELL_ENERGY_BOLT);
- EnergyBoltTimer = 1700;
- }else EnergyBoltTimer -= diff;
- if(VisualTimer < diff)
- {
- DoCast(m_creature->getVictim(), ASTRAL_FLARE_VISUAL, true);
- VisualTimer = 1000;
- }else VisualTimer -= diff;
+ if (temp && temp->isAlive())
+ slayer->CastSpell(slayer, SPELL_ENERGY_FEEDBACK, true, 0, 0, temp->GetGUID());
+ }
}
+
+ void EnterCombat(Unit *who) { }
+ void MoveInLineOfSight(Unit *who) { }
+ void AttackStart(Unit *who) { }
};
CreatureAI* GetAI_mob_pure_energy(Creature *_Creature)
@@ -224,13 +214,12 @@ void AddSC_boss_vexallus()
Script *newscript;
newscript = new Script;
- newscript->Name="boss_vexallus";
+ newscript->Name = "boss_vexallus";
newscript->GetAI = &GetAI_boss_vexallus;
newscript->RegisterSelf();
newscript = new Script;
- newscript->Name="mob_pure_energy";
+ newscript->Name = "mob_pure_energy";
newscript->GetAI = &GetAI_mob_pure_energy;
newscript->RegisterSelf();
}
-
diff --git a/src/bindings/scripts/scripts/zone/magisters_terrace/def_magisters_terrace.h b/src/bindings/scripts/scripts/zone/magisters_terrace/def_magisters_terrace.h
index f509a8bc73c..d6419ea409c 100644
--- a/src/bindings/scripts/scripts/zone/magisters_terrace/def_magisters_terrace.h
+++ b/src/bindings/scripts/scripts/zone/magisters_terrace/def_magisters_terrace.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
@@ -20,13 +20,12 @@
#define DATA_DELRISSA_DOOR 11
#define DATA_SELIN_ENCOUNTER_DOOR 12
-#define DATA_KAEL_STATUE_LEFT 13
-#define DATA_KAEL_STATUE_RIGHT 14
+#define DATA_KAEL_DOOR 13
+#define DATA_KAEL_STATUE_LEFT 14
+#define DATA_KAEL_STATUE_RIGHT 15
-#define DATA_DELRISSA_DEATH_COUNT 15
+#define DATA_DELRISSA_DEATH_COUNT 16
-#define DATA_KAEL 16
-
-#define ERROR_INST_DATA "SD2 Error: Instance Data not set properly for Magister's Terrace instance (map 585). Encounters will be buggy."
+#define ERROR_INST_DATA "TSCR Error: Instance Data not set properly for Magister's Terrace instance (map 585). Encounters will be buggy."
#endif
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 4ef61128257..57484cb5ef4 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -6,12 +6,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
*/
/* ScriptData
@@ -37,29 +37,25 @@ struct TRINITY_DLL_DECL instance_magisters_terrace : public ScriptedInstance
{
instance_magisters_terrace(Map* map) : ScriptedInstance(map) {Initialize();}
- uint32 DoorState[3];//0seline, 1vexallus, 2derlissa
uint32 Encounters[NUMBER_OF_ENCOUNTERS];
uint32 DelrissaDeathCount;
std::list<uint64> FelCrystals;
std::list<uint64>::iterator CrystalItr;
- uint64 KaelGUID;
uint64 SelinGUID;
uint64 DelrissaGUID;
uint64 VexallusDoorGUID;
uint64 SelinDoorGUID;
uint64 SelinEncounterDoorGUID;
uint64 DelrissaDoorGUID;
+ uint64 KaelDoorGUID;
uint64 KaelStatue[2];
bool InitializedItr;
void Initialize()
{
- for(uint8 i = 0; i < 3; i++)
- DoorState[i] = 1;//1 closed, 0 opened
-
for(uint8 i = 0; i < NUMBER_OF_ENCOUNTERS; i++)
Encounters[i] = NOT_STARTED;
@@ -67,13 +63,13 @@ struct TRINITY_DLL_DECL instance_magisters_terrace : public ScriptedInstance
DelrissaDeathCount = 0;
- KaelGUID = 0;
SelinGUID = 0;
DelrissaGUID = 0;
VexallusDoorGUID = 0;
SelinDoorGUID = 0;
SelinEncounterDoorGUID = 0;
DelrissaDoorGUID = 0;
+ KaelDoorGUID = 0;
KaelStatue[0] = 0;
KaelStatue[1] = 0;
@@ -106,30 +102,9 @@ struct TRINITY_DLL_DECL instance_magisters_terrace : public ScriptedInstance
{
switch(identifier)
{
- case DATA_SELIN_EVENT:
- Encounters[0] = data;
- if(data==DONE)
- {
- DoorState[0] = 0;
- SaveToDB();
- }
- break;
- case DATA_VEXALLUS_EVENT:
- Encounters[1] = data;
- if(data==DONE)
- {
- DoorState[1] = 0;
- SaveToDB();
- }
- break;
- case DATA_DELRISSA_EVENT:
- Encounters[2] = data;
- if(data==DONE)
- {
- DoorState[2] = 0;
- SaveToDB();
- }
- break;
+ case DATA_SELIN_EVENT: Encounters[0] = data; break;
+ case DATA_VEXALLUS_EVENT: Encounters[1] = data; break;
+ case DATA_DELRISSA_EVENT: Encounters[2] = data; break;
case DATA_KAELTHAS_EVENT: Encounters[3] = data; break;
case DATA_DELRISSA_DEATH_COUNT:
@@ -138,38 +113,13 @@ struct TRINITY_DLL_DECL instance_magisters_terrace : public ScriptedInstance
}
}
- const char* Save()
- {
- std::ostringstream ss;
- ss << "S " << DoorState[0] << " " << DoorState[1] << " " << DoorState[2];
- char* data = new char[ss.str().length()+1];
- strcpy(data, ss.str().c_str());
- return data;
- }
-
- void Load(const char* load)
- {
- if(!load) return;
- std::istringstream ss(load);
- char dataHead; // S
- uint32 data1, data2, data3;
- ss >> dataHead >> data1 >> data2 >> data3;
- if(dataHead == 'S')
- {
- DoorState[0] = data1;
- DoorState[1] = data2;
- DoorState[2] = data3;
- }else error_log("TSCR: Magister's Terrace: corrupted save data.");
- }
-
void OnCreatureCreate(Creature *creature, uint32 entry)
{
- switch(entry)
+ switch(creature->GetEntry())
{
case 24723: SelinGUID = creature->GetGUID(); break;
case 24560: DelrissaGUID = creature->GetGUID(); break;
case 24722: FelCrystals.push_back(creature->GetGUID()); break;
- case 24664: KaelGUID = creature->GetGUID(); break;
}
}
@@ -177,21 +127,13 @@ struct TRINITY_DLL_DECL instance_magisters_terrace : public ScriptedInstance
{
switch(go->GetEntry())
{
- case 187896:
- VexallusDoorGUID = go->GetGUID();
- go->SetGoState(DoorState[1]);
- break;
+ case 187896: VexallusDoorGUID = go->GetGUID(); break;
//SunwellRaid Gate 02
- case 187979:
- SelinDoorGUID = go->GetGUID();
- go->SetGoState(DoorState[0]);
- break;
+ case 187979: SelinDoorGUID = go->GetGUID(); break;
//Assembly Chamber Door
case 188065: SelinEncounterDoorGUID = go->GetGUID(); break;
- case 187770:
- DelrissaDoorGUID = go->GetGUID();
- go->SetGoState(DoorState[2]);
- break;
+ case 187770: DelrissaDoorGUID = go->GetGUID(); break;
+ case 188064: KaelDoorGUID = go->GetGUID(); break;
case 188165: KaelStatue[0] = go->GetGUID(); break;
case 188166: KaelStatue[1] = go->GetGUID(); break;
}
@@ -202,12 +144,12 @@ struct TRINITY_DLL_DECL instance_magisters_terrace : public ScriptedInstance
switch(identifier)
{
case DATA_SELIN: return SelinGUID;
- case DATA_KAEL: return KaelGUID;
case DATA_DELRISSA: return DelrissaGUID;
case DATA_VEXALLUS_DOOR: return VexallusDoorGUID;
case DATA_SELIN_DOOR: return SelinDoorGUID;
case DATA_SELIN_ENCOUNTER_DOOR: return SelinEncounterDoorGUID;
case DATA_DELRISSA_DOOR: return DelrissaDoorGUID;
+ case DATA_KAEL_DOOR: return KaelDoorGUID;
case DATA_KAEL_STATUE_LEFT: return KaelStatue[0];
case DATA_KAEL_STATUE_RIGHT: return KaelStatue[1];
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 16a6a301681..914a6b3d578 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -42,7 +42,7 @@ struct TRINITY_DLL_DECL celebras_the_cursedAI : public ScriptedAI
CorruptForces_Timer = 30000;
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void JustDied(Unit* Killer)
{
diff --git a/src/bindings/scripts/scripts/zone/maraudon/boss_landslide.cpp b/src/bindings/scripts/scripts/zone/maraudon/boss_landslide.cpp
index ca2253c96b1..c67bebeebb0 100644
--- a/src/bindings/scripts/scripts/zone/maraudon/boss_landslide.cpp
+++ b/src/bindings/scripts/scripts/zone/maraudon/boss_landslide.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -42,7 +42,7 @@ struct TRINITY_DLL_DECL boss_landslideAI : public ScriptedAI
Landslide_Timer = 0;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/maraudon/boss_noxxion.cpp b/src/bindings/scripts/scripts/zone/maraudon/boss_noxxion.cpp
index e59da4ff650..db5ad5214d2 100644
--- a/src/bindings/scripts/scripts/zone/maraudon/boss_noxxion.cpp
+++ b/src/bindings/scripts/scripts/zone/maraudon/boss_noxxion.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -49,7 +49,7 @@ struct TRINITY_DLL_DECL boss_noxxionAI : public ScriptedAI
Invisible = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 64b7c2c67f5..0ecac0e86c4 100644
--- a/src/bindings/scripts/scripts/zone/maraudon/boss_princess_theradras.cpp
+++ b/src/bindings/scripts/scripts/zone/maraudon/boss_princess_theradras.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -45,7 +45,7 @@ struct TRINITY_DLL_DECL boss_ptheradrasAI : public ScriptedAI
RepulsiveGaze_Timer = 23000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 5b34758714c..26361c68e2b 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -45,7 +45,7 @@ struct TRINITY_DLL_DECL boss_baron_geddonAI : public ScriptedAI
LivingBomb_Timer = 35000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 7f4758b8c79..3dcb017cf73 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_garr.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_garr.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -49,7 +49,7 @@ struct TRINITY_DLL_DECL boss_garrAI : public ScriptedAI
CheckAdds_Timer = 2000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -87,7 +87,7 @@ struct TRINITY_DLL_DECL mob_fireswornAI : public ScriptedAI
Immolate_Timer = 4000; //These times are probably wrong
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 fbe09203551..450d136e0be 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_gehennas.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_gehennas.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -42,7 +42,7 @@ struct TRINITY_DLL_DECL boss_gehennasAI : public ScriptedAI
GehennasCurse_Timer = 12000;
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void UpdateAI(const uint32 diff)
{
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 8684f10c509..b2baadc0b03 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_golemagg.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_golemagg.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -59,7 +59,7 @@ struct TRINITY_DLL_DECL boss_golemaggAI : public ScriptedAI
m_creature->CastSpell(m_creature,SPELL_MAGMASPLASH,true);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -131,7 +131,7 @@ struct TRINITY_DLL_DECL mob_core_ragerAI : public ScriptedAI
Check_Timer = 1000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 7b948fbf747..4514f4640dd 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_lucifron.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_lucifron.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -42,7 +42,7 @@ struct TRINITY_DLL_DECL boss_lucifronAI : public ScriptedAI
ShadowShock_Timer = 6000; //6 seconds
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 72c3a759dfa..0738457efae 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_magmadar.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_magmadar.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -48,7 +48,7 @@ struct TRINITY_DLL_DECL boss_magmadarAI : public ScriptedAI
m_creature->CastSpell(m_creature,SPELL_MAGMASPIT,true);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 c28867accbd..3da7134c471 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -79,7 +79,7 @@ struct TRINITY_DLL_DECL boss_majordomoAI : public ScriptedAI
DoScriptText(SAY_SLAY, m_creature);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
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 7d9a64666cf..929547ca900 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_ragnaros.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_ragnaros.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -127,7 +127,7 @@ struct TRINITY_DLL_DECL boss_ragnarosAI : public Scripted_NoMovementAI
DoScriptText(SAY_KILL, m_creature);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -225,6 +225,7 @@ struct TRINITY_DLL_DECL boss_ragnarosAI : public Scripted_NoMovementAI
{
target = SelectUnit(SELECT_TARGET_RANDOM,0);
Summoned = m_creature->SummonCreature(12143,target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
}
@@ -242,6 +243,7 @@ struct TRINITY_DLL_DECL boss_ragnarosAI : public Scripted_NoMovementAI
{
target = SelectUnit(SELECT_TARGET_RANDOM,0);
Summoned = m_creature->SummonCreature(12143,target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
}
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 d11a49e0cf9..89c0163700e 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_shazzrah.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_shazzrah.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -47,7 +47,7 @@ struct TRINITY_DLL_DECL boss_shazzrahAI : public ScriptedAI
Blink_Timer = 30000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 244bc6ece50..dc5b10a25d0 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -58,7 +58,7 @@ struct TRINITY_DLL_DECL boss_sulfuronAI : public ScriptedAI
Flamespear_Timer = 2000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -142,7 +142,7 @@ struct TRINITY_DLL_DECL mob_flamewaker_priestAI : public ScriptedAI
Immolate_Timer = 8000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/molten_core/def_molten_core.h b/src/bindings/scripts/scripts/zone/molten_core/def_molten_core.h
index e728c863767..5874d8b9408 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/def_molten_core.h
+++ b/src/bindings/scripts/scripts/zone/molten_core/def_molten_core.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
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 5c783edfe10..bfaa583e033 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
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 8d9977957d6..d25ddc7631c 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/molten_core.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/molten_core.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
diff --git a/src/bindings/scripts/scripts/zone/moonglade/moonglade.cpp b/src/bindings/scripts/scripts/zone/moonglade/moonglade.cpp
index 027ef125ca7..66fd81d53b6 100644
--- a/src/bindings/scripts/scripts/zone/moonglade/moonglade.cpp
+++ b/src/bindings/scripts/scripts/zone/moonglade/moonglade.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -317,7 +317,7 @@ public:
npc_escortAI::EnterEvadeMode();
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
uint32 rnd = rand()%2;
switch(rnd)
@@ -353,13 +353,16 @@ public:
return;
}
- if(!InCombat && !Event_onWait && checkPlayer_Timer < diff)
+ if(!m_creature->isInCombat() && !Event_onWait)
{
- Player *player = (Player *)Unit::GetUnit((*m_creature), PlayerGUID);
- if(player && player->isInCombat() && player->getAttackerForHelper())
- AttackStart(player->getAttackerForHelper());
- checkPlayer_Timer = 1000;
- } else if(!InCombat && !Event_onWait) checkPlayer_Timer -= diff;
+ if(checkPlayer_Timer < diff)
+ {
+ Player *player = (Player *)Unit::GetUnit((*m_creature), PlayerGUID);
+ if(player && player->isInCombat() && player->getAttackerForHelper())
+ AttackStart(player->getAttackerForHelper());
+ checkPlayer_Timer = 1000;
+ }else checkPlayer_Timer -= diff;
+ }
if(Event_onWait && Event_Timer < diff)
{
diff --git a/src/bindings/scripts/scripts/zone/mulgore/mulgore.cpp b/src/bindings/scripts/scripts/zone/mulgore/mulgore.cpp
index 74d800a5484..16ba4686719 100644
--- a/src/bindings/scripts/scripts/zone/mulgore/mulgore.cpp
+++ b/src/bindings/scripts/scripts/zone/mulgore/mulgore.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -75,7 +75,7 @@ struct TRINITY_DLL_DECL npc_kyle_frenziedAI : public ScriptedAI
m_creature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
m_creature->GetMotionMaster()->Initialize();
}
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void SpellHit(Unit *caster, const SpellEntry* spell)
{ // we can feed him without any quest
@@ -233,7 +233,7 @@ struct TRINITY_DLL_DECL npc_plains_visionAI : public ScriptedAI
amountWP = 49;
}
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void MovementInform(uint32 type, uint32 id)
{
diff --git a/src/bindings/scripts/scripts/zone/nagrand/nagrand.cpp b/src/bindings/scripts/scripts/zone/nagrand/nagrand.cpp
index 0266fa8ef43..25a27ac3a73 100644
--- a/src/bindings/scripts/scripts/zone/nagrand/nagrand.cpp
+++ b/src/bindings/scripts/scripts/zone/nagrand/nagrand.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -49,7 +49,7 @@ struct TRINITY_DLL_DECL mob_shattered_rumblerAI : public ScriptedAI
Spawn = false;
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void SpellHit(Unit *Hitter, const SpellEntry *Spellkind)
{
@@ -124,7 +124,7 @@ struct TRINITY_DLL_DECL mob_lumpAI : public ScriptedAI
m_creature->DeleteThreatList();
m_creature->CombatStop();
m_creature->setFaction(1080); //friendly
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_SIT);
+ m_creature->SetStandState(UNIT_STAND_STATE_SIT);
DoScriptText(LUMP_DEFEAT, m_creature);
bReset = true;
@@ -132,13 +132,13 @@ struct TRINITY_DLL_DECL mob_lumpAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
- if (m_creature->HasAura(SPELL_VISUAL_SLEEP,0))
- m_creature->RemoveAura(SPELL_VISUAL_SLEEP,0);
+ if (m_creature->HasAura(SPELL_VISUAL_SLEEP))
+ m_creature->RemoveAura(SPELL_VISUAL_SLEEP);
if (!m_creature->IsStandState())
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_NONE);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
switch(rand()%2)
{
@@ -226,10 +226,10 @@ struct TRINITY_DLL_DECL mob_sunspring_villagerAI : public ScriptedAI
void Reset()
{
m_creature->SetUInt32Value(UNIT_DYNAMIC_FLAGS, 32);
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,7); // lay down
+ m_creature->SetStandState(UNIT_STAND_STATE_DEAD);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void SpellHit(Unit *caster, const SpellEntry *spell)
{
@@ -525,7 +525,7 @@ struct TRINITY_DLL_DECL npc_creditmarker_visit_with_ancestorsAI : public Scripte
void Reset() {}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void MoveInLineOfSight(Unit *who)
{
@@ -584,7 +584,7 @@ struct TRINITY_DLL_DECL mob_sparrowhawkAI : public ScriptedAI
ScriptedAI::AttackStart(who);
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void MoveInLineOfSight(Unit *who)
{
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_anubrekhan.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_anubrekhan.cpp
index 86d4002718f..c0b23faa889 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_anubrekhan.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_anubrekhan.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -16,7 +16,7 @@
/* ScriptData
SDName: Boss_Anubrekhan
-SD%Complete: 70
+SD%Complete: 100
SDComment:
SDCategory: Naxxramas
EndScriptData */
@@ -33,45 +33,53 @@ EndScriptData */
#define SAY_TAUNT4 -1533007
#define SAY_SLAY -1533008
-#define SPELL_IMPALE 28783 //May be wrong spell id. Causes more dmg than I expect
-#define H_SPELL_IMPALE 56090
-#define SPELL_LOCUSTSWARM 28785 //This is a self buff that triggers the dmg debuff
-#define H_SPELL_LOCUSTSWARM 54021
-
-//invalid
-#define SPELL_SUMMONGUARD 29508 //Summons 1 crypt guard at targeted location
+#define SPELL_IMPALE HEROIC(28783,56090)
+#define SPELL_LOCUSTSWARM HEROIC(28785,54021)
#define SPELL_SELF_SPAWN_5 29105 //This spawns 5 corpse scarabs ontop of us (most likely the player casts this on death)
#define SPELL_SELF_SPAWN_10 28864 //This is used by the crypt guards when they die
+#define EVENT_IMPALE 1
+#define EVENT_LOCUST 2
+
+#define MOB_CRYPT_GUARD 16573
+
struct TRINITY_DLL_DECL boss_anubrekhanAI : public ScriptedAI
{
- boss_anubrekhanAI(Creature *c) : ScriptedAI(c) {}
+ boss_anubrekhanAI(Creature *c) : ScriptedAI(c), summons(me) {}
- uint32 Impale_Timer;
- uint32 LocustSwarm_Timer;
- uint32 Summon_Timer;
bool HasTaunted;
+ EventMap events;
+ SummonList summons;
void Reset()
{
- Impale_Timer = 15000; //15 seconds
- LocustSwarm_Timer = 80000 + (rand()%40000); //Random time between 80 seconds and 2 minutes for initial cast
- Summon_Timer = LocustSwarm_Timer + 45000; //45 seconds after initial locust swarm
+ events.Reset();
+ summons.DespawnAll();
+ HasTaunted = false;
+ DoSpawnCreature(MOB_CRYPT_GUARD, 0, 10, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
+ if(HeroicMode)
+ DoSpawnCreature(MOB_CRYPT_GUARD, 0, -10, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
}
- void KilledUnit(Unit* Victim)
+ void JustSummoned(Creature *summon)
{
- //Force the player to spawn corpse scarabs via spell
- Victim->CastSpell(Victim, SPELL_SELF_SPAWN_5, true);
+ summons.Summon(summon);
+ DoZoneInCombat(summon);
+ }
- if (rand()%5)
- return;
+ void SummonedCreatureDespawn(Creature *summon) {summons.Despawn(summon);}
- DoScriptText(SAY_SLAY, m_creature);
+ void KilledUnit(Unit* victim)
+ {
+ //Force the player to spawn corpse scarabs via spell
+ victim->CastSpell(victim, SPELL_SELF_SPAWN_5, true, NULL, NULL, me->GetGUID());
+
+ if(!(rand()%5))
+ DoScriptText(SAY_SLAY, me);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
@@ -79,62 +87,62 @@ struct TRINITY_DLL_DECL boss_anubrekhanAI : public ScriptedAI
case 1: DoScriptText(SAY_AGGRO2, m_creature); break;
case 2: DoScriptText(SAY_AGGRO3, m_creature); break;
}
+
+ DoZoneInCombat();
+
+ events.ScheduleEvent(EVENT_IMPALE, 15000, 1);
+ events.ScheduleEvent(EVENT_LOCUST, 80000 + rand()%40000, 1);
}
void MoveInLineOfSight(Unit *who)
{
-
- if (!HasTaunted && m_creature->IsWithinDistInMap(who, 60.0f))
+ if (!HasTaunted && m_creature->IsWithinDistInMap(who, 60.0f))
+ {
+ switch(rand()%5)
{
- switch(rand()%5)
- {
- case 0: DoScriptText(SAY_GREET, m_creature); break;
- case 1: DoScriptText(SAY_TAUNT1, m_creature); break;
- case 2: DoScriptText(SAY_TAUNT2, m_creature); break;
- case 3: DoScriptText(SAY_TAUNT3, m_creature); break;
- case 4: DoScriptText(SAY_TAUNT4, m_creature); break;
- }
- HasTaunted = true;
+ case 0: DoScriptText(SAY_GREET, m_creature); break;
+ case 1: DoScriptText(SAY_TAUNT1, m_creature); break;
+ case 2: DoScriptText(SAY_TAUNT2, m_creature); break;
+ case 3: DoScriptText(SAY_TAUNT3, m_creature); break;
+ case 4: DoScriptText(SAY_TAUNT4, m_creature); break;
}
+ HasTaunted = true;
+ }
ScriptedAI::MoveInLineOfSight(who);
}
void UpdateAI(const uint32 diff)
{
- if (!UpdateVictim())
+ if(!UpdateVictim())
return;
- //Impale_Timer
- if (Impale_Timer < diff)
+ events.Update(diff);
+
+ while(uint32 eventId = events.ExecuteEvent())
{
- //Cast Impale on a random target
- //Do NOT cast it when we are afflicted by locust swarm
- if (!m_creature->HasAura(SPELL_LOCUSTSWARM,1))
+ switch(eventId)
{
- if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0))
- DoCast(target,SPELL_IMPALE);
+ case EVENT_IMPALE:
+ //Cast Impale on a random target
+ //Do NOT cast it when we are afflicted by locust swarm
+ if(!me->HasAura(SPELL_LOCUSTSWARM))
+ if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_IMPALE);
+ events.ScheduleEvent(EVENT_IMPALE, 15000, 1);
+ events.DelayEvents(1500, 1);
+ return;
+ case EVENT_LOCUST:
+ DoCast(m_creature, SPELL_LOCUSTSWARM);
+ DoSpawnCreature(MOB_CRYPT_GUARD, 5, 5, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
+ events.ScheduleEvent(EVENT_LOCUST, 90000, 1);
+ return;
}
-
- Impale_Timer = 15000;
- }else Impale_Timer -= diff;
-
- //LocustSwarm_Timer
- if (LocustSwarm_Timer < diff)
- {
- DoCast(m_creature, SPELL_LOCUSTSWARM);
- LocustSwarm_Timer = 90000;
- }else LocustSwarm_Timer -= diff;
-
- //Summon_Timer
- if (Summon_Timer < diff)
- {
- DoCast(m_creature, SPELL_SUMMONGUARD);
- Summon_Timer = 45000;
- }else Summon_Timer -= diff;
+ }
DoMeleeAttackIfReady();
}
};
+
CreatureAI* GetAI_boss_anubrekhan(Creature *_Creature)
{
return new boss_anubrekhanAI (_Creature);
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_faerlina.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_faerlina.cpp
index c04cab35e58..5ec67a8920b 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_faerlina.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_faerlina.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -17,7 +17,7 @@
/* ScriptData
SDName: Boss_Faerlina
SD%Complete: 50
-SDComment: Without Mindcontrol boss cannot be defeated
+SDComment:
SDCategory: Naxxramas
EndScriptData */
@@ -32,6 +32,8 @@ EndScriptData */
#define SAY_SLAY2 -1533015
#define SAY_DEATH -1533016
+//#define SOUND_RANDOM_AGGRO 8955 //soundId containing the 4 aggro sounds, we not using this
+
#define SPELL_POSIONBOLT_VOLLEY 28796
#define H_SPELL_POSIONBOLT_VOLLEY 54098
#define SPELL_ENRAGE 28798
@@ -55,7 +57,7 @@ struct TRINITY_DLL_DECL boss_faerlinaAI : public ScriptedAI
HasTaunted = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch (rand()%4)
{
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_four_horsemen.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_four_horsemen.cpp
index 0ae5080d227..7e77afa7167 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_four_horsemen.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_four_horsemen.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -62,7 +62,7 @@
ShieldWall2 = true;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_BLAU_AGGRO, m_creature);
}
@@ -149,7 +149,7 @@
{
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch(rand()%3)
{
@@ -218,7 +218,7 @@
ShieldWall2 = true;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_KORT_AGGRO, m_creature);
}
@@ -313,7 +313,7 @@
ShieldWall2 = true;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_ZELI_AGGRO, m_creature);
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_gluth.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_gluth.cpp
index 80cbc347fe1..7a064fb922c 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_gluth.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_gluth.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -86,7 +86,7 @@ struct TRINITY_DLL_DECL boss_gluthAI : public ScriptedAI
Summon_Timer = 10000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp
index ed2ef9de4e6..0becff399da 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -41,8 +41,10 @@ EndScriptData */
#define SPELL_SHADOW_MARK 27825
//Unrelenting Rider
-#define SPELL_UNHOLY_AURA 28340
-#define SPELL_SHADOWBOLT 19729 //Search thru targets and find those who have the SHADOW_MARK to cast this on
+#define SPELL_UNHOLY_AURA 55606
+#define H_SPELL_UNHOLY_AURA 55608
+#define SPELL_SHADOWBOLT_VOLLEY 27831 //Search thru targets and find those who have the SHADOW_MARK to cast this on
+#define H_SPELL_SHADOWBOLT_VOLLEY 55638
//Spectral Trainee
#define SPELL_ARCANE_EXPLOSION 27989
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_grobbulus.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_grobbulus.cpp
index 88ce581e6dd..98ab76e4fc0 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_grobbulus.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_grobbulus.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -29,3 +29,93 @@ Enrages 26527*/
#include "precompiled.h"
+#define SPELL_BOMBARD_SLIME 28280
+
+#define SPELL_POISON_CLOUD 28240
+#define SPELL_MUTATING_INJECTION 28169
+#define SPELL_SLIME_SPRAY HEROIC(28157,54364)
+#define SPELL_BERSERK 26662
+
+#define EVENT_BERSERK 1
+#define EVENT_CLOUD 2
+#define EVENT_INJECT 3
+#define EVENT_SPRAY 4
+
+#define MOB_FALLOUT_SLIME 16290
+
+struct TRINITY_DLL_DECL boss_grobbulusAI : public ScriptedAI
+{
+ boss_grobbulusAI(Creature *c) : ScriptedAI(c) {}
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit *who)
+ {
+ DoZoneInCombat();
+ events.ScheduleEvent(EVENT_CLOUD, 15000);
+ events.ScheduleEvent(EVENT_INJECT, 20000);
+ events.ScheduleEvent(EVENT_SPRAY, 15000+rand()%15000); //not sure
+ events.ScheduleEvent(EVENT_BERSERK, 12*60000);
+ }
+
+ void SpellHitTarget(Unit *target, const SpellEntry *spell)
+ {
+ if(spell->Id == SPELL_SLIME_SPRAY)
+ {
+ if(TempSummon *slime = me->SummonCreature(MOB_FALLOUT_SLIME, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0))
+ DoZoneInCombat(slime);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_CLOUD:
+ DoCastAOE(SPELL_POISON_CLOUD);
+ events.ScheduleEvent(EVENT_CLOUD, 15000);
+ return;
+ case EVENT_BERSERK:
+ DoCastAOE(SPELL_BERSERK);
+ return;
+ case EVENT_SPRAY:
+ DoCastAOE(SPELL_SLIME_SPRAY);
+ events.ScheduleEvent(EVENT_SPRAY, 15000+rand()%15000);
+ return;
+ case EVENT_INJECT:
+ if(Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_MUTATING_INJECTION);
+ events.ScheduleEvent(EVENT_INJECT, 8000 + 12000 * me->GetHealth() / me->GetMaxHealth());
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_grobbulus(Creature *_Creature)
+{
+ return new boss_grobbulusAI (_Creature);
+}
+
+void AddSC_boss_grobbulus()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name="boss_grobbulus";
+ newscript->GetAI = &GetAI_boss_grobbulus;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_heigan.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_heigan.cpp
index 78921efff3d..d5f1e594d0c 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_heigan.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_heigan.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -21,20 +21,19 @@ SDComment: Place Holder
SDCategory: Naxxramas
EndScriptData */
-//Lotheb or Heigan?
-//8825 aggro1 - You are mine now!
-//8826 aggro2 - I see you!
-//8827 aggro3 - You...are next!
-//8828 death -
-//8829 slay - close your eyes... sleep
-//8830 taunt1 - The races of the world will perish. It is only a matter of time.
-//8831 taunt2 - I see endless suffering, I see torment, I see rage. I see... everything!
-//8832 taunt3 - Soon... the world will tremble!
-//8833 taunt4 - The end is upon you.
-//8834 taunt5 - Hungry worms will feast on your rotten flesh!
-
#include "precompiled.h"
+#define SAY_AGGRO1 -1533109
+#define SAY_AGGRO2 -1533110
+#define SAY_AGGRO3 -1533111
+#define SAY_SLAY -1533112
+#define SAY_TAUNT1 -1533113
+#define SAY_TAUNT2 -1533114
+#define SAY_TAUNT3 -1533115
+#define SAY_TAUNT4 -1533116
+#define SAY_TAUNT5 -1533117
+#define SAY_DEATH -1533118
+
//Spell used by floor peices to cause damage to players
#define SPELL_ERUPTION 29371
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_kelthuzad.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_kelthuzad.cpp
index 170ced981f7..4e74445d2cd 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_kelthuzad.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_kelthuzad.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -257,11 +257,11 @@ struct TRINITY_DLL_DECL boss_kelthuzadAI : public ScriptedAI
Walk_Pos_Z = ADDZ_RIGHT_NEAR;
break;
}
- pUnit->SendMonsterMoveWithSpeed(Walk_Pos_X, Walk_Pos_Y, Walk_Pos_Z,MOVEMENTFLAG_WALK_MODE);
+ pUnit->SendMonsterMoveWithSpeed(Walk_Pos_X, Walk_Pos_Y, Walk_Pos_Z);
}
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
switch(rand()%3)
{
@@ -407,7 +407,7 @@ struct TRINITY_DLL_DECL boss_kelthuzadAI : public ScriptedAI
{
//if we find no one to figth walk to the center
if(!pUnit->isInCombat())
- pUnit->SendMonsterMoveWithSpeed(Walk_Pos_X,Walk_Pos_Y,Walk_Pos_Z,MOVEMENTFLAG_WALK_MODE);
+ pUnit->SendMonsterMoveWithSpeed(Walk_Pos_X,Walk_Pos_Y,Walk_Pos_Z);
//Safe storing of creatures
GuardiansOfIcecrown[GuardiansOfIcecrown_Count] = pUnit->GetGUID();
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_loatheb.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_loatheb.cpp
index d5e382d80e6..3d50e8f084b 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_loatheb.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_loatheb.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -23,28 +23,6 @@ EndScriptData */
#include "precompiled.h"
-#define SAY_AGGRO1 "You are mine now!"
-#define SAY_AGGRO2 "I see you!"
-#define SAY_AGGRO3 "You...are next!"
-#define SAY_SLAY1 "Close your eyes... sleep!"
-#define SAY_SLAY2 "The races of the world will perish. It is only a matter of time."
-#define SAY_SLAY3 "I see endless suffering, I see torment, I see rage. I see... everything!"
-#define SAY_SLAY4 "Soon... the world will tremble!"
-#define SAY_SLAY5 "The end is upon you."
-#define SAY_SLAY6 "Hungry worms will feast on your rotten flesh!"
-#define SAY_DEATH ""
-
-#define SOUND_AGGRO1 8825
-#define SOUND_AGGRO2 8826
-#define SOUND_AGGRO3 8827
-#define SOUND_SLAY1 8829
-#define SOUND_SLAY2 8830
-#define SOUND_SLAY3 8831
-#define SOUND_SLAY4 8832
-#define SOUND_SLAY5 8833
-#define SOUND_SLAY6 8834
-#define SOUND_DEATH 8828
-
#define SPELL_CORRUPTED_MIND 29198
#define SPELL_POISON_AURA 29865
#define SPELL_INEVITABLE_DOOM 29204
@@ -83,60 +61,12 @@ struct TRINITY_DLL_DECL boss_loathebAI : public ScriptedAI
Summon_Timer = 8000;
}
- void Aggro(Unit *who)
- {
- switch (rand()%3)
- {
- case 0:
- DoYell(SAY_AGGRO1,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_AGGRO1);
- break;
- case 1:
- DoYell(SAY_AGGRO2,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_AGGRO2);
- break;
- case 2:
- DoYell(SAY_AGGRO3,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_AGGRO3);
- break;
- }
- }
-
- void KilledUnit(Unit* victim)
+ void EnterCombat(Unit *who)
{
- switch (rand()%6)
- {
- case 0:
- DoYell(SAY_SLAY1,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_SLAY1);
- break;
- case 1:
- DoYell(SAY_SLAY2,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_SLAY2);
- break;
- case 2:
- DoYell(SAY_SLAY3,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_SLAY3);
- break;
- case 3:
- DoYell(SAY_SLAY4,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_SLAY4);
- break;
- case 4:
- DoYell(SAY_SLAY5,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_SLAY5);
- break;
- case 5:
- DoYell(SAY_SLAY6,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_SLAY6);
- break;
- }
}
void JustDied(Unit* Killer)
{
- DoYell(SAY_DEATH,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_DEATH);
}
void UpdateAI(const uint32 diff)
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_maexxna.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_maexxna.cpp
index 235029f1cb7..937dd8bbb6d 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_maexxna.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_maexxna.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -16,8 +16,8 @@
/* ScriptData
SDName: Boss_Maexxna
-SD%Complete: 80
-SDComment:
+SD%Complete: 60
+SDComment: this needs review, and rewrite of the webwrap ability
SDCategory: Naxxramas
EndScriptData */
@@ -80,7 +80,7 @@ struct TRINITY_DLL_DECL mob_webwrapAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -114,7 +114,7 @@ struct TRINITY_DLL_DECL boss_maexxnaAI : public ScriptedAI
Enraged = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp
index 59f9d33e245..03f17450c5e 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -64,7 +64,7 @@ struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI
Summon_Timer = 12000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch (rand()%3)
{
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp
index 50f4559b4eb..ac8fa5ba568 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -16,8 +16,8 @@
/* ScriptData
SDName: Boss_Patchwerk
-SD%Complete: 100
-SDComment: Some issues with hateful strike inturrupting the melee swing timer. Probably core issue.
+SD%Complete: 80
+SDComment: Some issues with hateful strike inturrupting the melee swing timer.
SDCategory: Naxxramas
EndScriptData */
@@ -31,113 +31,106 @@ EndScriptData */
#define EMOTE_BERSERK -1533021
#define EMOTE_ENRAGE -1533022
-#define SPELL_HATEFULSTRIKE 28308
-#define H_SPELL_HATEFULSTRIKE 59192
-#define SPELL_ENRAGE 2813
+#define SPELL_HATEFULSTRIKE HEROIC(41926,59192)
+#define SPELL_FRENZY 28131
#define SPELL_BERSERK 26662
#define SPELL_SLIMEBOLT 32309
+#define EVENT_BERSERK 1
+#define EVENT_HATEFUL 2
+#define EVENT_SLIME 3
+
struct TRINITY_DLL_DECL boss_patchwerkAI : public ScriptedAI
{
boss_patchwerkAI(Creature *c) : ScriptedAI(c) {}
- uint32 HatefullStrike_Timer;
- uint32 Enrage_Timer;
- uint32 Slimebolt_Timer;
bool Enraged;
+ EventMap events;
void Reset()
{
- HatefullStrike_Timer = 1200; //1.2 seconds
- Enrage_Timer = 420000; //7 minutes 420,000
- Slimebolt_Timer = 450000; //7.5 minutes 450,000
+ events.Reset();
Enraged = false;
}
void KilledUnit(Unit* Victim)
{
- if (rand()%5)
- return;
-
- DoScriptText(SAY_SLAY, m_creature);
+ if(!(rand()%5))
+ DoScriptText(SAY_SLAY, me);
}
void JustDied(Unit* Killer)
{
- DoScriptText(SAY_DEATH, m_creature);
+ DoScriptText(SAY_DEATH, me);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
- if (rand()%2)
- {
- DoScriptText(SAY_AGGRO1, m_creature);
- }
- else
- {
- DoScriptText(SAY_AGGRO2, m_creature);
- }
+ DoScriptText(rand()%2 ? SAY_AGGRO1 : SAY_AGGRO2, me);
+ DoZoneInCombat();
+ events.ScheduleEvent(EVENT_HATEFUL, 1200);
+ events.ScheduleEvent(EVENT_BERSERK, 360000);
}
void UpdateAI(const uint32 diff)
{
- if (!UpdateVictim())
+ if(!UpdateVictim())
return;
- //HatefullStrike_Timer
- if (HatefullStrike_Timer < diff)
+ events.Update(diff);
+
+ while(uint32 eventId = events.ExecuteEvent())
{
- //Cast Hateful strike on the player with the highest
- //amount of HP within melee distance
- uint32 MostHP = 0;
- Unit* pMostHPTarget = NULL;
- Unit* pTemp = NULL;
- std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
-
- for (i = m_creature->getThreatManager().getThreatList().begin(); i!=m_creature->getThreatManager().getThreatList().end();)
+ switch(eventId)
{
- pTemp = Unit::GetUnit((*m_creature),(*i)->getUnitGuid());
- ++i;
- if (pTemp && pTemp->isAlive() && pTemp->GetHealth() > MostHP && m_creature->GetDistance2d(pTemp) < 5)
+ case EVENT_HATEFUL:
{
- MostHP = pTemp->GetHealth();
- pMostHPTarget = pTemp;
+ //Cast Hateful strike on the player with the highest
+ //amount of HP within melee distance
+ uint32 MostHP = 0;
+ Unit* pMostHPTarget = NULL;
+ std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
+ for(; i != m_creature->getThreatManager().getThreatList().end();)
+ {
+ Unit* pTemp = Unit::GetUnit(*m_creature, (*i)->getUnitGuid());
+ ++i;
+ if (pTemp && pTemp->isAlive() && pTemp->GetHealth() > MostHP && m_creature->IsWithinMeleeRange(pTemp))
+ {
+ MostHP = pTemp->GetHealth();
+ pMostHPTarget = pTemp;
+ }
+ }
+
+ if (pMostHPTarget)
+ DoCast(pMostHPTarget, SPELL_HATEFULSTRIKE, true);
+
+ events.ScheduleEvent(EVENT_HATEFUL, 1200);
+ return;
}
+ case EVENT_BERSERK:
+ DoCast(m_creature, SPELL_BERSERK);
+ DoScriptText(EMOTE_BERSERK, m_creature);
+ events.ScheduleEvent(EVENT_SLIME, 2000);
+ return;
+ case EVENT_SLIME:
+ DoCast(m_creature->getVictim(), SPELL_SLIMEBOLT);
+ events.ScheduleEvent(EVENT_SLIME, 2000);
+ return;
}
+ }
- if (pMostHPTarget)
- DoCast(pMostHPTarget, SPELL_HATEFULSTRIKE);
-
- HatefullStrike_Timer = 1200;
- }else HatefullStrike_Timer -= diff;
-
- //Enrage_Timer
- if (Enrage_Timer < diff)
- {
- DoCast(m_creature, SPELL_BERSERK);
- DoScriptText(EMOTE_BERSERK, m_creature);
-
- Enrage_Timer = 300000;
- }else Enrage_Timer -= diff;
-
- //Slimebolt_Timer
- if (Slimebolt_Timer < diff)
- {
- DoCast(m_creature->getVictim(),SPELL_SLIMEBOLT);
- Slimebolt_Timer = 5000;
- }else Slimebolt_Timer -= diff;
-
- //Enrage if not already enraged and below 5%
- if (!Enraged && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 5)
+ if(!Enraged && HealthBelowPct(5))
{
- DoCast(m_creature,SPELL_ENRAGE);
- DoScriptText(EMOTE_ENRAGE,NULL);
+ DoCast(m_creature, SPELL_FRENZY);
+ DoScriptText(EMOTE_ENRAGE, NULL);
Enraged = true;
+ return;
}
DoMeleeAttackIfReady();
}
};
+
CreatureAI* GetAI_boss_patchwerk(Creature *_Creature)
{
return new boss_patchwerkAI (_Creature);
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp
index 9a8277264e5..64147eaea8a 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -89,7 +89,7 @@ struct TRINITY_DLL_DECL boss_razuviousAI : public ScriptedAI
DoPlaySoundToSet(m_creature, SOUND_DEATH);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
switch (rand()%3)
{
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp
index 43396199f5f..eecbb9cf980 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -63,10 +63,10 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI
Icebolt_Count = 0;
IsInFly = false;
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -103,7 +103,7 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI
{
phase = 2;
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveIdle();
m_creature->SetHover(true);
@@ -141,7 +141,7 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI
{
phase = 1;
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
m_creature->SetHover(true);
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_thaddius.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_thaddius.cpp
index a8bc620ec17..259c1589791 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_thaddius.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_thaddius.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -17,7 +17,7 @@
/* ScriptData
SDName: Boss_Thaddius
SD%Complete: 0
-SDComment: Merge Feugen & Stalagg with this script
+SDComment: Placeholder. Includes Feugen & Stalagg.
SDCategory: Naxxramas
EndScriptData */
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp
index e589630c15f..2ed8399f57a 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
diff --git a/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp b/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp
index 05a6c9b6bf8..5991777c5d7 100644
--- a/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp
+++ b/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -83,7 +83,7 @@ struct TRINITY_DLL_DECL npc_manaforge_control_consoleAI : public ScriptedAI
Creature* add = NULL;
}
- void Aggro(Unit *who) { return; }
+ void EnterCombat(Unit *who) { return; }
/*void SpellHit(Unit *caster, const SpellEntry *spell)
{
@@ -391,7 +391,7 @@ struct TRINITY_DLL_DECL npc_commander_dawnforgeAI : public ScriptedAI
isEvent = false;
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
//Select any creature in a grid
Creature* SelectCreatureInGrid(uint32 entry, float range)
@@ -404,7 +404,7 @@ struct TRINITY_DLL_DECL npc_commander_dawnforgeAI : public ScriptedAI
cell.SetNoCreate();
Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck creature_check(*m_creature, entry, true, range);
- Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(pCreature, creature_check);
+ Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(m_creature, pCreature, creature_check);
TypeContainerVisitor<Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer> creature_searcher(searcher);
@@ -441,8 +441,8 @@ struct TRINITY_DLL_DECL npc_commander_dawnforgeAI : public ScriptedAI
ardonis->SendUpdateToPlayer(player);
//Set them to kneel
- m_creature->SetStandState(PLAYER_STATE_KNEEL);
- ardonis->SetStandState(PLAYER_STATE_KNEEL);
+ m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
+ ardonis->SetStandState(UNIT_STAND_STATE_KNEEL);
}
//Set them back to each other
@@ -466,8 +466,8 @@ struct TRINITY_DLL_DECL npc_commander_dawnforgeAI : public ScriptedAI
ardonis->SendUpdateToPlayer(player);
//Set state
- m_creature->SetStandState(PLAYER_STATE_NONE);
- ardonis->SetStandState(PLAYER_STATE_NONE);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ ardonis->SetStandState(UNIT_STAND_STATE_STAND);
}
}
@@ -639,7 +639,7 @@ Creature* SearchDawnforge(Player *source, uint32 entry, float range)
cell.SetNoCreate();
Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck creature_check(*source, entry, true, range);
- Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(pCreature, creature_check);
+ Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(source, pCreature, creature_check);
TypeContainerVisitor<Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer> creature_searcher(searcher);
@@ -652,7 +652,7 @@ Creature* SearchDawnforge(Player *source, uint32 entry, float range)
bool AreaTrigger_at_commander_dawnforge(Player *player, AreaTriggerEntry *at)
{
//if player lost aura or not have at all, we should not try start event.
- if (!player->HasAura(SPELL_SUNFURY_DISGUISE,0))
+ if (!player->HasAura(SPELL_SUNFURY_DISGUISE))
return false;
if (player->isAlive() && player->GetQuestStatus(QUEST_INFO_GATHERING) == QUEST_STATUS_INCOMPLETE)
@@ -814,7 +814,7 @@ struct TRINITY_DLL_DECL mob_phase_hunterAI : public ScriptedAI
ManaBurnTimer = 5000 + (rand()%3 * 1000); // 5-8 sec cd
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(Player *player = who->GetCharmerOrOwnerPlayerOrPlayerItself())
PlayerGUID = player->GetGUID();
@@ -858,7 +858,7 @@ struct TRINITY_DLL_DECL mob_phase_hunterAI : public ScriptedAI
DoScriptText(EMOTE_WEAK, m_creature);
Weak = true;
}
- if(Weak && !Drained && m_creature->HasAura(34219, 0))
+ if(Weak && !Drained && m_creature->HasAura(34219))
{
Drained = true;
@@ -961,7 +961,7 @@ struct TRINITY_DLL_DECL npc_bessyAI : public npc_escortAI
summoned->AI()->AttackStart(m_creature);
}
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void Reset()
{
diff --git a/src/bindings/scripts/scripts/zone/nexus/eye_of_eternity/boss_malygos.cpp b/src/bindings/scripts/scripts/zone/nexus/eye_of_eternity/boss_malygos.cpp
new file mode 100644
index 00000000000..def7d32fa12
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/eye_of_eternity/boss_malygos.cpp
@@ -0,0 +1,170 @@
+/* Script Data Start
+SDName: Boss malygos
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_ARCANE_BREATH_N 56272
+#define SPELL_ARCANE_BREATH_H 60072
+#define SPELL_ARCANE_PULSE 57432
+#define SPELL_ARCANE_STORM_1 57459
+#define SPELL_ARCANE_STORM_2 61693
+#define SPELL_ARCANE_STORM_3 61694
+#define SPELL_STATIC_FIELD 57430
+#define SPELL_SURGE_OF_POWER_1 56505
+#define SPELL_SURGE_OF_POWER_2 57407
+#define SPELL_SURGE_OF_POWER_3 60936
+#define SPELL_VORTEX 56105
+
+//Dragon "mounts" spells in Phase3
+//they use Rugelike energy
+#define SPELL_DMOUNT_FLAME_SPIKE 56091 //maybe not accurate
+#define SPELL_DMOUNT_ENGULF_IN_FLAMES 61621
+#define SPELL_DMOUNT_REVIVIFY 57090
+#define SPELL_DMOUNT_LIFE_BURST 57143
+#define SPELL_DMOUNT_FLAME_SHIELD 57108
+//#define SPELL_DMOUNT_UNKNOWN XYZ //Increases your drake's flight speed by 500%.
+
+
+//Yell
+//-->Other
+#define SAY_ANTI_MAGIC_SHELL -1616000
+#define SAY_BREATH_ATTACK -1616001
+#define SAY_HIGH_DAMAGE_MODE -1616002
+#define SAY_MAGIC_BLAST -1616003
+//--> Generic Spells
+#define SAY_GENERIC_SPELL_1 -1616004
+#define SAY_GENERIC_SPELL_2 -1616005
+#define SAY_GENERIC_SPELL_3 -1616006
+#define SAY_DEATH -1616007
+//--> Prefight
+#define SAY_PREFIGHT_1 -1616008
+#define SAY_PREFIGHT_2 -1616009
+#define SAY_PREFIGHT_3 -1616010
+#define SAY_PREFIGHT_4 -1616011
+#define SAY_PREFIGHT_5 -1616012
+//--> Phase1
+#define SAY_PHASE1_AGGRO -1616013
+#define SAY_PHASE1_END -1616014
+#define SAY_PHASE1_SLAY_1 -1616015
+#define SAY_PHASE1_SLAY_2 -1616016
+#define SAY_PHASE1_SLAY_3 -1616017
+
+//--> Phase2 at 50% HP,
+
+/*Malygos himself is not targetable during this phase, it will end when the adds he spawns are all killed. However, he does continue to play a part in the encounter.
+During this phase he drops anti-magic zones onto the ground the raid MUST stand inside of, it reduces magical damage taken by 50%. They shrink over time, so it's important that your raid moves to each new one he drops.
+Throughout the phase, he will deep breath doing ~4k damage per second, unless you are standing inside of the anti-magic zone.
+The way the fight works during this phase is there are NPCs riding around on disks in the room. There are two types of mobs, Lords and Scions.
+The Lords will move down onto the group, and need to be tanked (They will one-shot a non-tank). After they die, they drop a disk that a raid member can mount onto, which allows them to fly, to attack the Scions that do not come down to the ground.
+It is recommended to let melee take the first disks, then ranged. As those mobs die, they also drop disks, which allows the rest of your dps to get onto them.
+The Scions will continually cast Arcane Blast on random targets on the floor, which is mitigated by the anti-magic zones. While mounted on a disk, you will not take damage.
+After all of the NPCs riding on the disks die, the players on the disks need to dismount as Phase 3 is about to begin.*/
+
+#define SAY_PHASE2_AGGRO -1616018
+#define SAY_PHASE2_END -1616019
+#define SAY_PHASE2_SLAY_1 -1616020
+#define SAY_PHASE2_SLAY_2 -1616021
+#define SAY_PHASE2_SLAY_3 -1616022
+//--> Phase3 Malygos destroys the floor, encounter continues on dragon "mounts"
+#define SAY_PHASE3_INTRO -1616023
+#define SAY_PHASE3_AGGRO -1616024
+#define SAY_PHASE3_SLAY_1 -1616025
+#define SAY_PHASE3_SLAY_2 -1616026
+#define SAY_PHASE3_SLAY_3 -1616027
+#define SAY_PHASE3_BIG_ATTACK -1616028
+
+struct TRINITY_DLL_DECL boss_malygosAI : public ScriptedAI
+{
+ boss_malygosAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 phase,
+ enrage;
+
+ void Reset()
+ {
+ //Source Deadly Boss Mod
+ enrage = 615000; //10 min
+ }
+ void EnterCombat(Unit* who)
+ {
+ if(phase == 1)
+ DoScriptText(SAY_PHASE1_AGGRO, m_creature);
+ if(phase == 2)
+ DoScriptText(SAY_PHASE1_AGGRO, m_creature);
+ if(phase == 3)
+ DoScriptText(SAY_PHASE1_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ phase =1;
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) <= 50){
+ phase = 2;
+ //spawn adds
+ //set malygos unatackable untill all adds spawned dead
+ //start phase3
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ if(phase ==1)
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_PHASE1_SLAY_1, m_creature); break;
+ case 1: DoScriptText(SAY_PHASE1_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_PHASE1_SLAY_3, m_creature);break;
+ }
+ if(phase ==2)
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_PHASE2_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_PHASE2_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_PHASE2_SLAY_3, m_creature);break;
+ }
+ if(phase ==3)
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_PHASE3_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_PHASE3_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_PHASE3_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_malygos(Creature *_Creature)
+{
+ return new boss_malygosAI (_Creature);
+}
+
+void AddSC_boss_malygos()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_malygos";
+ newscript->GetAI = GetAI_boss_malygos;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/nexus/eye_of_eternity/def_eye_of_eternity.h b/src/bindings/scripts/scripts/zone/nexus/eye_of_eternity/def_eye_of_eternity.h
new file mode 100644
index 00000000000..caa82a92e95
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/eye_of_eternity/def_eye_of_eternity.h
@@ -0,0 +1,4 @@
+#ifndef DEF_EYE_OF_ETERNITY_H
+#define DEF_EYE_OF_ETERNITY_H
+
+#endif
diff --git a/src/bindings/scripts/scripts/zone/nexus/eye_of_eternity/instance_eye_of_eternity.cpp b/src/bindings/scripts/scripts/zone/nexus/eye_of_eternity/instance_eye_of_eternity.cpp
new file mode 100644
index 00000000000..48d26f2bcd9
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/eye_of_eternity/instance_eye_of_eternity.cpp
@@ -0,0 +1,21 @@
+#include "precompiled.h"
+#include "def_eye_of_eternity.h"
+
+struct TRINITY_DLL_DECL instance_eye_of_eternity : public ScriptedInstance
+{
+ instance_eye_of_eternity(Map *Map) : ScriptedInstance(Map) {Initialize();};
+};
+
+InstanceData* GetInstanceData_instance_eye_of_eternity(Map* map)
+{
+ return new instance_eye_of_eternity(map);
+}
+
+void AddSC_instance_eye_of_eternity()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_eye_of_eternity";
+ newscript->GetInstanceData = GetInstanceData_instance_eye_of_eternity;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/nexus/nexus/boss_anomalus.cpp b/src/bindings/scripts/scripts/zone/nexus/nexus/boss_anomalus.cpp
new file mode 100644
index 00000000000..d06129ac2b2
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/nexus/boss_anomalus.cpp
@@ -0,0 +1,149 @@
+/* Script Data Start
+SDName: Boss anomalus
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_SPARK_1 47751
+#define SPELL_SPARK_2 57062
+#define SPELL_RIFT_SHIELD 47748
+#define SPELL_CHARGE_RIFT 47747
+#define SPELL_ARCANE_ATTRACTION 57063
+#define SPELL_CREATE_RIFT 47743 //Dummy ---> summons (npc 26918) "Chaotic Rift", which spawns "Crazed Mana Wraith"s (npc 26746)
+
+#define MOB_CRAZED_MANA_WRAITH 26746
+#define NPC_CHAOTIC_RIFT 26918
+
+//Yell
+#define SAY_AGGRO -1576000
+#define SAY_KILL -1576001
+#define SAY_DEATH -1576002
+#define SAY_RIFT -1576003
+#define SAY_SHIELD -1576004
+
+struct TRINITY_DLL_DECL boss_anomalusAI : public ScriptedAI
+{
+ boss_anomalusAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ //Source DBM
+ if((((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 80) && ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) > 77))
+ || (((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 55) && ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) > 52))
+ || (((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 30) && ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) > 27)))
+ {
+ //Summon rift at a random location
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ DoScriptText(SAY_KILL, m_creature);
+ }
+};
+
+/*######
+## Crazed Mana Wraiths
+######*/
+#define SPELL_ARCANE_MISSILES 33833
+
+struct TRINITY_DLL_DECL mob_crazed_mana_wraithAI : public ScriptedAI
+{
+ mob_crazed_mana_wraithAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer) {}
+};
+
+/*######
+## Chaotic Rift
+######*/
+#define SPELL_CHAOTIC_ENERGY_BURST 47688
+#define SPELL_CHARGED_CHAOTIC_ENERGY_BURST 47737
+
+struct TRINITY_DLL_DECL npc_chaotic_riftAI : public ScriptedAI
+{
+ npc_chaotic_riftAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer) {}
+};
+
+CreatureAI* GetAI_npc_chaotic_rift(Creature *_Creature)
+{
+ return new npc_chaotic_riftAI (_Creature);
+}
+
+CreatureAI* GetAI_boss_anomalus(Creature *_Creature)
+{
+ return new boss_anomalusAI (_Creature);
+}
+
+CreatureAI* GetAI_mob_crazed_mana_wraith(Creature *_Creature)
+{
+ return new boss_anomalusAI (_Creature);
+}
+
+void AddSC_boss_anomalus()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_anomalus";
+ newscript->GetAI = GetAI_boss_anomalus;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_crazed_mana_wraith";
+ newscript->GetAI = GetAI_mob_crazed_mana_wraith;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="npc_chaotic_rift";
+ newscript->GetAI = GetAI_npc_chaotic_rift;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/nexus/nexus/boss_keristrasza.cpp b/src/bindings/scripts/scripts/zone/nexus/nexus/boss_keristrasza.cpp
new file mode 100644
index 00000000000..05679a3f9d5
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/nexus/boss_keristrasza.cpp
@@ -0,0 +1,89 @@
+/* Script Data Start
+SDName: Boss keristrasza
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_maiden_of_grief' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_TAIL_SWEEP 50155
+#define SPELL_CRYSTAL_CHAINS 50997
+#define SPELL_ENRAGE 8599
+#define SPELL_CRYSTALFIRE_BREATH_1 48096
+#define SPELL_CRYSTALFIRE_BREATH_2 57091
+#define SPELL_CRYSTALIZE 48179
+#define SPELL_INTENSE_COLD 48095 //stackable debuff
+
+//Yell
+#define SAY_AGGRO -1576005
+#define SAY_SLAY -1576006
+#define SAY_ENRAGE -1576007
+#define SAY_DEATH -1576008
+#define SAY_CRYSTAL_NOVA -1576009
+
+struct TRINITY_DLL_DECL boss_keristraszaAI : public ScriptedAI
+{
+ boss_keristraszaAI(Creature *c) : ScriptedAI(c) {}
+
+ bool enraged;
+
+ void Reset()
+ {
+ enraged = false;
+ }
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) == 10)
+ {
+ if(!enraged)
+ {
+ DoScriptText(SAY_ENRAGE, m_creature);
+ DoCast(m_creature, SPELL_ENRAGE);
+ enraged = true;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ DoScriptText(SAY_SLAY, m_creature);
+ }
+};
+
+CreatureAI* GetAI_boss_keristrasza(Creature *_Creature)
+{
+ return new boss_keristraszaAI (_Creature);
+}
+
+void AddSC_boss_keristrasza()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_keristrasza";
+ newscript->GetAI = GetAI_boss_keristrasza;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/nexus/nexus/boss_magus_telestra.cpp b/src/bindings/scripts/scripts/zone/nexus/nexus/boss_magus_telestra.cpp
new file mode 100644
index 00000000000..ee8018ecfc4
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/nexus/boss_magus_telestra.cpp
@@ -0,0 +1,118 @@
+/* Script Data Start
+SDName: Boss magus_telestra
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+#include "def_nexus.h"
+
+
+//Spells
+
+//phase 1
+#define SPELL_ICE_NOVA 47772
+#define SPELL_ICE_NOVA 56935
+#define SPELL_FIREBOMB 47773
+#define SPELL_FIREBOMB 56934
+#define SPELL_GAVITY_WELL 47756
+
+//Phase 2 -->50% HP (3 clones, Frost, Fire, Arcane)
+//Frost Magus (npc 26930)
+#define FROST_MAGUS_VISUAL 47706 //Dummy
+#define SPELL_BLIZZARD_N 47727
+#define SPELL_ICE_BARB_N 47729
+//heroic
+#define SPELL_BLIZZARD_H 56936
+#define SPELL_ICE_BARB_H 56937
+
+//Fire Magus (npc 26928)
+#define FIRE_MAGUS_VISUAL 47705 //Dummy
+#define SPELL_FIRE_BLAST 47721
+#define SPELL_SCORCH 47723
+//heroic
+#define SPELL_FIRE_BLAST_H 56939
+#define SPELL_SCORCH_H 56938
+
+//Arcane Magus (npc 26929)
+#define ARCANE_MAGUS_VISUAL 47704 //Dummy
+#define SPELL_CRITTER 47731
+#define SPELL_TIME_STOP 47736
+
+//Yell
+#define SAY_AGGRO -1576010
+#define SAY_KILL -1576011
+#define SAY_DEATH -1576012
+#define SAY_MERGE -1576013
+#define SAY_SPLIT_1 -1576014
+#define SAY_SPLIT_2 -1576015
+
+
+struct TRINITY_DLL_DECL boss_magus_telestraAI : public ScriptedAI
+{
+ boss_magus_telestraAI(Creature *c) : ScriptedAI(c) {}
+
+ bool splited;
+ uint64 Magus_frost,
+ Magus_fire,
+ Magus_arcane;
+
+ void Reset()
+ {
+ splited = false;
+ }
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ if(!splited)
+ {
+ if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) <= 50)
+ {
+ DoScriptText(SAY_SPLIT_1, m_creature);
+ //HandleSplit
+ splited = true;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ DoScriptText(SAY_KILL, m_creature);
+ }
+};
+
+CreatureAI* GetAI_boss_magus_telestra(Creature *_Creature)
+{
+ return new boss_magus_telestraAI (_Creature);
+}
+
+void AddSC_boss_magus_telestra()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_magus_telestra";
+ newscript->GetAI = GetAI_boss_magus_telestra;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/nexus/nexus/boss_ormorok.cpp b/src/bindings/scripts/scripts/zone/nexus/nexus/boss_ormorok.cpp
new file mode 100644
index 00000000000..d134cc43244
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/nexus/boss_ormorok.cpp
@@ -0,0 +1,90 @@
+/* Script Data Start
+SDName: Boss ormorok
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_CRYSTAL_SPIKES_1 47958
+#define SPELL_CRYSTAL_SPIKES_2 57082
+#define SPELL_CRYSTAL_SPIKES_3 57083
+#define SPELL_SPELL_REFLECTION 47981
+#define SPELL_TRAMPLE_N 48016
+#define SPELL_TRAMPLE_H 57066
+#define SPELL_FRENZY_N 48017
+#define SPELL_FRENZY_H 57086
+#define SPELL_SUMMON_CRYSTALLINE_TANGLER 61564 //summons npc 32665
+
+//Yell
+#define SAY_AGGRO -1576016
+#define SAY_KILL -1576017
+#define SAY_DEATH -1576018
+#define SAY_REFLECT -1576019
+#define SAY_ICE_SPIKES -1576020
+
+struct TRINITY_DLL_DECL boss_ormorokAI : public ScriptedAI
+{
+ boss_ormorokAI(Creature *c) : ScriptedAI(c) {}
+
+ bool frenzy;
+
+ void Reset()
+ {
+ frenzy = false;
+ }
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) == 25)
+ {
+ if(!frenzy)
+ {
+ DoCast(m_creature, SPELL_FRENZY_N);
+ frenzy = true;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ DoScriptText(SAY_KILL, m_creature);
+ }
+};
+
+CreatureAI* GetAI_boss_ormorok(Creature *_Creature)
+{
+ return new boss_ormorokAI (_Creature);
+}
+
+void AddSC_boss_ormorok()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_ormorok";
+ newscript->GetAI = GetAI_boss_ormorok;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/nexus/nexus/commander_kolurg.cpp b/src/bindings/scripts/scripts/zone/nexus/nexus/commander_kolurg.cpp
new file mode 100644
index 00000000000..ece7877cc7a
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/nexus/commander_kolurg.cpp
@@ -0,0 +1,57 @@
+/* Script Data Start
+SDName: Boss Commander Kolurg
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment: Only Alliance Heroic
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_commander_kolurg' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+#define SPELL_BATTLE_SHOUT 31403
+#define SPELL_CHARGE 60067
+#define SPELL_FRIGHTENING_SHOUT 19134
+#define SPELL_WHIRLWIND_1 38619
+#define SPELL_WHIRLWIND_2 38618
+
+//Yell
+#define SAY_AGGRO 1576024
+#define SAY_KILL 1576025
+#define SAY_DEATH 1576026
+
+struct TRINITY_DLL_DECL boss_commander_kolurgAI : public ScriptedAI
+{
+ boss_commander_kolurgAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who) {}
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer) {}
+};
+
+CreatureAI* GetAI_boss_commander_kolurg(Creature *_Creature)
+{
+ return new boss_commander_kolurgAI (_Creature);
+}
+
+void AddSC_boss_commander_kolurg()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_commander_kolurg";
+ newscript->GetAI = GetAI_boss_commander_kolurg;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/nexus/nexus/commander_stoutbeard.cpp b/src/bindings/scripts/scripts/zone/nexus/nexus/commander_stoutbeard.cpp
new file mode 100644
index 00000000000..6f3236629c7
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/nexus/commander_stoutbeard.cpp
@@ -0,0 +1,63 @@
+/* Script Data Start
+SDName: Boss Commander Stoutbeard
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment: Only Horde Heroic
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_commander_stoutbeard' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+#define SPELL_BATTLE_SHOUT 31403
+#define SPELL_CHARGE 60067
+#define SPELL_FRIGHTENING_SHOUT 19134
+#define SPELL_WHIRLWIND_1 38619
+#define SPELL_WHIRLWIND_2 38618
+
+//Yell
+#define SAY_AGGRO 1576021
+#define SAY_KILL 1576022
+#define SAY_DEATH 1576023
+
+struct TRINITY_DLL_DECL boss_commander_stoutbeardAI : public ScriptedAI
+{
+ boss_commander_stoutbeardAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+};
+
+CreatureAI* GetAI_boss_commander_stoutbeard(Creature *_Creature)
+{
+ return new boss_commander_stoutbeardAI (_Creature);
+}
+
+void AddSC_boss_commander_stoutbeard()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_commander_stoutbeard";
+ newscript->GetAI = GetAI_boss_commander_stoutbeard;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/nexus/nexus/def_nexus.h b/src/bindings/scripts/scripts/zone/nexus/nexus/def_nexus.h
new file mode 100644
index 00000000000..d868c72adf6
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/nexus/def_nexus.h
@@ -0,0 +1,35 @@
+#ifndef DEF_NEXUS_H
+#define DEF_NEXUS_H
+
+#define DATA_ANOMALUSDEAD 1
+#define DATA_ANOMALUS_DEATH 2
+#define DATA_ORMOROKDDEAD 3
+#define DATA_ORMOROK_DEATH 4
+
+#define DATA_MAGUSTELESTRADEAD 5
+#define DATA_MAGUSTELESTRA_DEATH 6
+#define DATA_MAGUSTELESTRA_A_DEAD 7
+#define DATA_MAGUSTELESTRA_A_DEATH 8
+#define DATA_MAGUSTELESTRA_F_DEAD 9
+#define DATA_MAGUSTELESTRA_F_DEATH 10
+#define DATA_MAGUSTELESTRA_FI_DEAD 11
+#define DATA_MAGUSTELESTRA_FI_DEATH 12
+
+#define DATA_KERISTRASZADEAD 13
+#define DATA_KERISTRASZA_DEATH 14
+#define DATA_COMMANDER_KOLURGDEAD 15
+#define DATA_COMMANDER_KOLURG_DEATH 16
+#define DATA_COMMANDER_STOUTBEARDDEAD 17
+#define DATA_COMMANDER_STOUTBEARD_DEATH 18
+#define DATA_ANOMALUS 19
+#define DATA_ORMOROK 20
+
+#define DATA_MAGUSTELESTRA 21
+#define DATA_MAGUSTELESTRA_A 22
+#define DATA_MAGUSTELESTRA_F 23
+#define DATA_MAGUSTELESTRA_FI 24
+
+#define DATA_KERISTRASZA 25
+#define DATA_COMMANDER_KOLURG 26
+#define DATA_COMMANDER_STOUTBEARD 27
+#endif
diff --git a/src/bindings/scripts/scripts/zone/nexus/nexus/instance_nexus.cpp b/src/bindings/scripts/scripts/zone/nexus/nexus/instance_nexus.cpp
new file mode 100644
index 00000000000..7f07b372be9
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/nexus/instance_nexus.cpp
@@ -0,0 +1,158 @@
+#include "precompiled.h"
+#include "def_nexus.h"
+
+struct TRINITY_DLL_DECL instance_nexus : public ScriptedInstance
+{
+ instance_nexus(Map *Map) : ScriptedInstance(Map) {Initialize();};
+
+ uint64 Anomalus,
+ Ormorok,
+ Magus_telestra,
+ Magus_frost,
+ Magus_fire,
+ Magus_arcane,
+ keristrasza,
+ Commander_kolurg,
+ Commander_stoutbeard;
+ bool IsBossDied[9];
+
+ void Initialize()
+ {
+ Anomalus = 0;
+ Ormorok = 0;
+ Magus_telestra =0;
+ Magus_frost =0;
+ Magus_fire =0;
+ Magus_arcane =0;
+ keristrasza =0;
+ Commander_kolurg = 0;
+ Commander_stoutbeard = 0;
+ IsBossDied[0] = false;
+ IsBossDied[1] = false;
+ IsBossDied[2] = false;
+ IsBossDied[3] = false;
+ IsBossDied[4] = false;
+ IsBossDied[5] = false;
+ IsBossDied[6] = false;
+ IsBossDied[7] = false;
+ IsBossDied[8] = false;
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ //not active
+ return false;
+ }
+ void OnCreatureCreate(Creature *creature, uint32 creature_entry)
+ {
+ switch(creature->GetEntry())
+ {
+ case 26763: Anomalus = creature->GetGUID(); break;
+ case 26794: Ormorok = creature->GetGUID(); break;
+ case 26731: Magus_telestra = creature->GetGUID(); break;
+ case 26930: Magus_frost = creature->GetGUID(); break;
+ case 26928: Magus_fire = creature->GetGUID(); break;
+ case 26926: Magus_arcane = creature->GetGUID(); break;
+ case 26723: keristrasza = creature->GetGUID(); break;
+ case 26798: Commander_kolurg = creature->GetGUID(); break;
+ case 26796: Commander_stoutbeard = creature->GetGUID(); break;
+ }
+ }
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_ANOMALUSDEAD:
+ if(IsBossDied[0])
+ return 1;
+ break;
+ case DATA_ORMOROKDDEAD:
+ if(IsBossDied[1])
+ return 1;
+ break;
+ case DATA_MAGUSTELESTRADEAD:
+ if(IsBossDied[2])
+ return 1;
+ break;
+ case DATA_MAGUSTELESTRA_A_DEAD:
+ if(IsBossDied[3])
+ return 1;
+ break;
+ case DATA_MAGUSTELESTRA_F_DEAD:
+ if(IsBossDied[4])
+ return 1;
+ break;
+ case DATA_MAGUSTELESTRA_FI_DEAD:
+ if(IsBossDied[5])
+ return 1;
+ break;
+ case DATA_KERISTRASZADEAD:
+ if(IsBossDied[6])
+ return 1;
+ break;
+ case DATA_COMMANDER_KOLURGDEAD:
+ if(IsBossDied[7])
+ return 1;
+ break;
+ case DATA_COMMANDER_STOUTBEARDDEAD:
+ if(IsBossDied[8])
+ return 1;
+ break;
+ }
+
+ return 0;
+ }
+
+ uint64 GetData64 (uint32 identifier)
+ {
+ return 0;
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_ANOMALUS_DEATH:
+ IsBossDied[0] = true;
+ break;
+ case DATA_ORMOROK_DEATH:
+ IsBossDied[1] = true;
+ break;
+ case DATA_MAGUSTELESTRA_DEATH:
+ IsBossDied[2] = true;
+ break;
+ case DATA_MAGUSTELESTRA_A_DEATH:
+ IsBossDied[3] = true;
+ break;
+ case DATA_MAGUSTELESTRA_F_DEATH:
+ IsBossDied[4] = true;
+ break;
+ case DATA_MAGUSTELESTRA_FI_DEAD:
+ IsBossDied[5] = true;
+ break;
+ case DATA_KERISTRASZA_DEATH:
+ IsBossDied[6] = true;
+ break;
+ case DATA_COMMANDER_KOLURG_DEATH:
+ IsBossDied[7] = true;
+ break;
+ case DATA_COMMANDER_STOUTBEARD_DEATH:
+ IsBossDied[8] = true;
+ break;
+ }
+ }
+};
+
+InstanceData* GetInstanceData_instance_nexus(Map* map)
+{
+ return new instance_nexus(map);
+}
+
+void AddSC_instance_nexus()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_nexus";
+ newscript->GetInstanceData = GetInstanceData_instance_nexus;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/nexus/oculus/boss_drakos.cpp b/src/bindings/scripts/scripts/zone/nexus/oculus/boss_drakos.cpp
new file mode 100644
index 00000000000..6ecb53f1ccb
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/oculus/boss_drakos.cpp
@@ -0,0 +1,82 @@
+/* Script Data Start
+SDName: Boss drakos
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_MAGIC_PULL 51336
+#define SPELL_THUNDERING_STOMP 50774
+#define SPELL_THUNDERING_STOMP_2 59370
+
+//Yell
+#define SAY_AGGRO -1578000
+#define SAY_KILL_1 -1578001
+#define SAY_KILL_2 -1578002
+#define SAY_KILL_3 -1578003
+#define SAY_DEATH -1578004
+#define SAY_PULL_1 -1578005
+#define SAY_PULL_2 -1578006
+#define SAY_PULL_3 -1578007
+#define SAY_PULL_4 -1578008
+#define SAY_STOMP_1 -1578009
+#define SAY_STOMP_2 -1578010
+#define SAY_STOMP_3 -1578011
+
+struct TRINITY_DLL_DECL boss_drakosAI : public ScriptedAI
+{
+ boss_drakosAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_KILL_1, m_creature);break;
+ case 1: DoScriptText(SAY_KILL_2, m_creature);break;
+ case 2: DoScriptText(SAY_KILL_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_drakos(Creature *_Creature)
+{
+ return new boss_drakosAI (_Creature);
+}
+
+void AddSC_boss_drakos()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_drakos";
+ newscript->GetAI = GetAI_boss_drakos;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/nexus/oculus/boss_eregos.cpp b/src/bindings/scripts/scripts/zone/nexus/oculus/boss_eregos.cpp
new file mode 100644
index 00000000000..4ab0ca59bdf
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/oculus/boss_eregos.cpp
@@ -0,0 +1,104 @@
+/* Script Data Start
+SDName: Boss eregos
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment: Encounter is done entirely on drake vehicles
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Types of drake mounts: Ruby(Tank), Amber(DPS), Emerald(Healer)
+//Two Repeating phases
+
+//Spells
+#define SPELL_ARCANE_BARRAGE 50804
+#define SPELL_ARCANE_VOLLEY 51153
+#define SPELL_ENRAGED_ASSAULT 51170
+#define SPELL_PLANAR_ANOMALIES 57959
+#define SPELL_PLANAR_SHIFT 51162
+
+//Heroic
+#define SPELL_ARCANE_BARRAGE_H 59381
+#define SPELL_ARCANE_VOLLEY_H 59382
+
+/*Ruby Drake ,
+(npc 27756) (item 37860)
+(summoned by spell Ruby Essence = 37860 ---> Call Amber Drake == 49462 ---> Summon 27756)
+*/
+#define NPC_RUBY_DRAKE_VEHICLE 27756
+#define SPELL_RIDE_RUBY_DRAKE_QUE 49463 //Apply Aura: Periodic Trigger, Interval: 3 seconds ---> 49464
+#define SPELL_RUBY_DRAKE_SADDLE 49464 //Allows you to ride on the back of an Amber Drake. ---> Dummy
+
+#define SPELL_RUBY_SEARING_WRATH 50232 //(60 yds) - Instant - Breathes a stream of fire at an enemy dragon, dealing 6800 to 9200 Fire damage and then jumping to additional dragons within 30 yards. Each jump increases the damage by 50%. Affects up to 5 total targets
+#define SPELL_RUBY_EVASIVE_AURA 50248 //Instant - Allows the Ruby Drake to generate Evasive Charges when hit by hostile attacks and spells.
+#define SPELL_RUBY_EVASIVE_MANEUVERS 50240 //Instant - 5 sec. cooldown - Allows your drake to dodge all incoming attacks and spells. Requires Evasive Charges to use. Each attack or spell dodged while this ability is active burns one Evasive Charge. Lasts 30 sec. or until all charges are exhausted.
+//you do not have acces to until you kill Mage-Lord Urom
+#define SPELL_RUBY_MARTYR 50253 //Instant - 10 sec. cooldown - Redirect all harmful spells cast at friendly drakes to yourself for 10 sec.
+
+/*Amber Drake,
+(npc 27755) (item 37859)
+(summoned by spell Amber Essence = 37859 ---> Call Amber Drake == 49461 ---> Summon 27755)
+*/
+#define NPC_AMBER_DRAKE_VEHICLE 27755
+#define SPELL_RIDE_AMBER_DRAKE_QUE 49459 //Apply Aura: Periodic Trigger, Interval: 3 seconds ---> 49460
+#define SPELL_AMBER_DRAKE_SADDLE 49460 //Allows you to ride on the back of an Amber Drake. ---> Dummy
+
+#define SPELL_AMBER_SHOCK_LANCE 49840 //(60 yds) - Instant - Deals 4822 to 5602 Arcane damage and detonates all Shock Charges on an enemy dragon. Damage is increased by 6525 for each detonated.
+#define SPELL_AMBER_STOP_TIME //Instant - 1 min cooldown - Halts the passage of time, freezing all enemy dragons in place for 10 sec. This attack applies 5 Shock Charges to each affected target.
+//you do not have access to until you kill the Mage-Lord Urom.
+#define SPELL_AMBER_TEMPORAL_RIFT 49592 //(60 yds) - Channeled - Channels a temporal rift on an enemy dragon for 10 sec. While trapped in the rift, all damage done to the target is increased by 100%. In addition, for every 15,000 damage done to a target affected by Temporal Rift, 1 Shock Charge is generated.
+
+/*Emerald Drake,
+(npc 27692) (item 37815),
+ (summoned by spell Emerald Essence = 37815 ---> Call Emerald Drake == 49345 ---> Summon 27692)
+*/
+#define NPC_EMERALD_DRAKE_VEHICLE 27692
+#define SPELL_RIDE_EMERALD_DRAKE_QUE 49427 //Apply Aura: Periodic Trigger, Interval: 3 seconds ---> 49346
+#define SPELL_EMERALD_DRAKE_SADDLE 49346 //Allows you to ride on the back of an Amber Drake. ---> Dummy
+
+#define SPELL_EMERALD_LEECHING_POISON 50328 //(60 yds) - Instant - Poisons the enemy dragon, leeching 1300 to the caster every 2 sec. for 12 sec. Stacks up to 3 times.
+#define SPELL_EMERALD_TOUCH_THE_NIGHTMARE 50341 //(60 yds) - Instant - Consumes 30% of the caster's max health to inflict 25,000 nature damage to an enemy dragon and reduce the damage it deals by 25% for 30 sec.
+// you do not have access to until you kill the Mage-Lord Urom
+#define SPELL_EMERALD_DREAM_FUNNEL 50344 //(60 yds) - Channeled - Transfers 5% of the caster's max health to a friendly drake every second for 10 seconds as long as the caster channels.
+
+struct TRINITY_DLL_DECL boss_eregosAI : public ScriptedAI
+{
+ boss_eregosAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 phase;
+
+ void Reset() {}
+ void EnterCombat(Unit* who) {}
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ phase =1;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer) {}
+};
+
+CreatureAI* GetAI_boss_eregos(Creature *_Creature)
+{
+ return new boss_eregosAI (_Creature);
+}
+
+void AddSC_boss_eregos()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_eregos";
+ newscript->GetAI = GetAI_boss_eregos;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/nexus/oculus/boss_urom.cpp b/src/bindings/scripts/scripts/zone/nexus/oculus/boss_urom.cpp
new file mode 100644
index 00000000000..793696ac2cd
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/oculus/boss_urom.cpp
@@ -0,0 +1,87 @@
+/* Script Data Start
+SDName: Boss urom
+SDAuthor: LordVanMartin
+SD%Complete: 1%
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_ARCANE_SHIELD 53813 //Dummy --> Channeled, shields the caster from damage.
+#define SPELL_EMPOWERED_ARCANE_EXPLOSION 51110
+#define SPELL_EMPOWERED_ARCANE_EXPLOSION_2 59377
+#define SPELL_FROSTBOMB 51103 //Urom throws a bomb, hitting its target with the highest aggro which inflict directly 650 frost damage and drops a frost zone on the ground. This zone deals 650 frost damage per second and reduce the movement speed by 35%. Lasts 1 minute.
+#define SPELL_SUMMON_MENAGERIE 50476 //Summons an assortment of creatures and teleports the caster to safety.
+#define SPELL_SUMMON_MENAGERIE_2 50495
+#define SPELL_SUMMON_MENAGERIE_3 50496
+#define SPELL_TELEPORT 51112 //Teleports to the center of Oculus
+#define SPELL_TIME_BOMB 51121 //Deals arcane damage to a random player, and after 6 seconds, deals zone damage to nearby equal to the health missing of the target afflicted by the debuff.
+#define SPELL_TIME_BOMB_2 59376
+
+//Yell
+#define SAY_AGGRO -1578012
+#define SAY_KILL_1 -1578013
+#define SAY_KILL_2 -1578014
+#define SAY_KILL_3 -1578015
+#define SAY_DEATH -1578016
+#define SAY_EXPLOSION_1 -1578017
+#define SAY_EXPLOSION_2 -1578018
+#define SAY_SUMMON_1 -1578019
+#define SAY_SUMMON_2 -1578020
+#define SAY_SUMMON_3 -1578021
+
+struct TRINITY_DLL_DECL boss_uromAI : public ScriptedAI
+{
+ boss_uromAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_KILL_1, m_creature);break;
+ case 1: DoScriptText(SAY_KILL_2, m_creature);break;
+ case 2: DoScriptText(SAY_KILL_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_urom(Creature *_Creature)
+{
+ return new boss_uromAI (_Creature);
+}
+
+void AddSC_boss_urom()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_urom";
+ newscript->GetAI = GetAI_boss_urom;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/nexus/oculus/boss_varos.cpp b/src/bindings/scripts/scripts/zone/nexus/oculus/boss_varos.cpp
new file mode 100644
index 00000000000..a14f616fc01
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/oculus/boss_varos.cpp
@@ -0,0 +1,85 @@
+/* Script Data Start
+SDName: Boss varos
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_ENERGIZE_CORES 50785 //Damage 5938 to 6562, effec2 Triggers 54069, effect3 Triggers 56251
+#define SPELL_ENERGIZE_CORES_TRIGGER_1 54069
+#define SPELL_ENERGIZE_CORES_TRIGGER_2 56251
+#define SPELL_ENERGIZE_CORES_2 59372 //Damage 9025 to 9975, effect2 Triggers 54069, effect 56251
+#define SPELL_CALL_AZURE_RING_CAPTAIN 51002 //Effect Send Event (12229)
+#define SPELL_CALL_AZURE_RING_CAPTAIN_2 51006 //Effect Send Event (10665)
+#define SPELL_CALL_AZURE_RING_CAPTAIN_3 51007 //Effect Send Event (18454)
+#define SPELL_CALL_AZURE_RING_CAPTAIN_4 51008 //Effect Send Event (18455)
+#define SPELL_CALL_AMPLIFY_MAGIC 51054
+#define SPELL_CALL_AMPLIFY_MAGIC_2 59371
+
+//Yell
+#define SAY_AGGRO -1578022
+#define SAY_KILL_1 -1578023
+#define SAY_KILL_2 -1578024
+#define SAY_DEATH -1578025
+#define SAY_STRIKE_1 -1578026
+#define SAY_STRIKE_2 -1578027
+#define SAY_STRIKE_3 -1578028
+#define SAY_SPAWN -1578029
+
+
+struct TRINITY_DLL_DECL boss_varosAI : public ScriptedAI
+{
+ boss_varosAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%2)
+ {
+ case 0: DoScriptText(SAY_KILL_1, m_creature);break;
+ case 1: DoScriptText(SAY_KILL_2, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_varos(Creature *_Creature)
+{
+ return new boss_varosAI (_Creature);
+}
+
+void AddSC_boss_varos()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_varos";
+ newscript->GetAI = GetAI_boss_varos;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/nexus/oculus/def_oculus.h b/src/bindings/scripts/scripts/zone/nexus/oculus/def_oculus.h
new file mode 100644
index 00000000000..0b63a52d866
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/oculus/def_oculus.h
@@ -0,0 +1,4 @@
+#ifndef DEF_OCULUS_H
+#define DEF_OCULUS_H
+
+#endif
diff --git a/src/bindings/scripts/scripts/zone/nexus/oculus/instance_oculus.cpp b/src/bindings/scripts/scripts/zone/nexus/oculus/instance_oculus.cpp
new file mode 100644
index 00000000000..ecf6bcfae89
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/nexus/oculus/instance_oculus.cpp
@@ -0,0 +1,21 @@
+#include "precompiled.h"
+#include "def_oculus.h"
+
+struct TRINITY_DLL_DECL instance_oculus : public ScriptedInstance
+{
+ instance_oculus(Map *Map) : ScriptedInstance(Map) {Initialize();};
+};
+
+InstanceData* GetInstanceData_instance_oculus(Map* map)
+{
+ return new instance_oculus(map);
+}
+
+void AddSC_instance_oculus()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_oculus";
+ newscript->GetInstanceData = GetInstanceData_instance_oculus;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/obsidian_sanctum/boss_sartharion.cpp b/src/bindings/scripts/scripts/zone/obsidian_sanctum/boss_sartharion.cpp
new file mode 100644
index 00000000000..7e71a0f527f
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/obsidian_sanctum/boss_sartharion.cpp
@@ -0,0 +1,300 @@
+/* Script Data Start
+SDName: Boss sartharion
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Sartharion Spells
+#define SPELL_BERSERK 61632 // Increases the caster's attack speed by 150% and all damage it deals by 500% for 5 min.
+#define SPELL_CLEAVE 56909 // Inflicts 35% weapon damage to an enemy and its nearest allies, affecting up to 10 targets.
+#define SPELL_FLAME_BREATH_N 56908 // Inflicts 8750 to 11250 Fire damage to enemies in a cone in front of the caster.
+#define SPELL_FLAME_BREATH_H 58956 // Inflicts 10938 to 14062 Fire damage to enemies in a cone in front of the caster.
+#define SPELL_TAIL_LASH_N 56910 // A sweeping tail strike hits all enemies behind the caster, inflicting 3063 to 3937 damage and stunning them for 2 sec.
+#define SPELL_TAIL_LASH_H 58957 // A sweeping tail strike hits all enemies behind the caster, inflicting 4375 to 5625 damage and stunning them for 2 sec.
+#define SPELL_WILL_OF_SARTHARION 61254 // Sartharion's presence bolsters the resolve of the Twilight Drakes, increasing their total health by 25%. This effect also increases Sartharion's health by 25%.
+#define SPELL_POWER_OF_SARTHARION 61254 //Shadron's presence increases Fire damage taken by all enemies by 100%.
+
+//Sartharion Yell
+#define SAY_SARTHARION_AGGRO -1615016
+#define SAY_SARTHARION_BERSERK -1615017
+#define SAY_SARTHARION_BREATH -1615018
+#define SAY_SARTHARION_CALL_SHADRON -1615019
+#define SAY_SARTHARION_CALL_TENEBRON -1615020
+#define SAY_SARTHARION_CALL_VESPERON -1615021
+#define SAY_SARTHARION_DEATH -1615022
+#define SAY_SARTHARION_SPECIAL_1 -1615023
+#define SAY_SARTHARION_SPECIAL_2 -1615024
+#define SAY_SARTHARION_SPECIAL_3 -1615025
+#define SAY_SARTHARION_SPECIAL_4 -1615026
+#define SAY_SARTHARION_SLAY_1 -1615027
+#define SAY_SARTHARION_SLAY_2 -1615028
+#define SAY_SARTHARION_SLAY_3 -1615029
+
+//Miniboses (Vesperon, Shadron, Tenebron)
+#define SPELL_SHADOW_BREATH_H 59126 //Inflicts 8788 to 10212 Fire damage to enemies in a cone in front of the caster.
+#define SPELL_SHADOW_BREATH_N 57570 //Inflicts 6938 to 8062 Fire damage to enemies in a cone in front of the caster.
+//TAIL LASH the same as Sartharion's
+#define SPELL_SHADOW_FISSURE_H 59127 //Deals 9488 to 13512 Shadow damage to any enemy within the Shadow fissure after 5 sec.
+#define SPELL_SHADOW_FISSURE_N 57579 //Deals 6188 to 8812 Shadow damage to any enemy within the Shadow fissure after 5 sec.
+
+//Vesperon
+#define MINIBOSS_VESPERON 30449 //npc 30449 //In portal is a disciple, when disciple killed remove Power_of_vesperon, portal spawns multiple times
+#define BUFF_POWER_OF_VESPERON 61251 //Vesperon's presence decreases the maximum health of all enemies by 25%.
+
+//Shadron
+#define MINIBOSS_SHADRON 30451 //npc 30451 //In portal is a disciple, when disciple killed remove Power_of_vesperon, portal spawns multiple times
+#define BUFF_POWER_OF_SHADRON 58105 //Shadron's presence increases Fire damage taken by all enemies by 100%.
+
+//Tenebron
+#define MINIBOSS_TENEBRON 30452 //npc 30452 //in the portal spawns 6 eggs, if not killed in time (approx. 20s) they will hatch, whelps can cast 60708
+#define BUFF_POWER_OF_TENEBRON 61248 //Tenebron's presence increases Shadow damage taken by all enemies by 100%.
+
+//Minibosses common spells
+#define SPELL_SHADOW_BREATH_N 57570
+#define SPELL_SHADOW_BREATH_H 59126
+#define SPELL_SHADOW_FISSURE_N 57579
+#define SPELL_SHADOW_FISSURE_H 59127
+#define SPELL_TWILIGHT_REVENGE 60639
+
+//Tenebron, dummy spell
+#define SPELL_HATCH_EGGS 58793
+
+//Whelps
+#define TWILIGHT_WHELP 30890 //npc 30890
+#define SHARTHARION_TWILIGHT_WHELP 31214 //npc 31214
+#define SPELL_FADE_ARMOR 60708 //Reduces the armor of an enemy by 1500 for 15s
+
+/*Summons a portal, which all DPS and one healer should go through and proceed to kill all eggs. After about 20 seconds these eggs will hatch into whelplings with 60k health. Whelplings that hatched should be picked up by a tank and killed.
+Hatch Eggs Tenebron summons a portal in which eggs are spawned. After about 20s the eggs hatches into Whelps (156,396 hp - amount of whelps determined by Normal or Heroic mode) that do Fade Armor. */
+
+struct TRINITY_DLL_DECL boss_sartharionAI : public ScriptedAI
+{
+ boss_sartharionAI(Creature *c) : ScriptedAI(c) {}
+
+ bool berserk;
+
+ void Reset()
+ {
+ berserk = false;
+ }
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_SARTHARION_DEATH,m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) <= 10)
+ {
+ if(!berserk){
+ DoCast(m_creature,SPELL_BERSERK);
+ berserk = true;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_SARTHARION_DEATH,m_creature);
+ }
+};
+
+/*######
+## Mob Vesperon
+######*/
+
+//Vesperon Yell
+#define SAY_VESPERON_AGGRO -1615030
+#define SAY_VESPERON_SLAY_1 -1615031
+#define SAY_VESPERON_SLAY_2 -1615032
+#define SAY_VESPERON_DEATH -1615033
+#define SAY_VESPERON_BREATH -1615034
+#define SAY_VESPERON_RESPOND -1615035
+#define SAY_VESPERON_SPECIAL_1 -1615036
+#define SAY_VESPERON_SPECIAL_2 -1615037
+
+struct TRINITY_DLL_DECL mob_vesperonAI : public ScriptedAI
+{
+ mob_vesperonAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_VESPERON_AGGRO,m_creature);
+ }
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_VESPERON_DEATH,m_creature);
+ }
+};
+
+/*######
+## Mob Shadron
+######*/
+
+//Shadron Yell
+#define SAY_SHADRON_AGGRO -1615000
+#define SAY_SHADRON_SLAY_1 -1615001
+#define SAY_SHADRON_SLAY_2 -1615002
+#define SAY_SHADRON_DEATH -1615003
+#define SAY_SHADRON_BREATH -1615004
+#define SAY_SHADRON_RESPOND -1615005
+#define SAY_SHADRON_SPECIAL_1 -1615006
+#define SAY_SHADRON_SPECIAL_2 -1615007
+
+struct TRINITY_DLL_DECL mob_shadronAI : public ScriptedAI
+{
+ mob_shadronAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset(){}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_SHADRON_AGGRO,m_creature);
+ }
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_SHADRON_DEATH,m_creature);
+ }
+};
+/*######
+## Mob Tenebron
+######*/
+
+//Yell
+#define SAY_TENEBRON_AGGRO -1615008
+#define SAY_TENEBRON_SLAY_1 -1615009
+#define SAY_TENEBRON_SLAY_2 -1615010
+#define SAY_TENEBRON_DEATH -1615011
+#define SAY_TENEBRON_BREATH -1615012
+#define SAY_TENEBRON_RESPOND -1615013
+#define SAY_TENEBRON_SPECIAL_1 -1615014
+#define SAY_TENEBRON_SPECIAL_2 -1615015
+
+struct TRINITY_DLL_DECL mob_tenebronAI : public ScriptedAI
+{
+ mob_tenebronAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_TENEBRON_AGGRO,m_creature);
+ }
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_TENEBRON_DEATH,m_creature);
+ }
+};
+
+/*######
+## Mob Whelps
+######*/
+struct TRINITY_DLL_DECL mob_whelpAI : public ScriptedAI
+{
+ mob_whelpAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 Fade_armor_Timer;
+
+ void Reset() {}
+ void EnterCombat(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer) {}
+};
+
+CreatureAI* GetAI_mob_whelp(Creature *_Creature)
+{
+ return new mob_whelpAI (_Creature);
+}
+
+CreatureAI* GetAI_mob_tenebron(Creature *_Creature)
+{
+ return new mob_tenebronAI (_Creature);
+}
+
+CreatureAI* GetAI_mob_shadron(Creature *_Creature)
+{
+ return new mob_shadronAI (_Creature);
+}
+
+CreatureAI* GetAI_mob_vesperon(Creature *_Creature)
+{
+ return new mob_vesperonAI (_Creature);
+}
+
+CreatureAI* GetAI_boss_sartharion(Creature *_Creature)
+{
+ return new boss_sartharionAI (_Creature);
+}
+
+void AddSC_boss_sartharion()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_sartharion";
+ newscript->GetAI = GetAI_boss_sartharion;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_vesperon";
+ newscript->GetAI = GetAI_mob_vesperon;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_shadron";
+ newscript->GetAI = GetAI_mob_shadron;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_tenebron";
+ newscript->GetAI = GetAI_mob_tenebron;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_whelp";
+ newscript->GetAI = GetAI_mob_whelp;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/obsidian_sanctum/def_obsidian_sanctum.h b/src/bindings/scripts/scripts/zone/obsidian_sanctum/def_obsidian_sanctum.h
new file mode 100644
index 00000000000..59d76502af3
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/obsidian_sanctum/def_obsidian_sanctum.h
@@ -0,0 +1,4 @@
+#ifndef DEF_OBSIDIAN_SANCTUM_H
+#define DEF_OBSIDIAN_SANCTUM_H
+
+#endif
diff --git a/src/bindings/scripts/scripts/zone/obsidian_sanctum/instance_obsidian_sanctum.cpp b/src/bindings/scripts/scripts/zone/obsidian_sanctum/instance_obsidian_sanctum.cpp
new file mode 100644
index 00000000000..2e24a1ae415
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/obsidian_sanctum/instance_obsidian_sanctum.cpp
@@ -0,0 +1,21 @@
+#include "precompiled.h"
+#include "def_obsidian_sanctum.h"
+
+struct TRINITY_DLL_DECL instance_obsidian_sanctum : public ScriptedInstance
+{
+ instance_obsidian_sanctum(Map *Map) : ScriptedInstance(Map) {Initialize();};
+};
+
+InstanceData* GetInstanceData_instance_obsidian_sanctum(Map* map)
+{
+ return new instance_obsidian_sanctum(map);
+}
+
+void AddSC_instance_obsidian_sanctum()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_obsidian_sanctum";
+ newscript->GetInstanceData = GetInstanceData_instance_obsidian_sanctum;
+ 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 eef29518ecd..a969c85f38c 100644
--- a/src/bindings/scripts/scripts/zone/onyxias_lair/boss_onyxia.cpp
+++ b/src/bindings/scripts/scripts/zone/onyxias_lair/boss_onyxia.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -102,7 +102,7 @@ struct TRINITY_DLL_DECL boss_onyxiaAI : public ScriptedAI
m_creature->ApplySpellImmune(1, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
DoZoneInCombat();
@@ -125,8 +125,7 @@ struct TRINITY_DLL_DECL boss_onyxiaAI : public ScriptedAI
if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 60) && (Phase == 1))
{
Phase = 2;
- m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->SetHover(true);
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveIdle();
@@ -136,8 +135,7 @@ struct TRINITY_DLL_DECL boss_onyxiaAI : public ScriptedAI
if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 40) && (Phase == 2))
{
Phase = 3;
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT);
- m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->SetHover(false);
m_creature->GetMotionMaster()->MovePoint(0, -10.6155, -219.357, -87.7344);
DoStartMovement(m_creature->getVictim());
diff --git a/src/bindings/scripts/scripts/zone/orgrimmar/orgrimmar.cpp b/src/bindings/scripts/scripts/zone/orgrimmar/orgrimmar.cpp
index a53794c2b7a..5b328aee776 100644
--- a/src/bindings/scripts/scripts/zone/orgrimmar/orgrimmar.cpp
+++ b/src/bindings/scripts/scripts/zone/orgrimmar/orgrimmar.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -90,7 +90,7 @@ struct TRINITY_DLL_DECL npc_shenthulAI : public ScriptedAI
playerGUID = 0;
}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void UpdateAI(const uint32 diff)
{
@@ -116,7 +116,18 @@ struct TRINITY_DLL_DECL npc_shenthulAI : public ScriptedAI
DoMeleeAttackIfReady();
}
+
+ void ReciveEmote_npc_shenthul(Player *player, uint32 emote)
+ {
+ if( emote == TEXTEMOTE_SALUTE && player->GetQuestStatus(QUEST_2460) == QUEST_STATUS_INCOMPLETE )
+ if(CanEmote)
+ {
+ player->AreaExploredOrEventHappens(QUEST_2460);
+ Reset();
+ }
+ }
};
+
CreatureAI* GetAI_npc_shenthul(Creature *_Creature)
{
return new npc_shenthulAI (_Creature);
@@ -132,17 +143,6 @@ bool QuestAccept_npc_shenthul(Player* player, Creature* creature, Quest const* q
return true;
}
-bool ReciveEmote_npc_shenthul(Player *player, Creature *_Creature, uint32 emote)
-{
- if( emote == TEXTEMOTE_SALUTE && player->GetQuestStatus(QUEST_2460) == QUEST_STATUS_INCOMPLETE )
- if( ((npc_shenthulAI*)_Creature->AI())->CanEmote )
- {
- player->AreaExploredOrEventHappens(QUEST_2460);
- ((npc_shenthulAI*)_Creature->AI())->Reset();
- }
- return true;
-}
-
/*######
## npc_thrall_warchief
######*/
@@ -174,7 +174,7 @@ struct TRINITY_DLL_DECL npc_thrall_warchiefAI : public ScriptedAI
Shock_Timer = 8000;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void UpdateAI(const uint32 diff)
{
@@ -263,7 +263,6 @@ void AddSC_orgrimmar()
newscript->Name="npc_shenthul";
newscript->GetAI = &GetAI_npc_shenthul;
newscript->pQuestAccept = &QuestAccept_npc_shenthul;
- newscript->pReceiveEmote = &ReciveEmote_npc_shenthul;
newscript->RegisterSelf();
newscript = new Script;
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 d8e1a297872..89fff0d3fd7 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -23,15 +23,16 @@ EndScriptData */
#include "precompiled.h"
-#define SAY_0 "You'll never leave this place... alive."
-#define SAY_1 "Come, spirits, attend your master."
-#define SAY_SLAY "Too...easy!"
-#define SOUND_AGGRO 5825
-#define SOUND_SLAY 5826
-#define SOUND_SUMMON 5829
+#define SAY_AGGRO -1129000
+#define SAY_SUMMON60 -1129001
+#define SAY_SUMMON30 -1129002
+#define SAY_HP -1129003
+#define SAY_KILL -1129004
-#define SPELL_AMNENNARSWRATH 13009
-#define SPELL_FROSTBOLT 10179
+#define SPELL_AMNENNARSWRATH 13009
+#define SPELL_FROSTBOLT 15530
+#define SPELL_FROST_NOVA 15531
+#define SPELL_FROST_SPECTRES 12642
struct TRINITY_DLL_DECL boss_amnennar_the_coldbringerAI : public ScriptedAI
{
@@ -39,50 +40,29 @@ struct TRINITY_DLL_DECL boss_amnennar_the_coldbringerAI : public ScriptedAI
uint32 AmnenarsWrath_Timer;
uint32 FrostBolt_Timer;
- bool Spectrals;
- int Rand;
- int RandX;
- int RandY;
- Creature* Summoned;
+ uint32 FrostNova_Timer;
+ bool Spectrals60;
+ bool Spectrals30;
+ bool Hp;
void Reset()
{
AmnenarsWrath_Timer = 8000;
FrostBolt_Timer = 1000;
- Spectrals = false;
+ FrostNova_Timer = 10000 + rand()%5000;
+ Spectrals30 = false;
+ Spectrals60 = false;
+ Hp = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
- DoYell(SAY_0,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_AGGRO);
+ DoScriptText(SAY_AGGRO, m_creature);
}
void KilledUnit()
{
- DoYell(SAY_SLAY, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_SLAY);
- }
-
- void SummonSpectrals(Unit* victim)
- {
- Rand = rand()%5;
- switch (rand()%2)
- {
- case 0: RandX = 0 - Rand; break;
- case 1: RandX = 0 + Rand; break;
- }
- Rand = 0;
- Rand = rand()%5;
- switch (rand()%2)
- {
- case 0: RandY = 0 - Rand; break;
- case 1: RandY = 0 + Rand; break;
- }
- Rand = 0;
- Summoned = DoSpawnCreature(8585, RandX, RandY, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
- if(Summoned)
- ((CreatureAI*)Summoned->AI())->AttackStart(victim);
+ DoScriptText(SAY_KILL, m_creature);
}
void UpdateAI(const uint32 diff)
@@ -100,25 +80,34 @@ struct TRINITY_DLL_DECL boss_amnennar_the_coldbringerAI : public ScriptedAI
//FrostBolt_Timer
if (FrostBolt_Timer < diff)
{
- Unit* target = NULL;
- target = SelectUnit(SELECT_TARGET_RANDOM,0);
- if (target) DoCast(target,SPELL_FROSTBOLT);
-
+ DoCast(m_creature->getVictim(),SPELL_FROSTBOLT);
FrostBolt_Timer = 8000;
} else FrostBolt_Timer -= diff;
- if ( !Spectrals && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 50 )
+ if (FrostNova_Timer < diff)
{
- DoYell(SAY_1, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_SUMMON);
+ DoCast(m_creature,SPELL_FROST_NOVA);
+ FrostNova_Timer = 15000;
+ } else FrostNova_Timer -= diff;
- Unit* target = NULL;
- target = SelectUnit(SELECT_TARGET_RANDOM,0);
+ if (!Spectrals60 && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 60)
+ {
+ DoScriptText(SAY_SUMMON60, m_creature);
+ DoCast(m_creature->getVictim(),SPELL_FROST_SPECTRES);
+ Spectrals60 = true;
+ }
- SummonSpectrals(target);
- SummonSpectrals(target);
- SummonSpectrals(target);
- Spectrals = true;
+ if (!Hp && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 50)
+ {
+ DoScriptText(SAY_HP, m_creature);
+ Hp = true;
+ }
+
+ if (!Spectrals30 && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 30)
+ {
+ DoScriptText(SAY_SUMMON30, m_creature);
+ DoCast(m_creature->getVictim(),SPELL_FROST_SPECTRES);
+ Spectrals30 = true;
}
DoMeleeAttackIfReady();
diff --git a/src/bindings/scripts/scripts/zone/razorfen_downs/razorfen_downs.cpp b/src/bindings/scripts/scripts/zone/razorfen_downs/razorfen_downs.cpp
new file mode 100644
index 00000000000..d5c09e504a8
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/razorfen_downs/razorfen_downs.cpp
@@ -0,0 +1,85 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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
+ */
+
+/* ScriptData
+SDName: Razorfen_Downs
+SD%Complete: 100
+SDComment: Support for Henry Stern(2 recipes)
+SDCategory: Razorfen Downs
+EndScriptData */
+
+/* ContentData
+npc_henry_stern
+EndContentData */
+
+#include "precompiled.h"
+
+/*###
+# npc_henry_stern
+####*/
+
+enum
+{
+ SPELL_GOLDTHORN_TEA = 13028,
+ SPELL_TEACHING_GOLDTHORN_TEA = 13029,
+ SPELL_MIGHT_TROLLS_BLOOD_POTION = 3451,
+ SPELL_TEACHING_MIGHTY_TROLLS_BLOOD_POTION = 13030,
+ GOSSIP_TEXT_TEA_ANSWER = 2114,
+ GOSSIP_TEXT_POTION_ANSWER = 2115,
+};
+
+#define GOSSIP_ITEM_TEA "Teach me the cooking recipe"
+#define GOSSIP_ITEM_POTION "Teach me the alchemy recipe"
+
+bool GossipHello_npc_henry_stern (Player* pPlayer, Creature* pCreature)
+{
+ if (pPlayer->GetBaseSkillValue(SKILL_COOKING) >= 175 && !pPlayer->HasSpell(SPELL_GOLDTHORN_TEA))
+ pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_TEA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+
+ if (pPlayer->GetBaseSkillValue(SKILL_ALCHEMY) >= 180 && !pPlayer->HasSpell(SPELL_MIGHT_TROLLS_BLOOD_POTION))
+ pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_POTION, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+
+ pPlayer->SEND_GOSSIP_MENU(pCreature->GetNpcTextId(), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_henry_stern (Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action)
+{
+ if (action == GOSSIP_ACTION_INFO_DEF + 1)
+ {
+ pCreature->CastSpell(pPlayer, SPELL_TEACHING_GOLDTHORN_TEA, true);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXT_TEA_ANSWER, pCreature->GetGUID());
+ }
+
+ if (action == GOSSIP_ACTION_INFO_DEF + 2)
+ {
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXT_POTION_ANSWER, pCreature->GetGUID());
+ pCreature->CastSpell(pPlayer, SPELL_TEACHING_MIGHTY_TROLLS_BLOOD_POTION, true);
+ }
+
+ return true;
+}
+
+void AddSC_razorfen_downs()
+{
+ Script* newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_henry_stern";
+ newscript->pGossipHello = &GossipHello_npc_henry_stern;
+ newscript->pGossipSelect = &GossipSelect_npc_henry_stern;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/razorfen_kraul/razorfen_kraul.cpp b/src/bindings/scripts/scripts/zone/razorfen_kraul/razorfen_kraul.cpp
index 39be57325d7..eef07d16591 100644
--- a/src/bindings/scripts/scripts/zone/razorfen_kraul/razorfen_kraul.cpp
+++ b/src/bindings/scripts/scripts/zone/razorfen_kraul/razorfen_kraul.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -100,7 +100,7 @@ npc_willixAI(Creature *c) : npc_escortAI(c) {}
void Reset() {}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO1, m_creature, NULL);
}
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 128ab315334..60830068e01 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -52,7 +52,7 @@ struct TRINITY_DLL_DECL boss_ayamissAI : public ScriptedAI
phase=1;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
pTarget = who;
}
diff --git a/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_buru.cpp b/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_buru.cpp
index 4297c32492f..58c48540362 100644
--- a/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_buru.cpp
+++ b/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_buru.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
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 9c888e98605..69d1babf173 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -44,7 +44,7 @@ struct TRINITY_DLL_DECL boss_kurinnaxxAI : public ScriptedAI
SANDTRAP_Timer = 30000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
pTarget = who;
}
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 5830b3a8070..df542a69693 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -52,7 +52,7 @@ struct TRINITY_DLL_DECL boss_moamAI : public ScriptedAI
DRAINMANA_Timer = 30000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(EMOTE_AGGRO, m_creature);
pTarget = who;
diff --git a/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_ossirian.cpp b/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_ossirian.cpp
index 1d389830045..5652b706917 100644
--- a/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_ossirian.cpp
+++ b/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_ossirian.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
diff --git a/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_rajaxx.cpp b/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_rajaxx.cpp
index 0639a02deb6..fb2c92ff59f 100644
--- a/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_rajaxx.cpp
+++ b/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_rajaxx.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
diff --git a/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp b/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp
index 27a0621b2be..b94e6f16a80 100644
--- a/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp
+++ b/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
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 222f927e5a0..454abb1602d 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -23,55 +23,40 @@ EndScriptData */
#include "precompiled.h"
-#define SPELL_POLYMORPH 12826
-#define SPELL_AOESILENCE 8988
-#define SPELL_ARCANEEXPLOSION3 8438
-#define SPELL_ARCANEEXPLOSION4 8439
-#define SPELL_FIREAOE 9435
-#define SPELL_BLINK 1953
-#define SPELL_FIREBALL 21162
-#define SPELL_MANASHIELD4 10191
-#define SPELL_ARCANEBUBBLE 9438
-
-#define SAY_AGGRO "You will not defile these mysteries!"
-#define SAY_SPECIALAE "Burn in righteous fire!"
-
-#define SOUND_AGGRO 5842
-#define SOUND_SPECIALAE 5843
+enum
+{
+ SAY_AGGRO = -1189019,
+ SAY_SPECIALAE = -1189020,
+
+ SPELL_POLYMORPH = 13323,
+ SPELL_AOESILENCE = 8988,
+ SPELL_ARCANEEXPLOSION = 9433,
+ SPELL_FIREAOE = 9435,
+ SPELL_ARCANEBUBBLE = 9438,
+};
struct TRINITY_DLL_DECL boss_arcanist_doanAI : public ScriptedAI
{
boss_arcanist_doanAI(Creature *c) : ScriptedAI(c) {}
- uint32 FullAOE_Timer;
uint32 Polymorph_Timer;
- uint32 Yell_Timer;
- uint32 ArcaneBubble_Timer;
uint32 AoESilence_Timer;
- uint32 ArcaneExplosion3_Timer;
- uint32 ArcaneExplosion4_Timer;
- uint32 Blink_Timer;
- uint32 Fireball_Timer;
- uint32 ManaShield4_Timer;
+ uint32 ArcaneExplosion_Timer;
+ bool bCanDetonate;
+ bool bShielded;
void Reset()
{
- FullAOE_Timer = 5000;
- Polymorph_Timer = 1;
- Yell_Timer = 2000;
- ArcaneBubble_Timer = 3000;
- AoESilence_Timer = 20000;
- ArcaneExplosion3_Timer = 10000;
- ArcaneExplosion4_Timer = 10000;
- Blink_Timer = 40000;
- Fireball_Timer = 6000;
- ManaShield4_Timer = 70000;
+ Polymorph_Timer = 20000;
+ AoESilence_Timer = 15000;
+ ArcaneExplosion_Timer = 3000;
+ bCanDetonate = false;
+ bShielded = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
- DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_AGGRO);
+ DoScriptText(SAY_AGGRO, m_creature);
}
void UpdateAI(const uint32 diff)
@@ -79,79 +64,50 @@ struct TRINITY_DLL_DECL boss_arcanist_doanAI : public ScriptedAI
if (!UpdateVictim())
return;
- //If we are <50% hp cast Arcane Bubble and start casting SPECIAL FIRE AOE
- if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 50 && !m_creature->IsNonMeleeSpellCasted(false))
+ if (bShielded && bCanDetonate)
{
- if (Polymorph_Timer < diff)
- {
- Unit* target = NULL;
-
- target = SelectUnit(SELECT_TARGET_RANDOM,0);
- if (target)DoCast(target,SPELL_POLYMORPH);
- Polymorph_Timer = 40000;
- }else Polymorph_Timer -= diff;
-
- if (Yell_Timer < diff)
- {
- DoYell(SAY_SPECIALAE,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_SPECIALAE);
- Yell_Timer = 40000;
- }else Yell_Timer -= diff;
-
- if (ArcaneBubble_Timer < diff)
- {
- DoCast(m_creature,SPELL_ARCANEBUBBLE);
- ArcaneBubble_Timer = 40000;
- }else ArcaneBubble_Timer -= diff;
-
- if (FullAOE_Timer < diff)
- {
- DoCast(m_creature->getVictim(),SPELL_FIREAOE);
- FullAOE_Timer = 40000;
- }else FullAOE_Timer -= diff;
+ DoCast(m_creature,SPELL_FIREAOE);
+ bCanDetonate = false;
}
- //AoESilence_Timer
- if (AoESilence_Timer < diff)
- {
- DoCast(m_creature->getVictim(),SPELL_AOESILENCE);
- AoESilence_Timer = 30000;
- }else AoESilence_Timer -= diff;
+ if (m_creature->HasAura(SPELL_ARCANEBUBBLE))
+ return;
- //ArcaneExplosion3_Timer
- if (ArcaneExplosion3_Timer < diff)
+ //If we are <50% hp cast Arcane Bubble
+ if (!bShielded && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 50)
{
- DoCast(m_creature->getVictim(),SPELL_ARCANEEXPLOSION3);
- ArcaneExplosion3_Timer = 8000;
- }else ArcaneExplosion3_Timer -= diff;
+ //wait if we already casting
+ if (m_creature->IsNonMeleeSpellCasted(false))
+ return;
- //ArcaneExplosion4_Timer
- if (ArcaneExplosion4_Timer < diff)
- {
- DoCast(m_creature->getVictim(),SPELL_ARCANEEXPLOSION4);
- ArcaneExplosion4_Timer = 10000;
- }else ArcaneExplosion4_Timer -= diff;
+ DoScriptText(SAY_SPECIALAE, m_creature);
+ DoCast(m_creature,SPELL_ARCANEBUBBLE);
- //Blink_Timer
- if (Blink_Timer < diff)
+ bCanDetonate = true;
+ bShielded = true;
+ }
+
+ if (Polymorph_Timer < diff)
{
- DoCast(m_creature,SPELL_BLINK);
- Blink_Timer = 30000;
- }else Blink_Timer -= diff;
+ if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,1))
+ DoCast(target,SPELL_POLYMORPH);
+
+ Polymorph_Timer = 20000;
+ }else Polymorph_Timer -= diff;
- //Fireball_Timer
- if (Fireball_Timer < diff)
+ //AoESilence_Timer
+ if (AoESilence_Timer < diff)
{
- DoCast(m_creature->getVictim(),SPELL_FIREBALL);
- Fireball_Timer = 12000;
- }else Fireball_Timer -= diff;
+ DoCast(m_creature->getVictim(),SPELL_AOESILENCE);
+ AoESilence_Timer = 15000 + rand()%5000;
+ }else AoESilence_Timer -= diff;
- //ManaShiled4_Timer
- if (ManaShield4_Timer < diff)
+ //ArcaneExplosion_Timer
+ if (ArcaneExplosion_Timer < diff)
{
- DoCast(m_creature,SPELL_MANASHIELD4);
- ManaShield4_Timer = 70000;
- }else ManaShield4_Timer -= diff;
+ DoCast(m_creature->getVictim(),SPELL_ARCANEEXPLOSION);
+ ArcaneExplosion_Timer = 8000;
+ }else ArcaneExplosion_Timer -= diff;
DoMeleeAttackIfReady();
}
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 e22de9b8fb3..2e2bb14a711 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -42,7 +42,7 @@ struct TRINITY_DLL_DECL boss_azshir_the_sleeplessAI : public ScriptedAI
Terrify_Timer = 20000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 f5c094d6127..c8ca71dff7c 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -23,45 +23,45 @@ EndScriptData */
#include "precompiled.h"
-#define SPELL_FROSTNOVA2 865
-#define SPELL_FLAMESHOCK3 8053
-#define SPELL_SHADOWBOLT5 1106
-#define SPELL_FLAMESPIKE 8814
-#define SPELL_FIRENOVA 16079
-
-#define SAY_AGGRO "We hunger for vengeance."
-#define SAY_HEALTH "No rest... for the angry dead!"
-#define SAY_DEATH "More... More souls!"
-
-#define SOUND_AGGRO 5844
-#define SOUND_HEALTH 5846
-#define SOUND_DEATH 5845
+enum
+{
+ SAY_AGGRO = -1189016,
+ SAY_HEALTH = -1189017,
+ SAY_KILL = -1189018,
+
+ SPELL_FLAMESHOCK = 8053,
+ SPELL_SHADOWBOLT = 1106,
+ SPELL_FLAMESPIKE = 8814,
+ SPELL_FIRENOVA = 16079,
+};
struct TRINITY_DLL_DECL boss_bloodmage_thalnosAI : public ScriptedAI
{
boss_bloodmage_thalnosAI(Creature *c) : ScriptedAI(c) {}
- uint32 FrostNova2_Timer;
- uint32 FlameShock3_Timer;
- uint32 ShadowBolt5_Timer;
+ bool HpYell;
+ uint32 FlameShock_Timer;
+ uint32 ShadowBolt_Timer;
uint32 FlameSpike_Timer;
uint32 FireNova_Timer;
- uint32 Yell_Timer;
void Reset()
{
- Yell_Timer = 1;
- FrostNova2_Timer = 10000;
- FlameShock3_Timer = 15000;
- ShadowBolt5_Timer = 20000;
- FlameSpike_Timer = 20000;
- FireNova_Timer = 10000;
+ HpYell = false;
+ FlameShock_Timer = 10000;
+ ShadowBolt_Timer = 2000;
+ FlameSpike_Timer = 8000;
+ FireNova_Timer = 40000;
+ }
+
+ void EnterCombat(Unit *who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
}
- void Aggro(Unit *who)
+ void KilledUnit(Unit* Victim)
{
- DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_AGGRO);
+ DoScriptText(SAY_KILL, m_creature);
}
void UpdateAI(const uint32 diff)
@@ -70,38 +70,18 @@ struct TRINITY_DLL_DECL boss_bloodmage_thalnosAI : public ScriptedAI
return;
//If we are <35% hp
- if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 35)
+ if (!HpYell && ((m_creature->GetHealth()*100) / m_creature->GetMaxHealth() <= 35))
{
- Yell_Timer -= diff;
-
- if (Yell_Timer < diff)
- {
- DoYell(SAY_HEALTH,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_HEALTH);
- Yell_Timer = 900000;
- }
+ DoScriptText(SAY_HEALTH, m_creature);
+ HpYell = true;
}
- //FrostNova2_Timer
- if (FrostNova2_Timer < diff)
+ //FlameShock_Timer
+ if (FlameShock_Timer < diff)
{
- DoCast(m_creature->getVictim(),SPELL_FROSTNOVA2);
- FrostNova2_Timer = 10000;
- }else FrostNova2_Timer -= diff;
-
- //FlameShock3_Timer
- if (FlameShock3_Timer < diff)
- {
- DoCast(m_creature->getVictim(),SPELL_FLAMESHOCK3);
- FlameShock3_Timer = 15000;
- }else FlameShock3_Timer -= diff;
-
- //ShadowBolt5_Timer
- if (ShadowBolt5_Timer < diff)
- {
- DoCast(m_creature->getVictim(),SPELL_SHADOWBOLT5);
- ShadowBolt5_Timer = 20000;
- }else ShadowBolt5_Timer -= diff;
+ DoCast(m_creature->getVictim(),SPELL_FLAMESHOCK);
+ FlameShock_Timer = 10000 + rand()%5000;
+ }else FlameShock_Timer -= diff;
//FlameSpike_Timer
if (FlameSpike_Timer < diff)
@@ -114,9 +94,16 @@ struct TRINITY_DLL_DECL boss_bloodmage_thalnosAI : public ScriptedAI
if (FireNova_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_FIRENOVA);
- FireNova_Timer = 20000;
+ FireNova_Timer = 40000;
}else FireNova_Timer -= diff;
+ //ShadowBolt_Timer
+ if (ShadowBolt_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(),SPELL_SHADOWBOLT);
+ ShadowBolt_Timer = 2000;
+ }else ShadowBolt_Timer -= diff;
+
DoMeleeAttackIfReady();
}
};
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp
index 441797ec158..9d0031f2af2 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -147,7 +147,7 @@ struct TRINITY_DLL_DECL mob_wisp_invisAI : public ScriptedAI
uint32 spell;
uint32 spell2;
void Reset(){}
- void Aggro(Unit *who){}
+ void EnterCombat(Unit *who){}
void SetType(uint32 _type)
{
Creaturetype = _type;
@@ -176,7 +176,7 @@ struct TRINITY_DLL_DECL mob_wisp_invisAI : public ScriptedAI
if (!who || Creaturetype != 1 || !who->isTargetableForAttack())
return;
- if (m_creature->GetDistance2d(who) < 0.1 && !who->HasAura(SPELL_SQUASH_SOUL,0))
+ if (m_creature->GetDistance2d(who) < 0.1 && !who->HasAura(SPELL_SQUASH_SOUL))
DoCast(who,SPELL_SQUASH_SOUL);
}
@@ -218,7 +218,7 @@ struct TRINITY_DLL_DECL mob_headAI : public ScriptedAI
laugh = 15000 + rand()%16 * 1000;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void SaySound(int32 textEntry, Unit *target = 0)
{
DoScriptText(textEntry, m_creature, target);
@@ -445,7 +445,7 @@ struct TRINITY_DLL_DECL boss_headless_horsemanAI : public ScriptedAI
++id;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
pInstance->SetData(DATA_HORSEMAN_EVENT, IN_PROGRESS);
@@ -505,7 +505,7 @@ struct TRINITY_DLL_DECL boss_headless_horsemanAI : public ScriptedAI
void SpellHitTarget(Unit* unit, const SpellEntry* spell)
{
if (spell->Id == SPELL_CONFLAGRATION)
- if (unit->HasAura(SPELL_CONFLAGRATION,0))
+ if (unit->HasAura(SPELL_CONFLAGRATION))
SaySound(SAY_CONFLAGRATION,unit);
}
@@ -572,7 +572,7 @@ struct TRINITY_DLL_DECL boss_headless_horsemanAI : public ScriptedAI
DoCast(m_creature,SPELL_BODY_REGEN,true);
m_creature->CastSpell(Head, SPELL_FLYING_HEAD,true);
DoCast(m_creature,SPELL_CONFUSE,false); //test
- done_by->ProcDamageAndSpell(m_creature,PROC_FLAG_KILL_AND_GET_XP,PROC_FLAG_KILLED,PROC_EX_NONE,0);
+ done_by->ProcDamageAndSpell(m_creature,PROC_FLAG_KILL,PROC_FLAG_KILLED,PROC_EX_NONE,0);
whirlwind = 4000 + (rand()%5)*1000;
regen = 0;
}
@@ -734,10 +734,10 @@ struct TRINITY_DLL_DECL mob_pulsing_pumpkinAI : public ScriptedAI
sprouted = false;
DoCast(m_creature,SPELL_PUMPKIN_AURA,true);
DoCast(m_creature,SPELL_SPROUTING);
- m_creature->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_ROTATE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_STUNNED);
}
- void Aggro(Unit *who){}
+ void EnterCombat(Unit *who){}
void SpellHit(Unit *caster, const SpellEntry *spell)
{
@@ -745,7 +745,7 @@ struct TRINITY_DLL_DECL mob_pulsing_pumpkinAI : public ScriptedAI
{
sprouted = true;
m_creature->RemoveAllAuras();
- m_creature->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_ROTATE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_STUNNED);
DoCast(m_creature,SPELL_SPROUT_BODY,true);
m_creature->UpdateEntry(PUMPKIN_FIEND);
DoStartMovement(m_creature->getVictim());
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 17f4aee1ae3..913097c4918 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_herod.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_herod.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -55,7 +55,7 @@ struct TRINITY_DLL_DECL boss_herodAI : public ScriptedAI
Whirlwind_Timer = 60000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
DoCast(m_creature,SPELL_RUSHINGCHARGE);
@@ -105,46 +105,23 @@ struct TRINITY_DLL_DECL boss_herodAI : public ScriptedAI
}
};
-CreatureAI* GetAI_boss_herod(Creature *_Creature)
+CreatureAI* GetAI_boss_herod(Creature* pCreature)
{
- return new boss_herodAI (_Creature);
+ return new boss_herodAI(pCreature);
}
-float Location[12][3]=
-{
- {1945.81, -431.54, 16.36},
- {1946.21, -436.41, 16.36},
- {1950.01, -444.11, 14.63},
- {1956.08, -449.34, 13.12},
- {1966.59, -450.55, 11.27},
- {1976.09, -447.51, 11.27},
- {1983.42, -435.85, 11.27},
- {1978.17, -428.81, 11.27},
- {1973.97, -422.08, 9.04},
- {1963.84, -418.90, 6.17},
- {1961.22, -422.74, 6.17},
- {1964.80, -431.26, 6.17}
-};
-
-uint32 Wait[12][1]=
-{
- {0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{600000}
-};
-
struct TRINITY_DLL_DECL mob_scarlet_traineeAI : public npc_escortAI
{
- mob_scarlet_traineeAI(Creature *c) : npc_escortAI(c) {}
-
- uint32 Start_Timer;
-
- void WaypointReached(uint32 i) { }
-
- void Reset()
+ mob_scarlet_traineeAI(Creature *c) : npc_escortAI(c)
{
- Start_Timer = urand(1500,4500);
+ Start_Timer = urand(1000,6000);
}
- void Aggro(Unit* who) { }
+ uint32 Start_Timer;
+
+ void Reset() { }
+ void WaypointReached(uint32 uiPoint) { }
+ void EnterCombat(Unit* who) { }
void UpdateAI(const uint32 diff)
{
@@ -161,14 +138,13 @@ struct TRINITY_DLL_DECL mob_scarlet_traineeAI : public npc_escortAI
}
};
-CreatureAI* GetAI_mob_scarlet_trainee(Creature* _Creature)
+CreatureAI* GetAI_mob_scarlet_trainee(Creature* pCreature)
{
- mob_scarlet_traineeAI* thisAI = new mob_scarlet_traineeAI(_Creature);
+ mob_scarlet_traineeAI* thisAI = new mob_scarlet_traineeAI(pCreature);
- for(uint32 i = 0; i < 12; ++i)
- thisAI->AddWaypoint(i, Location[i][0], Location[i][1], Location[i][2], Wait[i][0]);
+ thisAI->FillPointMovementListForCreature();
- return ((CreatureAI*)thisAI);
+ return (CreatureAI*)thisAI;
}
void AddSC_boss_herod()
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 b1c8bde0566..d477483b125 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -55,7 +55,7 @@ struct TRINITY_DLL_DECL boss_high_inquisitor_fairbanksAI : public ScriptedAI
MindBlast5_Timer = 20000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 5dde65cb840..370ed9aedc8 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -23,11 +23,10 @@ EndScriptData */
#include "precompiled.h"
-#define SPELL_SUMMONSCARLETHOUND 17164
-#define SPELL_ENRAGE 28747
+#define SAY_AGGRO -1189021
-#define SAY_AGGRO "Release the hounds!"
-#define SOUND_AGGRO 5841
+#define SPELL_SUMMONSCARLETHOUND 17164
+#define SPELL_ENRAGE 6742
struct TRINITY_DLL_DECL boss_houndmaster_lokseyAI : public ScriptedAI
{
@@ -37,15 +36,12 @@ struct TRINITY_DLL_DECL boss_houndmaster_lokseyAI : public ScriptedAI
void Reset()
{
- Enrage_Timer = 6000000;
+ Enrage_Timer = 0;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
- DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_AGGRO);
-
- DoCast(m_creature,SPELL_SUMMONSCARLETHOUND);
+ DoScriptText(SAY_AGGRO, m_creature);
}
void UpdateAI(const uint32 diff)
@@ -53,16 +49,17 @@ struct TRINITY_DLL_DECL boss_houndmaster_lokseyAI : public ScriptedAI
if (!UpdateVictim())
return;
- //If we are <10% hp cast healing spells at self and Mograine
- if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 10 && !m_creature->IsNonMeleeSpellCasted(false) && Enrage_Timer < diff)
+ //If we are <25% hp, bloodlust
+ if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 25 && Enrage_Timer < diff)
{
DoCast(m_creature,SPELL_ENRAGE);
- Enrage_Timer = 900000;
+ Enrage_Timer = 60000;
}else Enrage_Timer -= diff;
DoMeleeAttackIfReady();
}
};
+
CreatureAI* GetAI_boss_houndmaster_loksey(Creature *_Creature)
{
return new boss_houndmaster_lokseyAI (_Creature);
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 1366897eb05..f062419c6c1 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -22,36 +22,55 @@ SDCategory: Scarlet Monastery
EndScriptData */
#include "precompiled.h"
+#include "def_scarlet_monastery.h"
-#define SPELL_POWERWORDSHIELD 6065
-
-#define SAY_AGGRO "Tell me... tell me everything!"
-#define SAY_HEALTH1 "Naughty secrets"
-#define SAY_HEALTH2 "I'll rip the secrets from your flesh!"
-#define SAY_DEATH "Purged by pain!"
+enum
+{
+ SAY_AGGRO = -1189011,
+ SAY_HEALTH1 = -1189012,
+ SAY_HEALTH2 = -1189013,
+ SAY_KILL = -1189014,
+ SAY_TRIGGER_VORREL = -1189015,
-#define SOUND_AGGRO 5847
-#define SOUND_HEALTH1 5849
-#define SOUND_HEALTH2 5850
-#define SOUND_DEATH 5848
+ SPELL_SHADOWWORDPAIN = 2767,
+};
struct TRINITY_DLL_DECL boss_interrogator_vishasAI : public ScriptedAI
{
- boss_interrogator_vishasAI(Creature *c) : ScriptedAI(c) {}
+ boss_interrogator_vishasAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = (ScriptedInstance*)m_creature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
- uint32 Yell_Timer;
- uint32 PowerWordShield_Timer;
+ bool Yell30;
+ bool Yell60;
+ uint32 ShadowWordPain_Timer;
void Reset()
{
- Yell_Timer = 6000000;
- PowerWordShield_Timer = 60000;
+ ShadowWordPain_Timer = 5000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
- DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_AGGRO);
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+
+ void KilledUnit(Unit* Victim)
+ {
+ DoScriptText(SAY_KILL, m_creature);
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ if (!pInstance)
+ return;
+
+ //Any other actions to do with vorrel? setStandState?
+ if (Unit *vorrel = Unit::GetUnit(*m_creature,pInstance->GetData64(DATA_VORREL)))
+ DoScriptText(SAY_TRIGGER_VORREL, vorrel);
}
void UpdateAI(const uint32 diff)
@@ -60,44 +79,29 @@ struct TRINITY_DLL_DECL boss_interrogator_vishasAI : public ScriptedAI
return;
//If we are low on hp Do sayings
- if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 60 && !m_creature->IsNonMeleeSpellCasted(false))
+ if (!Yell60 && ((m_creature->GetHealth()*100) / m_creature->GetMaxHealth() <= 60))
{
- //Yell_Timer
- if (Yell_Timer < diff)
- {
- DoYell(SAY_HEALTH1,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_HEALTH1);
- return;
-
- //60 seconds until we should cast this agian
- Yell_Timer = 60000;
- }else Yell_Timer -= diff;
+ DoScriptText(SAY_HEALTH1, m_creature);
+ Yell60 = true;
}
- if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 30 && !m_creature->IsNonMeleeSpellCasted(false))
+ if (!Yell30 && ((m_creature->GetHealth()*100) / m_creature->GetMaxHealth() <= 30))
{
- //Yell_Timer
- if (Yell_Timer < diff)
- {
- DoYell(SAY_HEALTH2,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_HEALTH2);
- return;
-
- //60 seconds until we should cast this agian
- Yell_Timer = 6000000;
- }else Yell_Timer -= diff;
+ DoScriptText(SAY_HEALTH2, m_creature);
+ Yell30 = true;
}
- //PowerWordShield_Timer
- if (PowerWordShield_Timer < diff)
+ //ShadowWordPain_Timer
+ if (ShadowWordPain_Timer < diff)
{
- DoCast(m_creature,SPELL_POWERWORDSHIELD);
- PowerWordShield_Timer = 60000;
- }else PowerWordShield_Timer -= diff;
+ DoCast(m_creature->getVictim(),SPELL_SHADOWWORDPAIN);
+ ShadowWordPain_Timer = 5000 + rand()%10000;;
+ }else ShadowWordPain_Timer -= diff;
DoMeleeAttackIfReady();
}
};
+
CreatureAI* GetAI_boss_interrogator_vishas(Creature *_Creature)
{
return new boss_interrogator_vishasAI (_Creature);
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_mograine_and_whitemane.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_mograine_and_whitemane.cpp
index 6c2bd8a9be8..9bbe880cc69 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_mograine_and_whitemane.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_mograine_and_whitemane.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -70,7 +70,7 @@ struct TRINITY_DLL_DECL boss_scarlet_commander_mograineAI : public ScriptedAI
BlessingOfProtection3_Timer = 45000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_MO_AGGRO, m_creature);
DoCast(m_creature,SPELL_RETRIBUTIONAURA3);
@@ -199,7 +199,7 @@ struct TRINITY_DLL_DECL boss_high_inquisitor_whitemaneAI : public ScriptedAI
MindBlast6_Timer = 6000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_WH_INTRO, m_creature);
}
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 88cee632568..d4e2a1f5f69 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_scorn.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_scorn.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -45,7 +45,7 @@ struct TRINITY_DLL_DECL boss_scornAI : public ScriptedAI
FrostNova_Timer = 30000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/def_scarlet_monastery.h b/src/bindings/scripts/scripts/zone/scarlet_monastery/def_scarlet_monastery.h
index b8ab822129d..2b6399ae3e4 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/def_scarlet_monastery.h
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/def_scarlet_monastery.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
@@ -10,7 +10,9 @@
#define DATA_WHITEMANE 3
#define DATA_DOOR_WHITEMANE 4
-#define DATA_HORSEMAN_EVENT 5
-#define GAMEOBJECT_PUMPKIN_SHRINE 6
+#define DATA_HORSEMAN_EVENT 5
+#define GAMEOBJECT_PUMPKIN_SHRINE 6
+
+#define DATA_VORREL 7
#endif
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp
index 44152e6b4e0..4c1bd810388 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -43,6 +43,7 @@ struct TRINITY_DLL_DECL instance_scarlet_monastery : public ScriptedInstance
uint64 MograineGUID;
uint64 WhitemaneGUID;
+ uint64 VorrelGUID;
uint64 DoorHighInquisitorGUID;
uint32 Encounter[ENCOUNTERS];
@@ -56,6 +57,7 @@ struct TRINITY_DLL_DECL instance_scarlet_monastery : public ScriptedInstance
MograineGUID = 0;
WhitemaneGUID = 0;
+ VorrelGUID = 0;
DoorHighInquisitorGUID = 0;
for(uint8 i = 0; i < ENCOUNTERS; i++)
@@ -80,6 +82,7 @@ struct TRINITY_DLL_DECL instance_scarlet_monastery : public ScriptedInstance
case ENTRY_PUMPKIN: HorsemanAdds.insert(creature->GetGUID());break;
case 3976: MograineGUID = creature->GetGUID(); break;
case 3977: WhitemaneGUID = creature->GetGUID(); break;
+ case 3981: VorrelGUID = creature->GetGUID(); break;
}
}
@@ -90,23 +93,23 @@ struct TRINITY_DLL_DECL instance_scarlet_monastery : public ScriptedInstance
case TYPE_MOGRAINE_AND_WHITE_EVENT: Encounter[0] = data; break;
case GAMEOBJECT_PUMPKIN_SHRINE:
{
- GameObject *Shrine = instance->GetGameObjectInMap(PumpkinShrineGUID);
+ GameObject *Shrine = instance->GetGameObject(PumpkinShrineGUID);
if(Shrine)
- Shrine->SetUInt32Value(GAMEOBJECT_STATE,1);
+ Shrine->SetGoState(GO_STATE_READY);
}break;
case DATA_HORSEMAN_EVENT:
if (data == DONE)
{
for(std::set<uint64>::iterator itr = HorsemanAdds.begin(); itr != HorsemanAdds.end(); ++itr)
{
- Creature* add = instance->GetCreatureInMap(*itr);
+ Creature* add = instance->GetCreature(*itr);
if(add && add->isAlive())
add->DealDamage(add, add->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}
HorsemanAdds.clear();
- GameObject *Shrine = instance->GetGameObjectInMap(PumpkinShrineGUID);
+ GameObject *Shrine = instance->GetGameObject(PumpkinShrineGUID);
if(Shrine)
- Shrine->SetUInt32Value(GAMEOBJECT_STATE,1);
+ Shrine->SetGoState(GO_STATE_READY);
}
break;
}
@@ -121,6 +124,7 @@ struct TRINITY_DLL_DECL instance_scarlet_monastery : public ScriptedInstance
//case DATA_HEAD: return HeadGUID;
case DATA_MOGRAINE: return MograineGUID;
case DATA_WHITEMANE: return WhitemaneGUID;
+ case DATA_VORREL: return VorrelGUID;
case DATA_DOOR_WHITEMANE: return DoorHighInquisitorGUID;
}
return 0;
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 a20cd4d8b83..7dccb8c5e56 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -16,12 +16,13 @@
/* ScriptData
SDName: Boss_Darkmaster_Gandling
-SD%Complete: 99
+SD%Complete: 75
SDComment: Doors missing in instance script.
SDCategory: Scholomance
EndScriptData */
#include "precompiled.h"
+#include "def_scholomance.h"
#define SPELL_ARCANEMISSILES 22272
#define SPELL_SHADOWSHIELD 22417 //Not right ID. But 12040 is wrong either.
@@ -49,12 +50,18 @@ EndScriptData */
struct TRINITY_DLL_DECL boss_darkmaster_gandlingAI : public ScriptedAI
{
- boss_darkmaster_gandlingAI(Creature *c) : ScriptedAI(c) {}
+ boss_darkmaster_gandlingAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = (ScriptedInstance*)m_creature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
uint32 ArcaneMissiles_Timer;
uint32 ShadowShield_Timer;
uint32 Curse_Timer;
uint32 Teleport_Timer;
+
Creature *Summoned;
void Reset()
@@ -65,8 +72,14 @@ struct TRINITY_DLL_DECL boss_darkmaster_gandlingAI : public ScriptedAI
Teleport_Timer = 16000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
+ {
+ }
+
+ void JustDied(Unit *killer)
{
+ if (pInstance)
+ pInstance->SetData(TYPE_GANDLING, DONE);
}
void UpdateAI(const uint32 diff)
@@ -113,59 +126,79 @@ struct TRINITY_DLL_DECL boss_darkmaster_gandlingAI : public ScriptedAI
case 0:
DoTeleportPlayer(target, 250.0696,0.3921,84.8408,3.149);
Summoned = m_creature->SummonCreature(16119,254.2325,0.3417,84.8407,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(16119,257.7133,4.0226,84.8407,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(16119,258.6702,-2.60656,84.8407,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
break;
case 1:
DoTeleportPlayer(target, 181.4220,-91.9481,84.8410,1.608);
Summoned = m_creature->SummonCreature(16119,184.0519,-73.5649,84.8407,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(16119,179.5951,-73.7045,84.8407,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(16119,180.6452,-78.2143,84.8407,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(16119,283.2274,-78.1518,84.8407,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
break;
case 2:
DoTeleportPlayer(target, 95.1547,-1.8173,85.2289,0.043);
Summoned = m_creature->SummonCreature(16119,100.9404,-1.8016,85.2289,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(16119,101.3729,0.4882,85.2289,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(16119,101.4596,-4.4740,85.2289,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
break;
case 3:
DoTeleportPlayer(target, 250.0696,0.3921,72.6722,3.149);
Summoned = m_creature->SummonCreature(16119,240.34481,0.7368,72.6722,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(16119,240.3633,-2.9520,72.6722,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(16119,240.6702,3.34949,72.6722,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
break;
case 4:
DoTeleportPlayer(target, 181.4220,-91.9481,70.7734,1.608);
Summoned = m_creature->SummonCreature(16119,184.0519,-73.5649,70.7734,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(16119,179.5951,-73.7045,70.7734,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(16119,180.6452,-78.2143,70.7734,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(16119,283.2274,-78.1518,70.7734,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
break;
case 5:
DoTeleportPlayer(target, 106.1541,-1.8994,75.3663,0.043);
Summoned = m_creature->SummonCreature(16119,115.3945,-1.5555,75.3663,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(16119,257.7133,1.8066,75.3663,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(16119,258.6702,-5.1001,75.3663,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
+ if (Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(target);
break;
}
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 2e0eb4e09e2..5840b782575 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -39,7 +39,7 @@ struct TRINITY_DLL_DECL boss_death_knight_darkreaverAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
};
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 001c67c26b8..74f7f2a13a1 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -24,6 +24,8 @@ EndScriptData */
#include "precompiled.h"
#include "def_scholomance.h"
+#define EMOTE_GENERIC_FRENZY_KILL -1000001
+
#define SPELL_REND 18106
#define SPELL_CLEAVE 15584
#define SPELL_FRENZY 28371
@@ -50,12 +52,12 @@ struct TRINITY_DLL_DECL boss_theolenkrastinovAI : public ScriptedAI
{
pInstance->SetData(DATA_DOCTORTHEOLENKRASTINOV_DEATH, 0);
- if(pInstance->GetData(DATA_CANSPAWNGANDLING))
+ if (pInstance->GetData(TYPE_GANDLING) == IN_PROGRESS)
m_creature->SummonCreature(1853, 180.73, -9.43856, 75.507, 1.61399, TEMPSUMMON_DEAD_DESPAWN, 0);
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -84,7 +86,7 @@ struct TRINITY_DLL_DECL boss_theolenkrastinovAI : public ScriptedAI
if (Frenzy_Timer < diff)
{
DoCast(m_creature,SPELL_FRENZY);
- DoTextEmote("goes into a killing frenzy!",NULL);
+ DoScriptText(EMOTE_GENERIC_FRENZY_KILL, m_creature);
Frenzy_Timer = 8000;
}else Frenzy_Timer -= diff;
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 6eb5e1ec249..ff63af2719d 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_illucia_barov.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_illucia_barov.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -53,12 +53,12 @@ struct TRINITY_DLL_DECL boss_illuciabarovAI : public ScriptedAI
{
pInstance->SetData(DATA_LADYILLUCIABAROV_DEATH, 0);
- if(pInstance->GetData(DATA_CANSPAWNGANDLING))
+ if (pInstance->GetData(TYPE_GANDLING) == IN_PROGRESS)
m_creature->SummonCreature(1853, 180.73, -9.43856, 75.507, 1.61399, TEMPSUMMON_DEAD_DESPAWN, 0);
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 4ba2811dc52..4b262f625aa 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_instructor_malicia.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_instructor_malicia.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -60,12 +60,12 @@ struct TRINITY_DLL_DECL boss_instructormaliciaAI : public ScriptedAI
{
pInstance->SetData(DATA_INSTRUCTORMALICIA_DEATH, 0);
- if(pInstance->GetData(DATA_CANSPAWNGANDLING))
+ if (pInstance->GetData(TYPE_GANDLING) == IN_PROGRESS)
m_creature->SummonCreature(1853, 180.73, -9.43856, 75.507, 1.61399, TEMPSUMMON_DEAD_DESPAWN, 0);
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 c6ff12be817..26e296c3f54 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -51,7 +51,7 @@ struct TRINITY_DLL_DECL boss_jandicebarovAI : public ScriptedAI
Invisible = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -170,7 +170,7 @@ struct TRINITY_DLL_DECL mob_illusionofjandicebarovAI : public ScriptedAI
m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_kormok.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_kormok.cpp
index 355fbd90c9b..60b805f1db1 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_kormok.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_kormok.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -53,7 +53,7 @@ struct TRINITY_DLL_DECL boss_kormokAI : public ScriptedAI
Mages = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 195e5b048b4..fe9ff752dc7 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -49,12 +49,12 @@ struct TRINITY_DLL_DECL boss_lordalexeibarovAI : public ScriptedAI
{
pInstance->SetData(DATA_LORDALEXEIBAROV_DEATH, 0);
- if(pInstance->GetData(DATA_CANSPAWNGANDLING))
+ if (pInstance->GetData(TYPE_GANDLING) == IN_PROGRESS)
m_creature->SummonCreature(1853, 180.73, -9.43856, 75.507, 1.61399, TEMPSUMMON_DEAD_DESPAWN, 0);
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 728ad07e838..62409b26442 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_lorekeeper_polkelt.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_lorekeeper_polkelt.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -53,12 +53,12 @@ struct TRINITY_DLL_DECL boss_lorekeeperpolkeltAI : public ScriptedAI
{
pInstance->SetData(DATA_LOREKEEPERPOLKELT_DEATH, 0);
- if(pInstance->GetData(DATA_CANSPAWNGANDLING))
+ if (pInstance->GetData(TYPE_GANDLING) == IN_PROGRESS)
m_creature->SummonCreature(1853, 180.73, -9.43856, 75.507, 1.61399, TEMPSUMMON_DEAD_DESPAWN, 0);
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 154da52596a..9c0c8e29ff4 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_ras_frostwhisper.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_ras_frostwhisper.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -53,7 +53,7 @@ struct TRINITY_DLL_DECL boss_rasfrostAI : public ScriptedAI
m_creature->CastSpell(m_creature,SPELL_ICEARMOR,true);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 95ebafb092a..64172abe45c 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_the_ravenian.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_the_ravenian.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -29,8 +29,6 @@ EndScriptData */
#define SPELL_SUNDERINCLEAVE 25174
#define SPELL_KNOCKAWAY 10101
-#define SAY_AGGRO1 "Mine! Mine! Mine! Gizlock is the ruler of this domain! You shall never reveal my presence!"
-
struct TRINITY_DLL_DECL boss_theravenianAI : public ScriptedAI
{
boss_theravenianAI(Creature *c) : ScriptedAI(c) {}
@@ -57,14 +55,13 @@ struct TRINITY_DLL_DECL boss_theravenianAI : public ScriptedAI
{
pInstance->SetData(DATA_THERAVENIAN_DEATH, 0);
- if(pInstance->GetData(DATA_CANSPAWNGANDLING))
+ if (pInstance->GetData(TYPE_GANDLING) == IN_PROGRESS)
m_creature->SummonCreature(1853, 180.73, -9.43856, 75.507, 1.61399, TEMPSUMMON_DEAD_DESPAWN, 0);
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
- DoYell(SAY_AGGRO1, LANG_UNIVERSAL, NULL);
}
void UpdateAI(const uint32 diff)
@@ -103,6 +100,7 @@ struct TRINITY_DLL_DECL boss_theravenianAI : public ScriptedAI
DoMeleeAttackIfReady();
}
};
+
CreatureAI* GetAI_boss_theravenian(Creature *_Creature)
{
return new boss_theravenianAI (_Creature);
diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_vectus.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_vectus.cpp
index 280e0d194d7..55a50724294 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_vectus.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_vectus.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -23,6 +23,8 @@ EndScriptData */
#include "precompiled.h"
+#define EMOTE_GENERIC_FRENZY_KILL -1000001
+
#define SPELL_FIRESHIELD 19626
#define SPELL_BLASTWAVE 13021
#define SPELL_FRENZY 28371
@@ -42,7 +44,7 @@ struct TRINITY_DLL_DECL boss_vectusAI : public ScriptedAI
Frenzy_Timer = 0;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -71,7 +73,7 @@ struct TRINITY_DLL_DECL boss_vectusAI : public ScriptedAI
if (Frenzy_Timer < diff)
{
DoCast(m_creature,SPELL_FRENZY);
- DoTextEmote("goes into a killing frenzy!",NULL);
+ DoScriptText(EMOTE_GENERIC_FRENZY_KILL, m_creature);
Frenzy_Timer = 24000;
}else Frenzy_Timer -= diff;
diff --git a/src/bindings/scripts/scripts/zone/scholomance/def_scholomance.h b/src/bindings/scripts/scripts/zone/scholomance/def_scholomance.h
index 0216a48fc74..83ce26c9687 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/def_scholomance.h
+++ b/src/bindings/scripts/scripts/zone/scholomance/def_scholomance.h
@@ -1,16 +1,17 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef DEF_SCHOLOMANCE_H
#define DEF_SCHOLOMANCE_H
-#define DATA_CANSPAWNGANDLING 1
+#define TYPE_GANDLING 1
#define DATA_DOCTORTHEOLENKRASTINOV_DEATH 2
#define DATA_INSTRUCTORMALICIA_DEATH 3
#define DATA_LADYILLUCIABAROV_DEATH 4
#define DATA_LORDALEXEIBAROV_DEATH 5
#define DATA_LOREKEEPERPOLKELT_DEATH 6
#define DATA_THERAVENIAN_DEATH 7
+#define TYPE_KIRTONOS 8
#endif
diff --git a/src/bindings/scripts/scripts/zone/scholomance/instance_scholomance.cpp b/src/bindings/scripts/scripts/zone/scholomance/instance_scholomance.cpp
index 74b90dfdf53..d99546fbcea 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/instance_scholomance.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/instance_scholomance.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -24,36 +24,65 @@ EndScriptData */
#include "precompiled.h"
#include "def_scholomance.h"
+#define GO_GATE_KIRTONOS 175570
+#define GO_GATE_GANDLING 177374
+#define GO_GATE_MALICIA 177375
+#define GO_GATE_THEOLEN 177377
+#define GO_GATE_POLKELT 177376
+#define GO_GATE_RAVENIAN 177372
+#define GO_GATE_BAROV 177373
+#define GO_GATE_ILLUCIA 177371
+
+#define ENCOUNTERS 2
+
struct TRINITY_DLL_DECL instance_scholomance : public ScriptedInstance
{
instance_scholomance(Map *map) : ScriptedInstance(map) {Initialize();};
//Lord Alexei Barov, Doctor Theolen Krastinov, The Ravenian, Lorekeeper Polkelt, Instructor Malicia and the Lady Illucia Barov.
bool IsBossDied[6];
+ uint32 Encounter[ENCOUNTERS];
- void Initialize()
- {
- IsBossDied[0] = false;
- IsBossDied[1] = false;
- IsBossDied[2] = false;
- IsBossDied[3] = false;
- IsBossDied[4] = false;
- IsBossDied[5] = false;
- }
+ uint64 GateKirtonosGUID;
+ uint64 GateGandlingGUID;
+ uint64 GateMiliciaGUID;
+ uint64 GateTheolenGUID;
+ uint64 GatePolkeltGUID;
+ uint64 GateRavenianGUID;
+ uint64 GateBarovGUID;
+ uint64 GateIlluciaGUID;
- bool IsEncounterInProgress() const
+ void Initialize()
{
- //not active in scholomance
- return false;
+ GateKirtonosGUID = 0;
+ GateGandlingGUID = 0;
+ GateMiliciaGUID = 0;
+ GateTheolenGUID = 0;
+ GatePolkeltGUID = 0;
+ GateRavenianGUID = 0;
+ GateBarovGUID = 0;
+ GateIlluciaGUID = 0;
+
+ for(uint8 i = 0; i < 6; i++)
+ IsBossDied[i] = false;
+
+ for(uint8 i = 0; i < ENCOUNTERS; i++)
+ Encounter[i] = NOT_STARTED;
}
- uint32 GetData(uint32 type)
+ void OnObjectCreate(GameObject *go)
{
- if(type == DATA_CANSPAWNGANDLING)
- if(IsBossDied[0] && IsBossDied[1] && IsBossDied[2] && IsBossDied[3] && IsBossDied[4] && IsBossDied[5])
- return 1;
-
- return 0;
+ switch(go->GetEntry())
+ {
+ case GO_GATE_KIRTONOS: GateKirtonosGUID = go->GetGUID(); break;
+ case GO_GATE_GANDLING: GateGandlingGUID = go->GetGUID(); break;
+ case GO_GATE_MALICIA: GateMiliciaGUID = go->GetGUID(); break;
+ case GO_GATE_THEOLEN: GateTheolenGUID = go->GetGUID(); break;
+ case GO_GATE_POLKELT: GatePolkeltGUID = go->GetGUID(); break;
+ case GO_GATE_RAVENIAN: GateRavenianGUID = go->GetGUID(); break;
+ case GO_GATE_BAROV: GateBarovGUID = go->GetGUID(); break;
+ case GO_GATE_ILLUCIA: GateIlluciaGUID = go->GetGUID(); break;
+ }
}
void SetData(uint32 type, uint32 data)
@@ -63,28 +92,43 @@ struct TRINITY_DLL_DECL instance_scholomance : public ScriptedInstance
case DATA_LORDALEXEIBAROV_DEATH:
IsBossDied[0] = true;
break;
-
case DATA_DOCTORTHEOLENKRASTINOV_DEATH:
IsBossDied[1] = true;
break;
-
case DATA_THERAVENIAN_DEATH:
IsBossDied[2] = true;
break;
-
case DATA_LOREKEEPERPOLKELT_DEATH:
IsBossDied[3] = true;
break;
-
case DATA_INSTRUCTORMALICIA_DEATH:
IsBossDied[4] = true;
break;
-
case DATA_LADYILLUCIABAROV_DEATH:
IsBossDied[5] = true;
break;
+ case TYPE_GANDLING:
+ Encounter[0] = data;
+ break;
+ case TYPE_KIRTONOS:
+ Encounter[1] = data;
+ break;
}
}
+
+ uint32 GetData(uint32 type)
+ {
+ if (type == TYPE_GANDLING)
+ {
+ if (IsBossDied[0] && IsBossDied[1] && IsBossDied[2] && IsBossDied[3] && IsBossDied[4] && IsBossDied[5])
+ {
+ Encounter[0] = IN_PROGRESS;
+ return IN_PROGRESS;
+ }
+ }
+
+ return 0;
+ }
};
InstanceData* GetInstanceData_instance_scholomance(Map* map)
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 fff417bcf21..4d55b5d91fd 100644
--- a/src/bindings/scripts/scripts/zone/searing_gorge/searing_gorge.cpp
+++ b/src/bindings/scripts/scripts/zone/searing_gorge/searing_gorge.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
diff --git a/src/bindings/scripts/scripts/zone/shadowfang_keep/def_shadowfang_keep.h b/src/bindings/scripts/scripts/zone/shadowfang_keep/def_shadowfang_keep.h
index 1612bfd59f0..8383a5c3950 100644
--- a/src/bindings/scripts/scripts/zone/shadowfang_keep/def_shadowfang_keep.h
+++ b/src/bindings/scripts/scripts/zone/shadowfang_keep/def_shadowfang_keep.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
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 967cff5c769..caf18778abb 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -26,6 +26,18 @@ EndScriptData */
#define ENCOUNTERS 4
+enum
+{
+ SAY_BOSS_DIE_AD = -1033007,
+ SAY_BOSS_DIE_AS = -1033008,
+
+ NPC_ASH = 3850,
+ NPC_ADA = 3849,
+
+ GO_COURTYARD_DOOR = 18895, //door to open when talking to NPC's
+ GO_SORCERER_DOOR = 18972, //door to open when Fenrus the Devourer
+ GO_ARUGAL_DOOR = 18971 //door to open when Wolf Master Nandos
+};
struct TRINITY_DLL_DECL instance_shadowfang_keep : public ScriptedInstance
{
instance_shadowfang_keep(Map *map) : ScriptedInstance(map) {Initialize();};
@@ -33,12 +45,18 @@ struct TRINITY_DLL_DECL instance_shadowfang_keep : public ScriptedInstance
uint32 Encounter[ENCOUNTERS];
std::string str_data;
+ uint64 uiAshGUID;
+ uint64 uiAdaGUID;
+
uint64 DoorCourtyardGUID;
uint64 DoorSorcererGUID;
uint64 DoorArugalGUID;
void Initialize()
{
+ uiAshGUID = 0;
+ uiAdaGUID = 0;
+
DoorCourtyardGUID = 0;
DoorSorcererGUID = 0;
DoorArugalGUID = 0;
@@ -63,28 +81,52 @@ struct TRINITY_DLL_DECL instance_shadowfang_keep : public ScriptedInstance
return NULL;
}
+ void OnCreatureCreate(Creature* pCreature, uint32 uiCreature)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case NPC_ASH: uiAshGUID = pCreature->GetGUID(); break;
+ case NPC_ADA: uiAdaGUID = pCreature->GetGUID(); break;
+ }
+ }
+
void OnObjectCreate(GameObject *go)
{
switch(go->GetEntry())
{
- case 18895: DoorCourtyardGUID = go->GetGUID(); break;
- case 18972: DoorSorcererGUID = go->GetGUID(); break;
- case 18971: DoorArugalGUID = go->GetGUID(); break;
+ case GO_COURTYARD_DOOR:
+ DoorCourtyardGUID = go->GetGUID();
+ if (Encounter[0] == DONE)
+ go->SetGoState(GO_STATE_ACTIVE);
+ break;
+ case GO_SORCERER_DOOR:
+ DoorSorcererGUID = go->GetGUID();
+ if (Encounter[2] == DONE)
+ go->SetGoState(GO_STATE_ACTIVE);
+ break;
+ case GO_ARUGAL_DOOR:
+ DoorArugalGUID = go->GetGUID();
+ if (Encounter[3] == DONE)
+ go->SetGoState(GO_STATE_ACTIVE);
+ break;
}
}
- void HandleGameObject(uint64 guid, uint32 state)
+ void DoSpeech()
{
- Player *player = GetPlayerInMap();
+ Player* pPlayer = GetPlayerInMap();
- if (!player || !guid)
+ if (pPlayer)
{
- debug_log("TSCR: Instance Shadowfang Keep: HandleGameObject fail");
- return;
- }
+ Unit* pAda = Unit::GetUnit(*pPlayer,uiAdaGUID);
+ Unit* pAsh = Unit::GetUnit(*pPlayer,uiAshGUID);
- if (GameObject *go = GameObject::GetGameObject(*player,guid))
- go->SetGoState(state);
+ if (pAda && pAda->isAlive() && pAsh && pAsh->isAlive())
+ {
+ DoScriptText(SAY_BOSS_DIE_AD,pAda);
+ DoScriptText(SAY_BOSS_DIE_AS,pAsh);
+ }
+ }
}
void SetData(uint32 type, uint32 data)
@@ -97,6 +139,8 @@ struct TRINITY_DLL_DECL instance_shadowfang_keep : public ScriptedInstance
Encounter[0] = data;
break;
case TYPE_RETHILGORE:
+ if (data == DONE)
+ DoSpeech();
Encounter[1] = data;
break;
case TYPE_FENRUS:
@@ -160,8 +204,10 @@ struct TRINITY_DLL_DECL instance_shadowfang_keep : public ScriptedInstance
loadStream >> Encounter[0] >> Encounter[1] >> Encounter[2] >> Encounter[3];
for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ {
if (Encounter[i] == IN_PROGRESS)
Encounter[i] = NOT_STARTED;
+ }
OUT_LOAD_INST_DATA_COMPLETE;
}
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 a4f04f83ffd..3c557118f3b 100644
--- a/src/bindings/scripts/scripts/zone/shadowfang_keep/shadowfang_keep.cpp
+++ b/src/bindings/scripts/scripts/zone/shadowfang_keep/shadowfang_keep.cpp
@@ -1,4 +1,4 @@
- /* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ /* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -33,7 +33,20 @@ EndContentData */
## npc_shadowfang_prisoner
######*/
-#define SAY_FREE -1033000
+enum
+{
+ SAY_FREE_AS = -1033000,
+ SAY_OPEN_DOOR_AS = -1033001,
+ SAY_POST_DOOR_AS = -1033002,
+ SAY_FREE_AD = -1033003,
+ SAY_OPEN_DOOR_AD = -1033004,
+ SAY_POST1_DOOR_AD = -1033005,
+ SAY_POST2_DOOR_AD = -1033006,
+
+ SPELL_UNLOCK = 6421,
+ NPC_ASH = 3850
+};
+
#define GOSSIP_ITEM_DOOR "Thanks, I'll follow you to the door."
struct TRINITY_DLL_DECL npc_shadowfang_prisonerAI : public npc_escortAI
@@ -41,80 +54,89 @@ struct TRINITY_DLL_DECL npc_shadowfang_prisonerAI : public npc_escortAI
npc_shadowfang_prisonerAI(Creature *c) : npc_escortAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ uiNpcEntry = c->GetEntry();
}
ScriptedInstance *pInstance;
+ uint32 uiNpcEntry;
- void WaypointReached(uint32 i)
+ void WaypointReached(uint32 uiPoint)
{
- if( pInstance && i == 6)
+ switch(uiPoint)
{
- m_creature->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
- DoScriptText(SAY_FREE, m_creature);
- pInstance->SetData(TYPE_FREE_NPC, DONE);
+ case 0:
+ if (uiNpcEntry == NPC_ASH)
+ DoScriptText(SAY_FREE_AS, m_creature);
+ else
+ DoScriptText(SAY_FREE_AD, m_creature);
+ break;
+ case 10:
+ if (uiNpcEntry == NPC_ASH)
+ DoScriptText(SAY_OPEN_DOOR_AS, m_creature);
+ else
+ DoScriptText(SAY_OPEN_DOOR_AD, m_creature);
+ break;
+ case 11:
+ if (uiNpcEntry == NPC_ASH)
+ DoCast(m_creature, SPELL_UNLOCK);
+ break;
+ case 12:
+ if (uiNpcEntry == NPC_ASH)
+ DoScriptText(SAY_POST_DOOR_AS, m_creature);
+ else
+ DoScriptText(SAY_POST1_DOOR_AD, m_creature);
+
+ if (pInstance)
+ pInstance->SetData(TYPE_FREE_NPC, DONE);
+ break;
+ case 13:
+ if (uiNpcEntry != NPC_ASH)
+ DoScriptText(SAY_POST2_DOOR_AD, m_creature);
+ break;
}
}
void Reset() {}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
};
-CreatureAI* GetAI_npc_shadowfang_prisoner(Creature *_Creature)
+CreatureAI* GetAI_npc_shadowfang_prisoner(Creature* pCreature)
{
- npc_shadowfang_prisonerAI* prisonerAI = new npc_shadowfang_prisonerAI(_Creature);
-
- uint32 eCreature = _Creature->GetEntry();
-
- if( eCreature==3849) //adamant
- prisonerAI->AddWaypoint(0, -254.47, 2117.48, 81.17);
- if( eCreature==3850) //ashcrombe
- prisonerAI->AddWaypoint(0, -252.35, 2126.71, 81.17);
+ npc_shadowfang_prisonerAI* prisonerAI = new npc_shadowfang_prisonerAI(pCreature);
- prisonerAI->AddWaypoint(1, -253.63, 2131.27, 81.28);
- prisonerAI->AddWaypoint(2, -249.66, 2142.45, 87.01);
- prisonerAI->AddWaypoint(3, -248.08, 2143.68, 87.01);
- prisonerAI->AddWaypoint(4, -238.87, 2139.93, 87.01);
- prisonerAI->AddWaypoint(5, -235.47, 2149.18, 90.59);
- prisonerAI->AddWaypoint(6, -239.89, 2156.06, 90.62, 20000);
+ prisonerAI->FillPointMovementListForCreature();
return (CreatureAI*)prisonerAI;
}
-bool GossipHello_npc_shadowfang_prisoner(Player *player, Creature *_Creature)
+bool GossipHello_npc_shadowfang_prisoner(Player* pPlayer, Creature* pCreature)
{
- ScriptedInstance* pInstance = ((ScriptedInstance*)_Creature->GetInstanceData());
+ ScriptedInstance* pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
- if (!pInstance)
- return false;
-
- if (pInstance->GetData(TYPE_FREE_NPC) != DONE && pInstance->GetData(TYPE_RETHILGORE) == DONE)
- player->ADD_GOSSIP_ITEM( 0, GOSSIP_ITEM_DOOR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
+ if (pInstance && pInstance->GetData(TYPE_FREE_NPC) != DONE && pInstance->GetData(TYPE_RETHILGORE) == DONE)
+ pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_DOOR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->SEND_GOSSIP_MENU(pCreature->GetNpcTextId(), pCreature->GetGUID());
return true;
}
-bool GossipSelect_npc_shadowfang_prisoner(Player *player, Creature *_Creature, uint32 sender, uint32 action)
+bool GossipSelect_npc_shadowfang_prisoner(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
- if (action == GOSSIP_ACTION_INFO_DEF+1)
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
{
- player->CLOSE_GOSSIP_MENU();
- ((npc_escortAI*)(_Creature->AI()))->Start(false, false, false);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ ((npc_escortAI*)(pCreature->AI()))->Start(false, true, false);
}
return true;
}
-/*######
-## AddSC
-######*/
-
void AddSC_shadowfang_keep()
{
Script *newscript;
newscript = new Script;
- newscript->Name="npc_shadowfang_prisoner";
+ newscript->Name = "npc_shadowfang_prisoner";
newscript->pGossipHello = &GossipHello_npc_shadowfang_prisoner;
newscript->pGossipSelect = &GossipSelect_npc_shadowfang_prisoner;
newscript->GetAI = &GetAI_npc_shadowfang_prisoner;
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 014d7fe1153..f46476df98a 100644
--- a/src/bindings/scripts/scripts/zone/shadowmoon_valley/boss_doomwalker.cpp
+++ b/src/bindings/scripts/scripts/zone/shadowmoon_valley/boss_doomwalker.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -83,7 +83,7 @@ struct TRINITY_DLL_DECL boss_doomwalkerAI : public ScriptedAI
DoScriptText(SAY_DEATH, m_creature);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
@@ -131,7 +131,7 @@ struct TRINITY_DLL_DECL boss_doomwalkerAI : public ScriptedAI
//remove enrage before casting earthquake because enrage + earthquake = 16000dmg over 8sec and all dead
if (InEnrage)
- m_creature->RemoveAura(SPELL_ENRAGE, 0);
+ m_creature->RemoveAura(SPELL_ENRAGE);
DoCast(m_creature,SPELL_EARTHQUAKE);
Quake_Timer = 30000 + rand()%25000;
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 720d5aabb1c..426b0eb0202 100644
--- a/src/bindings/scripts/scripts/zone/shadowmoon_valley/shadowmoon_valley.cpp
+++ b/src/bindings/scripts/scripts/zone/shadowmoon_valley/shadowmoon_valley.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -57,6 +57,7 @@ struct TRINITY_DLL_DECL mob_mature_netherwing_drakeAI : public ScriptedAI
mob_mature_netherwing_drakeAI(Creature* c) : ScriptedAI(c)
{
PlayerGUID = 0;
+ Reset();
}
uint64 PlayerGUID;
@@ -78,7 +79,7 @@ struct TRINITY_DLL_DECL mob_mature_netherwing_drakeAI : public ScriptedAI
CastTimer = 5000;
}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void MoveInLineOfSight(Unit* who)
{
@@ -93,11 +94,11 @@ struct TRINITY_DLL_DECL mob_mature_netherwing_drakeAI : public ScriptedAI
if(!caster)
return;
- if(caster->GetTypeId() == TYPEID_PLAYER && spell->Id == SPELL_PLACE_CARCASS && !m_creature->HasAura(SPELL_JUST_EATEN, 0) && !PlayerGUID)
+ if(caster->GetTypeId() == TYPEID_PLAYER && spell->Id == SPELL_PLACE_CARCASS && !m_creature->HasAura(SPELL_JUST_EATEN) && !PlayerGUID)
{
float PlayerX, PlayerY, PlayerZ;
caster->GetClosePoint(PlayerX, PlayerY, PlayerZ, m_creature->GetObjectSize());
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->GetMotionMaster()->MovePoint(1, PlayerX, PlayerY, PlayerZ);
PlayerGUID = caster->GetGUID();
}
@@ -113,7 +114,7 @@ struct TRINITY_DLL_DECL mob_mature_netherwing_drakeAI : public ScriptedAI
IsEating = true;
EatTimer = 5000;
m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACKUNARMED);
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
}
}
@@ -180,6 +181,7 @@ struct TRINITY_DLL_DECL mob_enslaved_netherwing_drakeAI : public ScriptedAI
{
PlayerGUID = 0;
Tapped = false;
+ Reset();
}
uint64 PlayerGUID;
@@ -192,11 +194,11 @@ struct TRINITY_DLL_DECL mob_enslaved_netherwing_drakeAI : public ScriptedAI
m_creature->setFaction(FACTION_DEFAULT);
FlyTimer = 10000;
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->SetVisibility(VISIBILITY_ON);
}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void SpellHit(Unit* caster, const SpellEntry* spell)
{
@@ -241,7 +243,7 @@ struct TRINITY_DLL_DECL mob_enslaved_netherwing_drakeAI : public ScriptedAI
PlayerGUID = 0;
}
m_creature->SetVisibility(VISIBILITY_OFF);
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
m_creature->RemoveCorpse();
}
@@ -280,7 +282,7 @@ struct TRINITY_DLL_DECL mob_enslaved_netherwing_drakeAI : public ScriptedAI
dz += 25;
}
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->GetMotionMaster()->MovePoint(1, dx, dy, dz);
}
}
@@ -316,7 +318,7 @@ struct TRINITY_DLL_DECL mob_dragonmaw_peonAI : public ScriptedAI
PoisonTimer = 0;
}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void SpellHit(Unit* caster, const SpellEntry* spell)
{
@@ -688,7 +690,7 @@ struct TRINITY_DLL_DECL npc_overlord_morghorAI : public ScriptedAI
Event = false;
}
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void StartEvent()
{
@@ -757,7 +759,7 @@ struct TRINITY_DLL_DECL npc_overlord_morghorAI : public ScriptedAI
case 19: DoScriptText(LORD_ILLIDAN_SAY_7, Illi); return 5000; break;
case 20:
Illi->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
- Illi->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ Illi->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
return 500; break;
case 21: DoScriptText(OVERLORD_SAY_5, m_creature); return 500; break;
case 22:
@@ -865,7 +867,7 @@ struct TRINITY_DLL_DECL npc_earthmender_wildaAI : public npc_escortAI
bool Completed;
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
Player* player = Unit::GetPlayer(PlayerGUID);
@@ -1166,7 +1168,7 @@ struct TRINITY_DLL_DECL mob_illidari_spawnAI : public ScriptedAI
Timers = false;
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void JustDied(Unit* slayer);
void UpdateAI(const uint32 diff)
@@ -1279,7 +1281,7 @@ struct TRINITY_DLL_DECL mob_torloth_the_magnificentAI : public ScriptedAI
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
}
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void HandleAnimation()
{
@@ -1434,7 +1436,7 @@ struct TRINITY_DLL_DECL npc_lord_illidan_stormrageAI : public ScriptedAI
m_creature->SetVisibility(VISIBILITY_OFF);
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void AttackStart(Unit* who) {}
@@ -1693,7 +1695,7 @@ struct TRINITY_DLL_DECL npc_enraged_spiritAI : public ScriptedAI
void Reset() { }
- void Aggro(Unit *who){}
+ void EnterCombat(Unit *who){}
void JustDied(Unit* killer)
{
diff --git a/src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp b/src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp
index 36ea4354030..e346b9c25fc 100644
--- a/src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp
+++ b/src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -58,7 +58,7 @@ struct TRINITY_DLL_DECL npc_raliq_the_drunkAI : public ScriptedAI
m_creature->setFaction(FACTION_FRIENDLY_RD);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void UpdateAI(const uint32 diff)
{
@@ -121,7 +121,7 @@ struct TRINITY_DLL_DECL npc_salsalabimAI : public ScriptedAI
m_creature->setFaction(FACTION_FRIENDLY_SA);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void DamageTaken(Unit *done_by, uint32 &damage)
{
@@ -309,17 +309,17 @@ public:
case 54: DoScriptText(WHISP19, m_creature, pTemp); break;
case 55: DoScriptText(WHISP20, m_creature, pTemp); break;
case 56: DoScriptText(WHISP21, m_creature, pTemp);
- if( PlayerGUID )
+ if( PlayerGUID )
{
Player* player = (Unit::GetPlayer(PlayerGUID));
if( player )
- (player)->GroupEventHappens(10211,m_creature);
+ player->GroupEventHappens(10211,m_creature);
}
break;
}
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void MoveInLineOfSight(Unit *who)
{
@@ -350,64 +350,7 @@ CreatureAI* GetAI_npc_kservantAI(Creature *_Creature)
{
npc_kservantAI* kservantAI = new npc_kservantAI(_Creature);
- kservantAI->AddWaypoint(0, -1863.369019, 5419.517090, -10.463668, 4000);
- kservantAI->AddWaypoint(1, -1861.749023, 5416.465332, -10.508068);
- kservantAI->AddWaypoint(2, -1857.036133, 5410.966309, -12.428039);
- kservantAI->AddWaypoint(3, -1831.539185, 5365.472168, -12.428039);
- kservantAI->AddWaypoint(4, -1813.416504, 5333.776855, -12.428039);
- kservantAI->AddWaypoint(5, -1800.354370, 5313.290039, -12.428039);
- kservantAI->AddWaypoint(6, -1775.624878, 5268.786133, -38.809181);
- kservantAI->AddWaypoint(7, -1770.147339, 5259.268066, -38.829231);
- kservantAI->AddWaypoint(8, -1762.814209, 5261.098145, -38.848995);
- kservantAI->AddWaypoint(9, -1740.110474, 5268.858398, -40.208965);
- kservantAI->AddWaypoint(10, -1725.837402, 5270.936035, -40.208965);
- kservantAI->AddWaypoint(11, -1701.580322, 5290.323242, -40.209187);
- kservantAI->AddWaypoint(12, -1682.877808, 5291.406738, -34.429646);
- kservantAI->AddWaypoint(13, -1670.101685, 5291.201172, -32.786007);
- kservantAI->AddWaypoint(14, -1656.666870, 5294.333496, -37.862648);
- kservantAI->AddWaypoint(15, -1652.035767, 5295.413086, -40.245499);
- kservantAI->AddWaypoint(16, -1620.860596, 5300.133301, -40.208992);
- kservantAI->AddWaypoint(17, -1607.630981, 5293.983398, -38.577045, 5000);
- kservantAI->AddWaypoint(18, -1607.630981, 5293.983398, -38.577045, 5000);
- kservantAI->AddWaypoint(19, -1607.630981, 5293.983398, -38.577045, 5000);
- kservantAI->AddWaypoint(20, -1622.140869, 5301.955566, -40.208897);
- kservantAI->AddWaypoint(21, -1621.131836, 5333.112793, -40.208897);
- kservantAI->AddWaypoint(22, -1637.598999, 5342.134277, -40.208790);
- kservantAI->AddWaypoint(23, -1648.521606, 5352.309570, -47.496170);
- kservantAI->AddWaypoint(24, -1654.606934, 5357.419434, -45.870892);
- kservantAI->AddWaypoint(25, -1633.670044, 5422.067871, -42.835541);
- kservantAI->AddWaypoint(25, -1656.567505, 5426.236328, -40.405815);
- kservantAI->AddWaypoint(26, -1664.932373, 5425.686523, -38.846405);
- kservantAI->AddWaypoint(27, -1681.406006, 5425.871094, -38.810928);
- kservantAI->AddWaypoint(28, -1730.875977, 5427.413574, -12.427910);
- kservantAI->AddWaypoint(29, -1743.509521, 5369.599121, -12.427910);
- kservantAI->AddWaypoint(30, -1877.217041, 5303.710449, -12.427989);
- kservantAI->AddWaypoint(31, -1890.371216, 5289.273438, -12.428268);
- kservantAI->AddWaypoint(32, -1905.505737, 5266.534668, 2.630672);
- kservantAI->AddWaypoint(33, -1909.381348, 5273.008301, 1.663714, 10000);
- kservantAI->AddWaypoint(34, -1909.381348, 5273.008301, 1.663714, 12000);
- kservantAI->AddWaypoint(35, -1909.381348, 5273.008301, 1.663714, 8000);
- kservantAI->AddWaypoint(36, -1909.381348, 5273.008301, 1.663714, 15000);
- kservantAI->AddWaypoint(37, -1927.561401, 5275.324707, 1.984987);
- kservantAI->AddWaypoint(38, -1927.385498, 5300.879883, -12.427236);
- kservantAI->AddWaypoint(39, -1921.063965, 5314.318359, -12.427236);
- kservantAI->AddWaypoint(40, -1965.425415, 5379.298828, -12.427236);
- kservantAI->AddWaypoint(41, -1981.233154, 5450.743652, -12.427236);
- kservantAI->AddWaypoint(42, -1958.022461, 5455.904297, 0.487659);
- kservantAI->AddWaypoint(43, -1951.991455, 5463.580566, 0.874490, 10000);
- kservantAI->AddWaypoint(44, -1951.991455, 5463.580566, 0.874490, 12000);
- kservantAI->AddWaypoint(45, -1968.730225, 5481.752930, -12.427846);
- kservantAI->AddWaypoint(46, -1881.839844, 5554.040039, -12.427846);
- kservantAI->AddWaypoint(47, -1841.566650, 5545.965332, -12.427846);
- kservantAI->AddWaypoint(48, -1837.658325, 5523.780273, 0.558756);
- kservantAI->AddWaypoint(49, -1831.321777, 5534.821777, 1.221819, 6000);
- kservantAI->AddWaypoint(50, -1831.321777, 5534.821777, 1.221819, 8000);
- kservantAI->AddWaypoint(51, -1831.321777, 5534.821777, 1.221819, 5000);
- kservantAI->AddWaypoint(52, -1850.060669, 5472.610840, 0.857320, 6000);
- kservantAI->AddWaypoint(53, -1850.060669, 5472.610840, 0.857320, 8000);
- kservantAI->AddWaypoint(54, -1850.060669, 5472.610840, 0.857320, 9000);
- kservantAI->AddWaypoint(55, -1850.060669, 5472.610840, 0.857320, 9000);
- kservantAI->AddWaypoint(56, -1850.060669, 5472.610840, 0.857320, 4000);
+ kservantAI->FillPointMovementListForCreature();
return (CreatureAI*)kservantAI;
}
@@ -494,7 +437,7 @@ struct TRINITY_DLL_DECL npc_dirty_larryAI : public ScriptedAI
}
}
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void UpdateAI(const uint32 diff)
{
diff --git a/src/bindings/scripts/scripts/zone/silithus/silithus.cpp b/src/bindings/scripts/scripts/zone/silithus/silithus.cpp
index 35dca28ddc8..bd1ecf748a0 100644
--- a/src/bindings/scripts/scripts/zone/silithus/silithus.cpp
+++ b/src/bindings/scripts/scripts/zone/silithus/silithus.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
diff --git a/src/bindings/scripts/scripts/zone/silvermoon/silvermoon_city.cpp b/src/bindings/scripts/scripts/zone/silvermoon/silvermoon_city.cpp
index 330fcf937c2..982c00dfcab 100644
--- a/src/bindings/scripts/scripts/zone/silvermoon/silvermoon_city.cpp
+++ b/src/bindings/scripts/scripts/zone/silvermoon/silvermoon_city.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -47,12 +47,12 @@ struct TRINITY_DLL_DECL npc_blood_knight_stillbladeAI : public ScriptedAI
void Reset()
{
lifeTimer = 120000;
- m_creature->SetUInt32Value(UNIT_DYNAMIC_FLAGS, 32);
+ m_creature->SetStandState(UNIT_STAND_STATE_DEAD);
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,7); // lay down
spellHit = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -63,7 +63,7 @@ struct TRINITY_DLL_DECL npc_blood_knight_stillbladeAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
- if (!m_creature->GetUInt32Value(UNIT_FIELD_BYTES_1))
+ if (m_creature->IsStandState())
{
if(lifeTimer < diff)
m_creature->AI()->EnterEvadeMode();
@@ -79,7 +79,7 @@ struct TRINITY_DLL_DECL npc_blood_knight_stillbladeAI : public ScriptedAI
{
((Player*)Hitter)->AreaExploredOrEventHappens(QUEST_REDEEMING_THE_DEAD);
DoCast(m_creature,SPELL_REVIVE_SELF);
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
m_creature->SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0);
//m_creature->RemoveAllAuras();
DoScriptText(SAY_HEAL, m_creature);
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 a4236c82cef..3d61a6b0e87 100644
--- a/src/bindings/scripts/scripts/zone/silverpine_forest/silverpine_forest.cpp
+++ b/src/bindings/scripts/scripts/zone/silverpine_forest/silverpine_forest.cpp
@@ -1,4 +1,4 @@
- /* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ /* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -44,7 +44,7 @@ struct TRINITY_DLL_DECL npc_astor_hadrenAI : public ScriptedAI
m_creature->setFaction(68);
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
}
@@ -149,7 +149,7 @@ struct TRINITY_DLL_DECL npc_deathstalker_erlandAI : public npc_escortAI
void Reset() {}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
switch(rand()%2)
{
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 cd42b046d94..e600888905a 100644
--- a/src/bindings/scripts/scripts/zone/stonetalon_mountains/stonetalon_mountains.cpp
+++ b/src/bindings/scripts/scripts/zone/stonetalon_mountains/stonetalon_mountains.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -123,7 +123,7 @@ struct TRINITY_DLL_DECL npc_kaya_flathoofAI : public npc_escortAI
void Reset(){}
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void JustDied(Unit* killer)
{
diff --git a/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp b/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp
index 81016febdae..8212cb27254 100644
--- a/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp
+++ b/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -27,6 +27,7 @@ npc_bartleby
npc_dashel_stonefist
npc_general_marcus_jonathan
npc_lady_katrana_prestor
+npc_harbor_taxi
EndContentData */
#include "precompiled.h"
@@ -74,7 +75,7 @@ struct TRINITY_DLL_DECL npc_bartlebyAI : public ScriptedAI
void Reset()
{
m_creature->setFaction(11);
- m_creature->setEmoteState(7);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, 7);
PlayerGUID = 0;
}
@@ -101,7 +102,7 @@ struct TRINITY_DLL_DECL npc_bartlebyAI : public ScriptedAI
}
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
};
bool QuestAccept_npc_bartleby(Player *player, Creature *_Creature, Quest const *_Quest)
@@ -131,7 +132,7 @@ struct TRINITY_DLL_DECL npc_dashel_stonefistAI : public ScriptedAI
void Reset()
{
m_creature->setFaction(11);
- m_creature->setEmoteState(7);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, 7);
}
void DamageTaken(Unit *done_by, uint32 & damage)
@@ -151,7 +152,7 @@ struct TRINITY_DLL_DECL npc_dashel_stonefistAI : public ScriptedAI
}
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
};
bool QuestAccept_npc_dashel_stonefist(Player *player, Creature *_Creature, Quest const *_Quest)
@@ -173,6 +174,8 @@ CreatureAI* GetAI_npc_dashel_stonefist(Creature *_creature)
## npc_general_marcus_jonathan
######*/
+#define SAY_GREETING -1000005
+
bool ReceiveEmote_npc_general_marcus_jonathan(Player *player, Creature *_Creature, uint32 emote)
{
if(player->GetTeam() == ALLIANCE)
@@ -184,7 +187,7 @@ bool ReceiveEmote_npc_general_marcus_jonathan(Player *player, Creature *_Creatur
}
if (emote == TEXTEMOTE_WAVE)
{
- _Creature->MonsterSay("Greetings citizen",LANG_COMMON,0);
+ DoScriptText(SAY_GREETING, _Creature, player);
}
}
return true;
@@ -236,6 +239,28 @@ bool GossipSelect_npc_lady_katrana_prestor(Player *player, Creature *_Creature,
return true;
}
+/*######
+## npc_harbor_taxi
+######*/
+
+#define GOSSIP_STORMWIND "I'd like to take a flight around Stormwind Harbor."
+
+bool GossipHello_npc_stormwind_harbor_taxi(Player *player, Creature *_Creature)
+{
+ player->ADD_GOSSIP_ITEM(0, GOSSIP_STORMWIND, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 10);
+ player->SEND_GOSSIP_MENU(13454,_Creature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_stormwind_harbor_taxi(Player *player, Creature *_Creature, uint32 sender, uint32 action )
+{
+ if (action == GOSSIP_ACTION_INFO_DEF + 10)
+ {
+ player->GetSession()->SendDoFlight(1149, 1041);
+ }
+ return true;
+}
+
void AddSC_stormwind_city()
{
Script *newscript;
@@ -260,7 +285,7 @@ void AddSC_stormwind_city()
newscript = new Script;
newscript->Name = "npc_general_marcus_jonathan";
- newscript->pReceiveEmote = &ReceiveEmote_npc_general_marcus_jonathan;
+ //newscript->pReceiveEmote = &ReceiveEmote_npc_general_marcus_jonathan;
newscript->RegisterSelf();
newscript = new Script;
@@ -268,5 +293,11 @@ void AddSC_stormwind_city()
newscript->pGossipHello = &GossipHello_npc_lady_katrana_prestor;
newscript->pGossipSelect = &GossipSelect_npc_lady_katrana_prestor;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="npc_stormwind_harbor_taxi";
+ newscript->pGossipHello = &GossipHello_npc_stormwind_harbor_taxi;
+ newscript->pGossipSelect = &GossipSelect_npc_stormwind_harbor_taxi;
+ 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 c2aa57d8c49..f4233e5dd94 100644
--- a/src/bindings/scripts/scripts/zone/stranglethorn_vale/stranglethorn_vale.cpp
+++ b/src/bindings/scripts/scripts/zone/stranglethorn_vale/stranglethorn_vale.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -66,7 +66,7 @@ struct TRINITY_DLL_DECL mob_yennikuAI : public ScriptedAI
return;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void UpdateAI(const uint32 diff)
{
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 c8ad95038c0..d3a6db26e02 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_baron_rivendare.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_baron_rivendare.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -100,7 +100,7 @@ struct TRINITY_DLL_DECL boss_baron_rivendareAI : public ScriptedAI
SummonSkeletons_Timer = 34000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if (pInstance)
pInstance->SetData(TYPE_BARON,IN_PROGRESS);
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 c30f712a98b..f154cefa545 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_baroness_anastari.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_baroness_anastari.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -51,7 +51,7 @@ struct TRINITY_DLL_DECL boss_baroness_anastariAI : public ScriptedAI
//Possess_Timer = 35000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 9fc9194ca4b..e5a74cbc144 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -102,7 +102,7 @@ struct TRINITY_DLL_DECL boss_cannon_master_willeyAI : public ScriptedAI
m_creature->SummonCreature(11054,ADD_9X,ADD_9Y,ADD_9Z,ADD_9O,TEMPSUMMON_TIMED_DESPAWN,240000);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 0e70b4a3b43..8372393f2f7 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -129,7 +129,7 @@ struct TRINITY_DLL_DECL boss_dathrohan_balnazzarAI : public ScriptedAI
m_creature->SummonCreature(10698,ADD_8X,ADD_8Y,ADD_8Z,ADD_8O,TEMPSUMMON_TIMED_DESPAWN,240000);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 5d0eda58c37..5be1f35dc93 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_magistrate_barthilas.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_magistrate_barthilas.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -73,7 +73,7 @@ struct TRINITY_DLL_DECL boss_magistrate_barthilasAI : public ScriptedAI
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_HUMAN);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 652dd48e766..d010bcf07f3 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -49,7 +49,7 @@ struct TRINITY_DLL_DECL boss_maleki_the_pallidAI : public ScriptedAI
DrainLife_Timer = 31000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/stratholme/boss_nerubenkan.cpp b/src/bindings/scripts/scripts/zone/stratholme/boss_nerubenkan.cpp
index db425ebcca0..be7aa5d1e2a 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_nerubenkan.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_nerubenkan.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -55,7 +55,7 @@ struct TRINITY_DLL_DECL boss_nerubenkanAI : public ScriptedAI
RaiseUndeadScarab_Timer = 3000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 86602f40d34..e673652fc7e 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -81,7 +81,7 @@ struct TRINITY_DLL_DECL boss_silver_hand_bossesAI : public ScriptedAI
}
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
}
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 d6a87d43d8b..fb27ae43928 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_postmaster_malown.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_postmaster_malown.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -55,7 +55,7 @@ struct TRINITY_DLL_DECL boss_postmaster_malownAI : public ScriptedAI
HasYelled = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 2e16dc883cc..cbc615f9825 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -47,7 +47,7 @@ struct TRINITY_DLL_DECL boss_ramstein_the_gorgerAI : public ScriptedAI
Knockout_Timer = 12000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 f41c5f013b6..a3330d4710a 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -40,7 +40,7 @@ struct TRINITY_DLL_DECL boss_timmy_the_cruelAI : public ScriptedAI
HasYelled = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if (!HasYelled)
{
diff --git a/src/bindings/scripts/scripts/zone/stratholme/def_stratholme.h b/src/bindings/scripts/scripts/zone/stratholme/def_stratholme.h
index 79dd277c999..b9246091a7c 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/def_stratholme.h
+++ b/src/bindings/scripts/scripts/zone/stratholme/def_stratholme.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
diff --git a/src/bindings/scripts/scripts/zone/stratholme/instance_stratholme.cpp b/src/bindings/scripts/scripts/zone/stratholme/instance_stratholme.cpp
index 68718bd2dec..988667ebe5c 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/instance_stratholme.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/instance_stratholme.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -146,7 +146,7 @@ struct TRINITY_DLL_DECL instance_stratholme : public ScriptedInstance
if (withRestoreTime)
go->UseDoorOrButton(10);
else
- go->SetGoState(newState);
+ go->SetGoState((GOState)newState);
}
}
@@ -280,10 +280,10 @@ struct TRINITY_DLL_DECL instance_stratholme : public ScriptedInstance
if (!pGroupie)
continue;
- if (pGroupie->HasAura(SPELL_BARON_ULTIMATUM,0))
+ if (pGroupie->HasAura(SPELL_BARON_ULTIMATUM))
pGroupie->RemoveAurasDueToSpell(SPELL_BARON_ULTIMATUM);
}
- } else if (player->HasAura(SPELL_BARON_ULTIMATUM,0))
+ } else if (player->HasAura(SPELL_BARON_ULTIMATUM))
player->RemoveAurasDueToSpell(SPELL_BARON_ULTIMATUM);
if (Unit *temp = Unit::GetUnit(*player,GetData64(DATA_BARON)))
diff --git a/src/bindings/scripts/scripts/zone/stratholme/stratholme.cpp b/src/bindings/scripts/scripts/zone/stratholme/stratholme.cpp
index f22ca652fff..d843be2ee73 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/stratholme.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/stratholme.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -54,12 +54,12 @@ bool GOHello_go_gauntlet_gate(Player *player, GameObject* _GO)
continue;
if (pGroupie->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE &&
- !pGroupie->HasAura(SPELL_BARON_ULTIMATUM,0) &&
+ !pGroupie->HasAura(SPELL_BARON_ULTIMATUM) &&
pGroupie->GetMap() == _GO->GetMap())
pGroupie->CastSpell(pGroupie,SPELL_BARON_ULTIMATUM,true);
}
} else if (player->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE &&
- !player->HasAura(SPELL_BARON_ULTIMATUM,0) &&
+ !player->HasAura(SPELL_BARON_ULTIMATUM) &&
player->GetMap() == _GO->GetMap())
player->CastSpell(player,SPELL_BARON_ULTIMATUM,true);
@@ -72,10 +72,10 @@ bool GOHello_go_gauntlet_gate(Player *player, GameObject* _GO)
######*/
//Possibly more of these quotes around.
-#define SAY_ZAPPED0 "Thanks to Egan"
-#define SAY_ZAPPED1 "Rivendare must die"
-#define SAY_ZAPPED2 "Who you gonna call?"
-#define SAY_ZAPPED3 "Don't cross those beams!"
+#define SAY_ZAPPED0 -1329000
+#define SAY_ZAPPED1 -1329001
+#define SAY_ZAPPED2 -1329002
+#define SAY_ZAPPED3 -1329003
struct TRINITY_DLL_DECL mob_freed_soulAI : public ScriptedAI
{
@@ -85,14 +85,14 @@ struct TRINITY_DLL_DECL mob_freed_soulAI : public ScriptedAI
{
switch (rand()%4)
{
- case 0: DoSay(SAY_ZAPPED0,LANG_UNIVERSAL,NULL); break;
- case 1: DoSay(SAY_ZAPPED1,LANG_UNIVERSAL,NULL); break;
- case 2: DoSay(SAY_ZAPPED2,LANG_UNIVERSAL,NULL); break;
- case 3: DoSay(SAY_ZAPPED3,LANG_UNIVERSAL,NULL); break;
+ case 0: DoScriptText(SAY_ZAPPED0, m_creature); break;
+ case 1: DoScriptText(SAY_ZAPPED1, m_creature); break;
+ case 2: DoScriptText(SAY_ZAPPED2, m_creature); break;
+ case 3: DoScriptText(SAY_ZAPPED3, m_creature); break;
}
}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
};
CreatureAI* GetAI_mob_freed_soul(Creature *_Creature)
@@ -125,7 +125,7 @@ struct TRINITY_DLL_DECL mob_restless_soulAI : public ScriptedAI
Tagged = false;
}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void SpellHit(Unit *caster, const SpellEntry *spell)
{
@@ -187,7 +187,7 @@ struct TRINITY_DLL_DECL mobs_spectral_ghostly_citizenAI : public ScriptedAI
Tagged = false;
}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void SpellHit(Unit *caster, const SpellEntry *spell)
{
@@ -227,6 +227,32 @@ struct TRINITY_DLL_DECL mobs_spectral_ghostly_citizenAI : public ScriptedAI
DoMeleeAttackIfReady();
}
+
+ void ReciveEmote(Player *player, uint32 emote)
+ {
+ switch(emote)
+ {
+ case TEXTEMOTE_DANCE:
+ EnterEvadeMode();
+ break;
+ case TEXTEMOTE_RUDE:
+ //Should instead cast spell, kicking player back. Spell not found.
+ if (m_creature->IsWithinDistInMap(player, 5))
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_RUDE);
+ else
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_RUDE);
+ break;
+ case TEXTEMOTE_WAVE:
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_WAVE);
+ break;
+ case TEXTEMOTE_BOW:
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_BOW);
+ break;
+ case TEXTEMOTE_KISS:
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_FLEX);
+ break;
+ }
+ }
};
CreatureAI* GetAI_mobs_spectral_ghostly_citizen(Creature *_Creature)
@@ -234,34 +260,6 @@ CreatureAI* GetAI_mobs_spectral_ghostly_citizen(Creature *_Creature)
return new mobs_spectral_ghostly_citizenAI (_Creature);
}
-bool ReciveEmote_mobs_spectral_ghostly_citizen(Player *player, Creature *_Creature, uint32 emote)
-{
- switch(emote)
- {
- case TEXTEMOTE_DANCE:
- ((mobs_spectral_ghostly_citizenAI*)_Creature->AI())->EnterEvadeMode();
- break;
- case TEXTEMOTE_RUDE:
- //Should instead cast spell, kicking player back. Spell not found.
- if (_Creature->IsWithinDistInMap(player, 5))
- _Creature->HandleEmoteCommand(EMOTE_ONESHOT_RUDE);
- else
- _Creature->HandleEmoteCommand(EMOTE_ONESHOT_RUDE);
- break;
- case TEXTEMOTE_WAVE:
- _Creature->HandleEmoteCommand(EMOTE_ONESHOT_WAVE);
- break;
- case TEXTEMOTE_BOW:
- _Creature->HandleEmoteCommand(EMOTE_ONESHOT_BOW);
- break;
- case TEXTEMOTE_KISS:
- _Creature->HandleEmoteCommand(EMOTE_ONESHOT_FLEX);
- break;
- }
-
- return true;
-}
-
void AddSC_stratholme()
{
Script *newscript;
@@ -284,7 +282,6 @@ void AddSC_stratholme()
newscript = new Script;
newscript->Name = "mobs_spectral_ghostly_citizen";
newscript->GetAI = &GetAI_mobs_spectral_ghostly_citizen;
- newscript->pReceiveEmote = &ReciveEmote_mobs_spectral_ghostly_citizen;
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 6fb5c6d0743..6c5020e574c 100644
--- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_brutallus.cpp
+++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_brutallus.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -119,7 +119,7 @@ struct TRINITY_DLL_DECL boss_brutallusAI : public ScriptedAI
pInstance->SetData(DATA_BRUTALLUS_EVENT, NOT_STARTED);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(YELL_AGGRO, m_creature);
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 f408212b129..044f29a11aa 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
@@ -147,8 +147,8 @@ struct TRINITY_DLL_DECL boss_sacrolashAI : public ScriptedAI
if(pInstance)
pInstance->SetData(DATA_EREDAR_TWINS_EVENT, NOT_STARTED);
}
-
- void Aggro(Unit *who)
+
+ void EnterCombat(Unit *who)
{
DoZoneInCombat();
@@ -210,9 +210,9 @@ struct TRINITY_DLL_DECL boss_sacrolashAI : public ScriptedAI
switch(TouchedType)
{
case SPELL_FLAME_TOUCHED:
- if(!target->HasAura(SPELL_DARK_FLAME, 0))
+ if(!target->HasAura(SPELL_DARK_FLAME))
{
- if(target->HasAura(SPELL_DARK_TOUCHED, 0))
+ if(target->HasAura(SPELL_DARK_TOUCHED))
{
target->RemoveAurasDueToSpell(SPELL_DARK_TOUCHED);
target->CastSpell(target, SPELL_DARK_FLAME, true);
@@ -220,9 +220,9 @@ struct TRINITY_DLL_DECL boss_sacrolashAI : public ScriptedAI
}
break;
case SPELL_DARK_TOUCHED:
- if(!target->HasAura(SPELL_DARK_FLAME, 0))
+ if(!target->HasAura(SPELL_DARK_FLAME))
{
- if(target->HasAura(SPELL_FLAME_TOUCHED, 0))
+ if(target->HasAura(SPELL_FLAME_TOUCHED))
{
target->RemoveAurasDueToSpell(SPELL_FLAME_TOUCHED);
target->CastSpell(target, SPELL_DARK_FLAME, true);
@@ -407,8 +407,8 @@ struct TRINITY_DLL_DECL boss_alythessAI : public Scripted_NoMovementAI
if(pInstance)
pInstance->SetData(DATA_EREDAR_TWINS_EVENT, NOT_STARTED);
}
-
- void Aggro(Unit *who)
+
+ void EnterCombat(Unit *who)
{
DoZoneInCombat();
@@ -442,11 +442,9 @@ struct TRINITY_DLL_DECL boss_alythessAI : public Scripted_NoMovementAI
float attackRadius = m_creature->GetAttackDistance(who);
if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
{
- if (!InCombat)
+ if (!m_creature->isInCombat())
{
DoStartNoMovement(who);
- Aggro(who);
- InCombat = true;
}
}
}
@@ -503,9 +501,9 @@ struct TRINITY_DLL_DECL boss_alythessAI : public Scripted_NoMovementAI
switch(TouchedType)
{
case SPELL_FLAME_TOUCHED:
- if(!target->HasAura(SPELL_DARK_FLAME, 0))
+ if(!target->HasAura(SPELL_DARK_FLAME))
{
- if(target->HasAura(SPELL_DARK_TOUCHED, 0))
+ if(target->HasAura(SPELL_DARK_TOUCHED))
{
target->RemoveAurasDueToSpell(SPELL_DARK_TOUCHED);
target->CastSpell(target, SPELL_DARK_FLAME, true);
@@ -516,9 +514,9 @@ struct TRINITY_DLL_DECL boss_alythessAI : public Scripted_NoMovementAI
}
break;
case SPELL_DARK_TOUCHED:
- if(!target->HasAura(SPELL_DARK_FLAME, 0))
+ if(!target->HasAura(SPELL_DARK_FLAME))
{
- if(target->HasAura(SPELL_FLAME_TOUCHED, 0))
+ if(target->HasAura(SPELL_FLAME_TOUCHED))
{
target->RemoveAurasDueToSpell(SPELL_FLAME_TOUCHED);
target->CastSpell(target, SPELL_DARK_FLAME, true);
@@ -680,7 +678,7 @@ struct TRINITY_DLL_DECL mob_shadow_imageAI : public ScriptedAI
KillTimer = 15000;
}
- void Aggro(Unit *who){}
+ void EnterCombat(Unit *who){}
void SpellHitTarget(Unit* target,const SpellEntry* spell)
{
@@ -689,9 +687,9 @@ struct TRINITY_DLL_DECL mob_shadow_imageAI : public ScriptedAI
case SPELL_SHADOW_FURY:
case SPELL_DARK_STRIKE:
- if(!target->HasAura(SPELL_DARK_FLAME, 0))
+ if(!target->HasAura(SPELL_DARK_FLAME))
{
- if(target->HasAura(SPELL_FLAME_TOUCHED, 0))
+ if(target->HasAura(SPELL_FLAME_TOUCHED))
{
target->RemoveAurasDueToSpell(SPELL_FLAME_TOUCHED);
target->CastSpell(target, SPELL_DARK_FLAME, true);
@@ -703,7 +701,7 @@ struct TRINITY_DLL_DECL mob_shadow_imageAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
- if(!m_creature->HasAura(SPELL_IMAGE_VISUAL, 0))
+ if(!m_creature->HasAura(SPELL_IMAGE_VISUAL))
DoCast(m_creature, SPELL_IMAGE_VISUAL);
if(KillTimer < diff)
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 230ba2e9cd3..468d6801414 100644
--- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp
+++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp
@@ -158,7 +158,7 @@ struct TRINITY_DLL_DECL boss_felmystAI : public ScriptedAI
Timer[EVENT_BERSERK] = 600000;
FlightCount = 0;
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10);
m_creature->SetFloatValue(UNIT_FIELD_COMBATREACH, 10);
@@ -169,7 +169,7 @@ struct TRINITY_DLL_DECL boss_felmystAI : public ScriptedAI
pInstance->SetData(DATA_FELMYST_EVENT, NOT_STARTED);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
m_creature->setActive(true);
DoZoneInCombat();
@@ -293,7 +293,7 @@ struct TRINITY_DLL_DECL boss_felmystAI : public ScriptedAI
error_log("prevent fly phase");
m_creature->GetMotionMaster()->Clear(false);
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
- m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT);
+ m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING);
m_creature->StopMoving();
DoScriptText(YELL_TAKEOFF, m_creature);
Timer[EVENT_FLIGHT_SEQUENCE] = 2000;
@@ -395,7 +395,7 @@ struct TRINITY_DLL_DECL boss_felmystAI : public ScriptedAI
Timer[EVENT_FLIGHT_SEQUENCE] = 0;
break;
case 10:
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->StopMoving();
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
EnterPhase(PHASE_GROUND);
@@ -511,7 +511,7 @@ struct TRINITY_DLL_DECL boss_felmystAI : public ScriptedAI
cell.SetNoCreate();
Trinity::AllCreaturesOfEntryInRange check(m_creature, entry, 100);
- Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(templist, check);
+ Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(m_creature, templist, check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher);
@@ -543,7 +543,7 @@ struct TRINITY_DLL_DECL mob_felmyst_vaporAI : public ScriptedAI
m_creature->SetSpeed(MOVE_RUN, 0.8);
}
void Reset() {}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
DoZoneInCombat();
//m_creature->CastSpell(m_creature, SPELL_VAPOR_FORCE, true); core bug
@@ -565,7 +565,7 @@ struct TRINITY_DLL_DECL mob_felmyst_trailAI : public ScriptedAI
m_creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 0.01); // core bug
}
void Reset() {}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff) {}
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 e39f7e02bd7..aa818826d40 100644
--- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp
+++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -141,9 +141,9 @@ struct TRINITY_DLL_DECL boss_kalecgosAI : public ScriptedAI
m_creature->setFaction(14);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->SetVisibility(VISIBILITY_ON);
- m_creature->SetStandState(PLAYER_STATE_SLEEP);
+ m_creature->SetStandState(UNIT_STAND_STATE_SLEEP);
ArcaneBuffetTimer = 8000;
FrostBreathTimer = 15000;
@@ -165,9 +165,9 @@ struct TRINITY_DLL_DECL boss_kalecgosAI : public ScriptedAI
damage = 0;
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
- m_creature->SetStandState(PLAYER_STATE_NONE);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
DoScriptText(SAY_EVIL_AGGRO, m_creature);
GameObject *Door = GameObject::GetGameObject(*m_creature, DoorGUID);
if(Door) Door->SetLootState(GO_ACTIVATED);
@@ -211,7 +211,7 @@ struct TRINITY_DLL_DECL boss_kalecgosAI : public ScriptedAI
TalkTimer = 10000;
break;
case 3:
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->GetMotionMaster()->Clear();
m_creature->GetMotionMaster()->MovePoint(0,FLY_X,FLY_Y,FLY_Z);
TalkTimer = 600000;
@@ -230,7 +230,7 @@ struct TRINITY_DLL_DECL boss_kalecgosAI : public ScriptedAI
TalkTimer = 3000;
break;
case 2:
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->GetMotionMaster()->Clear();
m_creature->GetMotionMaster()->MovePoint(0,FLY_X,FLY_Y,FLY_Z);
TalkTimer = 600000;
@@ -293,7 +293,7 @@ struct TRINITY_DLL_DECL boss_sathrovarrAI : public ScriptedAI
pInstance->SetData(DATA_KALECGOS_EVENT, NOT_STARTED);
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
Creature *Kalec = m_creature->SummonCreature(MOB_KALEC, m_creature->GetPositionX() + 10, m_creature->GetPositionY() + 5, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
if(Kalec)
@@ -354,7 +354,7 @@ struct TRINITY_DLL_DECL boss_sathrovarrAI : public ScriptedAI
Map::PlayerList::const_iterator i;
for(i = PlayerList.begin(); i != PlayerList.end(); ++i)
if(Player* i_pl = i->getSource())
- if(i_pl->HasAura(AURA_SPECTRAL_REALM,0))
+ if(i_pl->HasAura(AURA_SPECTRAL_REALM))
i_pl->RemoveAurasDueToSpell(AURA_SPECTRAL_REALM);
}
@@ -403,7 +403,7 @@ struct TRINITY_DLL_DECL boss_sathrovarrAI : public ScriptedAI
if(ResetThreat < diff)
{
- if ( ( m_creature->getVictim()->HasAura(AURA_SPECTRAL_EXHAUSTION,0)) && (m_creature->getVictim()->GetTypeId() == TYPEID_PLAYER) )
+ if ( ( m_creature->getVictim()->HasAura(AURA_SPECTRAL_EXHAUSTION)) && (m_creature->getVictim()->GetTypeId() == TYPEID_PLAYER) )
{
for(std::list<HostilReference*>::iterator itr = m_creature->getThreatManager().getThreatList().begin(); itr != m_creature->getThreatManager().getThreatList().end(); ++itr)
{
@@ -473,7 +473,7 @@ struct TRINITY_DLL_DECL boss_kalecAI : public ScriptedAI
isEnraged = false;
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void DamageTaken(Unit *done_by, uint32 &damage)
{
@@ -627,7 +627,7 @@ void boss_kalecgosAI::UpdateAI(const uint32 diff)
{
//this is a hack. we need to find a victim without aura in core
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);
- if( ( target != m_creature->getVictim() ) && target->isAlive() && !(target->HasAura(AURA_SPECTRAL_EXHAUSTION, 0)) )
+ if( ( target != m_creature->getVictim() ) && target->isAlive() && !(target->HasAura(AURA_SPECTRAL_EXHAUSTION)) )
{
DoCast(target, SPELL_SPECTRAL_BLAST);
SpectralBlastTimer = 20000+(rand()%5000);
@@ -644,7 +644,7 @@ void boss_kalecgosAI::UpdateAI(const uint32 diff)
bool GOkalocegos_teleporter(Player *player, GameObject* _GO)
{
- if(player->HasAura(AURA_SPECTRAL_EXHAUSTION, 0))
+ if(player->HasAura(AURA_SPECTRAL_EXHAUSTION))
player->GetSession()->SendNotification(GO_FAILED);
else
player->CastSpell(player, SPELL_TELEPORT_SPECTRAL, true);
diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp
index 2ac90b87c35..a436c97029f 100644
--- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp
+++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp
@@ -331,7 +331,7 @@ struct TRINITY_DLL_DECL boss_kalecgosKJAI : public ScriptedAI
cell.SetNoCreate();
std::list<GameObject*> orbList;
AllOrbsInGrid check;
- Trinity::GameObjectListSearcher<AllOrbsInGrid> searcher(orbList, check);
+ Trinity::GameObjectListSearcher<AllOrbsInGrid> searcher(me, orbList, check);
TypeContainerVisitor<Trinity::GameObjectListSearcher<AllOrbsInGrid>, GridTypeMapContainer> visitor(searcher);
CellLock<GridReadGuard> cell_lock(cell, pair);
cell_lock->Visit(cell_lock, visitor, *(m_creature->GetMap()));
@@ -855,7 +855,7 @@ struct TRINITY_DLL_DECL mob_hand_of_the_deceiverAI : public ScriptedAI
}
void UpdateAI(const uint32 diff){
- if(!InCombat)
+ if(!me->isInCombat())
DoCast(m_creature, SPELL_SHADOW_CHANNELING);
if(!UpdateVictim())
diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/def_sunwell_plateau.h b/src/bindings/scripts/scripts/zone/sunwell_plateau/def_sunwell_plateau.h
index 95fca242175..9fbb5de7300 100644
--- a/src/bindings/scripts/scripts/zone/sunwell_plateau/def_sunwell_plateau.h
+++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/def_sunwell_plateau.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
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 283f5e5954a..f8bba5acf21 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
@@ -119,20 +119,6 @@ struct TRINITY_DLL_DECL instance_sunwell_plateau : public ScriptedInstance
return NULL;
}
- void HandleGameObject(uint64 guid, uint32 state)
- {
- Player *player = GetPlayerInMap();
-
- if (!player || !guid)
- {
- debug_log("TSCR: Sunwell Plateau: HandleGameObject fail");
- return;
- }
-
- if (GameObject *go = GameObject::GetGameObject(*player,guid))
- go->SetGoState(state);
- }
-
void OnCreatureCreate(Creature* creature, uint32 entry)
{
switch(entry)
diff --git a/src/bindings/scripts/scripts/zone/tanaris/tanaris.cpp b/src/bindings/scripts/scripts/zone/tanaris/tanaris.cpp
index 45d9eba60d5..5c2c6a57f46 100644
--- a/src/bindings/scripts/scripts/zone/tanaris/tanaris.cpp
+++ b/src/bindings/scripts/scripts/zone/tanaris/tanaris.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
* 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
@@ -17,7 +17,7 @@
/* ScriptData
SDName: Tanaris
SD%Complete: 80
-SDComment: Quest support: 2954, 4005, 10277, 648, 10279(Special flight path). Noggenfogger vendor
+SDComment: Quest support: 648, 2954, 4005, 10277, 10279(Special flight path). Noggenfogger vendor
SDCategory: Tanaris
EndScriptData */
@@ -78,7 +78,7 @@ struct TRINITY_DLL_DECL mob_aquementasAI : public ScriptedAI
}
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
DoScriptText(AGGRO_YELL_AQUE, m_creature, who);
}
@@ -191,7 +191,7 @@ struct TRINITY_DLL_DECL npc_custodian_of_timeAI : public npc_escortAI
if( who->GetTypeId() == TYPEID_PLAYER )
{
- if( ((Player*)who)->HasAura(34877,1) && ((Player*)who)->GetQuestStatus(10277) == QUEST_STATUS_INCOMPLETE )
+ if( ((Player*)who)->HasAura(34877) && ((Player*)who)->GetQuestStatus(10277) == QUEST_STATUS_INCOMPLETE )
{
float Radius = 10.0;
if( m_creature->IsWithinDistInMap(who, Radius) )
@@ -202,7 +202,7 @@ struct TRINITY_DLL_DECL npc_custodian_of_timeAI : public npc_escortAI
}
}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void Reset() { }
void UpdateAI(const uint32 diff)
@@ -211,38 +211,11 @@ struct TRINITY_DLL_DECL npc_custodian_of_timeAI : public npc_escortAI
}
};
-CreatureAI* GetAI_npc_custodian_of_time(Creature *_Creature)
+CreatureAI* GetAI_npc_custodian_of_time(Creature* pCreature)
{
- npc_custodian_of_timeAI* custodian_of_timeAI = new npc_custodian_of_timeAI(_Creature);
-
- custodian_of_timeAI->AddWaypoint(0, -8535.57,-4212.61, -212.04);
- custodian_of_timeAI->AddWaypoint(1, -8456.48,-4211.77, -213.30);
- custodian_of_timeAI->AddWaypoint(2, -8374.93,-4250.21, -205.05,5000);
- custodian_of_timeAI->AddWaypoint(3, -8374.93,-4250.21, -204.38,16000);
- custodian_of_timeAI->AddWaypoint(4, -8374.93,-4250.21, -204.38,10000);
- custodian_of_timeAI->AddWaypoint(5, -8374.93,-4250.21, -204.38,2000);
- custodian_of_timeAI->AddWaypoint(6, -8439.40,-4180.05, -209.25);
- custodian_of_timeAI->AddWaypoint(7, -8437.82,-4120.84, -208.59,10000);
- custodian_of_timeAI->AddWaypoint(8, -8437.82,-4120.84, -208.59,16000);
- custodian_of_timeAI->AddWaypoint(9, -8437.82,-4120.84, -208.59,13000);
- custodian_of_timeAI->AddWaypoint(10, -8437.82,-4120.84, -208.59,18000);
- custodian_of_timeAI->AddWaypoint(11, -8437.82,-4120.84, -208.59,15000);
- custodian_of_timeAI->AddWaypoint(12, -8437.82,-4120.84, -208.59,2000);
- custodian_of_timeAI->AddWaypoint(13, -8467.26,-4198.63, -214.21);
- custodian_of_timeAI->AddWaypoint(14, -8667.76,-4252.13, -209.56);
- custodian_of_timeAI->AddWaypoint(15, -8703.71,-4234.58, -209.5,14000);
- custodian_of_timeAI->AddWaypoint(16, -8703.71,-4234.58, -209.5,2000);
- custodian_of_timeAI->AddWaypoint(17, -8642.81,-4304.37, -209.57);
- custodian_of_timeAI->AddWaypoint(18, -8649.06,-4394.36, -208.46,6000);
- custodian_of_timeAI->AddWaypoint(19, -8649.06,-4394.36, -208.46,18000);
- custodian_of_timeAI->AddWaypoint(20, -8649.06,-4394.36, -208.46,2000);
- custodian_of_timeAI->AddWaypoint(21, -8468.72,-4437.67, -215.45);
- custodian_of_timeAI->AddWaypoint(22, -8427.54,-4426, -211.13);
- custodian_of_timeAI->AddWaypoint(23, -8364.83,-4393.32, -205.91);
- custodian_of_timeAI->AddWaypoint(24, -8304.54,-4357.2, -208.2,18000);
- custodian_of_timeAI->AddWaypoint(25, -8304.54,-4357.2, -208.2,2000);
- custodian_of_timeAI->AddWaypoint(26, -8375.42,-4250.41, -205.14,5000);
- custodian_of_timeAI->AddWaypoint(27, -8375.42,-4250.41, -205.14,5000);
+ npc_custodian_of_timeAI* custodian_of_timeAI = new npc_custodian_of_timeAI(pCreature);
+
+ custodian_of_timeAI->FillPointMovementListForCreature();
return (CreatureAI*)custodian_of_timeAI;
}
@@ -414,7 +387,7 @@ struct TRINITY_DLL_DECL npc_OOX17AI : public npc_escortAI
if (player)
{
DoScriptText(SAY_CHICKEN_COMP, m_creature);
- ((Player*)player)->GroupEventHappens(Q_OOX17, m_creature);
+ player->GroupEventHappens(Q_OOX17, m_creature);
}
break;
}
@@ -422,7 +395,7 @@ struct TRINITY_DLL_DECL npc_OOX17AI : public npc_escortAI
void Reset(){}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
switch (rand()%2)
{
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 a61a9c9b163..04963bf02c2 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/arcatraz.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/arcatraz.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -102,20 +102,12 @@ struct TRINITY_DLL_DECL npc_millhouse_manastormAI : public ScriptedAI
{
if (m_creature->Attack(who, true))
{
- m_creature->AddThreat(who, 0.0f);
-
- if (!InCombat)
- {
- InCombat = true;
- Aggro(who);
- }
-
//TODO: Make it so he moves when target out of range
DoStartNoMovement(who);
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -301,11 +293,11 @@ struct TRINITY_DLL_DECL npc_warden_mellicharAI : public ScriptedAI
float attackRadius = m_creature->GetAttackDistance(who)/10;
if( m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who) )
- Aggro(who);
+ EnterCombat(who);
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(YELL_INTRO1, m_creature);
DoCast(m_creature,SPELL_BUBBLE_VISUAL);
@@ -314,7 +306,7 @@ struct TRINITY_DLL_DECL npc_warden_mellicharAI : public ScriptedAI
{
pInstance->SetData(TYPE_HARBINGERSKYRISS,IN_PROGRESS);
if (GameObject* Sphere = GameObject::GetGameObject(*m_creature,pInstance->GetData64(DATA_SPHERE_SHIELD)))
- Sphere->SetGoState(1);
+ Sphere->SetGoState(GO_STATE_READY);
IsRunning = true;
}
}
@@ -347,7 +339,7 @@ struct TRINITY_DLL_DECL npc_warden_mellicharAI : public ScriptedAI
if( pInstance )
{
m_creature->InterruptNonMeleeSpells(true);
- m_creature->RemoveSpellsCausingAura(SPELL_AURA_DUMMY);
+ m_creature->RemoveAurasByType(SPELL_AURA_DUMMY);
switch( Phase )
{
@@ -355,7 +347,7 @@ struct TRINITY_DLL_DECL npc_warden_mellicharAI : public ScriptedAI
DoCast(m_creature,SPELL_TARGET_ALPHA);
pInstance->SetData(TYPE_WARDEN_1,IN_PROGRESS);
if (GameObject *Sphere = GameObject::GetGameObject(*m_creature,pInstance->GetData64(DATA_SPHERE_SHIELD)))
- Sphere->SetGoState(1);
+ Sphere->SetGoState(GO_STATE_READY);
break;
case 3:
DoCast(m_creature,SPELL_TARGET_BETA);
@@ -499,7 +491,7 @@ struct TRINITY_DLL_DECL mob_zerekethvoidzoneAI : public ScriptedAI
DoCast(m_creature,SPELL_VOID_ZONE_DAMAGE);
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
};
CreatureAI* GetAI_mob_zerekethvoidzoneAI(Creature *_Creature)
{
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 da2b392072a..9a9e0aa0966 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -101,7 +101,7 @@ struct TRINITY_DLL_DECL boss_harbinger_skyrissAI : public ScriptedAI
ScriptedAI::MoveInLineOfSight(who);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void JustDied(Unit* Killer)
{
@@ -163,7 +163,7 @@ struct TRINITY_DLL_DECL boss_harbinger_skyrissAI : public ScriptedAI
case 1:
DoScriptText(SAY_INTRO, m_creature);
if (GameObject* Sphere = GameObject::GetGameObject(*m_creature,pInstance->GetData64(DATA_SPHERE_SHIELD)))
- Sphere->SetGoState(0);
+ Sphere->SetGoState(GO_STATE_ACTIVE);
++Intro_Phase;
Intro_Timer = 25000;
break;
@@ -288,7 +288,7 @@ struct TRINITY_DLL_DECL boss_harbinger_skyriss_illusionAI : public ScriptedAI
void Reset() { }
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
};
CreatureAI* GetAI_boss_harbinger_skyriss_illusion(Creature *_Creature)
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/def_arcatraz.h b/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/def_arcatraz.h
index 76f8d575383..3f8dee8bbd0 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/def_arcatraz.h
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/def_arcatraz.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
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 5f1fb087655..a0d21e302b5 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
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 c9f88c57b2d..13e65b9e416 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -64,7 +64,7 @@ struct TRINITY_DLL_DECL boss_high_botanist_freywinnAI : public ScriptedAI
MoveFree = true;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
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 e95d8328907..69abca68dff 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -140,7 +140,7 @@ struct TRINITY_DLL_DECL boss_lajAI : public ScriptedAI
CanSummon = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 5306aa690cf..4dd70cb7d20 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -44,7 +44,7 @@ struct TRINITY_DLL_DECL mob_treantAI : public ScriptedAI
check_Timer = 0;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void MoveInLineOfSight(Unit*) {}
@@ -130,7 +130,7 @@ struct TRINITY_DLL_DECL boss_warp_splinterAI : public ScriptedAI
m_creature->SetSpeed( MOVE_RUN, 0.7f, true);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
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 813222b52c9..52c67125ee7 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
@@ -122,7 +122,7 @@ struct TRINITY_DLL_DECL boss_alarAI : public ScriptedAI
m_creature->setActive(false);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
pInstance->SetData(DATA_ALAREVENT, IN_PROGRESS);
@@ -241,12 +241,12 @@ struct TRINITY_DLL_DECL boss_alarAI : public ScriptedAI
WaitEvent = WE_DUMMY;
return;
case WE_DIE:
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_DEAD);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
WaitTimer = 5000;
WaitEvent = WE_REVIVE;
return;
case WE_REVIVE:
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_NONE);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND);
m_creature->SetHealth(m_creature->GetMaxHealth());
m_creature->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
@@ -348,7 +348,7 @@ struct TRINITY_DLL_DECL boss_alarAI : public ScriptedAI
if(Charge_Timer < diff)
{
- Unit *target= SelectUnit(SELECT_TARGET_RANDOM, 1, GetSpellMaxRange(SPELL_CHARGE), true);
+ Unit *target= SelectUnit(SELECT_TARGET_RANDOM, 1, GetSpellMaxRangeForHostile(SPELL_CHARGE), true);
DoCast(target, SPELL_CHARGE);
Charge_Timer = 30000;
}else Charge_Timer -= diff;
@@ -435,7 +435,7 @@ struct TRINITY_DLL_DECL mob_ember_of_alarAI : public ScriptedAI
bool toDie;
void Reset() {toDie = false;}
- void Aggro(Unit *who) {DoZoneInCombat();}
+ void EnterCombat(Unit *who) {DoZoneInCombat();}
void EnterEvadeMode() {m_creature->setDeathState(JUST_DIED);}
void DamageTaken(Unit* pKiller, uint32 &damage)
@@ -486,7 +486,7 @@ struct TRINITY_DLL_DECL mob_flame_patch_alarAI : public ScriptedAI
{
mob_flame_patch_alarAI(Creature *c) : ScriptedAI(c) {}
void Reset() {}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff) {}
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 bc215f8c683..41087682670 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -120,6 +120,7 @@ struct TRINITY_DLL_DECL boss_high_astromancer_solarianAI : public ScriptedAI
Jump_Timer=8000;
Wrath_Timer = 20000+rand()%5000;//twice in phase one
Phase = 1;
+ Wrath_Timer = 20000+rand()%5000;//twice in phase one
if(pInstance)
pInstance->SetData(DATA_HIGHASTROMANCERSOLARIANEVENT, NOT_STARTED);
@@ -161,7 +162,7 @@ struct TRINITY_DLL_DECL boss_high_astromancer_solarianAI : public ScriptedAI
pInstance->SetData(DATA_HIGHASTROMANCERSOLARIANEVENT, DONE);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
StartEvent();
}
@@ -407,7 +408,7 @@ struct TRINITY_DLL_DECL mob_solarium_priestAI : public ScriptedAI
aoesilenceTimer = 15000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 f4e80001cf7..d2784e55d77 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -193,7 +193,7 @@ struct TRINITY_DLL_DECL advisorbase_ai : public ScriptedAI
if(pInstance && (pInstance->GetData(DATA_KAELTHASEVENT) == 1 || pInstance->GetData(DATA_KAELTHASEVENT) == 3))
{
Creature *Kaelthas = NULL;
- Kaelthas = (Creature*)(Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KAELTHAS)));
+ Kaelthas = (Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_KAELTHAS)));
if(Kaelthas)
Kaelthas->AI()->EnterEvadeMode();
@@ -238,7 +238,7 @@ struct TRINITY_DLL_DECL advisorbase_ai : public ScriptedAI
m_creature->SetUInt64Value(UNIT_FIELD_TARGET,0);
m_creature->GetMotionMaster()->Clear();
m_creature->GetMotionMaster()->MoveIdle();
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,PLAYER_STATE_DEAD);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,UNIT_STAND_STATE_DEAD);
if (pInstance->GetData(DATA_KAELTHASEVENT) == 3)
JustDied(pKiller);
@@ -348,7 +348,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
IsCastingFireball = false;
ChainPyros = false;
- if(InCombat)
+ if(m_creature->isInCombat())
PrepareAdvisors();
DeleteLegs();
@@ -366,7 +366,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
Creature *pCreature;
for(uint8 i = 0; i < 4; ++i)
{
- pCreature = (Creature*)(Unit::GetUnit((*m_creature), AdvisorGuid[i]));
+ pCreature = (Unit::GetCreature((*m_creature), AdvisorGuid[i]));
if(pCreature)
{
pCreature->Respawn();
@@ -467,7 +467,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if (pInstance && !pInstance->GetData(DATA_KAELTHASEVENT) && !Phase)
StartEvent();
@@ -535,7 +535,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
case 1:
if(Phase_Timer < diff)
{
- Advisor = (Creature*)(Unit::GetUnit((*m_creature), AdvisorGuid[0]));
+ Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[0]));
if(Advisor)
{
@@ -553,8 +553,8 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
//Subphase 2 - Start
case 2:
- Advisor = (Creature*)(Unit::GetUnit((*m_creature), AdvisorGuid[0]));
- if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == PLAYER_STATE_DEAD))
+ Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[0]));
+ if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == UNIT_STAND_STATE_DEAD))
{
DoScriptText(SAY_INTRO_SANGUINAR, m_creature);
@@ -569,7 +569,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
case 3:
if(Phase_Timer < diff)
{
- Advisor = (Creature*)(Unit::GetUnit((*m_creature), AdvisorGuid[1]));
+ Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[1]));
if(Advisor)
{
@@ -587,8 +587,8 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
//Subphase 3 - Start
case 4:
- Advisor = (Creature*)(Unit::GetUnit((*m_creature), AdvisorGuid[1]));
- if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == PLAYER_STATE_DEAD))
+ Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[1]));
+ if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == UNIT_STAND_STATE_DEAD))
{
DoScriptText(SAY_INTRO_CAPERNIAN, m_creature);
@@ -603,7 +603,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
case 5:
if(Phase_Timer < diff)
{
- Advisor = (Creature*)(Unit::GetUnit((*m_creature), AdvisorGuid[2]));
+ Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[2]));
if(Advisor)
{
@@ -621,8 +621,8 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
//Subphase 4 - Start
case 6:
- Advisor = (Creature*)(Unit::GetUnit((*m_creature), AdvisorGuid[2]));
- if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == PLAYER_STATE_DEAD))
+ Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[2]));
+ if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == UNIT_STAND_STATE_DEAD))
{
DoScriptText(SAY_INTRO_TELONICUS, m_creature);
@@ -637,7 +637,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
case 7:
if(Phase_Timer < diff)
{
- Advisor = (Creature*)(Unit::GetUnit((*m_creature), AdvisorGuid[3]));
+ Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[3]));
if(Advisor)
{
@@ -657,8 +657,8 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
//End of phase 1
case 8:
- Advisor = (Creature*)(Unit::GetUnit((*m_creature), AdvisorGuid[3]));
- if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == PLAYER_STATE_DEAD))
+ Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[3]));
+ if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == UNIT_STAND_STATE_DEAD))
{
Phase = 2;
pInstance->SetData(DATA_KAELTHASEVENT, 2);
@@ -727,7 +727,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
Creature* Advisor;
for (uint32 i = 0; i < 4; ++i)
{
- Advisor = (Creature*)(Unit::GetUnit((*m_creature), AdvisorGuid[i]));
+ Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[i]));
if (!Advisor)
error_log("TSCR: Kael'Thas Advisor %u does not exist. Possibly despawned? Incorrectly Killed?", i);
else ((advisorbase_ai*)Advisor->AI())->Revive(Target);
@@ -1048,7 +1048,7 @@ struct TRINITY_DLL_DECL boss_thaladred_the_darkenerAI : public advisorbase_ai
DoScriptText(SAY_THALADRED_DEATH, m_creature);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
return;
@@ -1120,7 +1120,7 @@ struct TRINITY_DLL_DECL boss_lord_sanguinarAI : public advisorbase_ai
DoScriptText(SAY_SANGUINAR_DEATH, m_creature);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
return;
@@ -1188,19 +1188,11 @@ struct TRINITY_DLL_DECL boss_grand_astromancer_capernianAI : public advisorbase_
if (m_creature->Attack(who, true))
{
- m_creature->AddThreat(who, 0.0f);
-
- if (!InCombat)
- {
- InCombat = true;
- Aggro(who);
- }
-
DoStartMovement(who, CAPERNIAN_DISTANCE, M_PI/2);
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
return;
@@ -1302,7 +1294,7 @@ struct TRINITY_DLL_DECL boss_master_engineer_telonicusAI : public advisorbase_ai
DoScriptText(SAY_TELONICUS_DEATH, m_creature);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
return;
@@ -1364,7 +1356,7 @@ struct TRINITY_DLL_DECL mob_kael_flamestrikeAI : public ScriptedAI
m_creature->setFaction(14);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -1424,13 +1416,13 @@ struct TRINITY_DLL_DECL mob_phoenix_tkAI : public ScriptedAI
void Reset()
{
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);//birds can fly! :)
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);//birds can fly! :)
egg = true;
Cycle_Timer = 2000;
m_creature->CastSpell(m_creature,SPELL_BURN,true);
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void DamageTaken(Unit* pKiller, uint32 &damage)
{
@@ -1487,16 +1479,11 @@ struct TRINITY_DLL_DECL mob_phoenix_egg_tkAI : public ScriptedAI
{
if (m_creature->Attack(who, false))
{
- if (!InCombat)
- {
- InCombat = true;
- Aggro(who);
- }
DoStartNoMovement(who);
}
}
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void JustSummoned(Creature* summoned)
{
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 708e5feffcd..d5648e3a8ff 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -84,7 +84,7 @@ struct TRINITY_DLL_DECL boss_void_reaverAI : public ScriptedAI
pInstance->SetData(DATA_VOIDREAVEREVENT, DONE);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/def_the_eye.h b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/def_the_eye.h
index 7162fb90199..d0d3ea09061 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/def_the_eye.h
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/def_the_eye.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
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 c6352a9e67c..66e595ab729 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -77,7 +77,7 @@ struct TRINITY_DLL_DECL instance_the_eye : public ScriptedInstance
void OnCreatureCreate(Creature *creature, uint32 creature_entry)
{
- switch(creature_entry)
+ switch(creature->GetEntry())
{
case 20064: ThaladredTheDarkener = creature->GetGUID(); break;
case 20063: MasterEngineerTelonicus = creature->GetGUID(); break;
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 ef3860c0581..89d5e04e0c3 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -44,7 +44,7 @@ struct TRINITY_DLL_DECL mob_crystalcore_devastatorAI : public ScriptedAI
Knockaway_Timer = 25000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp
index c77989e27f3..268cfeb2918 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
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 bd8fc581e9d..34e131ba013 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -63,7 +63,7 @@ struct TRINITY_DLL_DECL boss_gatewatcher_iron_handAI : public ScriptedAI
Stream_of_Machine_Fluid_Timer = 55000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO_1, m_creature);
}
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 b3eddfa7ebe..beb663b5947 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -71,7 +71,7 @@ struct TRINITY_DLL_DECL boss_nethermancer_sepethreaAI : public ScriptedAI
pInstance->SetData(DATA_NETHERMANCER_EVENT, NOT_STARTED);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
pInstance->SetData(DATA_NETHERMANCER_EVENT, IN_PROGRESS);
@@ -109,7 +109,7 @@ struct TRINITY_DLL_DECL boss_nethermancer_sepethreaAI : public ScriptedAI
if(frost_attack_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_FROST_ATTACK);
- frost_attack_Timer = 7000 + rand()%30000;
+ frost_attack_Timer = 7000 + rand()%3000;
}else frost_attack_Timer -= diff;
//Arcane Blast
@@ -192,7 +192,7 @@ struct TRINITY_DLL_DECL mob_ragin_flamesAI : public ScriptedAI
m_creature->SetSpeed(MOVE_RUN, HeroicMode ? 0.7f : 0.5f);
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
}
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 338e115ef85..ddfcf6bda0a 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -78,7 +78,7 @@ struct TRINITY_DLL_DECL boss_pathaleon_the_calculatorAI : public ScriptedAI
Counter = 0;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
@@ -190,7 +190,7 @@ struct TRINITY_DLL_DECL mob_nether_wraithAI : public ScriptedAI
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
}
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 05866eb27fb..e8806b62957 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -56,7 +56,7 @@ struct TRINITY_DLL_DECL instance_mechanar : public ScriptedInstance
{
switch(type)
{
- case DATA_NETHERMANCER_EVENT: return Encounters[0];
+ case DATA_NETHERMANCER_EVENT: return Encounters[0];
}
return false;
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 dc1e4df24ca..d34c83aef92 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -61,7 +61,7 @@ struct TRINITY_DLL_DECL boss_kriAI : public ScriptedAI
Death = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -156,7 +156,7 @@ struct TRINITY_DLL_DECL boss_vemAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -244,7 +244,7 @@ struct TRINITY_DLL_DECL boss_yaujAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
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 9f28016dd46..e3c10237635 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -123,7 +123,7 @@ struct TRINITY_DLL_DECL flesh_tentacleAI : public Scripted_NoMovementAI
CheckTimer = 1000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -182,7 +182,7 @@ struct TRINITY_DLL_DECL eye_of_cthunAI : public Scripted_NoMovementAI
pInst->SetData(DATA_CTHUN_PHASE, 0);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoZoneInCombat();
}
@@ -301,7 +301,7 @@ struct TRINITY_DLL_DECL eye_of_cthunAI : public Scripted_NoMovementAI
DoCast(m_creature,SPELL_RED_COLORATION);
//Freeze animation
- m_creature->setEmoteState(53);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, 53);
//Darkbeam for 35 seconds
PhaseTimer = 35000;
@@ -351,7 +351,7 @@ struct TRINITY_DLL_DECL eye_of_cthunAI : public Scripted_NoMovementAI
m_creature->RemoveAurasDueToSpell(SPELL_RED_COLORATION);
//Freeze animation
- m_creature->setEmoteState(0);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
m_creature->SetUInt32Value(UNIT_FIELD_FLAGS, 0);
//Eye Beam for 50 seconds
@@ -397,7 +397,7 @@ struct TRINITY_DLL_DECL eye_of_cthunAI : public Scripted_NoMovementAI
m_creature->RemoveAurasDueToSpell(SPELL_RED_COLORATION);
//Reset to normal emote state and prevent select and attack
- m_creature->setEmoteState(0);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
//Remove Target field
@@ -498,7 +498,7 @@ struct TRINITY_DLL_DECL cthunAI : public Scripted_NoMovementAI
pInst->SetData(DATA_CTHUN_PHASE, 0);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoZoneInCombat();
}
@@ -566,13 +566,15 @@ struct TRINITY_DLL_DECL cthunAI : public Scripted_NoMovementAI
Map *map = m_creature->GetMap();
if(!map->IsDungeon()) return;
+ //Play random sound to the zone
Map::PlayerList const &PlayerList = map->GetPlayers();
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+
+ if (!PlayerList.isEmpty())
{
- if (Player* i_pl = i->getSource())
+ for(Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
{
- //Play random sound to the zone
- i_pl->SendPlaySound(RANDOM_SOUND_WHISPER, true);
+ if (Player* pPlr = itr->getSource())
+ pPlr->PlayDirectSound(RANDOM_SOUND_WHISPER,pPlr);
}
}
@@ -939,7 +941,7 @@ struct TRINITY_DLL_DECL eye_tentacleAI : public Scripted_NoMovementAI
KillSelfTimer = 35000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoZoneInCombat();
}
@@ -963,7 +965,7 @@ struct TRINITY_DLL_DECL eye_tentacleAI : public Scripted_NoMovementAI
{
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
- if (target && !target->HasAura(SPELL_DIGESTIVE_ACID, 0))
+ if (target && !target->HasAura(SPELL_DIGESTIVE_ACID))
DoCast(target,SPELL_MIND_FLAY);
//Mindflay every 10 seconds
@@ -1001,7 +1003,7 @@ struct TRINITY_DLL_DECL claw_tentacleAI : public Scripted_NoMovementAI
EvadeTimer = 5000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoZoneInCombat();
}
@@ -1031,7 +1033,7 @@ struct TRINITY_DLL_DECL claw_tentacleAI : public Scripted_NoMovementAI
return;
}
- if (!target->HasAura(SPELL_DIGESTIVE_ACID, 0))
+ if (!target->HasAura(SPELL_DIGESTIVE_ACID))
{
m_creature->GetMap()->CreatureRelocation(m_creature, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0);
Unit* p = DoSpawnCreature(MOB_SMALL_PORTAL,0,0,0,0,TEMPSUMMON_CORPSE_DESPAWN, 0);
@@ -1097,7 +1099,7 @@ struct TRINITY_DLL_DECL giant_claw_tentacleAI : public Scripted_NoMovementAI
EvadeTimer = 5000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoZoneInCombat();
}
@@ -1127,7 +1129,7 @@ struct TRINITY_DLL_DECL giant_claw_tentacleAI : public Scripted_NoMovementAI
return;
}
- if (!target->HasAura(SPELL_DIGESTIVE_ACID, 0))
+ if (!target->HasAura(SPELL_DIGESTIVE_ACID))
{
m_creature->GetMap()->CreatureRelocation(m_creature, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0);
Unit* p = DoSpawnCreature(MOB_GIANT_PORTAL,0,0,0,0,TEMPSUMMON_CORPSE_DESPAWN, 0);
@@ -1195,7 +1197,7 @@ struct TRINITY_DLL_DECL giant_eye_tentacleAI : public Scripted_NoMovementAI
BeamTimer = 500;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoZoneInCombat();
}
@@ -1211,7 +1213,7 @@ struct TRINITY_DLL_DECL giant_eye_tentacleAI : public Scripted_NoMovementAI
{
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
- if (target && !target->HasAura(SPELL_DIGESTIVE_ACID, 0))
+ if (target && !target->HasAura(SPELL_DIGESTIVE_ACID))
DoCast(target,SPELL_GREEN_BEAM);
//Beam every 2 seconds
@@ -1249,7 +1251,7 @@ void flesh_tentacleAI::JustDied(Unit* killer)
{
if (!Parent)
{
- DoYell("Error: No Parent variable", LANG_UNIVERSAL, NULL);
+ error_log("TSCR: flesh_tentacle: No Parent variable");
return;
}
@@ -1257,7 +1259,7 @@ void flesh_tentacleAI::JustDied(Unit* killer)
if (Cthun)
((cthunAI*)(Cthun->AI()))->FleshTentcleKilled();
- else DoYell("Error: No Cthun", LANG_UNIVERSAL, NULL);
+ else error_log("TSCR: flesh_tentacle: No Cthun");
}
//GetAIs
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 0888c395489..d53b9d78511 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -77,7 +77,7 @@ struct TRINITY_DLL_DECL boss_fankrissAI : public ScriptedAI
((CreatureAI*)Spawn->AI())->AttackStart(victim);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -135,34 +135,46 @@ struct TRINITY_DLL_DECL boss_fankrissAI : public ScriptedAI
case 0:
DoTeleportPlayer(target, -8106.0142,1289.2900,-74.419533,5.112);
Hatchling = m_creature->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()-3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Hatchling)
((CreatureAI*)Hatchling->AI())->AttackStart(target);
Hatchling = m_creature->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Hatchling)
((CreatureAI*)Hatchling->AI())->AttackStart(target);
Hatchling = m_creature->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Hatchling)
((CreatureAI*)Hatchling->AI())->AttackStart(target);
Hatchling = m_creature->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Hatchling)
((CreatureAI*)Hatchling->AI())->AttackStart(target);
break;
case 1:
DoTeleportPlayer(target, -7990.135354,1155.1907,-78.849319,2.608);
Hatchling = m_creature->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()-3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Hatchling)
((CreatureAI*)Hatchling->AI())->AttackStart(target);
Hatchling = m_creature->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Hatchling)
((CreatureAI*)Hatchling->AI())->AttackStart(target);
Hatchling = m_creature->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Hatchling)
((CreatureAI*)Hatchling->AI())->AttackStart(target);
Hatchling = m_creature->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Hatchling)
((CreatureAI*)Hatchling->AI())->AttackStart(target);
break;
case 2:
DoTeleportPlayer(target,-8159.7753,1127.9064,-76.868660,0.675);
Hatchling = m_creature->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()-3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Hatchling)
((CreatureAI*)Hatchling->AI())->AttackStart(target);
Hatchling = m_creature->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Hatchling)
((CreatureAI*)Hatchling->AI())->AttackStart(target);
Hatchling = m_creature->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Hatchling)
((CreatureAI*)Hatchling->AI())->AttackStart(target);
Hatchling = m_creature->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Hatchling)
((CreatureAI*)Hatchling->AI())->AttackStart(target);
break;
}
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 484a6260c86..d846fc18aa0 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -23,6 +23,9 @@ EndScriptData */
#include "precompiled.h"
+#define EMOTE_GENERIC_FRENZY_KILL -1000001
+#define EMOTE_GENERIC_BERSERK -1000004
+
#define SPELL_FRENZY 26051
#define SPELL_BERSERK 26068
#define SPELL_POISONBOLT 26052
@@ -57,7 +60,7 @@ struct TRINITY_DLL_DECL boss_huhuranAI : public ScriptedAI
Berserk = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -71,6 +74,7 @@ struct TRINITY_DLL_DECL boss_huhuranAI : public ScriptedAI
if (!Frenzy && Frenzy_Timer < diff)
{
DoCast(m_creature, SPELL_FRENZY);
+ DoScriptText(EMOTE_GENERIC_FRENZY_KILL, m_creature);
Frenzy = true;
PoisonBolt_Timer = 3000;
Frenzy_Timer = 25000 + rand()%10000;
@@ -119,7 +123,7 @@ struct TRINITY_DLL_DECL boss_huhuranAI : public ScriptedAI
if ( !Berserk && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 31 )
{
m_creature->InterruptNonMeleeSpells(false);
- DoTextEmote("is going berserk", NULL);
+ DoScriptText(EMOTE_GENERIC_BERSERK, m_creature);
DoCast(m_creature, SPELL_BERSERK);
Berserk = true;
}
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 7f5827d398b..d66cdb8e6ba 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -59,7 +59,7 @@ struct TRINITY_DLL_DECL boss_ouroAI : public ScriptedAI
Submerged = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoCast(m_creature->getVictim(), SPELL_BIRTH);
}
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 a9b0578279d..bcae80fcf3e 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -68,7 +68,7 @@ struct TRINITY_DLL_DECL boss_sarturaAI : public ScriptedAI
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
@@ -94,8 +94,12 @@ struct TRINITY_DLL_DECL boss_sarturaAI : public ScriptedAI
if (WhirlWindRandom_Timer < diff)
{
//Attack random Gamers
- if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,1))
- AttackStart(target);
+ Unit* target = NULL;
+ target = SelectUnit(SELECT_TARGET_RANDOM,1);
+ if (target)
+ m_creature->AddThreat(target, 1.0f);
+ m_creature->TauntApply(target);
+ AttackStart(target);
WhirlWindRandom_Timer = 3000 + rand()%4000;
}else WhirlWindRandom_Timer -= diff;
@@ -119,8 +123,12 @@ struct TRINITY_DLL_DECL boss_sarturaAI : public ScriptedAI
if (AggroReset_Timer < diff)
{
//Attack random Gamers
- if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,1))
- m_creature->TauntApply(target);
+ Unit* target = NULL;
+ target = SelectUnit(SELECT_TARGET_RANDOM,1);
+ if (target)
+ m_creature->AddThreat(target, 1.0f);
+ m_creature->TauntApply(target);
+ AttackStart(target);
AggroReset = true;
AggroReset_Timer = 2000 + rand()%3000;
@@ -190,7 +198,7 @@ struct TRINITY_DLL_DECL mob_sartura_royal_guardAI : public ScriptedAI
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -213,8 +221,12 @@ struct TRINITY_DLL_DECL mob_sartura_royal_guardAI : public ScriptedAI
if (WhirlWindRandom_Timer < diff)
{
//Attack random Gamers
- if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,1))
- m_creature->TauntApply(target);
+ Unit* target = NULL;
+ target = SelectUnit(SELECT_TARGET_RANDOM,1);
+ if (target)
+ m_creature->AddThreat(target, 1.0f);
+ m_creature->TauntApply(target);
+ AttackStart(target);
WhirlWindRandom_Timer = 3000 + rand()%4000;
}else WhirlWindRandom_Timer -= diff;
@@ -230,8 +242,12 @@ struct TRINITY_DLL_DECL mob_sartura_royal_guardAI : public ScriptedAI
if (AggroReset_Timer < diff)
{
//Attack random Gamers
- if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,1))
- AttackStart(target);
+ Unit* target = NULL;
+ target = SelectUnit(SELECT_TARGET_RANDOM,1);
+ if (target)
+ m_creature->AddThreat(target, 1.0f);
+ m_creature->TauntApply(target);
+ AttackStart(target);
AggroReset = true;
AggroReset_Timer = 2000 + rand()%3000;
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 84311d725f5..ae2c48742d6 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -109,7 +109,7 @@ struct TRINITY_DLL_DECL boss_skeramAI : public ScriptedAI
DoScriptText(SAY_DEATH, m_creature);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if (IsImage || Images75)
return;
@@ -261,6 +261,9 @@ struct TRINITY_DLL_DECL boss_skeramAI : public ScriptedAI
m_creature->SetVisibility(VISIBILITY_OFF);
m_creature->Relocate(bossc->x, bossc->y, bossc->z, bossc->r);
Invisible = true;
+ delete place1;
+ delete place2;
+ delete place3;
DoResetThreat();
DoStopAttack();
@@ -274,20 +277,24 @@ struct TRINITY_DLL_DECL boss_skeramAI : public ScriptedAI
Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0);
Image1 = m_creature->SummonCreature(15263, i1->x, i1->y, i1->z, i1->r, TEMPSUMMON_CORPSE_DESPAWN, 30000);
- Image1->SetMaxHealth(m_creature->GetMaxHealth() / 5);
- Image1->SetHealth(m_creature->GetHealth() / 5);
- if (target)
- Image1->AI()->AttackStart(target);
+ if (Image1)
+ {
+ Image1->SetMaxHealth(m_creature->GetMaxHealth() / 5);
+ Image1->SetHealth(m_creature->GetHealth() / 5);
+ if (target)
+ Image1->AI()->AttackStart(target);
+ ((boss_skeramAI*)Image1->AI())->IsImage = true;
+ }
Image2 = m_creature->SummonCreature(15263,i2->x, i2->y, i2->z, i2->r, TEMPSUMMON_CORPSE_DESPAWN, 30000);
- Image2->SetMaxHealth(m_creature->GetMaxHealth() / 5);
- Image2->SetHealth(m_creature->GetHealth() / 5);
- if (target)
- Image2->AI()->AttackStart(target);
-
- ((boss_skeramAI*)Image1->AI())->IsImage = true;
- ((boss_skeramAI*)Image2->AI())->IsImage = true;
-
+ if (Image2)
+ {
+ Image2->SetMaxHealth(m_creature->GetMaxHealth() / 5);
+ Image2->SetHealth(m_creature->GetHealth() / 5);
+ if (target)
+ Image2->AI()->AttackStart(target);
+ ((boss_skeramAI*)Image2->AI())->IsImage = true;
+ }
Invisible = true;
}
};
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 c707ad23cee..e98daf7cc11 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -140,17 +140,16 @@ struct TRINITY_DLL_DECL boss_twinemperorsAI : public ScriptedAI
DoPlaySoundToSet(m_creature, IAmVeklor() ? SOUND_VL_KILL : SOUND_VN_KILL);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoZoneInCombat();
- InCombat = true;
Creature *pOtherBoss = GetOtherBoss();
if (pOtherBoss)
{
// TODO: we should activate the other boss location so he can start attackning even if nobody
// is near I dont know how to do that
ScriptedAI *otherAI = (ScriptedAI*)pOtherBoss->AI();
- if (!otherAI->InCombat)
+ if (!pOtherBoss->isInCombat())
{
DoPlaySoundToSet(m_creature, IAmVeklor() ? SOUND_VL_AGGRO : SOUND_VN_AGGRO);
otherAI->AttackStart(who);
@@ -336,7 +335,7 @@ struct TRINITY_DLL_DECL boss_twinemperorsAI : public ScriptedAI
std::list<Creature*> unitList;
AnyBugCheck u_check(m_creature, 150);
- Trinity::CreatureListSearcher<AnyBugCheck> searcher(unitList, u_check);
+ Trinity::CreatureListSearcher<AnyBugCheck> searcher(m_creature, unitList, u_check);
TypeContainerVisitor<Trinity::CreatureListSearcher<AnyBugCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *(m_creature->GetMap()));
@@ -404,13 +403,6 @@ struct TRINITY_DLL_DECL boss_twinemperorsAI : public ScriptedAI
}
};
-class TRINITY_DLL_DECL BugAura : public Aura
-{
- public:
- BugAura(SpellEntry *spell, uint32 eff, int32 *bp, Unit *target, Unit *caster) : Aura(spell, eff, bp, target, caster, NULL)
- {}
-};
-
struct TRINITY_DLL_DECL boss_veknilashAI : public boss_twinemperorsAI
{
bool IAmVeklor() {return false;}
@@ -441,12 +433,14 @@ struct TRINITY_DLL_DECL boss_veknilashAI : public boss_twinemperorsAI
target->setFaction(14);
((CreatureAI*)target->AI())->AttackStart(m_creature->getThreatManager().getHostilTarget());
SpellEntry *spell = (SpellEntry *)GetSpellStore()->LookupEntry(SPELL_MUTATE_BUG);
+ uint8 eff_mask=0;
for (int i=0; i<3; i++)
{
if (!spell->Effect[i])
continue;
- target->AddAura(new BugAura(spell, i, NULL, target, target));
+ eff_mask|=1<<i;
}
+ target->AddAura(new Aura(spell, eff_mask, NULL, target, target));
target->SetHealth(target->GetMaxHealth());
}
@@ -524,12 +518,14 @@ struct TRINITY_DLL_DECL boss_veklorAI : public boss_twinemperorsAI
{
target->setFaction(14);
SpellEntry *spell = (SpellEntry *)GetSpellStore()->LookupEntry(SPELL_EXPLODEBUG);
+ uint8 eff_mask=0;
for (int i=0; i<3; i++)
{
if (!spell->Effect[i])
continue;
- target->AddAura(new BugAura(spell, i, NULL, target, target));
+ eff_mask|=1<<i;
}
+ target->AddAura(new Aura(spell, eff_mask, NULL, target, target));
target->SetHealth(target->GetMaxHealth());
}
@@ -607,12 +603,6 @@ struct TRINITY_DLL_DECL boss_veklorAI : public boss_twinemperorsAI
m_creature->GetMotionMaster()->MoveChase(who, VEKLOR_DIST, 0);
m_creature->AddThreat(who, 0.0f);
}
-
- if (!InCombat)
- {
- InCombat = true;
- Aggro(who);
- }
}
}
};
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_viscidus.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_viscidus.cpp
index 7b310dfe10d..2bb9f1bfb0b 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_viscidus.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_viscidus.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/def_temple_of_ahnqiraj.h b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/def_temple_of_ahnqiraj.h
index 95db307f778..5d545ed7c74 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/def_temple_of_ahnqiraj.h
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/def_temple_of_ahnqiraj.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
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 7ca0f33566f..9048591b774 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
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 fd3e7c56cb1..30106f62180 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
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -174,7 +174,7 @@ struct TRINITY_DLL_DECL aqsentinelAI : public ScriptedAI
std::list<Creature*> assistList;
NearbyAQSentinel u_check(nears);
- Trinity::CreatureListSearcher<NearbyAQSentinel> searcher(assistList, u_check);
+ Trinity::CreatureListSearcher<NearbyAQSentinel> searcher(m_creature, assistList, u_check);
TypeContainerVisitor<Trinity::CreatureListSearcher<NearbyAQSentinel>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *(nears->GetMap()));
@@ -220,6 +220,8 @@ struct TRINITY_DLL_DECL aqsentinelAI : public ScriptedAI
DoYell("I dont have enough buddies.", LANG_NEUTRAL, 0);*/
SendMyListToBuddies();
CallBuddiesToAttack(who);
+
+ delete[] chosenAbilities;
}
bool gatherOthersWhenAggro;
@@ -245,13 +247,16 @@ struct TRINITY_DLL_DECL aqsentinelAI : public ScriptedAI
void GainSentinelAbility(uint32 id)
{
const SpellEntry *spell = GetSpellStore()->LookupEntry(id);
+ uint8 eff_mask=0;
for (int i=0; i<3; i++)
{
if (!spell->Effect[i])
continue;
- SentinelAbilityAura *a = new SentinelAbilityAura(this, (SpellEntry *)spell, id, i);
- m_creature->AddAura(a);
+ eff_mask=1<<i;
}
+ SentinelAbilityAura *a = new SentinelAbilityAura(this, (SpellEntry *)spell, id, eff_mask);
+ m_creature->AddAura(a);
+
if (id == SPELL_KNOCK_BUFF)
{
m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
@@ -259,7 +264,7 @@ struct TRINITY_DLL_DECL aqsentinelAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if (gatherOthersWhenAggro)
GetOtherSentinels(who);
@@ -339,6 +344,5 @@ SentinelAbilityAura::SentinelAbilityAura(aqsentinelAI *abilityOwner, SpellEntry
{
aOwner = abilityOwner;
abilityId = ability;
- currentBasePoints = 0;
}
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 9e7e809ba66..f1abe49c46e 100644
--- a/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp
+++ b/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -60,17 +60,17 @@ struct TRINITY_DLL_DECL mob_unkor_the_ruthlessAI : public ScriptedAI
CanDoQuest = false;
UnkorUnfriendly_Timer = 0;
Pulverize_Timer = 3000;
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_NONE);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
m_creature->setFaction(FACTION_HOSTILE);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void DoNice()
{
DoScriptText(SAY_SUBMIT, m_creature);
m_creature->setFaction(FACTION_FRIENDLY);
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_SIT);
+ m_creature->SetStandState(UNIT_STAND_STATE_SIT);
m_creature->RemoveAllAuras();
m_creature->DeleteThreatList();
m_creature->CombatStop();
@@ -151,7 +151,7 @@ struct TRINITY_DLL_DECL mob_infested_root_walkerAI : public ScriptedAI
mob_infested_root_walkerAI(Creature *c) : ScriptedAI(c) {}
void Reset() { }
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void DamageTaken(Unit *done_by, uint32 &damage)
{
@@ -176,7 +176,7 @@ struct TRINITY_DLL_DECL mob_rotting_forest_ragerAI : public ScriptedAI
mob_rotting_forest_ragerAI(Creature *c) : ScriptedAI(c) {}
void Reset() { }
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void DamageTaken(Unit *done_by, uint32 &damage)
{
@@ -208,7 +208,7 @@ struct TRINITY_DLL_DECL mob_netherweb_victimAI : public ScriptedAI
mob_netherweb_victimAI(Creature *c) : ScriptedAI(c) {}
void Reset() { }
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void MoveInLineOfSight(Unit *who) { }
void JustDied(Unit* Killer)
@@ -268,7 +268,7 @@ struct TRINITY_DLL_DECL npc_floonAI : public ScriptedAI
m_creature->setFaction(FACTION_FRIENDLY_FL);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void UpdateAI(const uint32 diff)
{
@@ -389,7 +389,7 @@ struct TRINITY_DLL_DECL npc_isla_starmaneAI : public npc_escortAI
{
GameObject* Cage = FindGameObject(GO_CAGE, 10, m_creature);
if(Cage)
- Cage->SetGoState(0);
+ Cage->SetGoState(GO_STATE_ACTIVE);
}break;
case 2: DoScriptText(SAY_PROGRESS_1, m_creature, player); break;
case 5: DoScriptText(SAY_PROGRESS_2, m_creature, player); break;
@@ -415,7 +415,7 @@ struct TRINITY_DLL_DECL npc_isla_starmaneAI : public npc_escortAI
m_creature->setFaction(1660);
}
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void JustDied(Unit* killer)
{
diff --git a/src/bindings/scripts/scripts/zone/thousand_needles/thousand_needles.cpp b/src/bindings/scripts/scripts/zone/thousand_needles/thousand_needles.cpp
index 4e81d44a610..b4d89470229 100644
--- a/src/bindings/scripts/scripts/zone/thousand_needles/thousand_needles.cpp
+++ b/src/bindings/scripts/scripts/zone/thousand_needles/thousand_needles.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -75,7 +75,7 @@ npc_swiftmountainAI(Creature *c) : npc_escortAI(c) {}
m_creature->setFaction(104);
}
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void JustSummoned(Creature* summoned)
{
@@ -217,7 +217,7 @@ struct TRINITY_DLL_DECL npc_pluckyAI : public ScriptedAI
ChickenTimer = 0;
}
- void Aggro(Unit *who){}
+ void EnterCombat(Unit *who){}
void TransformHuman(uint32 emoteid)
{
@@ -259,19 +259,17 @@ struct TRINITY_DLL_DECL npc_pluckyAI : public ScriptedAI
DoMeleeAttackIfReady();
}
-};
-bool ReceiveEmote_npc_plucky( Player *player, Creature *_Creature, uint32 emote )
-{
- if( (emote == TEXTEMOTE_BECKON || emote == TEXTEMOTE_CHICKEN &&
- player->GetQuestStatus(QUEST_GET_THE_SCOOP) == QUEST_STATUS_INCOMPLETE) )
+ void ReceiveEmote( Player *player, uint32 emote )
{
- _Creature->SetInFront(player);
- ((npc_pluckyAI*)((Creature*)_Creature)->AI())->TransformHuman(emote);
+ if( (emote == TEXTEMOTE_BECKON || emote == TEXTEMOTE_CHICKEN &&
+ player->GetQuestStatus(QUEST_GET_THE_SCOOP) == QUEST_STATUS_INCOMPLETE) )
+ {
+ m_creature->SetInFront(player);
+ TransformHuman(emote);
+ }
}
-
- return true;
-}
+};
bool GossipHello_npc_plucky(Player *player, Creature *_Creature)
{
@@ -316,7 +314,6 @@ void AddSC_thousand_needles()
newscript = new Script;
newscript->Name = "npc_plucky";
newscript->GetAI = &GetAI_npc_plucky;
- newscript->pReceiveEmote = &ReceiveEmote_npc_plucky;
newscript->pGossipHello = &GossipHello_npc_plucky;
newscript->pGossipSelect = &GossipSelect_npc_plucky;
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 30312313ee8..fbc248cde94 100644
--- a/src/bindings/scripts/scripts/zone/thunder_bluff/thunder_bluff.cpp
+++ b/src/bindings/scripts/scripts/zone/thunder_bluff/thunder_bluff.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -54,7 +54,7 @@ struct TRINITY_DLL_DECL npc_cairne_bloodhoofAI : public ScriptedAI
Uppercut_Timer = 10000;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void UpdateAI(const uint32 diff)
{
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 7a69eab5153..78619c47782 100644
--- a/src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp
+++ b/src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -47,7 +47,7 @@ struct TRINITY_DLL_DECL npc_calvin_montagueAI : public ScriptedAI
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2);
}
- void Aggro(Unit* who) { }
+ void EnterCombat(Unit* who) { }
void JustDied(Unit* Killer)
{
@@ -100,7 +100,7 @@ GameObject* SearchMausoleumGo(Unit *source, uint32 entry, float range)
cell.SetNoCreate();
Trinity::NearestGameObjectEntryInObjectRangeCheck go_check(*source, entry, range);
- Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck> searcher(pGo, go_check);
+ Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck> searcher(source, pGo, go_check);
TypeContainerVisitor<Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer> go_searcher(searcher);
@@ -117,7 +117,7 @@ bool GOHello_go_mausoleum_door(Player *player, GameObject* _GO)
if (GameObject *trigger = SearchMausoleumGo(player, GO_TRIGGER, 30))
{
- trigger->SetGoState(1);
+ trigger->SetGoState(GO_STATE_READY);
player->SummonCreature(C_ULAG, 2390.26, 336.47, 40.01, 2.26, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000);
return false;
}
@@ -132,7 +132,7 @@ bool GOHello_go_mausoleum_trigger(Player *player, GameObject* _GO)
if (GameObject *door = SearchMausoleumGo(player, GO_DOOR, 30))
{
- _GO->SetGoState(0);
+ _GO->SetGoState(GO_STATE_ACTIVE);
door->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
return true;
}
diff --git a/src/bindings/scripts/scripts/zone/uldaman/boss_archaedas.cpp b/src/bindings/scripts/scripts/zone/uldaman/boss_archaedas.cpp
index adf88585a39..56c1d0d3f9d 100644
--- a/src/bindings/scripts/scripts/zone/uldaman/boss_archaedas.cpp
+++ b/src/bindings/scripts/scripts/zone/uldaman/boss_archaedas.cpp
@@ -94,7 +94,7 @@ struct TRINITY_DLL_DECL boss_archaedasAI : public ScriptedAI
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
m_creature->setFaction (14);
m_creature->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
@@ -231,7 +231,7 @@ struct TRINITY_DLL_DECL mob_archaedas_minionsAI : public ScriptedAI
m_creature->RemoveAllAuras();
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
m_creature->setFaction (14);
m_creature->RemoveAllAuras();
@@ -369,7 +369,7 @@ struct TRINITY_DLL_DECL mob_stonekeepersAI : public ScriptedAI
m_creature->RemoveAllAuras();
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
m_creature->setFaction (14);
m_creature->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
diff --git a/src/bindings/scripts/scripts/zone/uldaman/boss_ironaya.cpp b/src/bindings/scripts/scripts/zone/uldaman/boss_ironaya.cpp
index 14a788d29e2..ccee1e68790 100644
--- a/src/bindings/scripts/scripts/zone/uldaman/boss_ironaya.cpp
+++ b/src/bindings/scripts/scripts/zone/uldaman/boss_ironaya.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -23,12 +23,11 @@ EndScriptData */
#include "precompiled.h"
-#define SPELL_ARCINGSMASH 39144
-#define SPELL_KNOCKAWAY 22893
-#define SPELL_WSTOMP 16727
+#define SAY_AGGRO -1070000
-#define SAY_AGGRO "None may steal the secrets of the makers!"
-#define SOUND_AGGRO 5851
+#define SPELL_ARCINGSMASH 8374
+#define SPELL_KNOCKAWAY 10101
+#define SPELL_WSTOMP 11876
struct TRINITY_DLL_DECL boss_ironayaAI : public ScriptedAI
{
@@ -45,10 +44,9 @@ struct TRINITY_DLL_DECL boss_ironayaAI : public ScriptedAI
hasCastedWstomp = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
- DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL);
- DoPlaySoundToSet(m_creature,SOUND_AGGRO);
+ DoScriptText(SAY_AGGRO, m_creature);
}
void UpdateAI(const uint32 diff)
diff --git a/src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp b/src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp
index 7a5e50805f1..3da5e679cab 100644
--- a/src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp
+++ b/src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp
@@ -70,7 +70,7 @@ struct TRINITY_DLL_DECL instance_uldaman : public ScriptedInstance
break;
case ANCIENT_VAULT_DOOR:
- go->SetUInt32Value(GAMEOBJECT_STATE,1);
+ go->SetGoState(GO_STATE_READY);
go->SetUInt32Value(GAMEOBJECT_FLAGS, 33);
ancientVaultDoor = go->GetGUID();
break;
@@ -88,19 +88,19 @@ struct TRINITY_DLL_DECL instance_uldaman : public ScriptedInstance
void OpenDoor(uint64 guid)
{
- GameObject *go = instance->GetGameObjectInMap(guid);
+ GameObject *go = instance->GetGameObject(guid);
if(!go)
return;
go->SetUInt32Value(GAMEOBJECT_FLAGS, 33);
- go->SetUInt32Value(GAMEOBJECT_STATE, 0);
+ go->SetGoState(GO_STATE_ACTIVE);
}
void ActivateStoneKeepers()
{
for(std::vector<uint64>::iterator i = stoneKeeper.begin(); i != stoneKeeper.end(); ++i)
{
- Creature *target = instance->GetCreatureInMap(*i);
+ Creature *target = instance->GetCreature(*i);
if (!target || !target->isAlive() || target->getFaction()==14)
continue;
target->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE);
@@ -114,13 +114,13 @@ struct TRINITY_DLL_DECL instance_uldaman : public ScriptedInstance
void ActivateWallMinions()
{
- Creature *archaedas = instance->GetCreatureInMap(archaedasGUID);
+ Creature *archaedas = instance->GetCreature(archaedasGUID);
if(!archaedas)
return;
for(std::vector<uint64>::iterator i = archaedasWallMinions.begin(); i != archaedasWallMinions.end(); ++i)
{
- Creature *target = instance->GetCreatureInMap(*i);
+ Creature *target = instance->GetCreature(*i);
if (!target || !target->isAlive() || target->getFaction()==14)
continue;
archaedas->CastSpell(target, SPELL_AWAKEN_VAULT_WALKER, true);
@@ -135,7 +135,7 @@ struct TRINITY_DLL_DECL instance_uldaman : public ScriptedInstance
// first despawn any aggroed wall minions
for(std::vector<uint64>::iterator i = archaedasWallMinions.begin(); i != archaedasWallMinions.end(); ++i)
{
- Creature *target = instance->GetCreatureInMap(*i);
+ Creature *target = instance->GetCreature(*i);
if (!target || target->isDead() || target->getFaction()!=14)
continue;
target->setDeathState(JUST_DIED);
@@ -145,7 +145,7 @@ struct TRINITY_DLL_DECL instance_uldaman : public ScriptedInstance
// Vault Walkers
for(std::vector<uint64>::iterator i = vaultWalker.begin(); i != vaultWalker.end(); ++i)
{
- Creature *target = instance->GetCreatureInMap(*i);
+ Creature *target = instance->GetCreature(*i);
if (!target || target->isDead() || target->getFaction()!=14)
continue;
target->setDeathState(JUST_DIED);
@@ -155,7 +155,7 @@ struct TRINITY_DLL_DECL instance_uldaman : public ScriptedInstance
// Earthen Guardians
for(std::vector<uint64>::iterator i = earthenGuardian.begin(); i != earthenGuardian.end(); ++i)
{
- Creature *target = instance->GetCreatureInMap(*i);
+ Creature *target = instance->GetCreature(*i);
if (!target || target->isDead() || target->getFaction()!=14)
continue;
target->setDeathState(JUST_DIED);
@@ -165,7 +165,7 @@ struct TRINITY_DLL_DECL instance_uldaman : public ScriptedInstance
void ActivateArchaedas(uint64 target)
{
- Creature *archaedas = instance->GetCreatureInMap(archaedasGUID);
+ Creature *archaedas = instance->GetCreature(archaedasGUID);
if(!archaedas)
return;
@@ -181,7 +181,7 @@ struct TRINITY_DLL_DECL instance_uldaman : public ScriptedInstance
// first respawn any aggroed wall minions
for(std::vector<uint64>::iterator i = archaedasWallMinions.begin(); i != archaedasWallMinions.end(); ++i)
{
- Creature *target = instance->GetCreatureInMap(*i);
+ Creature *target = instance->GetCreature(*i);
if (target && target->isDead())
{
target->Respawn();
@@ -193,7 +193,7 @@ struct TRINITY_DLL_DECL instance_uldaman : public ScriptedInstance
// Vault Walkers
for(std::vector<uint64>::iterator i = vaultWalker.begin(); i != vaultWalker.end(); ++i)
{
- Creature *target = instance->GetCreatureInMap(*i);
+ Creature *target = instance->GetCreature(*i);
if (target && target->isDead())
{
target->Respawn();
@@ -205,7 +205,7 @@ struct TRINITY_DLL_DECL instance_uldaman : public ScriptedInstance
// Earthen Guardians
for(std::vector<uint64>::iterator i = earthenGuardian.begin(); i != earthenGuardian.end(); ++i)
{
- Creature *target = instance->GetCreatureInMap(*i);
+ Creature *target = instance->GetCreature(*i);
if (target && target->isDead())
{
target->Respawn();
diff --git a/src/bindings/scripts/scripts/zone/uldaman/uldaman.cpp b/src/bindings/scripts/scripts/zone/uldaman/uldaman.cpp
index de5f4889fe4..8498b3b5770 100644
--- a/src/bindings/scripts/scripts/zone/uldaman/uldaman.cpp
+++ b/src/bindings/scripts/scripts/zone/uldaman/uldaman.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -45,7 +45,7 @@ struct TRINITY_DLL_DECL mob_jadespine_basiliskAI : public ScriptedAI
Cslumber_Timer = 2000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/boss_bjarngrim.cpp b/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/boss_bjarngrim.cpp
new file mode 100644
index 00000000000..d9022fcf445
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/boss_bjarngrim.cpp
@@ -0,0 +1,94 @@
+/* Script Data Start
+SDName: Boss bjarngrim
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//AURAS AND STANCES
+#define BUFF_BATTLE_AURA 41106
+#define SPELL_BATTLE_STANCE 53792
+#define BUFF_BERSEKER_AURA 41107
+#define SPELL_BERSEKER_STANCE 53791
+#define BUFF_DEFENSIVE_AURA 41105
+#define SPELL_DEFENSIVE_STANCE 53790
+
+//OTHER SPELLS
+#define SPELL_CHARGE_UP 52098
+#define SPELL_CLEAVE 15284
+#define SPELL_INTERCEPT 58769
+#define SPELL_IRONFORM 52022
+#define SPELL_KNOCK_AWAY 52029
+#define SPELL_MORTAL_STRIKE 15708
+#define SPELL_SLAM 52026
+#define SPELL_SPELL_REFLECTION 36096
+#define SPELL_WHIRLWIND 52027
+
+//Yell
+#define SAY_AGGRO -1602000
+#define SAY_SLAY_1 -1602001
+#define SAY_SLAY_2 -1602002
+#define SAY_SLAY_3 -1602003
+#define SAY_DEATH -1602004
+#define SAY_BATTLE_STANCE -1602005
+#define SAY_BERSEKER_STANCE -1602006
+#define SAY_DEFENSIVE_STANCE -1602007
+
+struct TRINITY_DLL_DECL boss_bjarngrimAI : public ScriptedAI
+{
+ boss_bjarngrimAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 whirlwind;
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_bjarngrim(Creature *_Creature)
+{
+ return new boss_bjarngrimAI (_Creature);
+}
+
+void AddSC_boss_bjarngrim()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_bjarngrim";
+ newscript->GetAI = GetAI_boss_bjarngrim;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/boss_ionar.cpp b/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/boss_ionar.cpp
new file mode 100644
index 00000000000..30d1ac40fad
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/boss_ionar.cpp
@@ -0,0 +1,114 @@
+/* Script Data Start
+SDName: Boss ionar
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_ionar' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_BALL_LIGHTNING 52780
+#define SPELL_BALL_LIGHTNING_2 59800
+#define SPELL_DISPERSE 52770 //Disperse into Sparks of Ionar.
+#define SPELL_STATIC_OVERLOAD 52658 //Effect Apply Aura: Periodic Trigger Interval: 2 seconds Spell 52659
+#define SPELL_STATIC_OVERLOAD_2 52658 //Effect Apply Aura: Periodic Trigger Interval: 2 seconds Spell 59796
+
+//Spark of Ionar spells
+#define NPC_SPARK_OF_IONAR 28962 //invulnerable
+#define SPELL_ARCING_BURN 52617
+#define SPELL_ARCING_BURN_2 59834
+
+//Yell
+#define SAY_AGGRO -1602008
+#define SAY_SLAY_1 -1602009
+#define SAY_SLAY_2 -1602010
+#define SAY_SLAY_3 -1602011
+#define SAY_DEATH -1602012
+#define SAY_SPLIT_1 -1602013
+#define SAY_SPLIT_2 -1602014
+
+//he does "morph" every about 25% into 4 sparks of ionar that chase people around, they r slow and easily avoidable.
+
+struct TRINITY_DLL_DECL boss_ionarAI : public ScriptedAI
+{
+ boss_ionarAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+struct TRINITY_DLL_DECL npc_spark_of_ionarAI : public ScriptedAI
+{
+ npc_spark_of_ionarAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who) {}
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer) {}
+};
+
+CreatureAI* GetAI_npc_spark_of_ionar(Creature *_Creature)
+{
+ return new npc_spark_of_ionarAI (_Creature);
+}
+CreatureAI* GetAI_boss_ionar(Creature *_Creature)
+{
+ return new boss_ionarAI (_Creature);
+}
+
+void AddSC_boss_ionar()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_ionar";
+ newscript->GetAI = GetAI_boss_ionar;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="spark_of_ionar";
+ newscript->GetAI = GetAI_npc_spark_of_ionar;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/boss_loken.cpp b/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/boss_loken.cpp
new file mode 100644
index 00000000000..c479f6c7a93
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/boss_loken.cpp
@@ -0,0 +1,86 @@
+/* Script Data Start
+SDName: Boss loken
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_loken' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_ARC_NOVA 52921
+//Effect #1 School Damage (Nature), Value: 3238 to 3762
+//Effect #2 Apply Aura: Dummy, Value: 3238 to 3762, Server-side script
+
+#define SPELL_LIGHTNING_NOVA 52960
+#define SPELL_LIGHTNING_NOVA_2 59835
+
+//Yell
+#define SAY_AGGRO -1602015
+#define SAY_INTRO_1 -1602016
+#define SAY_INTRO_2 -1602017
+#define SAY_SLAY_1 -1602018
+#define SAY_SLAY_2 -1602019
+#define SAY_SLAY_3 -1602020
+#define SAY_DEATH -1602021
+#define SAY_NOVA_1 -1602022
+#define SAY_NOVA_2 -1602023
+#define SAY_NOVA_3 -1602024
+#define SAY_75HEALTH -1602025
+#define SAY_50HEALTH -1602026
+#define SAY_25HEALTH -1602027
+
+struct TRINITY_DLL_DECL boss_lokenAI : public ScriptedAI
+{
+ boss_lokenAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_loken(Creature *_Creature)
+{
+ return new boss_lokenAI (_Creature);
+}
+
+void AddSC_boss_loken()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_loken";
+ newscript->GetAI = GetAI_boss_loken;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/boss_volkhan.cpp b/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/boss_volkhan.cpp
new file mode 100644
index 00000000000..8cc20f64c17
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/boss_volkhan.cpp
@@ -0,0 +1,128 @@
+/* Script Data Start
+SDName: Boss volkhan
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_volkhan' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_HEAT 52387
+#define SPELL_HEAT_2 59528
+#define SPELL_SHATTERING_STOMP 52237
+#define SPELL_SHATTERING_STOMP_2 59529
+#define SPELL_TEMPER 52238 //Dummy ---> Strikes Volkhan's Anvil, creating a number of Molten Golems.
+
+#define NPC_VOLKHANS_ANVIL 28823
+#define MOB_MOLTEN_GOLEM 28695
+
+//Yells
+#define SAY_AGGRO -1602028
+#define SAY_SLAY_1 -1602029
+#define SAY_SLAY_2 -1602030
+#define SAY_SLAY_3 -1602031
+#define SAY_DEATH -1602032
+#define SAY_STOMP_1 -1602033
+#define SAY_STOMP_2 -1602034
+#define SAY_FORGE_1 -1602035
+#define SAY_FORGE_2 -1602036
+
+struct TRINITY_DLL_DECL boss_volkhanAI : public ScriptedAI
+{
+ boss_volkhanAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+/*######
+## Mob Molten Golem
+######*/
+//Molten Golem Spells
+#define SPELL_BLAST_WAVE 23113
+#define SPELL_IMMOLATION_STRIKE 52433
+#define SPELL_IMMOLATION_STRIKE_2 59530
+//Effect #1 Apply Aura: Periodic Damage, value: 900 every 3 seconds
+//Effect #2 School Damage (Fire), value: 900
+//Effect #3 Script Effect
+#define SPELL_SHATTER 52429
+//Effect #1 School Damage (Physical), value: 9250 to 10750, radius: 10 yards
+//Effect #2 Dummy, Server-side script
+#define SPELL_SHATTER_2
+
+struct TRINITY_DLL_DECL mob_molten_golemAI : public ScriptedAI
+{
+ mob_molten_golemAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who) {}
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer) {}
+};
+
+CreatureAI* GetAI_mob_molten_golem(Creature *_Creature)
+{
+ return new mob_molten_golemAI (_Creature);
+}
+
+CreatureAI* GetAI_boss_volkhan(Creature *_Creature)
+{
+ return new boss_volkhanAI (_Creature);
+}
+
+void AddSC_boss_volkhan()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_volkhan";
+ newscript->GetAI = GetAI_boss_volkhan;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_molten_golem";
+ newscript->GetAI = GetAI_mob_molten_golem;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/def_halls_of_lightning.h b/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/def_halls_of_lightning.h
new file mode 100644
index 00000000000..134e32850ae
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/def_halls_of_lightning.h
@@ -0,0 +1,4 @@
+#ifndef DEF_HALLS_OF_LIGHTNING_H
+#define DEF_HALLS_OF_LIGHTNING_H
+
+#endif
diff --git a/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp b/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp
new file mode 100644
index 00000000000..4e694df73a5
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp
@@ -0,0 +1,21 @@
+#include "precompiled.h"
+#include "def_halls_of_lightning.h"
+
+struct TRINITY_DLL_DECL instance_halls_of_lightning : public ScriptedInstance
+{
+ instance_halls_of_lightning(Map *Map) : ScriptedInstance(Map) {Initialize();};
+};
+
+InstanceData* GetInstanceData_instance_halls_of_lightning(Map* map)
+{
+ return new instance_halls_of_lightning(map);
+}
+
+void AddSC_instance_halls_of_lightning()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_halls_of_lightning";
+ newscript->GetInstanceData = GetInstanceData_instance_halls_of_lightning;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/boss_krystallus.cpp b/src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/boss_krystallus.cpp
new file mode 100644
index 00000000000..662e67a8941
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/boss_krystallus.cpp
@@ -0,0 +1,73 @@
+/* Script Data Start
+SDName: Boss krystallus
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_krystallus' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_BOULDER_TOSS 50843
+#define SPELL_BOULDER_TOSS_2 59742
+#define SPELL_GROUND_SPIKE 59750
+#define SPELL_SHATTER 50810
+#define SPELL_SHATTER_2 61546
+#define SPELL_STOMP 48131
+#define SPELL_STOMP_2 59744
+
+//Yell
+#define SAY_AGGRO -1599000
+#define SAY_KILL -1599001
+#define SAY_DEATH -1599002
+#define SAY_SHATTER -1599003
+
+struct TRINITY_DLL_DECL boss_krystallusAI : public ScriptedAI
+{
+ boss_krystallusAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ DoScriptText(SAY_KILL, m_creature);
+ }
+};
+
+CreatureAI* GetAI_boss_krystallus(Creature *_Creature)
+{
+ return new boss_krystallusAI (_Creature);
+}
+
+void AddSC_boss_krystallus()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_krystallus";
+ newscript->GetAI = GetAI_boss_krystallus;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/boss_maiden_of_grief.cpp b/src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/boss_maiden_of_grief.cpp
new file mode 100644
index 00000000000..3b7ae182d70
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/boss_maiden_of_grief.cpp
@@ -0,0 +1,81 @@
+/* Script Data Start
+SDName: Boss maiden_of_grief
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_maiden_of_grief' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spell
+#define SPELL_PARTING_SORROW 59723
+#define SPELL_STORM_OF_GRIEF 50752
+#define SPELL_STORM_OF_GRIEF_2 59772
+#define SPELL_SHOCK_OF_SORROW 50760
+#define SPELL_SHOCK_OF_SORROW_2 59726
+#define SPELL_PILLAR_OF_WOE 50761
+#define SPELL_PILLAR_OF_WOE_2 59727
+
+//Yell
+#define SAY_AGGRO -1599004
+#define SAY_SLAY_1 -1599005
+#define SAY_SLAY_2 -1599006
+#define SAY_SLAY_3 -1599007
+#define SAY_SLAY_4 -1599008
+#define SAY_DEATH -1599009
+#define SAY_STUN -1599010
+
+struct TRINITY_DLL_DECL boss_maiden_of_griefAI : public ScriptedAI
+{
+ boss_maiden_of_griefAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_maiden_of_grief(Creature *_Creature)
+{
+ return new boss_maiden_of_griefAI (_Creature);
+}
+
+void AddSC_boss_maiden_of_grief()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_maiden_of_grief";
+ newscript->GetAI = GetAI_boss_maiden_of_grief;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/boss_sjonnir.cpp b/src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/boss_sjonnir.cpp
new file mode 100644
index 00000000000..852395cf3b8
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/boss_sjonnir.cpp
@@ -0,0 +1,83 @@
+/* Script Data Start
+SDName: Boss sjonnir
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_sjonnir' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_LIGHTING_RING_1 50840 //Periodic Trigger (interval 2s) spell = 50841
+#define SPELL_LIGHTING_RING_2 51849 //Periodic Trigger (interval 2s) spell = 50841
+#define SPELL_LIGHTING_RING_2 59848 //Periodic Trigger (interval 2s) spell = 59849
+#define SPELL_LIGHTING_RING_3 59861 //Periodic Trigger (interval 2s) spell = 59849
+#define SPELL_STATIC_CHARGE_1 50834 //Periodic Trigger 2s interval, spell =50835
+#define SPELL_STATIC_CHARGE_2 59846 //Periodic Trigger 2s interval, spell =50847
+#define SPELL_CHAIN_LIGHTING_1 50830
+#define SPELL_CHAIN_LIGHTING_2 59844
+#define SPELL_LIGHTING_SHIELD_1 50831
+#define SPELL_LIGHTING_SHIELD_2 59845
+#define SPELL_FRENZY 28747
+
+//Yell
+#define SAY_AGGRO -1599011
+#define SAY_SLAY_1 -1599012
+#define SAY_SLAY_2 -1599013
+#define SAY_SLAY_3 -1599014
+#define SAY_DEATH -1599015
+
+struct TRINITY_DLL_DECL boss_sjonnirAI : public ScriptedAI
+{
+ boss_sjonnirAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_sjonnir(Creature *_Creature)
+{
+ return new boss_sjonnirAI (_Creature);
+}
+
+void AddSC_boss_sjonnir()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_sjonnir";
+ newscript->GetAI = GetAI_boss_sjonnir;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/def_halls_of_stone.h b/src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/def_halls_of_stone.h
new file mode 100644
index 00000000000..ade934ad921
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/def_halls_of_stone.h
@@ -0,0 +1,4 @@
+#ifndef DEF_HALLS_OF_STONE_H
+#define DEF_HALLS_OF_STONE_H
+
+#endif
diff --git a/src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/instance_halls_of_stone.cpp b/src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/instance_halls_of_stone.cpp
new file mode 100644
index 00000000000..3c7d3970b47
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/ulduar/halls_of_stone/instance_halls_of_stone.cpp
@@ -0,0 +1,21 @@
+#include "precompiled.h"
+#include "def_halls_of_stone.h"
+
+struct TRINITY_DLL_DECL instance_halls_of_stone : public ScriptedInstance
+{
+ instance_halls_of_stone(Map *Map) : ScriptedInstance(Map) {Initialize();};
+};
+
+InstanceData* GetInstanceData_instance_halls_of_stone(Map* map)
+{
+ return new instance_halls_of_stone(map);
+}
+
+void AddSC_instance_halls_of_stone()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_halls_of_stone";
+ newscript->GetInstanceData = GetInstanceData_instance_halls_of_stone;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/undercity/undercity.cpp b/src/bindings/scripts/scripts/zone/undercity/undercity.cpp
index b46acf1fcc2..b4e12f60ead 100644
--- a/src/bindings/scripts/scripts/zone/undercity/undercity.cpp
+++ b/src/bindings/scripts/scripts/zone/undercity/undercity.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -78,7 +78,7 @@ struct TRINITY_DLL_DECL npc_lady_sylvanas_windrunnerAI : public ScriptedAI
targetGUID = 0;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void JustSummoned(Creature *summoned)
{
@@ -91,7 +91,7 @@ struct TRINITY_DLL_DECL npc_lady_sylvanas_windrunnerAI : public ScriptedAI
summoned->CastSpell(target, SPELL_RIBBON_OF_SOULS, false);
}
- summoned->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+ summoned->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
targetGUID = summoned->GetGUID();
}
}
@@ -110,7 +110,7 @@ struct TRINITY_DLL_DECL npc_lady_sylvanas_windrunnerAI : public ScriptedAI
m_creature->SummonCreature(ENTRY_HIGHBORNE_BUNNY, raX, raY, myZ, 0, TEMPSUMMON_TIMED_DESPAWN, 3000);
LamentEvent_Timer = 2000;
- if( !m_creature->HasAura(SPELL_SYLVANAS_CAST, 0))
+ if( !m_creature->HasAura(SPELL_SYLVANAS_CAST))
{
DoScriptText(SAY_LAMENT_END, m_creature);
DoScriptText(EMOTE_LAMENT_END, m_creature);
@@ -166,7 +166,7 @@ struct TRINITY_DLL_DECL npc_highborne_lamenterAI : public ScriptedAI
EventCast = true;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void UpdateAI(const uint32 diff)
{
@@ -174,8 +174,8 @@ struct TRINITY_DLL_DECL npc_highborne_lamenterAI : public ScriptedAI
{
if( EventMove_Timer < diff )
{
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT | MOVEMENTFLAG_LEVITATING);
- m_creature->SendMonsterMoveWithSpeed(m_creature->GetPositionX(),m_creature->GetPositionY(),HIGHBORNE_LOC_Y_NEW,MOVEMENTFLAG_ONTRANSPORT,5000);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ m_creature->SendMonsterMoveWithSpeed(m_creature->GetPositionX(),m_creature->GetPositionY(),HIGHBORNE_LOC_Y_NEW,5000);
m_creature->GetMap()->CreatureRelocation(m_creature,m_creature->GetPositionX(),m_creature->GetPositionY(),HIGHBORNE_LOC_Y_NEW,m_creature->GetOrientation());
EventMove = false;
}else EventMove_Timer -= diff;
@@ -210,7 +210,7 @@ bool GossipHello_npc_parqual_fintallas(Player *player, Creature *_Creature)
if (_Creature->isQuestGiver())
player->PrepareQuestMenu( _Creature->GetGUID() );
- if (player->GetQuestStatus(6628) == QUEST_STATUS_INCOMPLETE && !player->HasAura(SPELL_MARK_OF_SHAME,0) )
+ if (player->GetQuestStatus(6628) == QUEST_STATUS_INCOMPLETE && !player->HasAura(SPELL_MARK_OF_SHAME) )
{
player->ADD_GOSSIP_ITEM( 0, GOSSIP_HPF1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->ADD_GOSSIP_ITEM( 0, GOSSIP_HPF2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
diff --git a/src/bindings/scripts/scripts/zone/ungoro_crater/ungoro_crater.cpp b/src/bindings/scripts/scripts/zone/ungoro_crater/ungoro_crater.cpp
index 9bb13dd7718..c3987526126 100644
--- a/src/bindings/scripts/scripts/zone/ungoro_crater/ungoro_crater.cpp
+++ b/src/bindings/scripts/scripts/zone/ungoro_crater/ungoro_crater.cpp
@@ -88,7 +88,7 @@ struct TRINITY_DLL_DECL npc_ameAI : public npc_escortAI
DEMORALIZINGSHOUT_Timer = 5000;
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{}
void JustSummoned(Creature* summoned)
diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_dalronn.cpp b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_dalronn.cpp
new file mode 100644
index 00000000000..9512444458b
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_dalronn.cpp
@@ -0,0 +1,97 @@
+/* Script Data Start
+SDName: Boss dalronn
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_dalronn' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_DEBILITATE 43650
+#define SPELL_SHADOWBOLT 43649
+#define SPELL_SHADOWBOLT_2 59575
+#define SPELL_SUMMON_SKELETONS 52611 //Trigger Spell: 52612, summons NPC (28878)
+#define SPELL_SKARVALD_GHOST 48613 //When Skarvald dies
+
+//Yell
+#define SAY_AGGRO -1574005
+#define SAY_KILL -1574006
+#define SAY_DEATH_1 -1574007
+#define SAY_DEATH_2 -1574008
+#define SAY_RAISES -1574009
+
+struct TRINITY_DLL_DECL boss_dalronnAI : public ScriptedAI
+{
+ boss_dalronnAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 killed;
+ uint64 Skarvald;
+
+ void Reset()
+ {
+ Skarvald = 0;
+ }
+ void Aggro(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ if (Skarvald)
+ {
+ Creature* Skravald_m = (Unit::GetCreature((*m_creature), Skarvald));
+ if (Skravald_m)
+ {
+ if (!Skravald_m->isAlive())
+ {
+ DoCast(Skravald_m,SPELL_SKARVALD_GHOST);
+ DoScriptText(SAY_RAISES, m_creature);
+ }
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ killed++;
+ //On first death resurected instatly by Skarvald as a ghost, having the same abilities as when alive and is unatackable
+ //If Skarvald dies first, Dalron resurects him and says "SAY_RAISES"
+ if(killed ==2)
+ DoScriptText(SAY_DEATH_2,m_creature);
+ else
+ DoScriptText(SAY_DEATH_1,m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ DoScriptText(SAY_KILL, m_creature);
+ }
+};
+
+CreatureAI* GetAI_boss_dalronn(Creature *_Creature)
+{
+ return new boss_dalronnAI (_Creature);
+}
+
+void AddSC_boss_dalronn()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_dalronn";
+ newscript->GetAI = GetAI_boss_dalronn;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_ingvar_the_plunderer.cpp b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_ingvar_the_plunderer.cpp
new file mode 100644
index 00000000000..ac4b22bb2f7
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_ingvar_the_plunderer.cpp
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2009 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
+ */
+
+/* ScriptData
+SDName: Boss_Ingvar_The_Plunderer
+SD%Complete: 95
+SDComment: Some Problems with Annhylde Movement, Blizzlike Timers
+SDCategory: Udgarde Keep
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_utgarde_keep.h"
+
+//Yells Ingvar
+#define YELL_AGGRO_1 -1574015
+#define YELL_AGGRO_2 -1574022
+
+#define YELL_DEAD_1 -1574017
+#define YELL_DEAD_2 -1574024
+
+#define YELL_KILL_1 -1574023
+#define YELL_KILL_2 -1574016
+
+//Ingvar Spells human form
+#define MOB_INGVAR_HUMAN 23954
+#define SPELL_CLEAVE 42724
+#define SPELL_SMASH 42669
+#define H_SPELL_SMASH 59706
+#define SPELL_STAGGERING_ROAR 42708
+#define H_SPELL_STAGGERING_ROAR 59708
+#define SPELL_ENRAGE 42705
+#define H_SPELL_ENRAGE 59707
+
+#define MOB_ANNHYLDE_THE_CALLER 24068
+#define SPELL_INGVAR_FEIGN_DEATH 42795
+#define SPELL_SUMMON_BANSHEE 42912
+#define SPELL_SCOURG_RESURRECTION_EFFEKTSPAWN 42863 //Spawn resurrecteffekt around Ingvar
+
+#define MODEL_INGVAR_UNDEAD 26351
+#define MODEL_INGVAR_HUMAN 21953
+
+//Ingvar Spells undead form
+#define MOB_INGVAR_UNDEAD 23980
+#define SPELL_DARK_SMASH 42723
+#define SPELL_DREADFUL_ROAR 42729
+#define H_SPELL_DREADFUL_ROAR 59734
+#define SPELL_WOE_STRIKE 42730
+#define H_SPELL_WOE_STRIKE 59735
+
+#define ENTRY_THROW_TARGET 23996
+#define SPELL_SHADOW_AXE_SUMMON 42749
+
+struct TRINITY_DLL_DECL boss_ingvar_the_plundererAI : public ScriptedAI
+{
+ boss_ingvar_the_plundererAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ HeroicMode = c->GetMap()->IsHeroic();
+ }
+
+ ScriptedInstance* pInstance;
+
+ bool HeroicMode;
+ bool undead;
+ bool event_inProgress;
+
+ uint32 Cleave_Timer;
+ uint32 Smash_Timer;
+ uint32 Enrage_Timer;
+ uint32 Roar_Timer;
+ uint32 SpawnResTimer;
+ uint32 wait_Timer;
+
+ void Reset()
+ {
+ if(undead) // Visual Hack
+ m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_INGVAR_HUMAN);
+
+ undead = false;
+ event_inProgress = false;
+
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+
+ Cleave_Timer = 2000;
+ Smash_Timer = 5000;
+ Enrage_Timer = 10000;
+ Roar_Timer = 15000;
+
+ SpawnResTimer = 3000;
+
+ wait_Timer = 0;
+
+ if(pInstance)
+ pInstance->SetData(DATA_INGVAR_EVENT, NOT_STARTED);
+ }
+
+ void DamageTaken(Unit *done_by, uint32 &damage)
+ {
+ if( damage >= m_creature->GetHealth() && !undead)
+ {
+ //DoCast(m_creature,SPELL_INGVAR_FEIGN_DEATH,true); // Dont work ???
+ // visuel hack
+ m_creature->SetHealth(0);
+ m_creature->InterruptNonMeleeSpells(true);
+ m_creature->RemoveAllAuras();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2);
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MoveIdle();
+ m_creature->SetStandState(UNIT_STAND_STATE_DEAD);
+ // visuel hack end
+
+ event_inProgress = true;
+ undead = true;
+
+ DoScriptText(YELL_DEAD_1,m_creature);
+ }
+
+ if(event_inProgress)
+ {
+ damage = 0;
+ }
+ }
+
+ void StartZombiePhase()
+ {
+ undead = true;
+ event_inProgress = false;
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2);
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ m_creature->AI()->AttackStart(m_creature->getVictim());
+
+ DoScriptText(YELL_AGGRO_2,m_creature);
+ }
+
+ void EnterCombat(Unit *who)
+ {
+ DoScriptText(YELL_AGGRO_1,m_creature);
+
+ if(pInstance)
+ pInstance->SetData(DATA_INGVAR_EVENT, IN_PROGRESS);
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(YELL_DEAD_2,m_creature);
+
+ if(pInstance)
+ pInstance->SetData(DATA_INGVAR_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ if(undead) { DoScriptText(YELL_KILL_1,m_creature); }
+ else { DoScriptText(YELL_KILL_2,m_creature); }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if(event_inProgress)
+ {
+ if(SpawnResTimer)
+ if(SpawnResTimer< diff)
+ {
+ DoCast(m_creature,SPELL_SUMMON_BANSHEE); // Summons direktly on caster position
+ //DoCast(m_creature,SPELL_SCOURG_RESURRECTION_EFFEKTSPAWN); // Dont needet ?
+ SpawnResTimer = 0;
+ }else SpawnResTimer -= diff;
+
+ return;
+ }
+
+ // This is used for a spell queue ... the spells should not castet if one spell is already casting
+ if(wait_Timer)
+ if(wait_Timer < diff)
+ {
+ wait_Timer = 0;
+ }else wait_Timer -= diff;
+
+ if(Cleave_Timer < diff)
+ {
+ if(!wait_Timer)
+ {
+ if(undead)
+ DoCast(m_creature->getVictim(),HeroicMode ? H_SPELL_WOE_STRIKE : SPELL_WOE_STRIKE);
+ else
+ DoCast(m_creature->getVictim(),SPELL_CLEAVE);
+ Cleave_Timer = rand()%5000 + 2000;
+
+ wait_Timer = 1000;
+ }
+ }else Cleave_Timer -= diff;
+
+ if(Smash_Timer < diff)
+ {
+ if(!wait_Timer)
+ {
+ if(undead)
+ DoCast(m_creature->getVictim(), SPELL_DARK_SMASH);
+ else
+ DoCast(m_creature->getVictim(),HeroicMode ? H_SPELL_SMASH : SPELL_SMASH);
+ Smash_Timer = 10000;
+
+ wait_Timer = 5000;
+ }
+ }else Smash_Timer -= diff;
+
+ if(!undead)
+ {
+ if(Enrage_Timer < diff)
+ {
+ DoCast(m_creature,HeroicMode ? H_SPELL_ENRAGE : SPELL_ENRAGE);
+ Enrage_Timer = 10000;
+ }else Enrage_Timer -= diff;
+ }else // In Undead form used to summon weapon
+ {
+ if(Enrage_Timer < diff)
+ {
+ if(!wait_Timer)
+ {
+ // Spawn target for Axe
+ Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 1);
+ if(target)
+ {
+ Creature* temp = m_creature->SummonCreature(ENTRY_THROW_TARGET,target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,2000);
+
+ DoCast(m_creature,SPELL_SHADOW_AXE_SUMMON);
+ }
+ Enrage_Timer = 30000;
+ }
+ }else Enrage_Timer -= diff;
+ }
+
+
+ if(Roar_Timer < diff)
+ {
+ if(!wait_Timer)
+ {
+ if(undead)
+ DoCast(m_creature,HeroicMode ? H_SPELL_DREADFUL_ROAR : SPELL_DREADFUL_ROAR);
+ else
+ DoCast(m_creature,HeroicMode ? H_SPELL_STAGGERING_ROAR : SPELL_STAGGERING_ROAR);
+ Roar_Timer = 10000;
+
+ wait_Timer = 5000;
+ }
+ }else Roar_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_ingvar_the_plunderer(Creature *_Creature)
+{
+ return new boss_ingvar_the_plundererAI (_Creature);
+}
+
+#define YELL_RESSURECT -1574025
+
+//Spells for Annhylde
+#define SPELL_SCOURG_RESURRECTION_HEAL 42704 //Heal Max + DummyAura
+#define SPELL_SCOURG_RESURRECTION_BEAM 42857 //Channeling Beam of Annhylde
+#define SPELL_SCOURG_RESURRECTION_DUMMY 42862 //Some Emote Dummy?
+#define SPELL_INGVAR_TRANSFORM 42796
+
+struct TRINITY_DLL_DECL mob_annhylde_the_callerAI : public ScriptedAI
+{
+ mob_annhylde_the_callerAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ }
+
+ float x,y,z;
+ ScriptedInstance* pInstance;
+ uint32 Resurect_Timer;
+ uint32 Resurect_Phase;
+
+ void Reset()
+ {
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_FLYING + MOVEMENTFLAG_FLYING2);
+ m_creature->SetSpeed(MOVE_SWIM , 0.1f);
+ m_creature->SetSpeed(MOVE_RUN , 0.1f);
+ m_creature->SetSpeed(MOVE_WALK , 0.1f);
+ m_creature->SetSpeed(MOVE_FLIGHT , 0.1f);
+
+ m_creature->GetPosition(x,y,z);
+ DoTeleportTo(x+1,y,z+30);
+
+ Unit* ingvar = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_INGVAR));
+ if(ingvar)
+ {
+ m_creature->GetMotionMaster()->MovePoint(1,x,y,z+15);
+
+ DoScriptText(YELL_RESSURECT,m_creature);
+ }
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if(type != POINT_MOTION_TYPE)
+ return;
+ Unit* ingvar = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_INGVAR));
+ if(ingvar)
+ {
+ switch (id)
+ {
+ case 1:
+ ingvar->RemoveAura(SPELL_SUMMON_BANSHEE);
+ ingvar->CastSpell(ingvar,SPELL_SCOURG_RESURRECTION_DUMMY,true);
+ DoCast(ingvar,SPELL_SCOURG_RESURRECTION_BEAM);
+ Resurect_Timer = 8000;
+ Resurect_Phase = 1;
+ break;
+ case 2:
+ m_creature->DealDamage(m_creature,m_creature->GetHealth());
+ m_creature->RemoveCorpse();
+ break;
+ }
+ }
+ }
+
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void EnterCombat(Unit *who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ if(Resurect_Timer)
+ if(Resurect_Timer < diff)
+ {
+ if(Resurect_Phase == 1)
+ {
+ Unit* ingvar = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_INGVAR));
+ if(ingvar)
+ {
+ ingvar->SetStandState(UNIT_STAND_STATE_STAND);
+ ingvar->CastSpell(ingvar,SPELL_SCOURG_RESURRECTION_HEAL,false);
+ }
+ Resurect_Timer = 3000;
+ Resurect_Phase = 2;
+ }else if (Resurect_Phase == 2)
+ {
+ Unit* ingvar = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_INGVAR));
+ if(ingvar)
+ {
+ ingvar->RemoveAurasDueToSpell(SPELL_SCOURG_RESURRECTION_DUMMY);
+ //ingvar->CastSpell(ingvar,SPELL_INGVAR_TRANSFORM,false);
+ ingvar->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_INGVAR_UNDEAD); // Visual Hack - when he dies he becomes human model -> wrong
+ Creature* c_ingvar = (Creature*)ingvar;
+
+ ((boss_ingvar_the_plundererAI*)(c_ingvar->AI()))->StartZombiePhase();
+
+ m_creature->GetMotionMaster()->MovePoint(2,x+1,y,z+30);
+ Resurect_Phase++;
+ }
+ }
+
+ }else Resurect_Timer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_annhylde_the_caller(Creature *_Creature)
+{
+ return new mob_annhylde_the_callerAI (_Creature);
+}
+
+#define SPELL_SHADOW_AXE_DAMAGE 42750
+#define H_SPELL_SHADOW_AXE_DAMAGE 59719
+
+struct TRINITY_DLL_DECL mob_ingvar_throw_dummyAI : public ScriptedAI
+{
+ mob_ingvar_throw_dummyAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ HeroicMode = c->GetMap()->IsHeroic();
+ }
+
+ bool HeroicMode;
+ uint32 Despawn_Timer;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ Unit* target = FindCreature(ENTRY_THROW_TARGET,50,m_creature);
+ if(target)
+ {
+ DoCast(m_creature, HeroicMode ? H_SPELL_SHADOW_AXE_DAMAGE : SPELL_SHADOW_AXE_DAMAGE);
+ float x,y,z;
+ target->GetPosition(x,y,z);
+ m_creature->GetMotionMaster()->MovePoint(0,x,y,z);
+ }
+ Despawn_Timer = 7000;
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void EnterCombat(Unit *who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ if(Despawn_Timer < diff)
+ {
+ m_creature->DealDamage(m_creature,m_creature->GetHealth());
+ m_creature->RemoveCorpse();
+ Despawn_Timer = 0;
+ }else Despawn_Timer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_ingvar_throw_dummy(Creature *_Creature)
+{
+ return new mob_ingvar_throw_dummyAI (_Creature);
+}
+
+void AddSC_boss_ingvar_the_plunderer()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_ingvar_the_plunderer";
+ newscript->GetAI = &GetAI_boss_ingvar_the_plunderer;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_annhylde_the_caller";
+ newscript->GetAI = &GetAI_mob_annhylde_the_caller;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_ingvar_throw_dummy";
+ newscript->GetAI = &GetAI_mob_ingvar_throw_dummy;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_keleseth.cpp b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_keleseth.cpp
new file mode 100644
index 00000000000..3ba7d16dd41
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_keleseth.cpp
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2009 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
+ */
+
+/* ScriptData
+SDName: Boss_Prince_Keleseth
+SD%Complete: 90
+SDComment: Needs Prince Movements, Needs adjustments to blizzlike timers, Needs Shadowbolt castbar, Needs right Ressurect Visual, Needs Some Heroic Spells
+SDCategory: Utgarde Keep
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_utgarde_keep.h"
+
+#define SPELL_SHADOWBOLT 43667
+#define SPELL_SHADOWBOLT_HEROIC 59389
+#define SPELL_FROST_TOMB 48400
+#define SPELL_FROST_TOMB_SUMMON 42714
+#define SPELL_DECREPIFY 42702
+#define SPELL_SCOURGE_RESSURRECTION 42704
+#define CREATURE_FROSTTOMB 23965
+#define CREATURE_SKELETON 23970
+
+#define SAY_AGGRO -1574000
+#define SAY_KILL -1574001
+#define SAY_DEATH -1574002
+#define SAY_FROST_TOMB -1574003
+#define SAY_SKELETONS -1574004
+
+#define SKELETONSPAWN_Z 42.8668
+
+float SkeletonSpawnPoint[5][5]=
+{
+ {156.2559, 259.2093},
+ {156.2559, 259.2093},
+ {156.2559, 259.2093},
+ {156.2559, 259.2093},
+ {156.2559, 259.2093},
+};
+
+float AttackLoc[3]={197.636, 194.046, 40.8164};
+
+struct TRINITY_DLL_DECL mob_frost_tombAI : public ScriptedAI
+{
+ mob_frost_tombAI(Creature *c) : ScriptedAI(c)
+ {
+ FrostTombGUID = 0;
+ }
+
+ uint64 FrostTombGUID;
+
+ void SetPrisoner(Unit* uPrisoner)
+ {
+ FrostTombGUID = uPrisoner->GetGUID();
+ }
+
+ void Reset(){ FrostTombGUID = 0; }
+ void EnterCombat(Unit* who) {}
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+
+ void JustDied(Unit *killer)
+ {
+ if(FrostTombGUID)
+ {
+ Unit* FrostTomb = Unit::GetUnit((*m_creature),FrostTombGUID);
+ if(FrostTomb)
+ FrostTomb->RemoveAurasDueToSpell(SPELL_FROST_TOMB);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ Unit* temp = Unit::GetUnit((*m_creature),FrostTombGUID);
+ if((temp && temp->isAlive() && !temp->HasAura(SPELL_FROST_TOMB)) || !temp )
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+};
+
+struct TRINITY_DLL_DECL boss_kelesethAI : public ScriptedAI
+{
+ boss_kelesethAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ Heroic = c->GetMap()->IsHeroic();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 FrostTombTimer;
+ uint32 SummonSkeletonsTimer;
+ uint32 RespawnSkeletonsTimer;
+ uint32 ShadowboltTimer;
+ uint64 SkeletonGUID[5];
+ bool Skeletons;
+ bool Heroic;
+ bool RespawnSkeletons;
+
+ void Reset()
+ {
+ ShadowboltTimer = 0;
+ Skeletons = false;
+
+ ResetTimer();
+
+ if(pInstance)
+ pInstance->SetData(DATA_PRINCEKELESETH_EVENT, NOT_STARTED);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+
+ DoScriptText(SAY_KILL, m_creature);
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+
+ if(pInstance)
+ pInstance->SetData(DATA_PRINCEKELESETH_EVENT, DONE);
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ DoZoneInCombat();
+
+ if(pInstance)
+ pInstance->SetData(DATA_PRINCEKELESETH_EVENT, IN_PROGRESS);
+ }
+
+ void ResetTimer(uint32 inc = 0)
+ {
+ SummonSkeletonsTimer = 5000 + inc;
+ FrostTombTimer = 28000 + inc;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if(ShadowboltTimer < diff)
+ {
+ Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0);
+ if(target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER)
+ m_creature->CastSpell(target, Heroic ? SPELL_SHADOWBOLT_HEROIC : SPELL_SHADOWBOLT, true);
+ ShadowboltTimer = 10000;
+ }else ShadowboltTimer -= diff;
+
+ if(!Skeletons)
+ if((SummonSkeletonsTimer < diff))
+ {
+ Creature* Skeleton;
+ DoScriptText(SAY_SKELETONS, m_creature);
+ for(uint8 i = 0; i < 5; ++i)
+ {
+ Skeleton = m_creature->SummonCreature(CREATURE_SKELETON, SkeletonSpawnPoint[i][0], SkeletonSpawnPoint[i][1] , SKELETONSPAWN_Z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN,20000);
+ if(Skeleton)
+ {
+ Skeleton->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ Skeleton->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(), m_creature->GetPositionY() , m_creature->GetPositionZ());
+ Skeleton->AddThreat(m_creature->getVictim(), 0.0f);
+ DoZoneInCombat(Skeleton);
+ }
+ }
+ Skeletons = true;
+ }else SummonSkeletonsTimer -= diff;
+
+ if(FrostTombTimer < diff)
+ {
+ Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
+ if(target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER)
+ {
+ //DoCast(target, SPELL_FROST_TOMB_SUMMON, true);
+ Creature* Chains = m_creature->SummonCreature(CREATURE_FROSTTOMB, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 20000);
+ if(Chains)
+ {
+ ((mob_frost_tombAI*)Chains->AI())->SetPrisoner(target);
+ Chains->CastSpell(target, SPELL_FROST_TOMB, true);
+
+ DoScriptText(SAY_FROST_TOMB, m_creature);
+ }
+ }
+ FrostTombTimer = 15000;
+ }else FrostTombTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct TRINITY_DLL_DECL mob_vrykul_skeletonAI : public ScriptedAI
+{
+ mob_vrykul_skeletonAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ }
+
+ ScriptedInstance *pInstance;
+ uint32 Respawn_Time;
+ uint64 Target_Guid;
+ uint32 Decrepify_Timer;
+
+ bool isDead;
+
+ void Reset()
+ {
+ Respawn_Time = 12000;
+ Decrepify_Timer = 10000 + rand()%20000;
+ isDead = false;
+ }
+
+ void EnterCombat(Unit *who){}
+ void DamageTaken(Unit *done_by, uint32 &damage)
+ {
+ if(done_by->GetGUID() == m_creature->GetGUID())
+ return;
+
+ if(damage >= m_creature->GetHealth())
+ {
+ PretendToDie();
+ damage = 0;
+ }
+ }
+
+
+ void PretendToDie()
+ {
+ isDead = true;
+ m_creature->InterruptNonMeleeSpells(true);
+ m_creature->RemoveAllAuras();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MoveIdle();
+ m_creature->SetStandState(UNIT_STAND_STATE_DEAD);
+ };
+
+ void Resurrect()
+ {
+ isDead = false;
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ m_creature->CastSpell(m_creature,SPELL_SCOURGE_RESSURRECTION,true);
+
+ if(m_creature->getVictim())
+ {
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ m_creature->AI()->AttackStart(m_creature->getVictim());
+ }
+ else
+ m_creature->GetMotionMaster()->Initialize();
+ };
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(pInstance->GetData(DATA_PRINCEKELESETH_EVENT) == IN_PROGRESS)
+ {
+ if(isDead)
+ {
+ if(Respawn_Time < diff)
+ {
+ Resurrect();
+ Respawn_Time = 12000;
+ }else Respawn_Time -= diff;
+ }
+ else
+ {
+ if(!UpdateVictim())
+ return;
+
+ if(Decrepify_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(),SPELL_DECREPIFY);
+ Decrepify_Timer = 30000;
+ }else Decrepify_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+ }else
+ {
+ if(m_creature->isAlive())
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+
+ }
+};
+
+CreatureAI* GetAI_mob_frost_tomb(Creature *_Creature)
+{
+ return new mob_frost_tombAI(_Creature);
+}
+
+CreatureAI* GetAI_boss_keleseth(Creature *_Creature)
+{
+ return new boss_kelesethAI (_Creature);
+}
+
+CreatureAI* GetAI_mob_vrykul_skeleton(Creature *_Creature)
+{
+ return new mob_vrykul_skeletonAI (_Creature);
+}
+
+void AddSC_boss_keleseth()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_keleseth";
+ newscript->GetAI = &GetAI_boss_keleseth;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_frost_tomb";
+ newscript->GetAI = &GetAI_mob_frost_tomb;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_vrykul_skeleton";
+ newscript->GetAI = &GetAI_mob_vrykul_skeleton;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_skarvald.cpp b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_skarvald.cpp
new file mode 100644
index 00000000000..1fc9bc1c995
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_skarvald.cpp
@@ -0,0 +1,96 @@
+/* Script Data Start
+SDName: Boss skarvald
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_skarvald' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_CHARGE 43651 //randomly charges anyone but tank WoWradio video 14s afer aggro, and then every 5s change target
+#define SPELL_ENRAGE 48193
+#define SPELL_STONE_STRIKE 48583
+#define SPELL_DALRON_GHOST 48612 //When Dalron dies
+
+//Yells
+#define SAY_AGGRO -1574010
+#define SAY_KILL -1574011
+#define SAY_DEATH_1 -1574012
+#define SAY_DEATH_2 -1574013
+#define SAY_RAISES -1574014
+
+struct TRINITY_DLL_DECL boss_skarvaldAI : public ScriptedAI
+{
+ boss_skarvaldAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 kiled;
+ uint64 Dalronn;
+
+ void Reset()
+ {
+ Dalronn = 0;
+ }
+ void Aggro(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ if (Dalronn)
+ {
+ Creature* Dalronn_m = (Unit::GetCreature((*m_creature), Dalronn));
+ if (Dalronn_m)
+ {
+ if (!Dalronn_m->isAlive())
+ {
+ DoCast(Dalronn_m,SPELL_DALRON_GHOST);
+ DoScriptText(SAY_RAISES, m_creature);
+ }
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ kiled++;
+ //On first death resurected instatly by Dalron as a ghost, having the same abilities as when alive and is unatackable
+ //If Dalron dies first, Skarvald resurects him and says "SAY_RAISES"
+ if(kiled ==2)
+ DoScriptText(SAY_DEATH_2,m_creature);
+ else
+ DoScriptText(SAY_DEATH_1,m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ DoScriptText(SAY_KILL, m_creature);
+ }
+};
+
+CreatureAI* GetAI_boss_skarvald(Creature *_Creature)
+{
+ return new boss_skarvaldAI (_Creature);
+}
+
+void AddSC_boss_skarvald()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_skarvald";
+ newscript->GetAI = GetAI_boss_skarvald;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_skarvald_dalronn.cpp b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_skarvald_dalronn.cpp
new file mode 100644
index 00000000000..40b365736cf
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_skarvald_dalronn.cpp
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2009 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
+ */
+
+/* ScriptData
+SDName: Boss_Skarvald_Dalronn
+SD%Complete: 95
+SDComment: Needs adjustments to blizzlike timers, Yell Text + Sound to DB
+SDCategory: Utgarde Keep
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_utgarde_keep.h"
+
+#define YELL_SKARVALD_AGGRO -1574010
+#define YELL_DALRONN_AGGRO -1574005
+
+#define YELL_SKARVALD_KILL -1574011
+#define YELL_DALRONN_KILL -1574006
+
+#define YELL_DALRONN_DAL_DIEDFIRST -1574007
+#define YELL_SKARVALD_DAL_DIEDFIRST -1574014
+#define YELL_SKARVALD_DAL_DIED -1574013
+
+#define YELL_SKARVALD_SKA_DIEDFIRST -1574012
+#define YELL_DALRONN_SKA_DIEDFIRST -1574009
+#define YELL_DALRONN_SKA_DIED -1574008
+
+//Spells of Skarvald and his Ghost
+#define MOB_SKARVALD_THE_CONSTRUCTOR 24200
+#define SPELL_CHARGE 43651
+#define SPELL_STONE_STRIKE 48583
+#define SPELL_SUMMON_SKARVALD_GHOST 48613
+#define MOB_SKARVALD_GHOST 27390
+//Spells of Dalronn and his Ghost
+#define MOB_DALRONN_THE_CONTROLLER 24201
+#define SPELL_SHADOW_BOLT 43649
+#define H_SPELL_SHADOW_BOLT 59575
+#define H_SPELL_SUMMON_SKELETONS 52611
+#define SPELL_DEBILITATE 43650
+#define SPELL_SUMMON_DALRONN_GHOST 48612
+#define MOB_DALRONN_GHOST 27389
+
+struct TRINITY_DLL_DECL boss_skarvald_the_constructorAI : public ScriptedAI
+{
+ boss_skarvald_the_constructorAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ HeroicMode = m_creature->GetMap()->IsHeroic();
+ }
+
+ ScriptedInstance* pInstance;
+
+ bool ghost;
+ bool HeroicMode;
+ uint32 Charge_Timer;
+ uint32 StoneStrike_Timer;
+ uint32 Response_Timer;
+ uint32 Check_Timer;
+ bool Dalronn_isDead;
+
+ void Reset()
+ {
+ Charge_Timer = 5000;
+ StoneStrike_Timer = 10000;
+ Dalronn_isDead = false;
+ Check_Timer = 5000;
+
+ ghost = (m_creature->GetEntry() == MOB_SKARVALD_GHOST);
+ if(!ghost)
+ {
+ Unit* dalronn = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_DALRONN));
+ if(dalronn && dalronn->isDead())
+ ((Creature*)dalronn)->Respawn();
+
+ if(pInstance)
+ pInstance->SetData(DATA_SKARVALD_DALRONN_EVENT, NOT_STARTED);
+ }
+ }
+
+ void EnterCombat(Unit *who)
+ {
+ if(!ghost)
+ {
+ DoScriptText(YELL_SKARVALD_AGGRO,m_creature);
+
+ Unit* dalronn = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_DALRONN));
+ if(dalronn && dalronn->isAlive() && !dalronn->getVictim())
+ dalronn->getThreatManager().addThreat(who,0.0f);
+
+ if(pInstance)
+ pInstance->SetData(DATA_SKARVALD_DALRONN_EVENT, IN_PROGRESS);
+ }
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ if(!ghost)
+ {
+ Unit* dalronn = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_DALRONN));
+ if(dalronn)
+ {
+ if(dalronn->isDead())
+ {
+ DoScriptText(YELL_SKARVALD_DAL_DIED,m_creature);
+
+ if(pInstance)
+ pInstance->SetData(DATA_SKARVALD_DALRONN_EVENT, DONE);
+ }
+ else
+ {
+ DoScriptText(YELL_SKARVALD_SKA_DIEDFIRST,m_creature);
+
+ m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ //DoCast(m_creature,SPELL_SUMMON_SKARVALD_GHOST,true);
+ Creature* temp = m_creature->SummonCreature(MOB_SKARVALD_GHOST,m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ(),0,TEMPSUMMON_CORPSE_DESPAWN,5000);
+ temp->AI()->AttackStart(Killer);
+ }
+ }
+ }
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ if(!ghost)
+ {
+ DoScriptText(YELL_SKARVALD_KILL,m_creature);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(ghost)
+ {
+ if(pInstance->GetData(DATA_SKARVALD_DALRONN_EVENT) != IN_PROGRESS)
+ {
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ }
+
+ if(!UpdateVictim())
+ return;
+
+ if(!ghost)
+ {
+ if(Check_Timer)
+ if(Check_Timer < diff)
+ {
+ Check_Timer = 5000;
+ Unit* dalronn = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_DALRONN));
+ if(dalronn && dalronn->isDead())
+ {
+ Dalronn_isDead = true;
+ Response_Timer = 2000;
+ Check_Timer = 0;
+ }
+ }else Check_Timer -= diff;
+
+ if(Response_Timer)
+ if(Dalronn_isDead)
+ if(Response_Timer < diff)
+ {
+ DoScriptText(YELL_SKARVALD_DAL_DIEDFIRST,m_creature);
+
+ Response_Timer = 0;
+ }else Response_Timer -= diff;
+ }
+
+ if(Charge_Timer < diff)
+ {
+ DoCast(SelectUnit(SELECT_TARGET_RANDOM, 1), SPELL_CHARGE);
+ Charge_Timer = 5000+rand()%5000;
+ }else Charge_Timer -= diff;
+
+ if(StoneStrike_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_STONE_STRIKE);
+ StoneStrike_Timer = 5000+rand()%5000;
+ }else StoneStrike_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_skarvald_the_constructor(Creature *_Creature)
+{
+ return new boss_skarvald_the_constructorAI (_Creature);
+}
+
+struct TRINITY_DLL_DECL boss_dalronn_the_controllerAI : public ScriptedAI
+{
+ boss_dalronn_the_controllerAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ HeroicMode = m_creature->GetMap()->IsHeroic();
+ }
+
+ ScriptedInstance* pInstance;
+
+ bool ghost;
+ bool HeroicMode;
+ uint32 ShadowBolt_Timer;
+ uint32 Debilitate_Timer;
+ uint32 Summon_Timer;
+
+ uint32 Response_Timer;
+ uint32 Check_Timer;
+ uint32 AggroYell_Timer;
+ bool Skarvald_isDead;
+
+
+ void Reset()
+ {
+ ShadowBolt_Timer = 1000;
+ Debilitate_Timer = 5000;
+ Summon_Timer = 10000;
+ Check_Timer = 5000;
+ Skarvald_isDead = false;
+ AggroYell_Timer = 0;
+
+ ghost = m_creature->GetEntry() == MOB_DALRONN_GHOST;
+ if(!ghost)
+ {
+ Unit* skarvald = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_SKARVALD));
+ if(skarvald && skarvald->isDead())
+ ((Creature*)skarvald)->Respawn();
+
+ if(pInstance)
+ pInstance->SetData(DATA_SKARVALD_DALRONN_EVENT, NOT_STARTED);
+ }
+ }
+
+ void EnterCombat(Unit *who)
+ {
+ if(!ghost)
+ {
+ Unit* skarvald = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_SKARVALD));
+ if(skarvald && skarvald->isAlive() && !skarvald->getVictim())
+ skarvald->getThreatManager().addThreat(who,0.0f);
+
+ AggroYell_Timer = 5000;
+
+ if(pInstance)
+ pInstance->SetData(DATA_SKARVALD_DALRONN_EVENT, IN_PROGRESS);
+ }
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ if(!ghost)
+ {
+ Unit* skarvald = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_SKARVALD));
+ if(skarvald)
+ if(skarvald->isDead())
+ {
+ DoScriptText(YELL_DALRONN_SKA_DIED,m_creature);
+
+ if(pInstance)
+ pInstance->SetData(DATA_SKARVALD_DALRONN_EVENT, DONE);
+ }
+ else
+ {
+ DoScriptText(YELL_DALRONN_DAL_DIEDFIRST,m_creature);
+
+ m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ //DoCast(m_creature,SPELL_SUMMON_DALRONN_GHOST,true);
+ Creature* temp = m_creature->SummonCreature(MOB_DALRONN_GHOST,m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ(),0,TEMPSUMMON_CORPSE_DESPAWN,5000);
+ temp->AI()->AttackStart(Killer);
+ }
+ }
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ if(!ghost)
+ {
+ DoScriptText(YELL_DALRONN_KILL,m_creature);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(ghost)
+ {
+ if(pInstance->GetData(DATA_SKARVALD_DALRONN_EVENT) != IN_PROGRESS)
+ {
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ }
+
+ if(!UpdateVictim())
+ return;
+
+ if(AggroYell_Timer)
+ if(AggroYell_Timer < diff)
+ {
+ DoScriptText(YELL_DALRONN_AGGRO,m_creature);
+
+ AggroYell_Timer = 0;
+ }else AggroYell_Timer -= diff;
+
+ if(!ghost)
+ {
+ if(Check_Timer)
+ if(Check_Timer < diff)
+ {
+ Check_Timer = 5000;
+ Unit* skarvald = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_SKARVALD));
+ if(skarvald && skarvald->isDead())
+ {
+ Skarvald_isDead = true;
+ Response_Timer = 2000;
+ Check_Timer = 0;
+ }
+ }else Check_Timer -= diff;
+
+ if(Response_Timer)
+ if(Skarvald_isDead)
+ if(Response_Timer < diff)
+ {
+ DoScriptText(YELL_DALRONN_SKA_DIEDFIRST,m_creature);
+
+ Response_Timer = 0;
+ }else Response_Timer -= diff;
+ }
+
+ if(ShadowBolt_Timer < diff)
+ {
+ if (!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0),HeroicMode ? H_SPELL_SHADOW_BOLT : SPELL_SHADOW_BOLT);
+ ShadowBolt_Timer = 1000;
+ }
+ }else ShadowBolt_Timer -= diff;
+
+ if(Debilitate_Timer < diff)
+ {
+ if (!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0),SPELL_DEBILITATE);
+ Debilitate_Timer = 5000+rand()%5000;
+ }
+ }else Debilitate_Timer -= diff;
+
+ if(HeroicMode)
+ if(Summon_Timer < diff)
+ {
+ DoCast(m_creature,H_SPELL_SUMMON_SKELETONS);
+ Summon_Timer = (rand()%10000) + 20000;
+ }else Summon_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_dalronn_the_controller(Creature *_Creature)
+{
+ return new boss_dalronn_the_controllerAI (_Creature);
+}
+
+void AddSC_boss_skarvald_dalronn()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_skarvald_the_constructor";
+ newscript->GetAI = &GetAI_boss_skarvald_the_constructor;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="boss_dalronn_the_controller";
+ newscript->GetAI = &GetAI_boss_dalronn_the_controller;
+ newscript->RegisterSelf();
+} \ No newline at end of file
diff --git a/src/shared/Database/DatabaseSqlite.h b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/def_utgarde_keep.h
index 32d49d0124b..ec416e5729a 100644
--- a/src/shared/Database/DatabaseSqlite.h
+++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/def_utgarde_keep.h
@@ -1,7 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
- *
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2009 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
@@ -18,29 +16,16 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef DO_POSTGRESQL
-
-#ifndef _DATABASESQLITE_H
-#define _DATABASESQLITE_H
-
-#include <sqlite/sqlite.h>
-
-class DatabaseSqlite : public Database
-{
- public:
- DatabaseSqlite();
- ~DatabaseSqlite();
+#ifndef DEF_UTGARDE_KEEP_H
+#define DEF_UTGARDE_KEEP_H
- bool Initialize(const char *infoString);
+#define DATA_PRINCEKELESETH 1
+#define DATA_SKARVALD 3
+#define DATA_DALRONN 4
+#define DATA_INGVAR 6
- QueryResult* Query(const char *sql);
- bool Execute(const char *sql);
+#define DATA_PRINCEKELESETH_EVENT 2
+#define DATA_SKARVALD_DALRONN_EVENT 5
+#define DATA_INGVAR_EVENT 7
- operator bool () const { return mSqlite != NULL; }
-
- private:
- sqlite *mSqlite;
-};
-#endif
#endif
-
diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp
new file mode 100644
index 00000000000..d1cf7ad33bc
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2009 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
+ */
+
+/* ScriptData
+SDName: Instance_Utgarde_Keep
+SD%Complete: 90
+SDComment: Instance Data Scripts and functions to acquire mobs and set encounter status for use in various Utgarde Keep Scripts
+SDCategory: Utgarde Keep
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_utgarde_keep.h"
+
+#define ENCOUNTERS 3
+
+/* Utgarde Keep encounters:
+0 - Prince Keleseth
+1 - Skarvald Dalronn
+2 - Ingvar the Plunderer
+*/
+
+struct TRINITY_DLL_DECL instance_utgarde_keep : public ScriptedInstance
+{
+ instance_utgarde_keep(Map *Map) : ScriptedInstance(Map) {Initialize();};
+
+ uint64 Keleseth;
+ uint64 Skarvald;
+ uint64 Dalronn;
+ uint64 Ingvar;
+
+ uint32 Encounters[ENCOUNTERS];
+ std::string str_data;
+
+ void Initialize()
+ {
+ Keleseth = 0;
+ Skarvald = 0;
+ Dalronn =0;
+ Ingvar =0;
+
+ for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ Encounters[i] = NOT_STARTED;
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ if(Encounters[i] == IN_PROGRESS) return true;
+
+ return false;
+ }
+
+ Player* GetPlayerInMap()
+ {
+ Map::PlayerList const& players = instance->GetPlayers();
+
+ if (!players.isEmpty())
+ {
+ for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ {
+ if (Player* plr = itr->getSource())
+ return plr;
+ }
+ }
+
+ debug_log("TSCR: Instance Utgarde Keep: GetPlayerInMap, but PlayerList is empty!");
+ return NULL;
+ }
+
+ void OnCreatureCreate(Creature *creature, uint32 creature_entry)
+ {
+ switch(creature_entry)
+ {
+ case 23953: Keleseth = creature->GetGUID(); break;
+ case 24201: Dalronn = creature->GetGUID(); break;
+ case 24200: Skarvald = creature->GetGUID(); break;
+ case 23954: Ingvar = creature->GetGUID(); break;
+ }
+ }
+
+ void OnObjectCreate(GameObject* go)
+ {
+ //switch(go->GetEntry())
+ //{
+ //door and object id
+ //}
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_PRINCEKELESETH: return Keleseth;
+ case DATA_DALRONN: return Dalronn;
+ case DATA_SKARVALD: return Skarvald;
+ case DATA_INGVAR: return Ingvar;
+ }
+
+ return 0;
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_PRINCEKELESETH_EVENT:
+ if(data == DONE)
+ {
+ //HandleGameObject(doorname, 0);
+ }
+ Encounters[0] = data;break;
+ case DATA_SKARVALD_DALRONN_EVENT:
+ if(data == DONE)
+ {
+ //HandleGameObject(doorname, 0);
+ }
+ Encounters[1] = data; break;
+ case DATA_INGVAR_EVENT:
+ if(data == DONE)
+ {
+ //HandleGameObject(doorname, 0);
+ }
+ Encounters[2] = data; break;
+ }
+
+ if (data == DONE)
+ {
+ SaveToDB();
+ }
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_PRINCEKELESETH_EVENT: return Encounters[0];
+ case DATA_SKARVALD_DALRONN_EVENT: return Encounters[1];
+ case DATA_INGVAR_EVENT: return Encounters[2];
+ }
+
+ return 0;
+ }
+
+ const char* Save()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "U K " << Encounters[0] << " " << Encounters[1] << " "
+ << Encounters[2];
+
+ str_data = saveStream.str();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return str_data.c_str();
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0,data1,data2;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2;
+
+ if( dataHead1 == 'U' && dataHead2 == 'K')
+ {
+ Encounters[0] = data0;
+ Encounters[1] = data1;
+ Encounters[2] = data2;
+
+ for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ if (Encounters[i] == IN_PROGRESS)
+ Encounters[i] = NOT_STARTED;
+
+ }else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_utgarde_keep(Map* map)
+{
+ return new instance_utgarde_keep(map);
+}
+
+void AddSC_instance_utgarde_keep()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_utgarde_keep";
+ newscript->GetInstanceData = &GetInstanceData_instance_utgarde_keep;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp
new file mode 100644
index 00000000000..16d8c33d889
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp
@@ -0,0 +1,78 @@
+/* Script Data Start
+SDName: Boss palehoof
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_palehoof' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_ARCING_SMASH 48260
+#define SPELL_IMPALE 48261
+#define SPELL_WITHERING_ROAR 48256
+
+//Yell
+#define SAY_AGGRO -1575000
+#define SAY_SLAY_1 -1575001
+#define SAY_SLAY_2 -1575002
+#define SAY_DEATH -1575003
+
+struct TRINITY_DLL_DECL boss_palehoofAI : public ScriptedAI
+{
+ boss_palehoofAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ switch(rand()%2)
+ {
+ case 0:
+ DoScriptText(SAY_SLAY_1, m_creature);
+ break;
+ case 1:
+ DoScriptText(SAY_SLAY_2, m_creature);
+ break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_palehoof(Creature *_Creature)
+{
+ return new boss_palehoofAI (_Creature);
+}
+
+void AddSC_boss_palehoof()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_palehoof";
+ newscript->GetAI = GetAI_boss_palehoof;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp
new file mode 100644
index 00000000000..ee6208ce65c
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp
@@ -0,0 +1,89 @@
+/* Script Data Start
+SDName: Boss skadi
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_skadi' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Phase 0 "gauntlet even" Skadi on a flying mount, waves of adds charging to the group periodicaly carrying harpoons
+//Phase 1 Kill the Skadi drake mount with harppons launcher
+//Phase 2 Kill the Skadi
+
+//Skadi Spells
+#define SPELL_CRUSH 50234
+#define SPELL_POISONED_SPEAR 50225
+#define SPELL_WHIRLWIND 50228 //random target, but not the tank approx. every 20s
+
+//Yell
+#define SAY_AGGRO -1575004
+#define SAY_KILL_1 -1575005
+#define SAY_KILL_2 -1575006
+#define SAY_KILL_3 -1575007
+#define SAY_DEATH -1575008
+#define SAY_DRAKE_DEATH -1575009
+#define SAY_DRAKE_HIT_1 -1575010
+#define SAY_DRAKE_HIT_2 -1575011
+#define SAY_DRAKE_BREATH_1 -1575012
+#define SAY_DRAKE_BREATH_2 -1575013
+#define SAY_DRAKE_BREATH_3 -1575014
+
+struct TRINITY_DLL_DECL boss_skadiAI : public ScriptedAI
+{
+ boss_skadiAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 phase;
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ phase = 0;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_KILL_1, m_creature);break;
+ case 1: DoScriptText(SAY_KILL_2, m_creature);break;
+ case 2: DoScriptText(SAY_KILL_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_skadi(Creature *_Creature)
+{
+ return new boss_skadiAI (_Creature);
+}
+
+void AddSC_boss_skadi()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_skadi";
+ newscript->GetAI = GetAI_boss_skadi;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/boss_svala.cpp b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/boss_svala.cpp
new file mode 100644
index 00000000000..39306430a29
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/boss_svala.cpp
@@ -0,0 +1,83 @@
+/* Script Data Start
+SDName: Boss svala
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_svala' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_CALL_FLAMES 48258
+#define SPELL_RITUAL_OF_THE_SWORD 48276 //Effect #1 Teleport, Effect #2 Dummy
+#define SPELL_SINSTER_STRIKE 15667
+
+//Yells
+#define SAY_DIALOG_WITH_ARTHAS_1 -1575015
+#define SAY_DIALOG_WITH_ARTHAS_2 -1575016
+#define SAY_DIALOG_WITH_ARTHAS_3 -1575017
+#define SAY_AGGRO -1575018
+#define SAY_SLAY_1 -1575019
+#define SAY_SLAY_2 -1575020
+#define SAY_SLAY_3 -1575021
+#define SAY_DEATH -1575022
+#define SAY_SACRIFICE_PLAYER_1 -1575023
+#define SAY_SACRIFICE_PLAYER_2 -1575024
+#define SAY_SACRIFICE_PLAYER_3 -1575025
+#define SAY_SACRIFICE_PLAYER_4 -1575026
+#define SAY_SACRIFICE_PLAYER_5 -1575027
+
+struct TRINITY_DLL_DECL boss_svalaAI : public ScriptedAI
+{
+ boss_svalaAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_svala(Creature *_Creature)
+{
+ return new boss_svalaAI (_Creature);
+}
+
+void AddSC_boss_svala()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_svala";
+ newscript->GetAI = GetAI_boss_svala;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp
new file mode 100644
index 00000000000..ff1c5390659
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp
@@ -0,0 +1,85 @@
+/* Script Data Start
+SDName: Boss ymiron
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_ymiron' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_BANE 48294
+#define SPELL_DARK_SLASH 48292
+#define SPELL_FETID_ROT 48291
+#define SPELL_SCREAMS_OF_THE_DEAD 51750
+#define SPELL_SPIRIT_BURST 48529
+#define SPELL_SPIRIT_STRIKE 48423
+//every 20% stuns the party and runs to a boat
+
+//Yell
+#define SAY_AGGRO -1575028
+#define SAY_SLAY_1 -1575029
+#define SAY_SLAY_2 -1575030
+#define SAY_SLAY_3 -1575031
+#define SAY_SLAY_4 -1575032
+#define SAY_DEATH -1575033
+#define SAY_SUMMON_BJORN -1575034
+#define SAY_SUMMON_HALDOR -1575035
+#define SAY_SUMMON_RANULF -1575036
+#define SAY_SUMMON_TORGYN -1575037
+
+struct TRINITY_DLL_DECL boss_ymironAI : public ScriptedAI
+{
+ boss_ymironAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%4)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ case 3: DoScriptText(SAY_SLAY_4, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_ymiron(Creature *_Creature)
+{
+ return new boss_ymironAI (_Creature);
+}
+
+void AddSC_boss_ymiron()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_ymiron";
+ newscript->GetAI = GetAI_boss_ymiron;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/def_pinnacle.h b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/def_pinnacle.h
new file mode 100644
index 00000000000..82e2173fab5
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/def_pinnacle.h
@@ -0,0 +1,4 @@
+#ifndef DEF_PINNACLE_H
+#define DEF_PINNACLE_H
+
+#endif
diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp
new file mode 100644
index 00000000000..0772aee0647
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp
@@ -0,0 +1,21 @@
+#include "precompiled.h"
+#include "def_pinnacle.h"
+
+struct TRINITY_DLL_DECL instance_pinnacle : public ScriptedInstance
+{
+ instance_pinnacle(Map *Map) : ScriptedInstance(Map) {Initialize();};
+};
+
+InstanceData* GetInstanceData_instance_pinnacle(Map* map)
+{
+ return new instance_pinnacle(map);
+}
+
+void AddSC_instance_pinnacle()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_pinnacle";
+ newscript->GetInstanceData = GetInstanceData_instance_pinnacle;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_archavon.cpp b/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_archavon.cpp
new file mode 100644
index 00000000000..824ab27259e
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_archavon.cpp
@@ -0,0 +1,93 @@
+/* Script Data Start
+SDName: Boss archavon
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells Archavon
+#define SPELL_ROCK_SHARDS 60883 //Instant -- Hurls a jagged rock shard, inflicting 707 to 793 Physical damage to any enemies within 5 of the target.
+#define SPELL_CRUSHING_LEAP 60895 //Instant (10-80yr range) -- Leaps at an enemy, inflicting 8000 Physical damage, knocking all nearby enemies away, and creating a cloud of choking debris.
+#define SPELL_CHOKING_CLOUD 61672 //Leaving behind CRUSHING_LEAP --> Slams into the ground, kicking up an asphyxiating cloud of debris, inflicting 2828 to 3172 Nature damage per second to all enemies caught within and reducing their chance to hit by 50%.
+//#define SPELL_STOMP //48131 or 55292 or 60880
+#define SPELL_IMPALE 60882 //Lifts an enemy off the ground with a spiked fist, inflicting 47125 to 52875 Physical damage and 9425 to 10575 additional damage each second for 8 sec.
+
+//Spells Archavon Warders
+#define SPELL_ROCK_SHOWER_N 60919
+#define SPELL_ROCK_SHOWER_H 60923
+#define SPELL_SHIELD_CRUSH_N 60897
+#define SPELL_SHIELD_CRUSH_H 60899
+#define SPELL_WHIRL_N 60902
+#define SPELL_WHIRL_H 60916
+
+//4 Warders spawned
+#define ARCHAVON_WARDER 32353 //npc 32353
+
+//Yell
+#define SAY_LEAP "Archavon the Stone Watcher lunges for $N!" //$N should be the target
+
+struct TRINITY_DLL_DECL boss_archavonAI : public ScriptedAI
+{
+ boss_archavonAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+/*######
+## Mob Archavon Warder
+######*/
+struct TRINITY_DLL_DECL mob_warderAI : public ScriptedAI //npc 32353
+{
+ mob_warderAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_warder(Creature *_Creature)
+{
+ return new mob_warderAI (_Creature);
+}
+
+CreatureAI* GetAI_boss_archavon(Creature *_Creature)
+{
+ return new boss_archavonAI (_Creature);
+}
+
+void AddSC_boss_archavon()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_archavon";
+ newscript->GetAI = GetAI_boss_archavon;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_archavon_warder";
+ newscript->GetAI = GetAI_mob_warder;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/vault_of_archavon/def_vault_of_archavon.h b/src/bindings/scripts/scripts/zone/vault_of_archavon/def_vault_of_archavon.h
new file mode 100644
index 00000000000..f46ba447945
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/vault_of_archavon/def_vault_of_archavon.h
@@ -0,0 +1,4 @@
+#ifndef DEF_ARCHAVON_H
+#define DEF_ARCHAVON_H
+
+#endif
diff --git a/src/bindings/scripts/scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp b/src/bindings/scripts/scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp
new file mode 100644
index 00000000000..94ee36212ec
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp
@@ -0,0 +1,21 @@
+#include "precompiled.h"
+#include "def_vault_of_archavon.h"
+
+struct TRINITY_DLL_DECL instance_archavon : public ScriptedInstance
+{
+ instance_archavon(Map *Map) : ScriptedInstance(Map) {Initialize();};
+};
+
+InstanceData* GetInstanceData_instance_archavon(Map* map)
+{
+ return new instance_archavon(map);
+}
+
+void AddSC_instance_archavon()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_archavon";
+ newscript->GetInstanceData = GetInstanceData_instance_archavon;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/violet_hold/boss_cyanigosa.cpp b/src/bindings/scripts/scripts/zone/violet_hold/boss_cyanigosa.cpp
new file mode 100644
index 00000000000..c3a7dd550f5
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/violet_hold/boss_cyanigosa.cpp
@@ -0,0 +1,82 @@
+/* Script Data Start
+SDName: Boss cyanigosa
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_ARCANE_VACUM 58694
+#define SPELL_BLIZZARD 58693
+#define SPELL_MANA_DESTRUCTION 59374
+#define SPELL_TAIL_SWEEP 58690
+#define SPELL_UNCONTROLLABLE_ENERGY 58688
+
+//Yells
+#define SAY_AGGRO -1608000
+#define SAY_SLAY_1 -1608001
+#define SAY_SLAY_2 -1608002
+#define SAY_SLAY_3 -1608003
+#define SAY_DEATH -1608004
+#define SAY_SPAWN -1608005
+#define SAY_DISRUPTION -1608006
+#define SAY_BREATH_ATTACK -1608007
+#define SAY_SPECIAL_ATTACK_1 -1608008
+#define SAY_SPECIAL_ATTACK_2 -1608009
+
+struct TRINITY_DLL_DECL boss_cyanigosaAI : public ScriptedAI
+{
+ boss_cyanigosaAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_cyanigosa(Creature *_Creature)
+{
+ return new boss_cyanigosaAI (_Creature);
+}
+
+void AddSC_boss_cyanigosa()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_cyanigosa";
+ newscript->GetAI = GetAI_boss_cyanigosa;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/violet_hold/boss_erekem.cpp b/src/bindings/scripts/scripts/zone/violet_hold/boss_erekem.cpp
new file mode 100644
index 00000000000..46b88666e6f
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/violet_hold/boss_erekem.cpp
@@ -0,0 +1,82 @@
+/* Script Data Start
+SDName: Boss erekem
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_BLOODLUST 54516
+#define SPELL_BREAK_BONDS 59463
+#define SPELL_CHAIN_HEAL 54481
+#define SPELL_EARTH_SHIELD 54479
+#define SPELL_EARTH_SHOCK 54511
+#define SPELL_LIGHTNING_BOLT 53044
+#define SPELL_STORMSTRIKE 51876
+
+//Yells
+#define SAY_AGGRO -1608010
+#define SAY_SLAY_1 -1608011
+#define SAY_SLAY_2 -1608012
+#define SAY_SLAY_3 -1608013
+#define SAY_DEATH -1608014
+#define SAY_SPAWN -1608015
+#define SAY_ADD_KILED -1608016
+#define SAY_BOTH_ADDS_KILED -1608017
+
+struct TRINITY_DLL_DECL boss_erekemAI : public ScriptedAI
+{
+ boss_erekemAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_erekem(Creature *_Creature)
+{
+ return new boss_erekemAI (_Creature);
+}
+
+void AddSC_boss_erekem()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_erekem";
+ newscript->GetAI = GetAI_boss_erekem;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/violet_hold/boss_ichoron.cpp b/src/bindings/scripts/scripts/zone/violet_hold/boss_ichoron.cpp
new file mode 100644
index 00000000000..ae10e434f78
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/violet_hold/boss_ichoron.cpp
@@ -0,0 +1,81 @@
+/* Script Data Start
+SDName: Boss ichoron
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_DRAINED 59820
+#define SPELL_FRENZY 54312
+#define SPELL_PROTECTIVE_BUBBLE 54306
+#define SPELL_WATER_BLAST 54237
+#define SPELL_WATER_BOLT_VOLLEY 54241
+
+//Yells
+#define SAY_AGGRO -1608018
+#define SAY_SLAY_1 -1608019
+#define SAY_SLAY_2 -1608020
+#define SAY_SLAY_3 -1608021
+#define SAY_DEATH -1608022
+#define SAY_SPAWN -1608023
+#define SAY_ENRAGE -1608024
+#define SAY_SHATTER -1608025
+#define SAY_BUBBLE -1608026
+
+struct TRINITY_DLL_DECL boss_ichoronAI : public ScriptedAI
+{
+ boss_ichoronAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_ichoron(Creature *_Creature)
+{
+ return new boss_ichoronAI (_Creature);
+}
+
+void AddSC_boss_ichoron()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_ichoron";
+ newscript->GetAI = GetAI_boss_ichoron;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/violet_hold/boss_lavanthor.cpp b/src/bindings/scripts/scripts/zone/violet_hold/boss_lavanthor.cpp
new file mode 100644
index 00000000000..525a1969328
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/violet_hold/boss_lavanthor.cpp
@@ -0,0 +1,52 @@
+/* Script Data Start
+SDName: Boss lavanthor
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_CAUTERIZING_FLAMES 59466
+#define SPELL_FIREBOLT 54235
+#define SPELL_FLAME_BREATH 54282
+#define SPELL_LAVA_BURN 54249
+
+struct TRINITY_DLL_DECL boss_lavanthorAI : public ScriptedAI
+{
+ boss_lavanthorAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who) {}
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer) {}
+};
+
+CreatureAI* GetAI_boss_lavanthor(Creature *_Creature)
+{
+ return new boss_lavanthorAI (_Creature);
+}
+
+void AddSC_boss_lavanthor()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_lavanthor";
+ newscript->GetAI = GetAI_boss_lavanthor;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/violet_hold/boss_moragg.cpp b/src/bindings/scripts/scripts/zone/violet_hold/boss_moragg.cpp
new file mode 100644
index 00000000000..87cc0a1fb5f
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/violet_hold/boss_moragg.cpp
@@ -0,0 +1,50 @@
+/* Script Data Start
+SDName: Boss moragg
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_CORROSICE_SALIVA 54527
+#define SPELL_OPTIC_LINK 54396
+
+struct TRINITY_DLL_DECL boss_moraggAI : public ScriptedAI
+{
+ boss_moraggAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who) {}
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer) {}
+};
+
+CreatureAI* GetAI_boss_moragg(Creature *_Creature)
+{
+ return new boss_moraggAI (_Creature);
+}
+
+void AddSC_boss_moragg()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_moragg";
+ newscript->GetAI = GetAI_boss_moragg;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/violet_hold/boss_xevozz.cpp b/src/bindings/scripts/scripts/zone/violet_hold/boss_xevozz.cpp
new file mode 100644
index 00000000000..16d00aba3c6
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/violet_hold/boss_xevozz.cpp
@@ -0,0 +1,82 @@
+/* Script Data Start
+SDName: Boss xevozz
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_ARCANE_BARRAGE_VOLLEY 54202
+#define SPELL_ARCANE_BUFFET 54226
+#define SPELL_SUMMON_ETHEREAL_SPHERE_1 54102
+#define SPELL_SUMMON_ETHEREAL_SPHERE_2 54137
+#define SPELL_SUMMON_ETHEREAL_SPHERE_3 54138
+
+//Yells
+#define SAY_AGGRO -1608027
+#define SAY_SLAY_1 -1608028
+#define SAY_SLAY_2 -1608029
+#define SAY_SLAY_3 -1608030
+#define SAY_DEATH -1608031
+#define SAY_SPAWN -1608032
+#define SAY_CHARGED -1608033
+#define SAY_REPEAT_SUMMON_1 -1608034
+#define SAY_REPEAT_SUMMON_2 -1608035
+#define SAY_SUMMON_ENERGY -1608036
+
+struct TRINITY_DLL_DECL boss_xevozzAI : public ScriptedAI
+{
+ boss_xevozzAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_xevozz(Creature *_Creature)
+{
+ return new boss_xevozzAI (_Creature);
+}
+
+void AddSC_boss_xevozz()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_xevozz";
+ newscript->GetAI = GetAI_boss_xevozz;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/violet_hold/boss_zuramat.cpp b/src/bindings/scripts/scripts/zone/violet_hold/boss_zuramat.cpp
new file mode 100644
index 00000000000..3eb91c1d47a
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/violet_hold/boss_zuramat.cpp
@@ -0,0 +1,82 @@
+/* Script Data Start
+SDName: Boss zuramat
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "precompiled.h"
+
+//Spells
+#define SPELL_SHROUD_OF_DARKNESS 54524
+#define SPELL_SUMMON_VOID_SENTRY 54524
+#define SPELL_VOID_SHIFT 54524
+
+#define NPC_VOID_SENTRY 29364
+
+//Yells
+#define SAY_AGGRO -1608037
+#define SAY_SLAY_1 -1608038
+#define SAY_SLAY_2 -1608039
+#define SAY_SLAY_3 -1608040
+#define SAY_DEATH -1608041
+#define SAY_SPAWN -1608042
+#define SAY_SHIELD -1608043
+#define SAY_WHISPER -1608044
+
+struct TRINITY_DLL_DECL boss_zuramatAI : public ScriptedAI
+{
+ boss_zuramatAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 void_shift;
+
+ void Reset() {}
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if(!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
+ case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
+ case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_zuramat(Creature *_Creature)
+{
+ return new boss_zuramatAI (_Creature);
+}
+
+void AddSC_boss_zuramat()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_zuramat";
+ newscript->GetAI = GetAI_boss_zuramat;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/violet_hold/def_violet_hold.h b/src/bindings/scripts/scripts/zone/violet_hold/def_violet_hold.h
new file mode 100644
index 00000000000..71bc0d18d2f
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/violet_hold/def_violet_hold.h
@@ -0,0 +1,4 @@
+#ifndef DEF_VIOLET_HOLD_H
+#define DEF_VIOLET_HOLD_H
+
+#endif
diff --git a/src/bindings/scripts/scripts/zone/violet_hold/instance_violet_hold.cpp b/src/bindings/scripts/scripts/zone/violet_hold/instance_violet_hold.cpp
new file mode 100644
index 00000000000..5d6ba3a5be3
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/violet_hold/instance_violet_hold.cpp
@@ -0,0 +1,21 @@
+#include "precompiled.h"
+#include "def_violet_hold.h"
+
+struct TRINITY_DLL_DECL instance_violet_hold : public ScriptedInstance
+{
+ instance_violet_hold(Map *Map) : ScriptedInstance(Map) {Initialize();};
+};
+
+InstanceData* GetInstanceData_instance_violet_hold(Map* map)
+{
+ return new instance_violet_hold(map);
+}
+
+void AddSC_instance_violet_hold()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_violet_hold";
+ newscript->GetInstanceData = GetInstanceData_instance_violet_hold;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/wailing_caverns/instance_wailing_caverns.cpp b/src/bindings/scripts/scripts/zone/wailing_caverns/instance_wailing_caverns.cpp
index 9aaa32725c1..5327bf7041d 100644
--- a/src/bindings/scripts/scripts/zone/wailing_caverns/instance_wailing_caverns.cpp
+++ b/src/bindings/scripts/scripts/zone/wailing_caverns/instance_wailing_caverns.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
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 3019331ea05..5ab59db8c40 100644
--- a/src/bindings/scripts/scripts/zone/western_plaguelands/western_plaguelands.cpp
+++ b/src/bindings/scripts/scripts/zone/western_plaguelands/western_plaguelands.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -100,7 +100,7 @@ struct TRINITY_DLL_DECL npc_the_scourge_cauldronAI : public ScriptedAI
void Reset() {}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void DoDie()
{
diff --git a/src/bindings/scripts/scripts/zone/westfall/westfall.cpp b/src/bindings/scripts/scripts/zone/westfall/westfall.cpp
index 749296167fe..a865b763ae5 100644
--- a/src/bindings/scripts/scripts/zone/westfall/westfall.cpp
+++ b/src/bindings/scripts/scripts/zone/westfall/westfall.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -38,9 +38,7 @@ EndContentData */
struct TRINITY_DLL_DECL npc_defias_traitorAI : public npc_escortAI
{
- npc_defias_traitorAI(Creature *c) : npc_escortAI(c) {}
-
- bool IsWalking;
+ npc_defias_traitorAI(Creature *c) : npc_escortAI(c) { Reset(); }
void WaypointReached(uint32 i)
{
@@ -49,13 +47,10 @@ struct TRINITY_DLL_DECL npc_defias_traitorAI : public npc_escortAI
if (!player)
return;
- if (IsWalking && !m_creature->HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE))
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
-
switch (i)
{
case 35:
- IsWalking = true;
+ SetRun(false);
break;
case 36:
DoScriptText(SAY_PROGRESS, m_creature, player);
@@ -63,13 +58,13 @@ struct TRINITY_DLL_DECL npc_defias_traitorAI : public npc_escortAI
case 44:
DoScriptText(SAY_END, m_creature, player);
{
- if (player && player->GetTypeId() == TYPEID_PLAYER)
- ((Player*)player)->GroupEventHappens(QUEST_DEFIAS_BROTHERHOOD,m_creature);
+ if (player)
+ player->GroupEventHappens(QUEST_DEFIAS_BROTHERHOOD,m_creature);
}
break;
}
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
switch(rand()%2)
{
@@ -79,14 +74,7 @@ struct TRINITY_DLL_DECL npc_defias_traitorAI : public npc_escortAI
}
void Reset()
- {
- if (IsWalking && !m_creature->HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE))
- {
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
- return;
- }
- IsWalking = false;
- }
+ {}
void JustDied(Unit* killer)
{
@@ -114,55 +102,11 @@ bool QuestAccept_npc_defias_traitor(Player* player, Creature* creature, Quest co
return true;
}
-CreatureAI* GetAI_npc_defias_traitor(Creature *_Creature)
+CreatureAI* GetAI_npc_defias_traitor(Creature* pCreature)
{
- npc_defias_traitorAI* thisAI = new npc_defias_traitorAI(_Creature);
-
- thisAI->AddWaypoint(0, -10508.40, 1068.00, 55.21);
- thisAI->AddWaypoint(1, -10518.30, 1074.84, 53.96);
- thisAI->AddWaypoint(2, -10534.82, 1081.92, 49.88);
- thisAI->AddWaypoint(3, -10546.51, 1084.88, 50.13);
- thisAI->AddWaypoint(4, -10555.29, 1084.45, 45.75);
- thisAI->AddWaypoint(5, -10566.57, 1083.53, 42.10);
- thisAI->AddWaypoint(6, -10575.83, 1082.34, 39.46);
- thisAI->AddWaypoint(7, -10585.67, 1081.08, 37.77);
- thisAI->AddWaypoint(8, -10600.08, 1078.19, 36.23);
- thisAI->AddWaypoint(9, -10608.69, 1076.08, 35.88);
- thisAI->AddWaypoint(10, -10621.26, 1073.00, 35.40);
- thisAI->AddWaypoint(11, -10638.12, 1060.18, 33.61);
- thisAI->AddWaypoint(12, -10655.87, 1038.99, 33.48);
- thisAI->AddWaypoint(13, -10664.68, 1030.54, 32.70);
- thisAI->AddWaypoint(14, -10708.68, 1033.86, 33.32);
- thisAI->AddWaypoint(15, -10754.43, 1017.93, 32.79);
- thisAI->AddWaypoint(16, -10802.26, 1018.01, 32.16);
- thisAI->AddWaypoint(17, -10832.60, 1009.04, 32.71);
- thisAI->AddWaypoint(18, -10866.56, 1006.51, 31.71); // Fix waypoints from roughly this point, test first to get proper one
- thisAI->AddWaypoint(19, -10879.98, 1005.10, 32.84);
- thisAI->AddWaypoint(20, -10892.45, 1001.32, 34.46);
- thisAI->AddWaypoint(21, -10906.14, 997.11, 36.15);
- thisAI->AddWaypoint(22, -10922.26, 1002.23, 35.74);
- thisAI->AddWaypoint(23, -10936.32, 1023.38, 36.52);
- thisAI->AddWaypoint(24, -10933.35, 1052.61, 35.85);
- thisAI->AddWaypoint(25, -10940.25, 1077.66, 36.49);
- thisAI->AddWaypoint(26, -10957.09, 1099.33, 36.83);
- thisAI->AddWaypoint(27, -10956.53, 1119.90, 36.73);
- thisAI->AddWaypoint(28, -10939.30, 1150.75, 37.42);
- thisAI->AddWaypoint(29, -10915.14, 1202.09, 36.55);
- thisAI->AddWaypoint(30, -10892.59, 1257.03, 33.37);
- thisAI->AddWaypoint(31, -10891.93, 1306.66, 35.45);
- thisAI->AddWaypoint(32, -10896.17, 1327.86, 37.77);
- thisAI->AddWaypoint(33, -10906.03, 1368.05, 40.91);
- thisAI->AddWaypoint(34, -10910.18, 1389.33, 42.62);
- thisAI->AddWaypoint(35, -10915.42, 1417.72, 42.93);
- thisAI->AddWaypoint(36, -10926.37, 1421.18, 43.04); // walk here and say
- thisAI->AddWaypoint(37, -10952.31, 1421.74, 43.40);
- thisAI->AddWaypoint(38, -10980.04, 1411.38, 42.79);
- thisAI->AddWaypoint(39, -11006.06, 1420.47, 43.26);
- thisAI->AddWaypoint(40, -11021.98, 1450.59, 43.09);
- thisAI->AddWaypoint(41, -11025.36, 1491.59, 43.15);
- thisAI->AddWaypoint(42, -11036.09, 1508.32, 43.28);
- thisAI->AddWaypoint(43, -11060.68, 1526.72, 43.19);
- thisAI->AddWaypoint(44, -11072.75, 1527.77, 43.20, 5000);// say and quest credit
+ npc_defias_traitorAI* thisAI = new npc_defias_traitorAI(pCreature);
+
+ thisAI->FillPointMovementListForCreature();
return (CreatureAI*)thisAI;
}
diff --git a/src/bindings/scripts/scripts/zone/winterspring/winterspring.cpp b/src/bindings/scripts/scripts/zone/winterspring/winterspring.cpp
index 1986d2c1b27..db6555d058f 100644
--- a/src/bindings/scripts/scripts/zone/winterspring/winterspring.cpp
+++ b/src/bindings/scripts/scripts/zone/winterspring/winterspring.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
diff --git a/src/bindings/scripts/scripts/zone/zangarmarsh/zangarmarsh.cpp b/src/bindings/scripts/scripts/zone/zangarmarsh/zangarmarsh.cpp
index b5f194d8035..df3fe6dd0fe 100644
--- a/src/bindings/scripts/scripts/zone/zangarmarsh/zangarmarsh.cpp
+++ b/src/bindings/scripts/scripts/zone/zangarmarsh/zangarmarsh.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -137,7 +137,7 @@ struct TRINITY_DLL_DECL npc_cooshcooshAI : public ScriptedAI
m_creature->setFaction(FACTION_FRIENDLY_CO);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void UpdateAI(const uint32 diff)
{
@@ -277,7 +277,7 @@ struct TRINITY_DLL_DECL npc_kayra_longmaneAI : public npc_escortAI
m_creature->setFaction(1660);
}
- void Aggro(Unit* who){}
+ void EnterCombat(Unit* who){}
void JustSummoned(Creature *summoned)
{
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp
index ea832370ea3..f31f944a3d4 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp
@@ -112,7 +112,7 @@ struct TRINITY_DLL_DECL boss_akilzonAI : public ScriptedAI
SetWeather(WEATHER_STATE_FINE, 0.0f);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoYell(SAY_ONAGGRO, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_ONAGGRO);
@@ -187,7 +187,7 @@ struct TRINITY_DLL_DECL boss_akilzonAI : public ScriptedAI
{
Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(m_creature, m_creature, 999);
- Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(tempUnitMap, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(m_creature, tempUnitMap, u_check);
TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
@@ -381,16 +381,7 @@ struct TRINITY_DLL_DECL mob_soaring_eagleAI : public ScriptedAI
m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING);
}
- void Aggro(Unit *who) {DoZoneInCombat();}
-
- void AttackStart(Unit *who)
- {
- if (!InCombat)
- {
- Aggro(who);
- InCombat = true;
- }
- }
+ void EnterCombat(Unit *who) {DoZoneInCombat();}
void MoveInLineOfSight(Unit *) {}
@@ -431,9 +422,7 @@ struct TRINITY_DLL_DECL mob_soaring_eagleAI : public ScriptedAI
m_creature->SetSpeed(MOVE_RUN, 5.0f);
TargetGUID = target->GetGUID();
}
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
m_creature->GetMotionMaster()->MovePoint(0, x, y, z);
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
arrived = false;
}
}
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_halazzi.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_halazzi.cpp
index 6e7311d8917..279e8985774 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_halazzi.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_halazzi.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -112,7 +112,7 @@ struct TRINITY_DLL_DECL boss_halazziAI : public ScriptedAI
EnterPhase(PHASE_LYNX);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
pInstance->SetData(DATA_HALAZZIEVENT, IN_PROGRESS);
@@ -353,7 +353,7 @@ struct TRINITY_DLL_DECL boss_spiritlynxAI : public ScriptedAI
ScriptedAI::AttackStart(who);
}
- void Aggro(Unit *who) {/*DoZoneInCombat();*/}
+ void EnterCombat(Unit *who) {/*DoZoneInCombat();*/}
void UpdateAI(const uint32 diff)
{
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp
index 8792a988c6f..9587bc167ba 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp
@@ -184,7 +184,7 @@ struct TRINITY_DLL_DECL boss_hexlord_addAI : public ScriptedAI
void Reset() {}
- void Aggro(Unit* who) {DoZoneInCombat();}
+ void EnterCombat(Unit* who) {DoZoneInCombat();}
void UpdateAI(const uint32 diff)
{
@@ -237,12 +237,11 @@ struct TRINITY_DLL_DECL boss_hex_lord_malacrassAI : public ScriptedAI
SpawnAdds();
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 46916);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 50268674);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 46916);
m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
}
- void Aggro(Unit* who)
+ void EnterCombat(Unit* who)
{
if(pInstance)
pInstance->SetData(DATA_HEXLORDEVENT, IN_PROGRESS);
@@ -526,12 +525,6 @@ struct TRINITY_DLL_DECL boss_alyson_antilleAI : public boss_hexlord_addAI
m_creature->GetMotionMaster()->MoveChase(who, 20);
m_creature->AddThreat(who, 0.0f);
}
-
- if (!InCombat)
- {
- Aggro(who);
- InCombat = true;
- }
}
}
@@ -611,12 +604,6 @@ struct TRINITY_DLL_DECL boss_gazakrothAI : public boss_hexlord_addAI
m_creature->GetMotionMaster()->MoveChase(who, 20);
m_creature->AddThreat(who, 0.0f);
}
-
- if (!InCombat)
- {
- Aggro(who);
- InCombat = true;
- }
}
}
@@ -731,12 +718,6 @@ struct TRINITY_DLL_DECL boss_slitherAI : public boss_hexlord_addAI
m_creature->GetMotionMaster()->MoveChase(who, 20);
m_creature->AddThreat(who, 0.0f);
}
-
- if (!InCombat)
- {
- Aggro(who);
- InCombat = true;
- }
}
}
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_janalai.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_janalai.cpp
index c70bd007c58..852be55c195 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_janalai.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_janalai.cpp
@@ -1,4 +1,4 @@
- /* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ /* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -171,7 +171,7 @@ struct TRINITY_DLL_DECL boss_janalaiAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
pInstance->SetData(DATA_JANALAIEVENT, IN_PROGRESS);
@@ -238,7 +238,7 @@ struct TRINITY_DLL_DECL boss_janalaiAI : public ScriptedAI
cell.SetNoCreate();
Trinity::AllCreaturesOfEntryInRange check(m_creature, MOB_EGG, 100);
- Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(templist, check);
+ Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(m_creature, templist, check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher);
@@ -273,7 +273,7 @@ struct TRINITY_DLL_DECL boss_janalaiAI : public ScriptedAI
cell.SetNoCreate();
Trinity::AllCreaturesOfEntryInRange check(m_creature, MOB_FIRE_BOMB, 100);
- Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(templist, check);
+ Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(m_creature, templist, check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher);
@@ -397,7 +397,7 @@ struct TRINITY_DLL_DECL boss_janalaiAI : public ScriptedAI
m_creature->AttackStop();
m_creature->GetMotionMaster()->Clear();
- DoTeleportTo(JanalainPos[0][0],JanalainPos[0][1],JanalainPos[0][2]);
+ DoTeleportTo(JanalainPos[0][0],JanalainPos[0][1],JanalainPos[0][2]);
m_creature->StopMoving();
m_creature->CastSpell(m_creature, SPELL_HATCH_ALL, false);
HatchAllEggs(2);
@@ -463,7 +463,7 @@ struct TRINITY_DLL_DECL mob_janalai_firebombAI : public ScriptedAI
m_creature->CastSpell(m_creature, SPELL_FIRE_BOMB_DUMMY, true);
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void AttackStart(Unit* who) {}
@@ -517,7 +517,7 @@ struct TRINITY_DLL_DECL mob_amanishi_hatcherAI : public ScriptedAI
cell.SetNoCreate();
Trinity::AllCreaturesOfEntryInRange check(m_creature, 23817, 50);
- Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(templist, check);
+ Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(m_creature, templist, check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher);
@@ -542,7 +542,7 @@ struct TRINITY_DLL_DECL mob_amanishi_hatcherAI : public ScriptedAI
return true;
}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void AttackStart(Unit*) {}
void MoveInLineOfSight(Unit*) {}
void MovementInform(uint32, uint32)
@@ -629,7 +629,7 @@ struct TRINITY_DLL_DECL mob_hatchlingAI : public ScriptedAI
m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING);
}
- void Aggro(Unit *who) {/*DoZoneInCombat();*/}
+ void EnterCombat(Unit *who) {/*DoZoneInCombat();*/}
void UpdateAI(const uint32 diff)
{
@@ -662,7 +662,7 @@ struct TRINITY_DLL_DECL mob_eggAI : public ScriptedAI
{
mob_eggAI(Creature *c) : ScriptedAI(c){}
void Reset() {}
- void Aggro(Unit* who) {}
+ void EnterCombat(Unit* who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff) {}
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp
index 75d08661834..8f2efe7189f 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp
@@ -1,4 +1,4 @@
- /* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ /* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -142,7 +142,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
Berserk_Timer = 600000;
inBearForm = false;
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 5122);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122);
}
void SendAttacker(Unit* target)
@@ -158,7 +158,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
cell.SetNoCreate();
Trinity::AllFriendlyCreaturesInGrid check(m_creature);
- Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> searcher(templist, check);
+ Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> searcher(m_creature, templist, check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid>, GridTypeMapContainer> cSearcher(searcher);
@@ -258,7 +258,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
pInstance->SetData(DATA_NALORAKKEVENT, IN_PROGRESS);
@@ -360,7 +360,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
{
if(inBearForm)
{
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 5122);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122);
DoYell(YELL_SHIFTEDTOTROLL, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_YELL_TOTROLL);
m_creature->RemoveAurasDueToSpell(SPELL_BEARFORM);
@@ -372,7 +372,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
}
else
{
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0);
DoYell(YELL_SHIFTEDTOBEAR, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_YELL_TOBEAR);
DoCast(m_creature, SPELL_BEARFORM, true);
@@ -394,7 +394,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
if(Mangle_Timer < diff)
{
- if(m_creature->getVictim() && !m_creature->getVictim()->HasAura(SPELL_MANGLEEFFECT, 0))
+ if(m_creature->getVictim() && !m_creature->getVictim()->HasAura(SPELL_MANGLEEFFECT))
{
DoCast(m_creature->getVictim(), SPELL_MANGLE);
Mangle_Timer = 1000;
@@ -406,7 +406,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
{
DoYell(YELL_SURGE, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_YELL_SURGE);
- Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 1, GetSpellMaxRange(SPELL_SURGE), true);
+ Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 1, GetSpellMaxRangeForHostile(SPELL_SURGE), true);
DoCast(target, SPELL_SURGE);
Surge_Timer = 15000 + rand()%5000;
}else Surge_Timer -= diff;
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp
index cf319c8f063..16c3dd3f333 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp
@@ -206,12 +206,12 @@ struct TRINITY_DLL_DECL boss_zuljinAI : public ScriptedAI
Summons.DespawnAll();
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 47174);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 218172674);
- m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 47174);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 218172674);
+ //m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
if(pInstance)
pInstance->SetData(DATA_ZULJINEVENT, IN_PROGRESS);
@@ -252,7 +252,7 @@ struct TRINITY_DLL_DECL boss_zuljinAI : public ScriptedAI
Summons.DespawnEntry(CREATURE_COLUMN_OF_FIRE);
if(Unit *Temp = Unit::GetUnit(*m_creature, SpiritGUID[3]))
- Temp->SetUInt32Value(UNIT_FIELD_BYTES_1,PLAYER_STATE_DEAD);
+ Temp->SetUInt32Value(UNIT_FIELD_BYTES_1,UNIT_STAND_STATE_DEAD);
}
void AttackStart(Unit *who)
@@ -339,7 +339,7 @@ struct TRINITY_DLL_DECL boss_zuljinAI : public ScriptedAI
case 4:
DoTeleportTo(CENTER_X, CENTER_Y, CENTER_Z, 100);
DoResetThreat();
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
m_creature->RemoveAurasDueToSpell(Transform[Phase].unaura);
DoCast(m_creature, Transform[Phase].spell);
DoYell(Transform[Phase].text, LANG_UNIVERSAL, NULL);
@@ -347,7 +347,7 @@ struct TRINITY_DLL_DECL boss_zuljinAI : public ScriptedAI
if(Phase > 0)
{
if(Unit *Temp = Unit::GetUnit(*m_creature, SpiritGUID[Phase - 1]))
- Temp->SetUInt32Value(UNIT_FIELD_BYTES_1,PLAYER_STATE_DEAD);
+ Temp->SetUInt32Value(UNIT_FIELD_BYTES_1,UNIT_STAND_STATE_DEAD);
}
if(Unit *Temp = Unit::GetUnit(*m_creature, SpiritGUID[NextPhase - 1]))
Temp->CastSpell(m_creature, SPELL_SIPHON_SOUL, false); // should m cast on temp
@@ -577,7 +577,7 @@ struct TRINITY_DLL_DECL feather_vortexAI : public ScriptedAI
void Reset() {}
- void Aggro(Unit* target) {}
+ void EnterCombat(Unit* target) {}
void SpellHit(Unit *caster, const SpellEntry *spell)
{
diff --git a/src/bindings/scripts/scripts/zone/zulaman/def_zulaman.h b/src/bindings/scripts/scripts/zone/zulaman/def_zulaman.h
index c249cf6b3ec..6fb0ef173bd 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/def_zulaman.h
+++ b/src/bindings/scripts/scripts/zone/zulaman/def_zulaman.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
diff --git a/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp b/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp
index fa33bf578f9..4ebf541515b 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp
@@ -1,4 +1,4 @@
- /* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ /* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -106,7 +106,7 @@ struct TRINITY_DLL_DECL instance_zulaman : public ScriptedInstance
void OnCreatureCreate(Creature *creature, uint32 creature_entry)
{
- switch(creature_entry)
+ switch(creature->GetEntry())
{
case 23578://janalai
case 23863://zuljin
@@ -139,8 +139,8 @@ struct TRINITY_DLL_DECL instance_zulaman : public ScriptedInstance
void OpenDoor(uint64 DoorGUID, bool open)
{
- if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID))
- Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1);
+ if(GameObject *Door = instance->GetGameObject(DoorGUID))
+ Door->SetGoState(open ? GO_STATE_ACTIVE : GO_STATE_READY);
}
void SummonHostage(uint8 num)
diff --git a/src/bindings/scripts/scripts/zone/zulaman/zulaman.cpp b/src/bindings/scripts/scripts/zone/zulaman/zulaman.cpp
index 9f3588e387a..8bc21dbba1d 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/zulaman.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/zulaman.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -47,7 +47,7 @@ struct TRINITY_DLL_DECL npc_forest_frogAI : public ScriptedAI
void Reset() { }
- void Aggro(Unit *who) { }
+ void EnterCombat(Unit *who) { }
void DoSpawnRandom()
{
@@ -111,7 +111,7 @@ struct TRINITY_DLL_DECL npc_zulaman_hostageAI : public ScriptedAI
bool IsLoot;
uint64 PlayerGUID;
void Reset() {}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void JustDied(Unit *)
{
Player* player = Unit::GetPlayer(PlayerGUID);
diff --git a/src/bindings/scripts/scripts/zone/zulfarrak/zulfarrak.cpp b/src/bindings/scripts/scripts/zone/zulfarrak/zulfarrak.cpp
index 3d233037d16..bdc5c264c51 100644
--- a/src/bindings/scripts/scripts/zone/zulfarrak/zulfarrak.cpp
+++ b/src/bindings/scripts/scripts/zone/zulfarrak/zulfarrak.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -63,7 +63,7 @@ struct TRINITY_DLL_DECL npc_sergeant_blyAI : public ScriptedAI
pInstance->SetData(0, NOT_STARTED);*/
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
/*if( pInstance )
pInstance->SetData(0, IN_PROGRESS);*/
@@ -152,7 +152,7 @@ struct TRINITY_DLL_DECL npc_weegli_blastfuseAI : public ScriptedAI
pInstance->SetData(0, NOT_STARTED);*/
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
/*if( pInstance )
pInstance->SetData(0, IN_PROGRESS);*/
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp
index a472fff2076..1b75cd12ee6 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -78,7 +78,7 @@ struct TRINITY_DLL_DECL boss_arlokkAI : public ScriptedAI
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_gahzranka.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_gahzranka.cpp
index 7cf15d53416..c5f45901245 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_gahzranka.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_gahzranka.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -23,7 +23,7 @@ EndScriptData */
#include "precompiled.h"
-#define SPELL_FROSTBREATH 21099
+#define SPELL_FROSTBREATH 16099
#define SPELL_MASSIVEGEYSER 22421 //Not working. Cause its a summon...
#define SPELL_SLAM 24326
@@ -41,7 +41,7 @@ struct TRINITY_DLL_DECL boss_gahzrankaAI : public ScriptedAI
Slam_Timer = 17000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp
index 623015acb73..6a7455e731e 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -40,7 +40,7 @@ struct TRINITY_DLL_DECL boss_grilekAI : public ScriptedAI
GroundTremor_Timer = 8000 + rand()%8000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_hakkar.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_hakkar.cpp
index 0d490781ec7..0de85d55986 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_hakkar.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_hakkar.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -94,7 +94,7 @@ struct TRINITY_DLL_DECL boss_hakkarAI : public ScriptedAI
Enraged = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_hazzarah.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_hazzarah.cpp
index efe847045d5..a8de44dc712 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_hazzarah.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_hazzarah.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -43,7 +43,7 @@ struct TRINITY_DLL_DECL boss_hazzarahAI : public ScriptedAI
Illusions_Timer = 10000 + rand()%8000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_jeklik.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_jeklik.cpp
index aecc2f450db..67231fd69bd 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_jeklik.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_jeklik.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -77,7 +77,7 @@ struct TRINITY_DLL_DECL boss_jeklikAI : public ScriptedAI
PhaseTwo = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
DoCast(m_creature,SPELL_BAT_FORM);
@@ -229,7 +229,7 @@ struct TRINITY_DLL_DECL mob_batriderAI : public ScriptedAI
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void UpdateAI (const uint32 diff)
{
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp
index 100d8881127..d1cf79ed183 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -54,10 +54,6 @@ struct TRINITY_DLL_DECL boss_jindoAI : public ScriptedAI
uint32 Delusions_Timer;
uint32 Teleport_Timer;
- Creature *Shade;
- Creature *Skeletons;
- Creature *HealingWard;
-
void Reset()
{
BrainWashTotem_Timer = 20000;
@@ -67,7 +63,7 @@ struct TRINITY_DLL_DECL boss_jindoAI : public ScriptedAI
Teleport_Timer = 5000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
@@ -88,7 +84,7 @@ struct TRINITY_DLL_DECL boss_jindoAI : public ScriptedAI
if (HealingWard_Timer < diff)
{
//DoCast(m_creature, SPELL_POWERFULLHEALINGWARD);
- HealingWard = m_creature->SummonCreature(14987, m_creature->GetPositionX()+3, m_creature->GetPositionY()-2, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,30000);
+ m_creature->SummonCreature(14987, m_creature->GetPositionX()+3, m_creature->GetPositionY()-2, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,30000);
HealingWard_Timer = 14000 + rand()%6000;
}else HealingWard_Timer -= diff;
@@ -110,7 +106,8 @@ struct TRINITY_DLL_DECL boss_jindoAI : public ScriptedAI
{
DoCast(target, SPELL_DELUSIONSOFJINDO);
- Shade = m_creature->SummonCreature(14986, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ Creature *Shade = m_creature->SummonCreature(14986, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Shade)
Shade->AI()->AttackStart(target);
}
@@ -129,23 +126,33 @@ struct TRINITY_DLL_DECL boss_jindoAI : public ScriptedAI
if(DoGetThreat(m_creature->getVictim()))
DoModifyThreatPercent(target,-100);
+ Creature *Skeletons;
Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()+2, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Skeletons)
Skeletons->AI()->AttackStart(target);
Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()-2, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Skeletons)
Skeletons->AI()->AttackStart(target);
Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()+4, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Skeletons)
Skeletons->AI()->AttackStart(target);
Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()-4, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Skeletons)
Skeletons->AI()->AttackStart(target);
Skeletons = m_creature->SummonCreature(14826, target->GetPositionX(), target->GetPositionY()+2, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Skeletons)
Skeletons->AI()->AttackStart(target);
Skeletons = m_creature->SummonCreature(14826, target->GetPositionX(), target->GetPositionY()-2, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Skeletons)
Skeletons->AI()->AttackStart(target);
Skeletons = m_creature->SummonCreature(14826, target->GetPositionX(), target->GetPositionY()+4, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Skeletons)
Skeletons->AI()->AttackStart(target);
Skeletons = m_creature->SummonCreature(14826, target->GetPositionX(), target->GetPositionY()-4, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Skeletons)
Skeletons->AI()->AttackStart(target);
Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()+3, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ if (Skeletons)
Skeletons->AI()->AttackStart(target);
}
@@ -173,7 +180,7 @@ struct TRINITY_DLL_DECL mob_healing_wardAI : public ScriptedAI
Heal_Timer = 2000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -212,7 +219,7 @@ struct TRINITY_DLL_DECL mob_shade_of_jindoAI : public ScriptedAI
m_creature->CastSpell(m_creature, SPELL_INVISIBLE,true);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_mandokir.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_mandokir.cpp
index 87939596324..13eac015d6d 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_mandokir.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_mandokir.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -123,7 +123,7 @@ struct TRINITY_DLL_DECL boss_mandokirAI : public ScriptedAI
}
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
@@ -281,7 +281,7 @@ struct TRINITY_DLL_DECL mob_ohganAI : public ScriptedAI
SunderArmor_Timer = 5000;
}
- void Aggro(Unit *who) {}
+ void EnterCombat(Unit *who) {}
void JustDied(Unit* Killer)
{
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp
index 69588bdfbb8..7d18ed5a14f 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -76,7 +76,7 @@ struct TRINITY_DLL_DECL boss_marliAI : public ScriptedAI
m_creature->ApplySpellImmune(1, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
@@ -208,7 +208,7 @@ struct TRINITY_DLL_DECL mob_spawn_of_marliAI : public ScriptedAI
LevelUp_Timer = 3000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp
index 1b01afd9aa1..9881555aaf3 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -52,7 +52,7 @@ struct TRINITY_DLL_DECL boss_renatakiAI : public ScriptedAI
Ambushed = false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -65,9 +65,9 @@ struct TRINITY_DLL_DECL boss_renatakiAI : public ScriptedAI
if (Invisible_Timer < diff)
{
m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
- m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
- m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO , 218171138);
- m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 1, 3);
+ m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
+ //m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO , 218171138);
+ //m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 1, 3);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID,11686);
Invisible = true;
@@ -99,9 +99,9 @@ struct TRINITY_DLL_DECL boss_renatakiAI : public ScriptedAI
m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID,15268);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 31818);
- m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO , 218171138);
- m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 1, 3);
+ m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_ID, 31818);
+ //m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO , 218171138);
+ //m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 1, 3);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
Invisible = false;
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp
index 36e9fd9c84d..72594a0b8f8 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -92,7 +92,7 @@ struct TRINITY_DLL_DECL boss_thekalAI : public ScriptedAI
pInstance->SetData(DATA_THEKAL_ALIVE, 0);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
@@ -118,7 +118,7 @@ struct TRINITY_DLL_DECL boss_thekalAI : public ScriptedAI
{
//Resurrect LorKhan
Unit *pLorKhan = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_LORKHAN));
- pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ pLorKhan->SetStandState(UNIT_STAND_STATE_STAND);
pLorKhan->setFaction(14);
pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
pLorKhan->SetHealth(int(pLorKhan->GetMaxHealth()*1.0));
@@ -128,7 +128,7 @@ struct TRINITY_DLL_DECL boss_thekalAI : public ScriptedAI
{
//Resurrect Zath
Unit *pZath = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_ZATH));
- pZath->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ pZath->SetStandState(UNIT_STAND_STATE_STAND);
pZath->setFaction(14);
pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
pZath->SetHealth(int(pZath->GetMaxHealth()*1.0));
@@ -153,7 +153,7 @@ struct TRINITY_DLL_DECL boss_thekalAI : public ScriptedAI
if (!PhaseTwo && !WasDead && m_creature->GetHealth() <= m_creature->GetMaxHealth() * 0.05)
{
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 3);
+ m_creature->SetStandState(UNIT_STAND_STATE_SLEEP);
m_creature->AttackStop();
if(pInstance)
@@ -169,7 +169,7 @@ struct TRINITY_DLL_DECL boss_thekalAI : public ScriptedAI
{
DoCast(m_creature,SPELL_TIGER_FORM);
m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.00f);
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->SetHealth(int(m_creature->GetMaxHealth()*1.0));
const CreatureInfo *cinfo = m_creature->GetCreatureInfo();
@@ -265,7 +265,7 @@ struct TRINITY_DLL_DECL mob_zealot_lorkhanAI : public ScriptedAI
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -328,7 +328,7 @@ struct TRINITY_DLL_DECL mob_zealot_lorkhanAI : public ScriptedAI
{
//Resurrect Thekal
Unit *pThekal = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_THEKAL));
- pThekal->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ pThekal->SetStandState(UNIT_STAND_STATE_STAND);
pThekal->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
pThekal->setFaction(14);
pThekal->SetHealth(int(pThekal->GetMaxHealth()*1.0));
@@ -338,7 +338,7 @@ struct TRINITY_DLL_DECL mob_zealot_lorkhanAI : public ScriptedAI
{
//Resurrect Zath
Unit *pZath = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_ZATH));
- pZath->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ pZath->SetStandState(UNIT_STAND_STATE_STAND);
pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
pZath->setFaction(14);
pZath->SetHealth(int(pZath->GetMaxHealth()*1.0));
@@ -351,7 +351,7 @@ struct TRINITY_DLL_DECL mob_zealot_lorkhanAI : public ScriptedAI
if (m_creature->GetHealth() <= m_creature->GetMaxHealth() * 0.05)
{
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 3);
+ m_creature->SetStandState(UNIT_STAND_STATE_SLEEP);
m_creature->setFaction(35);
m_creature->AttackStop();
@@ -398,11 +398,11 @@ struct TRINITY_DLL_DECL mob_zealot_zathAI : public ScriptedAI
if(pInstance)
pInstance->SetData(DATA_ZATH_ALIVE, 0);
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
@@ -459,7 +459,7 @@ struct TRINITY_DLL_DECL mob_zealot_zathAI : public ScriptedAI
{
//Resurrect LorKhan
Unit *pLorKhan = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_LORKHAN));
- pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ pLorKhan->SetStandState(UNIT_STAND_STATE_STAND);
pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
pLorKhan->setFaction(14);
pLorKhan->SetHealth(int(pLorKhan->GetMaxHealth()*1.0));
@@ -469,7 +469,7 @@ struct TRINITY_DLL_DECL mob_zealot_zathAI : public ScriptedAI
{
//Resurrect Thekal
Unit *pThekal = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_THEKAL));
- pThekal->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ pThekal->SetStandState(UNIT_STAND_STATE_STAND);
pThekal->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
pThekal->setFaction(14);
pThekal->SetHealth(int(pThekal->GetMaxHealth()*1.0));
@@ -482,7 +482,7 @@ struct TRINITY_DLL_DECL mob_zealot_zathAI : public ScriptedAI
if (m_creature->GetHealth() <= m_creature->GetMaxHealth() * 0.05)
{
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 3);
+ m_creature->SetStandState(UNIT_STAND_STATE_SLEEP);
m_creature->setFaction(35);
m_creature->AttackStop();
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_venoxis.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_venoxis.cpp
index 29c79a28187..ea939289696 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_venoxis.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_venoxis.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -73,7 +73,7 @@ struct TRINITY_DLL_DECL boss_venoxisAI : public ScriptedAI
InBerserk= false;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_wushoolay.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_wushoolay.cpp
index c69e2c6204e..9c6aab1a0e4 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_wushoolay.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_wushoolay.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
@@ -40,7 +40,7 @@ struct TRINITY_DLL_DECL boss_wushoolayAI : public ScriptedAI
LightningWave_Timer = 8000 + rand()%8000;
}
- void Aggro(Unit *who)
+ void EnterCombat(Unit *who)
{
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/def_zulgurub.h b/src/bindings/scripts/scripts/zone/zulgurub/def_zulgurub.h
index fd1c905048e..f14bd8eca98 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/def_zulgurub.h
+++ b/src/bindings/scripts/scripts/zone/zulgurub/def_zulgurub.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/instance_zulgurub.cpp b/src/bindings/scripts/scripts/zone/zulgurub/instance_zulgurub.cpp
index a49ff110b2d..eb3cbd1d495 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/instance_zulgurub.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/instance_zulgurub.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
diff --git a/src/bindings/scripts/sql/WotLK/npc_taxi.sql b/src/bindings/scripts/sql/WotLK/npc_taxi.sql
new file mode 100644
index 00000000000..b93f5dfdfca
--- /dev/null
+++ b/src/bindings/scripts/sql/WotLK/npc_taxi.sql
@@ -0,0 +1,10 @@
+#Taxi in Archerus
+UPDATE `creature_template` SET `ScriptName`='npc_acherus_taxi' WHERE `entry`='28864';
+
+#Stormwind Harbor
+UPDATE `creature_template` SET `ScriptName`='npc_stormwindharbor_taxi' WHERE `entry`='29154';
+
+#Taxis to the 3 parts of the Wyrmresttempel
+UPDATE `creature_template` SET `ScriptName`='npc_wyrmresttempelbottom_taxi' WHERE `entry`='26443';
+UPDATE `creature_template` SET `ScriptName`='npc_wyrmresttempelmiddle_taxi' WHERE `entry`='27575';
+UPDATE `creature_template` SET `ScriptName`='npc_wyrmresttempeltop_taxi' WHERE `entry`='26949';
diff --git a/src/bindings/scripts/sql/WotLK/script_texts_wotlk.sql b/src/bindings/scripts/sql/WotLK/script_texts_wotlk.sql
new file mode 100644
index 00000000000..de3de7b9464
--- /dev/null
+++ b/src/bindings/scripts/sql/WotLK/script_texts_wotlk.sql
@@ -0,0 +1,530 @@
+-- -1 574 000 UTGARDE KEEP
+INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) VALUES
+-- Prince Keleseth
+ (-1574000, 'Your blood is mine!',13221,1,0,'keleseth SAY_AGGRO'),
+ (-1574001, 'Darkness waits',13223,1,0, 'keleseth SAY_KILL'),
+ (-1574002, 'I join... the night.',13225,1,0, 'keleseth SAY_DEATH'),
+ (-1574003, 'Not so fast.',13222,1,0, 'keleseth SAY_FROST_TOMB'),
+ (-1574004, 'Aranal, lidel! Their fate shall be yours!',13224,1,0, 'keleseth SAY_SKELETONS'),
+-- Dalronn the Controller
+ (-1574005, 'By all means, don\'t assess the situation, you halfwit! Just jump into the fray!',13199, 1,0,'dalronn SAY_AGGRO'),
+ (-1574006, 'You may serve me yet.',13202, 1,0,'dalronn SAY_KILL'),
+ (-1574007, 'See... you... soon.',13200, 1,0,'dalronn SAY_DEATH_1'),
+ (-1574008, 'There\'s no... greater... glory.',13201, 1,0,'dalronn SAY_DEATH_2'),
+ (-1574009, 'Skarvald, you incompetent slug! Return and make yourself useful!',13203,1,0, 'dalronn SAY_RAISES'),
+-- Skarvald the Constructor
+ (-1574010, 'Dalronn! See if you can muster the nerve to join my attack!',13229, 1,0,'skarvald SAY_AGGRO'),
+ (-1574011, '...',13232,1,0, 'skarvald SAY_KILL'),
+ (-1574012, 'Not... over... yet.',13230,1,0, 'skarvald SAY_DEATH_1'),
+ (-1574013, 'A warrior\'s death.',13231,1,0, 'skarvald SAY_DEATH_2'),
+ (-1574014, 'Pagh! What sort of necromancer lets death stop him? I knew you were worthless!',13233,1,0, 'skarvald SAY_RAISES'),
+-- Ingvar the Plunderer
+ (-1574015, 'I\'ll paint my face with your blood!',13207,1,0, 'ingvar SAY_AGGRO'),
+ (-1574016, 'I am a warrior born!',13214,1,0, 'ingvar SAY_KILL'),
+ (-1574017, 'My life for the... death god!',13213,1,0, 'ingvar SAY_DEATH'),
+ (-1574018, 'Fight on or face me!',13208,1,0, 'ingvar SAY_ATTACK_1'),
+ (-1574019, '...',13240, 1,0,'ingvar SAY_ATTACK_2'),
+ (-1574020, 'Slay them all, no excuses, no mercy, no rest!',13241,1,0, 'ingvar SAY_ATTACK_3'),
+ (-1574021, '... of destruction silence every ...!',13242,1,0, 'ingvar SAY_ATTACK_4'),
+ (-1574022, 'I return! A second chance to carve out your skull!',13208,1,0, 'ingvar SAY_PHASE2_AGGRO'),
+ (-1574023, 'Mjul orm agn gjor!',13212, 1,0,'ingvar SAY_PHASE2_KILL'),
+ (-1574024, 'No! I can do... better! I can...',13211,1,0, 'ingvar SAY_PHASE2_DEATH'),
+-- Said by Annhylde the Caller when resurecting Ingvar
+ (-1574025, 'Ingvar! Your pathetic failure will serve as a warning to all... you are damned! Arise and carry out the master\'s will!',13754, 1,0,'ingvar SAY_ANNHYLDE_THE_CALLER_RESURECTION');
+
+-- -1 575 000 UTGARDE PINNACLE
+INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) VALUES
+-- Gortok Palehoof
+ (-1575000, 'What this place? I will destroy you!',13464,1,0, 'palehoof SAY_AGGRO'),
+ (-1575001, 'You die! That what master wants!',13465,1,0, 'palehoof SAY_SLAY_1'),
+ (-1575002, 'An easy task!',13466,1,0, 'palehoof SAY_SLAY_2'),
+ (-1575003, '...',13467,1,0, 'palehoof SAY_DEATH'),
+-- Skadi the Ruthless
+ (-1575004, 'What mongrels dare intrude here? Look alive, my brothers! A feast for the one that brings me their heads!',13497,1,0, 'skadi SAY_AGGRO'),
+ (-1575005, 'Mjor Na Ul Kaval!',13503,1,0, 'skadi SAY_KILL_1'),
+ (-1575006, 'Not so brash now, are you?',13504,1,0, 'skadi SAY_KILL_2'),
+ (-1575007, 'I\'ll mount your skull from the highest tower!',13505,1,0, 'skadi SAY_KILL_3'),
+ (-1575008, 'ARGH! You call that... an attack? I\'ll... show... aghhhh...',13506,1,0, 'skadi SAY_DEATH'),
+ (-1575009, 'You motherless knaves! Your corpses will make fine morsels for my new drake!',13507,1,0, 'skadi SAY_DRAKE_DEATH'),
+ (-1575010, 'I ask for ... to kill them, yet all I get is feeble whelps! By Ye.. SLAUGHTER THEM!',13501,1,0, 'skadi SAY_DRAKE_HIT_1'),
+ (-1575011, 'If one more harpoon touches my drake I\'ll flae my miserable heins.',13502,1,0, 'skadi SAY_DRAKE_HIT_2'),
+ (-1575012, 'Sear them to the bone!',13498,1,0, 'skadi SAY_DRAKE_BREATH_1'),
+ (-1575013, 'Go now! Leave nothing but ash in your wake!',13499,1,0, 'skadi SAY_DRAKE_BREATH_2'),
+ (-1575014, 'Cleanse our sacred halls with flame!',13500,1,0, 'skadi SAY_DRAKE_BREATH_3'),
+-- Svala Sorrowgrave
+ (-1575015, 'I will vanquish your soul!',13842,1,0, 'svala SAY_AGGRO'),
+ (-1575016, 'You were a fool to challenge the power of the Lich King!',13845, 1,0,'svala SAY_SLAY_1'),
+ (-1575017, 'Your will is done, my king.',13847,1,0, 'svala SAY_SLAY_2'),
+ (-1575018, 'Another soul for my master.',13848, 1,0,'svala SAY_SLAY_3'),
+ (-1575019, 'Nooo! I did not come this far... to...',13855,1,0, 'svala SAY_DEATH'),
+ (-1575020, 'Your death approaches.',13850,1,0, 'svala SAY_SACRIFICE_PLAYER_1'),
+ (-1575021, 'Go now to my master.',13851,1,0, 'svala SAY_SACRIFICE_PLAYER_2'),
+ (-1575022, 'Your end is inevitable.',13852,1,0, 'svala SAY_SACRIFICE_PLAYER_3'),
+ (-1575023, '...',13853,1,0, 'svala SAY_SACRIFICE_PLAYER_4'),
+ (-1575024, 'Any last words?',13854,1,0, 'svala SAY_SACRIFICE_PLAYER_5'),
+ (-1575025, 'My liege! I have done as you asked, and now beseech you for your blessing!',13856,1,0, 'svala SAY_SAY_DIALOG_WITH_ARTHAS_1'),
+ (-1575026, 'The sensation is... beyond my imagining. I am yours to command, my king.',13857,1,0, 'svala SAY_SAY_DIALOG_WITH_ARTHAS_2'),
+ (-1575027, 'I will be happy to slaughter them in your name! Come, enemies of the Scourge! I will show you the might of the Lich King!',13858,1,0, 'svala SAY_SAY_DIALOG_WITH_ARTHAS_3'),
+-- King Ymiron
+ (-1575028, 'You invade my home and then dare to challenge me? I will tear the hearts from your chests and offer them as gifts to the death god! Rualg nja gaborr!',13609, 1,0,'ymiron SAY_AGGRO'),
+ (-1575029, 'Your death is only the beginning!',13614,1,0, 'ymiron SAY_SLAY_1'),
+ (-1575030, 'You have failed your people!',13615, 1,0,'ymiron SAY_SLAY_2'),
+ (-1575031, 'There is a reason I am king!',13616, 1,0,'ymiron SAY_SLAY_3'),
+ (-1575032, 'Bleed no more!',13617, 1,0,'ymiron SAY_SLAY_4'),
+ (-1575033, 'What... awaits me... now?',13618,1,0, 'ymiron SAY_DEATH'),
+ (-1575034, 'Bjorn of the Black Storm! Honor me now with your presence!',13610,1,0, 'ymiron SAY_SUMMON_BJORN'),
+ (-1575035, 'Haldor of the rocky cliffs, grant me your strength!',13611, 1,0,'ymiron SAY_SUMMON_HALDOR'),
+ (-1575036, 'Ranulf of the screaming abyss, snuff these maggots with darkest night!',13612,1,0, 'ymiron SAY_SUMMON_RANULF'),
+ (-1575037, 'Tor of the Brutal Siege! Bestow your might upon me!',13613,1,0, 'ymiron SAY_SUMMON_TORGYN');
+
+-- -1 576 000 NEXUS
+INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) VALUES
+-- Anomalus
+ (-1576000, 'Chaos beckons.',13186,1,0,'anomalus SAY_AGGRO'),
+ (-1576001, 'Expiration... is necessary...',13274,1,0,'anomalus SAY_KILL'),
+ (-1576002, 'Of course.',13187,1,0,'anomalus SAY_DEATH'),
+ (-1576003, 'Reality... unwoven.',13188,1,0,'anomalus SAY_RIFT'),
+ (-1576004, 'Indestructible.',13189,1,0,'anomalus SAY_SHIELD'),
+-- Keristrasza
+ (-1576005, 'Preserve? Why? There\'s no truth in it. No no no... only in the taking! I see that now!',13450,1,0,'keristrasza SAY_AGGRO'),
+ (-1576006, 'Now we\'ve come to the truth! ',13453,1,0,'keristrasza SAY_SLAY'),
+ (-1576007, 'Finish it! Finish it! Kill me, or I swear by the Dragonqueen you\'ll never see daylight again!',13452,1,0,'keristrasza SAY_ENRAGE'),
+ (-1576008, 'Dragonqueen... Life-Binder... preserve... me.',13454,1,0,'keristrasza SAY_DEATH'),
+ (-1576009, 'Stay. Enjoy your final moments.',13451,1,0,'keristrasza SAY_CRYSTAL_NOVA'),
+-- Grand Magus Telestra
+ (-1576010, 'You know what they say about curiosity.',13319,1,0,'magus_telestra SAY_AGGRO'),
+ (-1576011, 'Death becomes you!',13324,1,0,'magus_telestra SAY_KILL'),
+ (-1576012, 'Damn the... luck.',13320,1,0,'magus_telestra SAY_DEATH'),
+ (-1576013, 'Now to finish the job!',13323,1,0,'magus_telestra SAY_MERGE'),
+ (-1576014, 'There\'s plenty of me to go around.',13321,1,0,'magus_telestra SAY_SPLIT_1'),
+ (-1576015, 'I\'ll give you more than you can handle.',13322,1,0,'magus_telestra SAY_SPLIT_2'),
+-- Ormorok
+ (-1576016, 'Noo!',13328,1,0,'ormorok SAY_AGGRO'),
+ (-1576017, 'Aargh Kill!',13329,1,0,'ormorok SAY_KILL'),
+ (-1576018, 'Aaggh!',13330,1,0,'ormorok SAY_DEATH'),
+ (-1576019, 'Back!',13331,1,0,'ormorok SAY_REFLECT'),
+ (-1576020, 'Bleed!',13332,1,0,'ormorok SAY_ICE_SPIKES'),
+-- Commander Stoutbeard
+ (-1576021, 'What? Where in a..? Don\'t just stand around lads KILL SOMEBODY!',13193,1,0,'commander_stoutbeard SAY_AGGRO'),
+ (-1576022, 'Now we\re getting someplace!',13195,1,0,'commander_stoutbeard SAY_KILL'),
+ (-1576023, 'Is that all you\'ve... got?',13194,1,0,'commander_stoutbeard SAY_DEATH'),
+-- Commander Kolurg
+ (-1576024, 'What is this? Mag thorin Kar! Kill them!',13458,1,0,'commander_kolurg SAY_AGGRO'),
+ (-1576025, 'Our task is not yet done!',13459,1,0,'commander_kolurg SAY_KILL'),
+ (-1576026, 'GOOO!',13460,1,0,'commander_kolurg SAY_DEATH');
+
+-- -1 578 000 OCULUS
+INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) VALUES
+-- Drakos the Interrogator
+ (-1578000, 'The prisoners shall not go free. The word of Malygos is law!',13594,1,0, 'drakos SAY_AGGRO'),
+ (-1578001, 'A fitting punishment!',13602, 1,0,'drakos SAY_KILL_1'),
+ (-1578002, 'Sentence: executed!',13603,1,0, 'drakos SAY_KILL_2'),
+ (-1578003, 'Another casualty of war!',13604, 1,0,'drakos SAY_KILL_3'),
+ (-1578004, 'The war... goes on.',13605,1,0, 'drakos SPELL_DEATH'),
+ (-1578005, 'It is too late to run!',13598, 1,0,'drakos SAY_PULL_1'),
+ (-1578006, 'Gather \'round! ',13599, 1,0,'drakos SAY_PULL_2'),
+ (-1578007, 'None shall escape!',13600, 1,0,'drakos SAY_PULL_3'),
+ (-1578008, 'I condemn you to death!',13601,1,0, 'drakos SAY_PULL_4'),
+ (-1578009, 'Tremble, worms!',13595,1,0, 'drakos SAY_STOMP_1'),
+ (-1578010, 'I will crush you!',13596, 1,0,'drakos SAY_STOMP_2'),
+ (-1578011, 'Can you fly?',13597, 1,0,'drakos SAY_STOMP_3'),
+-- Mage-Lord Urom
+ (-1578012, 'Poor blind fools!',13638,1,0, 'urom SAY_AGGRO'),
+ (-1578013, 'If only you understood!',13641,1,0, 'urom SAY_KILL_1'),
+ (-1578014, 'Now, do you see? DO YOU?!',13642,1,0, 'urom SAY_KILL_2'),
+ (-1578015, 'Unfortunate, but necessary.',13643,1,0, 'urom SAY_KILL_3'),
+ (-1578016, 'Everything I\'ve done... has been for Azeroth...',13644,1,0, 'urom SAY_DEATH'),
+ (-1578017, 'A taste... just a small taste... of the Spell-Weaver\'s power!',13639,1,0, 'urom SAY_EXPLOSION_1'),
+ (-1578018, 'So much unstable energy... but worth the risk to destroy you!',13640,1,0, 'urom SAY_EXPLOSION_2'),
+ (-1578019, 'What do we have here... those would defy the Spell-Weaver? Those without foresight or understanding. How could I make you see? Malygos is saving the world from itself! Bah! You are hardly worth my time!',13635,1,0, 'urom SAY_SUMMON_1'),
+ (-1578020, 'Clearly my pets failed. Perhaps another demonstration is in order.',13636,1,0, 'urom SAY_SUMMON_2'),
+ (-1578021, 'Still you fight. Still you cling to misguided principles. If you survive, you\'ll find me in the center ring.',13637,1,0, 'urom SAY_SUMMON_3'),
+-- Varos Cloudstrider
+ (-1578022, 'There will be no mercy!',13649,1,0, 'varos SAY_AGGRO'),
+ (-1578023, 'You were warned.',13653,1,0, 'varos SAY_KILL_1'),
+ (-1578024, 'The Oculus is ours.',13654,1,0, 'varos SAY_KILL_2'),
+ (-1578025, 'They are... too strong! Underestimated their... fortitude.',13655,1,0, 'varos SAY_DEATH'),
+ (-1578026, 'Blast them! Destroy them!',13650,1,0, 'varos SAY_STRIKE_1'),
+ (-1578027, 'Take no prisoners! Attack!',13651,1,0, 'varos SAY_STRIKE_2'),
+ (-1578028, 'Strike now! Obliterate them!',13652,1,0, 'varos SAY_STRIKE_3'),
+-- Varos says when Drakos dies
+ (-1578029, 'Intruders, your victory will be short-lived. I am Commander Varos Cloudstrider. My drakes control the skies and protest this conduit. I will see to it personally that the Oculus does not fall into your hands!',13648,1,0, 'varos SAY_SPAWN');
+
+-- -1 595 000 CULLING OF STRATHOLME
+INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) VALUES
+-- Epoch
+ (-1595000, 'We\'ll see about that, young prince.',13409,1,0, 'epoch SAY_AGGRO'),
+ (-1595001, 'Tick tock, tick tock...',13410, 1,0,'epoch SAY_TIME_WARP_1'),
+ (-1595002, 'Not quick enough!',13411,1,0, 'epoch SAY_TIME_WARP_2'),
+ (-1595003, 'Let\'s get this over with. ',13412, 1,0,'epoch SAY_TIME_WARP_3'),
+ (-1595004, 'There is no future for you.',13413,1,0, 'epoch SAY_SLAY_1'),
+ (-1595005, 'This is the hour of our greatest triumph!',13414,1,0, 'epoch SAY_SLAY_2'),
+ (-1595006, 'You would destined to fail. ',13415,1,0, 'epoch SAY_SLAY_3'),
+ (-1595007, 'Prince Arthas Menethil, on this day, a powerful darkness has taken hold of your soul. The death you are destined to visit upon others will this day be your own.',13408,1,0, 'epoch SAY_INTRO'),
+ (-1595008, '*gurgles*',13416,1,0, 'epoch SAY_DEATH'),
+-- Mal'ganis
+ (-1595009, 'Yes...this is the beginning...I\'ve been waiting for you...young prince...I...am Mal\'Ganis..', 14410,1,0, 'mal_ganis SAY_INTRO_1'),
+ (-1595010, 'As you can see, your people...are now mine. I will now turn this city, household by household, until the flame of life has been snuffed out...forever...', 14411,1,0, 'mal_ganis SAY_INTRO_2'),
+ (-1595011, 'This will be a fine test...Prince Arthas...', 14413,1,0, 'mal_ganis SAY_AGGRO'),
+ (-1595012, 'All too easy...', 14416,1,0, 'mal_ganis SAY_KILL_1'),
+ (-1595013, 'The dark lord is displeased with your interference...', 14417, 1,0,'mal_ganis SAY_KILL_2'),
+ (-1595014, 'It is Prince Arthas I want...not you...', 14418,1,0, 'mal_ganis SAY_KILL_3'),
+ (-1595015, 'Anak\'Keri...', 14422, 1,0,'mal_ganis SAY_SLAY_1'),
+ (-1595016, 'My onslaught will wash over the Lich King\'s forces...', 14423,1,0, 'mal_ganis SAY_SLAY_2'),
+ (-1595017, 'Your death is in vain, tiny mortal...', 14424, 1,0,'mal_ganis SAY_SLAY_3'),
+ (-1595018, 'Your time has come to an end! ', 14425,1,0, 'mal_ganis SAY_SLAY_4'),
+ (-1595019, 'Time out...', 14414, 1,0,'mal_ganis SAY_SLEEP_1'),
+ (-1595020, 'You seem...tired... ', 14415,1,0, 'mal_ganis SAY_SLEEP_2'),
+ (-1595021, '*Struggling sounds* I spent too much time in that weak little shell... ', 14426,1,0, 'mal_ganis SAY_30HEALTH'),
+ (-1595022, '(Eredun) I AM MAL\'GANIS! I AM ETERNAL! ', 14427,1,0, 'mal_ganis SAY_15HEALTH'),
+ (-1595023, 'ENOUGH! I waste my time here...I must gather my strength on the home world...', 14428,1,0, 'mal_ganis SAY_ESCAPE_SPEECH_1'),
+ (-1595024, 'You\'ll never defeat the Lich King without my forces! I\'ll have my revenge...on him, AND you... ', 14429,1,0, 'mal_ganis SAY_ESCAPE_SPEECH_2'),
+ (-1595025, 'Your journey has just begun, young prince...Gather your forces, and meet me in the arctic land of Northrend...It is there we shall settle the score between us...It is there that your true destiny will unfold...', 14412,1,0, 'mal_ganis SAY_OUTRO'),
+-- Meathook
+ (-1595026, 'New toys!',13429,1,0, 'meathook SAY_AGGRO'),
+ (-1595027, 'Boring...',13430,1,0, 'meathook SAY_SLAY_1'),
+ (-1595028, 'Why you stop moving?',13431,1,0, 'meathook SAY_SLAY_2'),
+ (-1595029, 'Get up! Me not done! ',13432,1,0, 'meathook SAY_SLAY_3'),
+ (-1595030, 'Play time! ',13428,1,0, 'meathook SAY_SPAWN'),
+ (-1595031, 'This not fun...',13433,1,0, 'meathook SAY_DEATH'),
+-- Salramm the Fleshcrafter
+ (-1595032, 'Ah, the entertainment has arrived!',13472,1,0, 'salramm SAY_AGGRO'),
+ (-1595033, 'You are too late, champion of Lordaeron. The dead shall have their day. ',13471,1,0, 'salramm SAY_SPAWN'),
+ (-1595034, 'The fun is just beginning!',13473,1,0, 'salramm SAY_SLAY_1'),
+ (-1595035, 'Aah, quality materials!',13474, 1,0,'salramm SAY_SLAY_2'),
+ (-1595036, 'Don\'t worry, I\'ll make good use of you. ',137475, 1,0,'salramm SAY_SLAY_3'),
+ (-1595037, 'You only advance... the master\'s plan...',13483,1,0, 'salramm SAY_DEATH'),
+ (-1595038, 'BOOM! Hahahahah...',13478, 1,0,'salramm SAY_EXPLODE_GHOUL_1'),
+ (-1595039, 'Blood... destruction... EXHILARATING! ',13479,1,0, 'salramm SAY_EXPLODE_GHOUL_2'),
+ (-1595040, 'I want a sample...',13480,1,0, 'salramm SAY_STEAL_FLESH_1'),
+ (-1595041, 'Such strength... it must be mine!',13481,1,0, 'salramm SAY_STEAL_FLESH_2'),
+ (-1595042, 'Your flesh betrays you.',13482,1,0, 'salramm SAY_STEAL_FLESH_3'),
+ (-1595043, 'Say hello to some friends of mine.',13476,1,0, 'salramm SAY_SUMMON_GHOULS_1'),
+ (-1595044, 'Come, citizen of Stratholme! Meet your saviors.',13477,1,0, 'salramm SAY_SUMMON_GHOULS_2');
+
+-- -1 599 000 HALLS OF STONE
+INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) VALUES
+-- Krystallus
+ (-1599000, 'Crush....', 14176, 1,0,'krystallus SAY_AGGRO'),
+ (-1599001, 'Ha...ha...ha...ha...', 14177,1,0, 'krystallus SAY_KILL'),
+ (-1599002, 'Uuuuhhhhhhhhhh......', 14179,1,0, 'krystallus SAY_DEATH'),
+ (-1599003, 'Break.... you....', 14178,1,0, 'krystallus SAY_SHATTER'),
+-- Maiden of Grief
+ (-1599004, 'You shouldn\'t have come...now you will die!',13487,1,0, 'maiden_of_grief SAY_AGGRO'),
+ (-1599005, 'Why must it be this way?',13488,1,0, 'maiden_of_grief SAY_SLAY_1'),
+ (-1599006, 'You had it coming!',13489, 1,0,'maiden_of_grief SAY_SLAY_2'),
+ (-1599007, 'My burden grows heavier.',13490,1,0, 'maiden_of_grief SAY_SLAY_3'),
+ (-1599008, 'This is your own fault!',13491,1,0, 'maiden_of_grief SAY_SLAY_4'),
+ (-1599009, 'I hope you all rot! I never...wanted...this.',13493, 1,0,'maiden_of_grief SAY_DEATH'),
+ (-1599010, 'So much lost time... that you\'ll never get back!',13492,1,0, 'maiden_of_grief SAY_STUN'),
+-- Sjonnir
+ (-1599011, 'Soft, vulnerable shells. Brief, fragile lives. You can not escape the curse of flesh!', 14180,1,0, 'sjonnir SAY_AGGRO'),
+ (-1599012, '...', 14181,1,0, 'sjonnir SAY_SLAY_1'),
+ (-1599013, 'Flesh is no match for iron!', 14182, 1,0,'sjonnir SAY_SLAY_2'),
+ (-1599014, 'Armies of iron will smother the world!', 14183, 1,0,'sjonnir SAY_SLAY_3'),
+ (-1599015, 'Loken will not rest, until the forge is retaken. You changed nothing!', 14184,1,0, 'sjonnir SAY_DEATH');
+
+-- -1 600 000 DRAK'THARON KEEP
+INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) VALUES
+-- Novos the Summoner
+ (-1600000, 'The chill you feel is the herald of your doom.', 13173, 1,0, 'novos SAY_AGGRO'),
+ (-1600001, 'Such is the faith of all who oppose the Lich King!', 13175, 1,0, 'novos SAY_KILL'),
+ (-1600002, 'Your efforts... are in vain.', 13174, 1,0, 'novos SAY_DEATH'),
+ (-1600003, 'Surely you can see the futility of it all!', 13177, 1,0, 'novos SAY_REBUBLE_1'),
+ (-1600004, 'Just give up and die already!', 13178, 1,0, 'novos SAY_REBUBLE_2'),
+ (-1600005, 'Bolster my defenses! Hurry, curse you!', 13176, 1,0, 'novos SAY_NECRO_ADD'),
+-- Trollgore
+ (-1600006, 'Mogas moblath moghuld!', 13181, 1,0, 'trollgore SAY_AGGRO'),
+ (-1600007, '... I will eat you!', 13185, 1,0, 'trollgore SAY_KILL'),
+ (-1600008, '... .. so hungry, .. ... must\'t feed.', 13182, 1,0, 'trollgore SAY_CONSUME'),
+ (-1600009, '*laugh* Corpse go boom!', 13184, 1,0, 'trollgore SAY_EXPLODE'),
+ (-1600010, '...', 13183, 1,0, 'trollgore SAY_DEATH'),
+-- The Prophet Tharon'ja
+ (-1600011, 'Tharon\'ja sees all! The work of mortals shall not end the eternal dynasty!', 13862, 1, 0, 'tharon_ja SAY_AGGRO'),
+ (-1600012, 'As Tharon\'ja predicted.', 13863, 1, 0, 'tharon_ja SAY_KILL_1'),
+ (-1600013, 'As it was written.', 13863, 1, 0, 'tharon_ja SAY_KILL_2'),
+ (-1600014, 'Your flesh serves Tharon\'ja now!', 13865, 1, 0, 'tharon_ja SAY_FLESH_1'),
+ (-1600015, 'Tharon\'ja has a use for your mortal shell!', 13866, 1, 0, 'tharon_ja SAY_FLESH_2'),
+ (-1600016, 'No! A taste... all too brief!', 13868, 1, 0, 'tharon_ja SAY_SKELETON_1'),
+ (-1600017, 'Tharon\'ja will have more!', 13868, 1, 0, 'tharon_ja SAY_SKELETON_2'),
+ (-1600018, 'Im... impossible! Tharon\'ja is eternal! Tharon\'ja... is...', 13869, 1, 0, 'tharon_ja SAY_DEATH');
+
+-- -1 601 000 AZJOL-NERUB
+INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) VALUES
+-- Anub'arak
+ (-1601000, 'Eternal agony awaits you!', 14054,1,0, 'anub_arak SAY_AGGRO'),
+ (-1601001, 'You shall experience my torment, first-hand!', 14055,1,0, 'anub_arak SAY_SLAY_1'),
+ (-1601002, 'You have made your choice.', 14056,1,0, 'anub_arak SAY_SLAY_2'),
+ (-1601003, 'Soon, the Master\'s voice will call to you.', 14057,1,0, 'anub_arak SAY_SLAY_3'),
+ (-1601004, 'Ahhh... RAAAAAGH! Never thought... I would be free of him...', 14069,1,0, 'anub_arak SAY_DEATH'),
+ (-1601005, 'Your armor is useless against my locusts!', 14060, 1,0,'anub_arak SAY_LOCUST_1'),
+ (-1601006, '?!!??!!!', 14067,1,0, 'anub_arak SAY_LOCUST_2'),
+ (-1601007, 'The pestilence upon you!', 14068,1,0, 'anub_arak SAY_LOCUST_3'),
+ (-1601008, '!!!???!!!', 14058,1,0, 'anub_arak SAY_SUBMERGE_1'),
+ (-1601009, 'Come forth, my brethren. Feast on their flesh!', 14059,1,0, 'anub_arak SAY_SUBMERGE_2'),
+ (-1601010, 'I was king of this empire once, long ago. In life I stood as champion. In death I returned as conqueror. Now I protect the kingdom once more. Ironic, yes?', 14053, 1,0,'anub_arak SAY_INTRO'),
+-- Krik'thir
+ (-1601011, 'This kingdom belongs to the Scourge! Only the dead may enter.', 14075,1,0, 'krik_thir SAY_AGGRO'),
+ (-1601012, 'Hash\'tak hi\'tak.', 14076,1,0, 'krik_thir SAY_SLAY_1'),
+ (-1601013, 'You were foolish to come.', 14077, 1,0,'krik_thir SAY_SLAY_2'),
+ (-1601014, 'As Anub\'Arak commands!', 14078,1,0, 'krik_thir SAY_SLAY_3'),
+ (-1601015, 'I should be grateful. But I long ago lost the capacity.', 14087,1,0, 'krik_thir SAY_DEATH'),
+ (-1601016, 'They hunger.', 14085,1,0, 'krik_thir SAY_SWARM_1'),
+ (-1601017, 'Dinner time, my pets.', 14086,1,0, 'krik_thir SAY_SWARM_2'),
+ (-1601018, 'We are besieged. Strike out and bring back their corpses!', 14079,1,0, 'krik_thir SAY_SEND_GROUP_1'),
+ (-1601019, 'We must hold the gate. Attack! Tear them limb from limb!', 14080,1,0, 'krik_thir SAY_SEND_GROUP_2'),
+ (-1601020, 'The gate must be protected at all costs. Rip them to shreds!', 14081,1,0, 'krik_thir SAY_SEND_GROUP_3'),
+ (-1601021, 'Keep an eye on the tunnel. We must not let anyone through!', 14082,1,0, 'krik_thir SAY_PREFIGHT_1'),
+ (-1601022, 'I hear footsteps. Be on your guard.', 14083,1,0, 'krik_thir SAY_PREFIGHT_2'),
+ (-1601023, 'I sense the living. Be ready.', 14084,1,0, 'krik_thir SAY_PREFIGHT_3');
+
+-- -1 602 000 HALLS OF LIGHTNING
+INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) VALUES
+-- General Bjarngrim
+ (-1602000, 'I am the greatest of my father\'s sons! Your end has come!', 14149,1,0,'bjarngrim SAY_AGGRO'),
+ (-1602001, 'So ends your curse!', 14153,1,0, 'bjarngrim SAY_SLAY_1'),
+ (-1602002, 'Flesh... is... weak!', 14154,1,0, 'bjarngrim SAY_SLAY_2'),
+ (-1602003, '...', 14155,1,0, 'bjarngrim SAY_SLAY_3'),
+ (-1602004, 'How can it be...? Flesh is not... stronger!', 14156,1,0, 'bjarngrim SAY_DEATH'),
+ (-1602005, 'Defend yourself, for all the good it will do!', 14151,1,0, 'bjarngrim SAY_BATTLE_STANCE'),
+ (-1602006, 'GRAAAAAH! Behold the fury of iron and steel!', 14152,1,0, 'bjarngrim SAY_BERSEKER_STANCE'),
+ (-1602007, 'Give me your worst!', 14150,1,0, 'bjarngrim SAY_DEFENSIVE_STANCE'),
+-- Ionar
+ (-1602008, 'You wish to confront the master? You must weather the storm!', 14453,1,0, 'ionar SAY_AGGRO'),
+ (-1602009, 'Shocking ... I know!', 14456,1,0, 'ionar SAY_SLAY_1'),
+ (-1602010, 'You atempt the unpossible.', 14457,1,0, 'ionar SAY_SLAY_2'),
+ (-1602011, 'Your spark of light is ... extinguish.', 14458,1,0, 'ionar SAY_SLAY_3'),
+ (-1602012, 'Master... you have guests.', 14459,1,0, 'ionar SAY_DEATH'),
+ (-1602013, 'The slightest spark shall be your undoing.', 14454,1,0, 'ionar SAY_SPLIT_1'),
+ (-1602014, 'No one is safe!', 14455,1,0, 'ionar SAY_SPLIT_2'),
+-- Loken
+ (-1602015, 'What hope is there for you? None!', 14162,1,0, 'loken SAY_AGGRO0'),
+ (-1602016, 'I have witnessed the rise and fall of empires. The birth and extinction of entire species. Over countless millennia the foolishness of mortals has remained beyond a constant. Your presence here confirms this.', 14160,1,0, 'loken SAY_INTRO_1'),
+ (-1602017, 'My master has shown me the future, and you have no place in it. Azeroth will be reborn in darkness. Yogg-Saron shall be released! The Pantheon shall fall!', 14162,1,0, 'loken SAY_INTRO_2'),
+ (-1602018, 'Only mortal...', 14166,1,0, 'loken SAY_SLAY_1'),
+ (-1602019, 'I... am... FOREVER!', 14167,1,0, 'loken SAY_SLAY_2'),
+ (-1602020, 'What little time you had, you wasted!', 14168,1,0, 'loken SAY_SLAY_3'),
+ (-1602021, 'My death... heralds the end of this world.', 14172,1,0, 'loken SAY_DEATH'),
+ (-1602022, 'You cannot hide from fate!', 14163,1,0, 'lokenSAY_NOVA_1'),
+ (-1602023, 'Come closer. I will make it quick.', 14164,1,0, 'loken SAY_NOVA_2'),
+ (-1602024, 'Your flesh cannot hold out for long.', 14165,1,0, 'loken SAY_NOVA_3'),
+ (-1602025, 'You stare blindly into the abyss!', 14169,1,0, 'loken SAY_75HEALTH'),
+ (-1602026, 'Your ignorance is profound. Can you not see where this path leads?', 14170,1,0, 'loken SAY_50HEALTH'),
+ (-1602027, 'You cross the precipice of oblivion!', 14171,1,0, 'loken SAY_25HEALTH'),
+-- Volkhan
+ (-1602028, 'It is you who have destroyed my children? You... shall... pay!',13960,1,0, 'volkhan SAY_AGGRO'),
+ (-1602029, 'The armies of iron will conquer all!',13965, 1,0,'volkhan SAY_SLAY_1'),
+ (-1602030, 'Ha, pathetic!',13966,1,0, 'volkhan SAY_SLAY_2'),
+ (-1602031, 'You have cost me too much work!',13967,1,0, 'volkhan SAY_SLAY_3'),
+ (-1602032, 'The master was right... to be concerned.',13968, 1,0,'volkhan SAY_DEATH'),
+ (-1602033, 'I will crush you beneath my boots!',13963, 1,0,'volkhan SAY_STOMP_1'),
+ (-1602034, 'All my work... undone!',13964, 1,0,'volkhan SAY_STOMP_2'),
+ (-1602035, 'Life from the lifelessness... death for you.',13961,1,0, 'volkhan SAY_FORGE_1'),
+ (-1602036, 'Nothing is wasted in the process. You will see....',13962, 1,0,'volkhan SAY_FORGE_2');
+
+-- -1 603 000 ULDUAR (RAID NIU)
+
+-- -1 604 000 GUNDRAK
+INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) VALUES
+-- Gal'darah
+ (-1604000, 'I\'m gonna spil your guts, man!', 14430, 1,0,'gal_darah SAY_AGGRO'),
+ (-1604001, 'What a rush.', 14436,1,0, 'gal_darah SAY_SLAY_1'),
+ (-1604002, 'Who needs gods, when we ARE gods!', 14437, 1,0,'gal_darah SAY_SLAY_2'),
+ (-1604003, 'I told ya so ...', 14438,1,0, 'gal_darah SAY_SLAY_3'),
+ (-1604004, 'Even the mighty ... can .. fall.', 14439,1,0, 'gal_darah SAY_DEATH'),
+ (-1604005, 'God damn! Impale them!', 14433, 1,0,'gal_darah SAY_SUMMON_RHINO_1'),
+ (-1604006, 'Kill them ALL!', 14434, 1,0,'gal_darah SAY_SUMMON_RHINO_2'),
+ (-1604007, 'Say hello to my BIG friend.', 14435,1,0, 'gal_darah SAY_SUMMON_RHINO_3'),
+ (-1604008, 'Ain\'t gonna bee nothig left after this.', 14431,1,0, 'gal_darah SAY_TRANSFORM_1'),
+ (-1604009, 'You wanna see POWER? I\'m gonna show you POWER!', 14432,1,0, 'gal_darah SAY_TRANSFORM_2'),
+-- Moorabi
+ (-1604010, 'We fought back the Scourge. What chance you be thinking you got?', 14721,1,0, 'moorabi SAY_AGGRO'),
+ (-1604011, 'I crush you, cockroaches!', 14725,1,0, 'moorabi SAY_SLAY_1'),
+ (-1604012, 'Who gonna stop me, you?', 14726,1,0, 'moorabi SAY_SLAY_2'),
+ (-1604013, 'Not so tough now.', 14727,1,0, 'moorabi SAY_SLAY_3'),
+ (-1604014, 'If our gods can die, then so can we.', 14728,1,0, 'moorabi SAY_DEATH'),
+ (-1604015, 'Get ready for something much bigger!', 14722,1,0, 'moorabi SAY_TRANSFORM'),
+ (-1604016, 'The ground will swallow you up!', 14723,1,0, 'moorabi SAY_QUAKE'),
+-- Slad'ran
+ (-1604017, 'Drak\'thari gonna kill anybody who trespass on this lands.', 14443,1,0, 'slad_ran SAY_AGGRO'),
+ (-1604018, 'Can not breath then, good ...', 14446,1,0, 'slad_ran SAY_SLAY_1'),
+ (-1604019, 'You\'re scared now.', 14447,1,0, 'slad_ran SAY_SLAY_2'),
+ (-1604020, 'I eat you next man!', 14448,1,0, 'slad_ran SAY_SLAY_3'),
+ (-1604021, 'I ... see now. Scourge was not tha greatest enemy.', 14449,1,0, 'slad_ran SAY_DEATH'),
+ (-1604022, 'Minions of this ... heed my call.', 14444,1,0, 'slad_ran SAY_SUMMON_SNAKES'),
+ (-1604023, 'A thousand fangs gonna rim yar flesh.', 14445,1,0, 'slad_ran SAY_SUMMON_CONSTRICTORS');
+
+-- -1 608 000 VIOLET HOLD
+INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) VALUES
+-- Cyanigosa
+ (-1608000, 'We finish this now, champions of Kirin Tor!', 13947, 1, 0, 'cyanigosa SAY_AGGRO'),
+ (-1608001, 'I will end the Kirin Tor!', 13952, 1, 0, 'cyanigosa SAY_SLAY_1'),
+ (-1608002, 'Dalaran will fall!', 13953, 1, 0, 'cyanigosa SAY_SLAY_2'),
+ (-1608003, 'So ends your defiance of the Spell-Weaver!', 13954, 1, 0, 'cyanigosa SAY_SLAY_3'),
+ (-1608004, 'Perhaps... we have... underestimated... you.', 13955, 1, 0, 'cyanigosa SAY_DEATH'),
+ (-1608005, 'A valiant defense, but this city must be razed. I will fulfill Malygos\'s wishes myself!', 13946, 1, 0, 'cyanigosa SAY_SPAWN'),
+ (-1608006, 'Am I interrupting?', 13951, 1, 0, 'cyanigosa SAY_DISRUPTION'),
+ (-1608007, 'Shiver and die!', 13948, 1, 0, 'cyanigosa SAY_BREATH_ATTACK'),
+ (-1608008, 'The world has forgotten what true magic is! Let this be a reminder!', 13949, 1, 0, 'cyanigosa SAY_SPECIAL_ATTACK_1'),
+ (-1608009, 'Who among you can withstand my power?', 13950, 1, 0, 'cyanigosa SAY_SPECIAL_ATTACK_2'),
+-- Erekem
+ (-1608010, 'Notcawwget in way ofrrak-rrakflee!', 14219, 1, 0, 'erekem SAY_AGGRO'),
+ (-1608011, '...', 14222, 1, 0, 'erekem SAY_SLAY_1'),
+ (-1608012, 'Precious life ... wasted.', 14223, 1, 0, 'erekem SAY_SLAY_2'),
+ (-1608013, 'Only strong ... survive.', 14224, 1, 0, 'erekem SAY_SLAY_3'),
+ (-1608014, 'Nokaw, kawflee...', 14225, 1, 0, 'erekem SAY_DEATH'),
+ (-1608015, 'Free tommfly onw. Ra-aak... Not find usekh-ekh! Escape!', 14218, 1, 0, 'erekem SAY_SPAWN'),
+ (-1608016, 'My-raaakfavorite! Awk awk awk! Raa-kaa!', 14220, 1, 0, 'erekem SAY_ADD_KILLED'),
+ (-1608017, 'Nasty little...A-ak, kaw! Kill! Yes, kill you!', 14221, 1, 0, 'erekem SAY_BOTH_ADDS_KILLED'),
+-- Ichoron
+ (-1608018, 'Stand aside, mortals!', 14230, 1, 0, 'ichoron SAY_AGGRO'),
+ (-1608019, 'I am a force of nature!', 14234, 1, 0, 'ichoron SAY_SLAY_1'),
+ (-1608020, 'I shall pass!', 14235, 1, 0, 'ichoron SAY_SLAY_2'),
+ (-1608021, 'You can not stop the tide!', 14236, 1, 0, 'ichoron SAY_SLAY_3'),
+ (-1608022, 'I... recede.', 14237, 1, 0, 'ichoron SAY_DEATH'),
+ (-1608023, 'I... am fury... unrestrained!', 14239, 1, 0, 'ichoron SAY_SPAWN'),
+ (-1608024, 'I shall consume, decimate, devastate, and destroy! Yield now to the wrath of the pounding sea!', 14231, 1, 0, 'ichoron SAY_ENRAGE'),
+ (-1608025, 'I will not be contained! Ngyah!!', 14233, 1, 0, 'ichoron SAY_SHATTER'),
+ (-1608026, 'Water can hold any form, take any shape... overcome any obstacle.', 14232, 1, 0, 'ichoron SAY_BUBBLE'),
+-- Xevozz
+ (-1608027, 'It seems my freedom must be bought with blood...', 14499, 1, 0, 'xevozz SAY_AGGRO'),
+ (-1608028, 'Nothing personal.', 14504, 1, 0, 'xevozz SAY_SLAY_1'),
+ (-1608029, 'Business concluded.', 14505, 1, 0, 'xevozz SAY_SLAY_2'),
+ (-1608030, 'Profit!', 14506, 1, 0, 'xevozz SAY_SLAY_3'),
+ (-1608031, 'This is an... unrecoverable... loss.', 14507, 1, 0, 'xevozz SAY_DEATH'),
+ (-1608032, 'Back in business! Now to execute an exit strategy.', 14498, 1, 0, 'xevozz SAY_SPAWNED'),
+ (-1608033, 'It would seem that a renegotiation is in order.', 14503, 1, 0, 'xevozz SAY_CHARGED'),
+ (-1608034, 'The air teems with latent energy... quite the harvest!', 14501, 1, 0, 'xevozz SAY_REPEAT_SUMMON_1'),
+ (-1608035, 'Plentiful, exploitable resources... primed for acquisition!', 14502, 1, 0, 'xevozz SAY_REPEAT_SUMMON_2'),
+ (-1608036, 'Intriguing... a high quantity of arcane energy is near. Time for some prospecting...', 14500, 1, 0, 'xevozz SAY_SUMMON_ENERGY'),
+-- Zuramat
+ (-1608037, 'Eradicate.', 13996, 1, 0, 'zuramat SAY_AGGRO'),
+ (-1608038, 'More... energy.', 13999, 1, 0, 'zuramat SAY_SLAY_1'),
+ (-1608039, 'Relinquish.', 14000, 1, 0, 'zuramat SAY_SLAY_2'),
+ (-1608040, 'Fall... to shadow.', 14001, 1, 0, 'zuramat SAY_SLAY_3'),
+ (-1608041, 'Disperse.', 14002, 1, 0, 'zuramat SAY_DEATH'),
+ (-1608042, 'I am... renewed.', 13995, 1, 0, 'zuramat SAY_SPAWN'),
+ (-1608043, 'Know... my... pain.', 13997, 1, 0, 'zuramat SAY_SHIELD'),
+ (-1608044, 'Gaze... into the void.', 13998, 1, 0, 'zuramat SAY_WHISPER');
+
+-- -1 615 000 OBSIDIAN SANCTUM
+INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) VALUES
+-- Shadron
+ (-1615000, 'I fear nothing! Least of all you!', 14111,1,0, 'shadron SAY_SHADRON_AGGRO'),
+ (-1615001, 'You are insignificant!', 14112,1,0, 'shadron SAY_SHADRON_SLAY_1'),
+ (-1615002, 'Such mediocre resistance!', 14113,1,0, 'shadron SAY_SHADRON_SLAY_2'),
+ (-1615003, 'We...are superior! How could this...be...', 14118, 1,0,'shadron SAY_SHADRON_DEATH'),
+ (-1615004, 'You are easily bested! ', 14114,1,0, 'shadron SAY_SHADRON_BREATH'),
+ (-1615005, 'I will take pity on you Sartharion, just this once.', 14117, 1,0,'shadron SAY_SHADRON_RESPOND'),
+ (-1615006, 'Father tought me well!', 14115,1,0, 'shadron SAY_SHADRON_SPECIAL_1'),
+ (-1615007, 'On your knees!', 14116,1,0, 'shadron SAY_SHADRON_SPECIAL_2'),
+-- Tenebron
+ (-1615008, 'You have no place here. Your place is among the departed.', 14122,1,0, 'tenebron SAY_TENEBRON_AGGRO'),
+ (-1615009, 'No contest.', 14123,1,0, 'tenebron SAY_TENEBRON_SLAY_1'),
+ (-1615010, 'Typical... Just as I was having fun.', 14124,1,0, 'tenebron SAY_TENEBRON_SLAY_2'),
+ (-1615011, 'I should not... have held back...', 14129,1,0, 'tenebron SAY_TENEBRON_DEATH'),
+ (-1615012, 'To darkness I condemn you...', 14125,1,0, 'tenebron SAY_TENEBRON_BREATH'),
+ (-1615013, 'It is amusing to watch you struggle. Very well, witness how it is done.', 14128, 1,0,'tenebron SAY_TENEBRON_RESPOND'),
+ (-1615014, 'Arrogant little creatures! To challenge powers you do not yet understand...', 14126,1,0, 'tenebron SAY_TENEBRON_SPECIAL_1'),
+ (-1615015, 'I am no mere dragon! You will find I am much, much, more...', 14127, 1,0,'tenebron SAY_TENEBRON_SPECIAL_2'),
+-- Sartharion
+ (-1615016, 'It is my charge to watch over these eggs. I will see you burn before any harm comes to them!', 14093,1,0, 'sartharion SAY_SARTHARION_AGGRO'),
+ (-1615017, 'This pathetic siege ends NOW!', 14103,1,0, 'sartharion SAY_SARTHARION_BERSERK'),
+ (-1615018, 'Burn, you miserable wretches!', 14098, 1,0,'sartharion SAY_SARTHARION_BREATH'),
+ (-1615019, 'Shadron! Come to me, all is at risk!', 14105,1,0, 'sartharion SARTHARION_CALL_SHADRON'),
+ (-1615020, 'Tenebron! The eggs are yours to protect as well!', 14106,1,0, 'sartharion SAY_SARTHARION_CALL_TENEBRON'),
+ (-1615021, 'Vesperon! The clutch is in danger! Assist me!', 14104,1,0, 'sartharion SAY_SARTHARION_CALL_VESPERON'),
+ (-1615022, 'Such is the price... of failure...', 14107,1,0, 'sartharion SAY_SARTHARION_DEATH'),
+ (-1615023, 'Such flammable little insects....', 14099,1,0, 'sartharion SAY_SARTHARION_SPECIAL_1'),
+ (-1615024, 'Your charred bones will litter the floor!', 14100,1,0, 'sartharion SAY_SARTHARION_SPECIAL_2'),
+ (-1615025, 'How much heat can you take?', 14101,1,0, 'sartharion SAY_SARTHARION_SPECIAL_3'),
+ (-1615026, 'All will be reduced to ash!', 14102,1,0, 'sartharion SAY_SARTHARION_SPECIAL_4'),
+ (-1615027, 'You will make a fine meal for the hatchlings.', 14094,1,0, 'sartharion SAY_SARTHARION_SLAY_1'),
+ (-1615028, 'You are the grave disadvantage.', 14096,1,0, 'sartharion SAY_SARTHARION_SLAY_2'),
+ (-1615029, 'This is why we call you lesser beeings.', 14097,1,0, 'sartharion SAY_SARTHARION_SLAY_3'),
+-- Vesperon
+ (-1615030, 'You pose no threat, lesser beings...give me your worst!', 14133, 1,0,'vesperon SAY_VESPERON_AGGRO'),
+ (-1615031, 'The least you could do is put up a fight...', 14134,1,0, 'vesperon SAY_VESPERON_SLAY_1'),
+ (-1615032, 'Was that the best you can do?', 14135,1,0, 'vesperon SAY_VESPERON_SLAY_2'),
+ (-1615033, 'I still have some...fight..in...me...', 14140, 1,0,'vesperon SAY_VESPERON_DEATH'),
+ (-1615034, 'I will pick my teeth with your bones!', 14136,1,0, 'vesperon SAY_VESPERON_BREATH'),
+ (-1615035, 'Father was right about you, Sartharion...You are a weakling!', 14139,1,0, 'vesperon SAY_VESPERON_RESPOND'),
+ (-1615036, 'Aren\'t you tricky...I have a few tricks of my own...', 14137,1,0, 'vesperon SAY_VESPERON_SPECIAL_1'),
+ (-1615037, 'Unlike, I have many talents.', 14138,1,0, 'vesperon SAY_VESPERON_SPECIAL_2');
+
+-- -1 616 000 EYE OF ETERNITY
+INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) VALUES
+-- Malygos
+ (-1616000, 'I will teach you IGNORANT children just how little you know of magic...', 14524,1,0, 'malygos SAY_ANTI_MAGIC_SHELL'),
+ (-1616001, 'YOU WILL NOT SUCCEED WHILE I DRAW BREATH!', 14518,1,0, 'malygos SAY_BREATH_ATTACK'),
+ (-1616002, 'I AM UNSTOPPABLE!', 14533,1,0, 'malygos SAY_HIGH_DAMAGE_MODE'),
+ (-1616003, 'Watch helplessly as your hopes are swept away...', 14525, 1,0,'malygos SAY_MAGIC_BLAST'),
+ (-1616004, 'Still standing? Not for long...', 14537, 1,0,'malygos SAY_GENERIC_SPELL_1'),
+ (-1616005, 'Your cause is lost!', 14538, 1,0,'malygos SAY_GENERIC_SPELL_2'),
+ (-1616006, 'Your fragile mind will be shattered! ', 14539,1,0, 'malygos SAY_GENERIC_SPELL_3'),
+ (-1616007, 'UNTHINKABLE! The mortals will destroy...e-everything...my sister...what have you-', 14540,1,0, 'malygos SAY_DEATH'),
+ (-1616008, 'Lesser beings, intruding here! A shame that your excess courage does not compensate for your stupidity!', 14512,1,0, 'malygos SAY_PREFIGHT_1'),
+ (-1616009, 'None but the blue dragonflight are welcome here! Perhaps this is the work of Alexstrasza? Well then, she has sent you to your deaths.', 14513,1,0, 'malygos SAY_PREFIGHT_2'),
+ (-1616010, 'What could you hope to accomplish, to storm brassily into my domain? To employ MAGIC? Against ME? *Laughs*', 14514,1,0, 'malygos SAY_PREFIGHT_3'),
+ (-1616011, 'I am without limits here...the rules of your cherished reality do not apply...In this realm, I am in control...', 14515, 1,0,'malygos SAY_PREFIGHT_4'),
+ (-1616012, 'I give you one chance. Pledge loyalty to me, and perhaps I won\'t slaughter you for your insolence!', 14516,1,0, 'malygos SAY_PREFIGHT_5'),
+ (-1616013, 'My patience has reached its limit, I WILL BE RID OF YOU!', 14517,1,0, 'malygos SAY_PHASE1_AGGRO'),
+ (-1616014, 'I had hoped to end your lives quickly, but you have proven more...resilient then I had anticipated. None the less, your efforts are in vain, it is you reckless, careless mortals who are to blame for this war! I do what I must...And if it means your...extinction...THEN SO BE IT!', 14522,1,0, 'malygos SAY_PHASE1_END'),
+ (-1616015, 'Your stupidity has finally caught up to you!', 14519,1,0, 'malygos SAY_PHASE1_SLAY_1'),
+ (-1616016, 'More artifacts to confiscate...', 14520, 1,0,'malygos SAY_PHASE1_SLAY_2'),
+ (-1616017, '*Laughs* How very...naive.. ', 14521,1,0, 'malygos SAY_PHASE1_SLAY_3'),
+ (-1616018, 'Few have experienced the pain I will now inflict on you!', 14523, 1,0,'malygos SAY_PHASE2_AGGRO'),
+ (-1616019, 'ENOUGH! If you intend to reclaim Azeroth\'s magic, then you shall have it... ', 14529,1,0, 'malygos SAY_PHASE2_END'),
+ (-1616020, 'Your energy will be put to good use!', 14526,1,0, 'malygos SAY_PHASE2_SLAY_1'),
+ (-1616021, 'I AM THE SPELL WEAVER! My power is INFINITE!', 14527, 1,0,'malygos SAY_PHASE2_SLAY_2'),
+ (-1616022, 'Your spirit will linger here forever!', 14528, 1,0,'malygos SAY_PHASE2_SLAY_3'),
+ (-1616023, 'Now your benefactors make their appearance...But they are too late. The powers contained here are powerful enough to destroy the world ten times over! What do you think they will do to you?', 14530,1,0, 'malygos SAY_PHASE3_INTRO'),
+ (-1616024, 'SUBMIT!', 14531,1,0, 'malygos SAY_PHASE3_AGGRO'),
+ (-1616025, 'Alexstrasza! Another of your brood falls!', 14534,1,0, 'malygos SAY_PHASE3_SLAY_1'),
+ (-1616026, 'Little more then gnats!', 14535, 1,0,'malygos SAY_PHASE3_SLAY_2'),
+ (-1616027, 'Your red allies will share your fate...', 14536, 1,0,'slad_ran SAY_PHASE3_SLAY_3'),
+ (-1616028, 'The powers at work here exceed anything you could possibly imagine!', 14532, 1,0,'malygos SAY_PHASE3_BIG_ATTACK');
+
+-- -1 619 000 AHN'KAHET
+ INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) VALUES
+-- Jedoga Shadowseeker
+ (-1619000, 'These are sacred halls, your intrusion will be met with death', 14343, 1, 0, 'jedoga SAY_AGGRO'),
+ (-1619001, 'Who among you is devoted', 14344, 1, 0, 'jedoga SAY_C_SACRIFICE_1'),
+ (-1619002, 'You there! Step foward', 14345, 1, 0, 'jedoga SAY_C_SACRIFICE_2'),
+ (-1619003, 'Yogg-Saron, grant me your power!', 14346, 1, 0, 'jedoga SAY_SACRIFICE_1'),
+ (-1619004, 'Master, a gift for you!', 14347, 1, 0, 'jedoga SAY_SACRIFICE_2'),
+ (-1619005, 'Glory to the Yogg-Saron!', 14348, 1, 0, 'jedoga SAY_SLAY_1'),
+ (-1619006, 'You are unworthy', 14349, 1, 0, 'jedoga SAY_SLAY_2'),
+ (-1619007, 'Get up! You haven\'t suffered enough', 14350, 1, 0, 'jedoga SAY_SLAY_3'),
+ (-1619008, 'Do not expect your sacrilege... to go unpunished.', 14351, 1, 0, 'jedoga SAY_DEATH'),
+ (-1619009, 'The elements themselves will rise up against the civilized world! Only the faithful will be spared!', 14352, 1, 0, 'jedoga SAY_PREACHING_1'),
+ (-1619010, 'Immortality can be yours. But only if you pledge yourself fully to Yogg-Saron!', 14353, 1, 0, 'jedoga SAY_PREACHING_2'),
+ (-1619011, 'Here on the very borders of his domain. You will expirience powers you would never have imagined!', 14354, 1, 0, 'jedoga SAY_PREACHING_3'),
+ (-1619012, 'You have traveled long and risked much to be here. Your devotion shall be rewarded.', 14355, 1, 0, 'jedoga SAY_PREACHING_4'),
+ (-1619013, 'The faithful shall be exalted! But there is more work to be done. We will press on until all of Azeroth lies beneath his shadow!', 14356, 1, 0, 'jedoga SAY_PREACHING_5'),
+-- Elder Nadox
+ (-1619014, 'The secrets of the deep shall remain hidden.', 14033, 1, 0, 'nadox SAY_AGGRO'),
+ (-1619015, 'Sleep now, in the cold dark.', 14036, 1, 0, 'nadox SAY_SLAY_1'),
+ (-1619016, 'For the Lich King!', 14307, 1, 0, 'nadox SAY_SLAY_2'),
+ (-1619017, 'Perhaps we will be allies soon.', 14038, 1, 0, 'nadox SAY_SLAY_3'),
+ (-1619018, 'Master, is my service complete?', 14039, 1, 0, 'nadox SAY_DEATH'),
+ (-1619019, 'The young must not grow hungry.', 14034, 1, 0, 'nadox SAY_EGG_SAC_1'),
+ (-1619020, 'Shad\'ak kerish\'akak', 14035, 1, 0, 'nadox SAY_EGG_SAC_2'),
+-- Prince Taldaram
+ (-1619021, 'I will feast on your remains.', 14360, 1, 0, 'taldaram SAY_AGGRO'),
+ (-1619022, '(Elfish)', 14365, 1, 0, 'taldaram SAY_SLAY_1'),
+ (-1619023, 'I will drink no blood before it is time.', 14366, 1, 0, 'taldaram SAY_SLAY_2'),
+ (-1619024, 'One final embrace.', 14367, 1, 0, 'taldaram SAY_SLAY_3'),
+ (-1619025, 'Still ... I hunger, still ... I thirst...', 14368, 1, 0, 'taldaram SAY_DEATH'),
+ (-1619026, 'Your heartbeat is music to my ears.', 14361, 1, 0, 'taldaram SAY_VANISH_1'),
+ (-1619027, 'I am nowhere. I am everywhere. I am the watcher, unseen.', 14362, 1, 0, 'taldaram SAY_VANISH_2'),
+ (-1619028, 'So appetizing.', 14363, 1, 0, 'taldaram SAY_FEED_1'),
+ (-1619029, 'Fresh, warm blood. It has been too long.', 14364, 1, 0, 'taldaram SAY_FEED_2'),
+-- Herald Volazj
+ (-1619030, '??? ??? ???', 14043, 1, 0, 'volazj SAY_AGGRO'),
+ (-1619031, 'Ywaq ma phgwa\\\'cul hnakf. - They are the whisper on the shivering wind.', 14045, 1, 0, 'volazj SAY_AGGRO'),
+ (-1619032, '?!? !?! ?!?', 14046, 1, 0, 'volazj SAY_AGGRO'),
+ (-1619033, '!?! !?! !?!', 14047, 1, 0, 'volazj SAY_AGGRO'),
+ (-1619034, 'Iilth vwah, uhn\'agth fhssh za. - Where one falls, many shall take its place.', 14048, 1, 0, 'volazj SAY_AGGRO'),
+ (-1619035, '... ...! ...?', 14049, 1, 0, 'volazj SAY_AGGRO'),
+ (-1619036, 'Phasing', 14044, 1, 0, 'volazj SAY_AGGRO');
diff --git a/src/bindings/scripts/sql/WotLK/wotlk_bosses.sql b/src/bindings/scripts/sql/WotLK/wotlk_bosses.sql
new file mode 100644
index 00000000000..f8d10a64cf3
--- /dev/null
+++ b/src/bindings/scripts/sql/WotLK/wotlk_bosses.sql
@@ -0,0 +1,124 @@
+/* */
+/* AZJOL-NERUB */
+/* */
+
+/* AHN'KAHET */
+UPDATE `instance_template` SET `script`='instance_ahn_kahet' WHERE `map`=4494;
+UPDATE `creature_template` SET `ScriptName`='boss_jedoga' WHERE `entry`='29310';
+UPDATE `creature_template` SET `ScriptName`='boss_nadox' WHERE `entry`='29309';
+UPDATE `creature_template` SET `ScriptName`='boss_taldaram' WHERE `entry`='29308';
+UPDATE `creature_template` SET `ScriptName`='boss_volazj' WHERE `entry`='29311';
+
+/* AZJOL-NERUB */
+UPDATE `instance_template` SET `script`='instance_azjol_nerub' WHERE `map`=3477;
+UPDATE `creature_template` SET `ScriptName`='boss_anub_arak' WHERE `entry`='29120';
+UPDATE `creature_template` SET `ScriptName`='boss_hardronox' WHERE `entry`='28921';
+UPDATE `creature_template` SET `ScriptName`='boss_krik_thir' WHERE `entry`='28684';
+
+/* THE CULLING OF STRATHOLME */
+UPDATE `instance_template` SET `script`='instance_culling_of_stratholme' WHERE `map`=4100;
+UPDATE `creature_template` SET `ScriptName`='boss_epoch' WHERE `entry`='26532';
+UPDATE `creature_template` SET `ScriptName`='boss_mal_ganis' WHERE `entry`='26533';
+UPDATE `creature_template` SET `ScriptName`='boss_meathook' WHERE `entry`='26529';
+UPDATE `creature_template` SET `ScriptName`='boss_salramm' WHERE `entry`='26530';
+
+/* DRAK'THARON KEEP */
+UPDATE `instance_template` SET `script`='instance_drak_tharon' WHERE `map`=4196;
+UPDATE `creature_template` SET `ScriptName`='boss_dred' WHERE `entry`='27483';
+UPDATE `creature_template` SET `ScriptName`='boss_novos' WHERE `entry`='26631';
+UPDATE `creature_template` SET `ScriptName`='boss_tharon_ja' WHERE `entry`='26632';
+UPDATE `creature_template` SET `ScriptName`='boss_trollgore' WHERE `entry`='26630';
+
+/* GUNDRAK */
+UPDATE `instance_template` SET `script`='instance_gundrak' WHERE `map` =4375;
+UPDATE `creature_template` SET `ScriptName`='boss_eck' WHERE `entry`='29932';
+UPDATE `creature_template` SET `ScriptName`='boss_drakkari_colossus' WHERE `entry`='29307';
+UPDATE `creature_template` SET `ScriptName`='boss_gal_darah' WHERE `entry`='29306';
+UPDATE `creature_template` SET `ScriptName`='boss_moorabi' WHERE `entry`='29305';
+UPDATE `creature_template` SET `ScriptName`='boss_slad_ran' WHERE `entry`='29304';
+
+/* */
+/* THE NEXUS */
+/* */
+
+/* EYE OF ETERNITY */
+UPDATE `instance_template` SET `script`='instance_eye_of_eternity' WHERE `map`=4500;
+UPDATE `creature_template` SET `ScriptName`='boss_malygos' WHERE `entry`='28859';
+
+/* NEXUS */
+UPDATE `instance_template` SET `script`='instance_nexus' WHERE `map`=4120;
+UPDATE `creature_template` SET `ScriptName`='boss_anomalus' WHERE `entry`='26763';
+UPDATE `creature_template` SET `ScriptName`='npc_chaotic_rift' WHERE `entry`='26918';
+UPDATE `creature_template` SET `ScriptName`='mob_crazed_mana_wraith' WHERE `entry`='26746';
+UPDATE `creature_template` SET `ScriptName`='boss_keristrasza' WHERE `entry`='26723';
+UPDATE `creature_template` SET `ScriptName`='boss_magus_telestra' WHERE `entry`='26731';
+UPDATE `creature_template` SET `ScriptName`='boss_ormorok' WHERE `entry`='26794';
+UPDATE `creature_template` SET `ScriptName`='boss_commander_stoutbeard' WHERE `entry`='26796';
+UPDATE `creature_template` SET `ScriptName`='boss_commander_kolurg' WHERE `entry`='26798';
+
+/* OCULUS */
+UPDATE `instance_template` SET `script`='instance_oculus' WHERE `map`=4228;
+UPDATE `creature_template` SET `ScriptName`='boss_drakos' WHERE `entry`='27654';
+UPDATE `creature_template` SET `ScriptName`='boss_eregos' WHERE `entry`='27656';
+UPDATE `creature_template` SET `ScriptName`='boss_urom' WHERE `entry`='27655';
+UPDATE `creature_template` SET `ScriptName`='boss_varos' WHERE `entry`='27447';
+
+/* OBSIDIAN SANCTUM */
+UPDATE `instance_template` SET `script`='instance_obsidian_sanctum' WHERE `map`=4493;
+UPDATE `creature_template` SET `ScriptName`='boss_sartharion' WHERE `entry`='28860';
+UPDATE `creature_template` SET `ScriptName`='mob_vesperon' WHERE `entry`='30449';
+UPDATE `creature_template` SET `ScriptName`='mob_shadron' WHERE `entry`='30451';
+UPDATE `creature_template` SET `ScriptName`='mob_tenebron' WHERE `entry`='30452';
+UPDATE `creature_template` SET `ScriptName`='mob_whelp' WHERE `entry`='30890';
+UPDATE `creature_template` SET `ScriptName`='mob_whelp' WHERE `entry`='31214';
+
+/* */
+/* ULDUAR */
+/* */
+
+/* HALLS OF LIGHTNING */
+UPDATE `instance_template` SET `script`='instance_halls_of_lightning' WHERE `map`=4272;
+UPDATE `creature_template` SET `ScriptName`='boss_bjarngrim' WHERE `entry`='28586';
+UPDATE `creature_template` SET `ScriptName`='boss_ionar' WHERE `entry`='28546';
+UPDATE `creature_template` SET `ScriptName`='spark_of_ionar' WHERE `entry`='28962';
+UPDATE `creature_template` SET `ScriptName`='boss_volkhan' WHERE `entry`='28587';
+UPDATE `creature_template` SET `ScriptName`='mob_molten_golem' WHERE `entry`='28695';
+UPDATE `creature_template` SET `ScriptName`='boss_loken' WHERE `entry`='28923';
+/* HALLS OF STONE */
+UPDATE `instance_template` SET `script`='instance_halls_of_stone' WHERE `map`=4264;
+UPDATE `creature_template` SET `ScriptName`='boss_krystallus' WHERE `entry`='27977';
+UPDATE `creature_template` SET `ScriptName`='boss_maiden_of_grief' WHERE `entry`='27975';
+UPDATE `creature_template` SET `ScriptName`='boss_sjonnir' WHERE `entry`='27978';
+
+/* */
+/* UTGARDE KEEP */
+/* */
+
+/* UTGARDE KEEP */
+UPDATE `instance_template` SET `script`='instance_keep' WHERE `map`=206;
+UPDATE `creature_template` SET `ScriptName`='boss_dalronn' WHERE `entry`='24201';
+UPDATE `creature_template` SET `ScriptName`='boss_ingvar' WHERE `entry`='23954';
+UPDATE `creature_template` SET `ScriptName`='boss_keleseth' WHERE `entry`='23953';
+UPDATE `creature_template` SET `ScriptName`='boss_skarvald' WHERE `entry`='24200';
+
+/* UTGARDE PINNACLE */
+UPDATE `instance_template` SET `script`='instance_pinnacle' WHERE `map`=1196;
+UPDATE `creature_template` SET `ScriptName`='boss_palehoof' WHERE `entry`='26687';
+UPDATE `creature_template` SET `ScriptName`='boss_skadi' WHERE `entry`='26693';
+UPDATE `creature_template` SET `ScriptName`='boss_svala' WHERE `entry`='26668';
+UPDATE `creature_template` SET `ScriptName`='boss_ymiron' WHERE `entry`='26861';
+
+/* VAULT OF ARCHAVON */
+UPDATE `instance_template` SET `script`='instance_archavon' WHERE `map`=4603;
+UPDATE `creature_template` SET `ScriptName`='boss_archavon' WHERE `entry`='31125';
+UPDATE `creature_template` SET `ScriptName`='mob_archavon_warder' WHERE `entry`='32353';
+
+/* VIOLET HOLD */
+UPDATE `instance_template` SET `script`='instance_violet_hold' WHERE `map`=4415;
+UPDATE `creature_template` SET `ScriptName`='boss_cyanigosa' WHERE `entry`='31134';
+UPDATE `creature_template` SET `ScriptName`='boss_erekem' WHERE `entry`='29315';
+UPDATE `creature_template` SET `ScriptName`='boss_ichoron' WHERE `entry`='29313';
+UPDATE `creature_template` SET `ScriptName`='boss_lavanthor' WHERE `entry`='29312';
+UPDATE `creature_template` SET `ScriptName`='boss_moragg' WHERE `entry`='29316';
+UPDATE `creature_template` SET `ScriptName`='boss_xevozz' WHERE `entry`='29266';
+UPDATE `creature_template` SET `ScriptName`='boss_zuramat' WHERE `entry`='29314';
diff --git a/src/bindings/scripts/system.cpp b/src/bindings/scripts/system.cpp
index 893e476e2fd..ab62e530681 100644
--- a/src/bindings/scripts/system.cpp
+++ b/src/bindings/scripts/system.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/framework/Dynamic/FactoryHolder.h b/src/framework/Dynamic/FactoryHolder.h
index 39c6061a687..858b8c1e1d3 100644
--- a/src/framework/Dynamic/FactoryHolder.h
+++ b/src/framework/Dynamic/FactoryHolder.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Dynamic/ObjectRegistry.h b/src/framework/Dynamic/ObjectRegistry.h
index 6e4b9aca53b..8c2659e8f53 100644
--- a/src/framework/Dynamic/ObjectRegistry.h
+++ b/src/framework/Dynamic/ObjectRegistry.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/GameSystem/Grid.h b/src/framework/GameSystem/Grid.h
index 326101d68dd..cebaebc68c6 100644
--- a/src/framework/GameSystem/Grid.h
+++ b/src/framework/GameSystem/Grid.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/GameSystem/GridLoader.h b/src/framework/GameSystem/GridLoader.h
index 23d32858e50..8a483044f8f 100644
--- a/src/framework/GameSystem/GridLoader.h
+++ b/src/framework/GameSystem/GridLoader.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/GameSystem/GridRefManager.h b/src/framework/GameSystem/GridRefManager.h
index 715d13fa2fe..bd32f836e18 100644
--- a/src/framework/GameSystem/GridRefManager.h
+++ b/src/framework/GameSystem/GridRefManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/GameSystem/GridReference.h b/src/framework/GameSystem/GridReference.h
index 5f9dbaf5279..d4bd6752515 100644
--- a/src/framework/GameSystem/GridReference.h
+++ b/src/framework/GameSystem/GridReference.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/GameSystem/NGrid.h b/src/framework/GameSystem/NGrid.h
index a4863bb287e..126703febd2 100644
--- a/src/framework/GameSystem/NGrid.h
+++ b/src/framework/GameSystem/NGrid.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -75,21 +75,21 @@ class TRINITY_DLL_DECL NGrid
public:
typedef Grid<ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> GridType;
- NGrid(uint32 id, int32 x, int32 y, time_t expiry, bool unload = true) :
- i_gridId(id), i_cellstate(GRID_STATE_INVALID), i_x(x), i_y(y), i_GridObjectDataLoaded(false)
- {
- i_GridInfo = GridInfo(expiry, unload);
- }
+ NGrid(uint32 id, int32 x, int32 y, time_t expiry, bool unload = true)
+ : i_gridId(id), i_x(x), i_y(y), i_cellstate(GRID_STATE_INVALID), i_GridObjectDataLoaded(false)
+ {
+ i_GridInfo = GridInfo(expiry, unload);
+ }
const GridType& operator()(unsigned short x, unsigned short y) const { return i_cells[x][y]; }
GridType& operator()(unsigned short x, unsigned short y) { return i_cells[x][y]; }
- inline const uint32& GetGridId(void) const { return i_gridId; }
- inline void SetGridId(const uint32 id) const { i_gridId = id; }
- inline grid_state_t GetGridState(void) const { return i_cellstate; }
- inline void SetGridState(grid_state_t s) { i_cellstate = s; }
- inline int32 getX() const { return i_x; }
- inline int32 getY() const { return i_y; }
+ const uint32& GetGridId(void) const { return i_gridId; }
+ void SetGridId(const uint32 id) const { i_gridId = id; }
+ grid_state_t GetGridState(void) const { return i_cellstate; }
+ void SetGridState(grid_state_t s) { i_cellstate = s; }
+ int32 getX() const { return i_x; }
+ int32 getY() const { return i_y; }
void link(GridRefManager<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> >* pTo)
{
diff --git a/src/framework/GameSystem/TypeContainer.h b/src/framework/GameSystem/TypeContainer.h
index 8d4989debb7..9e4c6da65e2 100644
--- a/src/framework/GameSystem/TypeContainer.h
+++ b/src/framework/GameSystem/TypeContainer.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/GameSystem/TypeContainerFunctions.h b/src/framework/GameSystem/TypeContainerFunctions.h
index 4ca4e660236..f9945f84ac7 100644
--- a/src/framework/GameSystem/TypeContainerFunctions.h
+++ b/src/framework/GameSystem/TypeContainerFunctions.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/GameSystem/TypeContainerFunctionsPtr.h b/src/framework/GameSystem/TypeContainerFunctionsPtr.h
index 6bb4c9e4bf5..b22c07db2b4 100644
--- a/src/framework/GameSystem/TypeContainerFunctionsPtr.h
+++ b/src/framework/GameSystem/TypeContainerFunctionsPtr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/GameSystem/TypeContainerVisitor.h b/src/framework/GameSystem/TypeContainerVisitor.h
index 40f61b65cc4..97570b370c2 100644
--- a/src/framework/GameSystem/TypeContainerVisitor.h
+++ b/src/framework/GameSystem/TypeContainerVisitor.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Makefile.am b/src/framework/Makefile.am
new file mode 100644
index 00000000000..34ec997cc06
--- /dev/null
+++ b/src/framework/Makefile.am
@@ -0,0 +1,65 @@
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+#
+# Copyright (C) 2008-2009 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
+
+## Process this file with automake to produce Makefile.in
+
+## Sub-directories to parse
+
+## CPP flags for includes, defines, etc.
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(srcdir)
+
+## Build MaNGOS framework library as convenience library.
+# libMaNGOSScript shared library will later be reused by world server daemon.
+noinst_LIBRARIES = libmangosframework.a
+libmangosframework_a_SOURCES = \
+ Policies/ObjectLifeTime.cpp \
+ Utilities/EventProcessor.cpp
+
+## Additional files to include when running 'make dist'
+# Source and header files for the Framework.
+EXTRA_DIST = \
+ Dynamic/FactoryHolder.h \
+ Dynamic/ObjectRegistry.h \
+ GameSystem/Grid.h \
+ GameSystem/GridLoader.h \
+ GameSystem/GridRefManager.h \
+ GameSystem/GridReference.h \
+ GameSystem/NGrid.h \
+ GameSystem/TypeContainer.h \
+ GameSystem/TypeContainerFunctions.h \
+ GameSystem/TypeContainerFunctionsPtr.h \
+ GameSystem/TypeContainerVisitor.h \
+ Network/SocketDefines.h \
+ Platform/CompilerDefs.h \
+ Platform/Define.h \
+ Policies/CreationPolicy.h \
+ Policies/ObjectLifeTime.h \
+ Policies/Singleton.h \
+ Policies/SingletonImp.h \
+ Policies/ThreadingModel.h \
+ Utilities/CountedReference/Reference.h \
+ Utilities/CountedReference/ReferenceHolder.h \
+ Utilities/CountedReference/ReferenceImpl.h \
+ Utilities/LinkedReference/RefManager.h \
+ Utilities/LinkedReference/Reference.h \
+ Utilities/ByteConverter.h \
+ Utilities/Callback.h \
+ Utilities/EventProcessor.h \
+ Utilities/UnorderedMap.h \
+ Utilities/LinkedList.h \
+ Utilities/TypeList.h
diff --git a/src/framework/Network/SocketDefines.h b/src/framework/Network/SocketDefines.h
index bb59725bb76..e69f2fb41e0 100644
--- a/src/framework/Network/SocketDefines.h
+++ b/src/framework/Network/SocketDefines.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Platform/CompilerDefs.h b/src/framework/Platform/CompilerDefs.h
index 64d4976210c..691acb2e6d7 100644
--- a/src/framework/Platform/CompilerDefs.h
+++ b/src/framework/Platform/CompilerDefs.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Platform/Define.h b/src/framework/Platform/Define.h
index 5e0cdfdd179..59c2418c745 100644
--- a/src/framework/Platform/Define.h
+++ b/src/framework/Platform/Define.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 Mangos <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -57,6 +57,8 @@
# define TRINITY_GET_PROC_ADDR dlsym
# if defined(__APPLE_CC__) && defined(BIG_ENDIAN)
# define TRINITY_IMPORT __attribute__ ((longcall))
+# elif defined(__x86_64__)
+# define TRINITY_IMPORT
# else
# define TRINITY_IMPORT __attribute__ ((cdecl))
# endif //__APPLE_CC__ && BIG_ENDIAN
diff --git a/src/framework/Policies/CreationPolicy.h b/src/framework/Policies/CreationPolicy.h
index df46d764917..91bec9eab37 100644
--- a/src/framework/Policies/CreationPolicy.h
+++ b/src/framework/Policies/CreationPolicy.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Policies/ObjectLifeTime.cpp b/src/framework/Policies/ObjectLifeTime.cpp
index cb963f9c2b0..852e382a0e9 100644
--- a/src/framework/Policies/ObjectLifeTime.cpp
+++ b/src/framework/Policies/ObjectLifeTime.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Policies/ObjectLifeTime.h b/src/framework/Policies/ObjectLifeTime.h
index aaf46810085..86303f889fb 100644
--- a/src/framework/Policies/ObjectLifeTime.h
+++ b/src/framework/Policies/ObjectLifeTime.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -34,7 +34,7 @@ namespace Trinity
class TRINITY_DLL_DECL ObjectLifeTime
{
public:
- inline static void ScheduleCall(void (*destroyer)() )
+ static void ScheduleCall(void (*destroyer)() )
{
at_exit( destroyer );
}
@@ -44,7 +44,7 @@ namespace Trinity
};
template <class T>
- inline void ObjectLifeTime<T>::OnDeadReference(void)// We don't handle Dead Reference for now
+ void ObjectLifeTime<T>::OnDeadReference(void) // We don't handle Dead Reference for now
{
throw std::runtime_error("Dead Reference");
}
diff --git a/src/framework/Policies/Singleton.h b/src/framework/Policies/Singleton.h
index 6961200c760..66daaba5a9a 100644
--- a/src/framework/Policies/Singleton.h
+++ b/src/framework/Policies/Singleton.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Policies/SingletonImp.h b/src/framework/Policies/SingletonImp.h
index 20d311858a7..89a4738ae22 100644
--- a/src/framework/Policies/SingletonImp.h
+++ b/src/framework/Policies/SingletonImp.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Policies/ThreadingModel.h b/src/framework/Policies/ThreadingModel.h
index e41ed53b416..a380fe78323 100644
--- a/src/framework/Policies/ThreadingModel.h
+++ b/src/framework/Policies/ThreadingModel.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Utilities/ByteConverter.h b/src/framework/Utilities/ByteConverter.h
index bfb5fea1471..d9282c1787d 100644
--- a/src/framework/Utilities/ByteConverter.h
+++ b/src/framework/Utilities/ByteConverter.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Utilities/Callback.h b/src/framework/Utilities/Callback.h
index 05fa2d9d160..28c0931e6e7 100644
--- a/src/framework/Utilities/Callback.h
+++ b/src/framework/Utilities/Callback.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Utilities/CountedReference/Reference.h b/src/framework/Utilities/CountedReference/Reference.h
index 3c4a2185651..1e1083e1a66 100644
--- a/src/framework/Utilities/CountedReference/Reference.h
+++ b/src/framework/Utilities/CountedReference/Reference.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Utilities/CountedReference/ReferenceHolder.h b/src/framework/Utilities/CountedReference/ReferenceHolder.h
index f4cbf240493..4cfb7d16ded 100644
--- a/src/framework/Utilities/CountedReference/ReferenceHolder.h
+++ b/src/framework/Utilities/CountedReference/ReferenceHolder.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Utilities/CountedReference/ReferenceImpl.h b/src/framework/Utilities/CountedReference/ReferenceImpl.h
index b3f7ab2aab7..c3116a21cf4 100644
--- a/src/framework/Utilities/CountedReference/ReferenceImpl.h
+++ b/src/framework/Utilities/CountedReference/ReferenceImpl.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Utilities/EventProcessor.cpp b/src/framework/Utilities/EventProcessor.cpp
index b547392065a..852f84bc4e2 100644
--- a/src/framework/Utilities/EventProcessor.cpp
+++ b/src/framework/Utilities/EventProcessor.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Utilities/EventProcessor.h b/src/framework/Utilities/EventProcessor.h
index 0ce4251def7..d0a98c80e30 100644
--- a/src/framework/Utilities/EventProcessor.h
+++ b/src/framework/Utilities/EventProcessor.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Utilities/LinkedList.h b/src/framework/Utilities/LinkedList.h
index a25bbf75d5e..171ff3601e3 100644
--- a/src/framework/Utilities/LinkedList.h
+++ b/src/framework/Utilities/LinkedList.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Utilities/LinkedReference/RefManager.h b/src/framework/Utilities/LinkedReference/RefManager.h
index 5f0e3a9e10b..ed580f49ec2 100644
--- a/src/framework/Utilities/LinkedReference/RefManager.h
+++ b/src/framework/Utilities/LinkedReference/RefManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Utilities/LinkedReference/Reference.h b/src/framework/Utilities/LinkedReference/Reference.h
index bba58cf06d3..c77d3a2cbdb 100644
--- a/src/framework/Utilities/LinkedReference/Reference.h
+++ b/src/framework/Utilities/LinkedReference/Reference.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -44,7 +44,7 @@ template <class TO, class FROM> class Reference : public LinkedListElement
virtual ~Reference() {}
// Create new link
- inline void link(TO* toObj, FROM* fromObj)
+ void link(TO* toObj, FROM* fromObj)
{
assert(fromObj); // fromObj MUST not be NULL
if(isValid())
@@ -59,16 +59,16 @@ template <class TO, class FROM> class Reference : public LinkedListElement
// We don't need the reference anymore. Call comes from the refFrom object
// Tell our refTo object, that the link is cut
- inline void unlink() { targetObjectDestroyLink(); delink(); iRefTo = NULL; iRefFrom = NULL; }
+ void unlink() { targetObjectDestroyLink(); delink(); iRefTo = NULL; iRefFrom = NULL; }
// Link is invalid due to destruction of referenced target object. Call comes from the refTo object
// Tell our refFrom object, that the link is cut
- inline void invalidate() // the iRefFrom MUST remain!!
+ void invalidate() // the iRefFrom MUST remain!!
{
sourceObjectDestroyLink(); delink(); iRefTo = NULL;
}
- inline bool isValid() const // Only check the iRefTo
+ bool isValid() const // Only check the iRefTo
{
return iRefTo != NULL;
}
@@ -83,10 +83,10 @@ template <class TO, class FROM> class Reference : public LinkedListElement
Reference<TO,FROM> * nocheck_prev() { return((Reference<TO,FROM> *) LinkedListElement::nocheck_prev()); }
Reference<TO,FROM> const * nocheck_prev() const { return((Reference<TO,FROM> const *) LinkedListElement::nocheck_prev()); }
- inline TO* operator ->() const { return iRefTo; }
- inline TO* getTarget() const { return iRefTo; }
+ TO* operator ->() const { return iRefTo; }
+ TO* getTarget() const { return iRefTo; }
- inline FROM* getSource() const { return iRefFrom; }
+ FROM* getSource() const { return iRefFrom; }
};
//=====================================================
diff --git a/src/framework/Utilities/TypeList.h b/src/framework/Utilities/TypeList.h
index 143a9738381..07b1ebad3e6 100644
--- a/src/framework/Utilities/TypeList.h
+++ b/src/framework/Utilities/TypeList.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/framework/Utilities/UnorderedMap.h b/src/framework/Utilities/UnorderedMap.h
index a1de27cb615..dd539cc0bda 100644
--- a/src/framework/Utilities/UnorderedMap.h
+++ b/src/framework/Utilities/UnorderedMap.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/AccountMgr.cpp b/src/game/AccountMgr.cpp
index 6d27df2cb73..a39203f3755 100644
--- a/src/game/AccountMgr.cpp
+++ b/src/game/AccountMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -25,11 +25,7 @@
#include "Policies/SingletonImp.h"
#include "Util.h"
-#ifdef DO_POSTGRESQL
-extern DatabasePostgre LoginDatabase;
-#else
-extern DatabaseMysql LoginDatabase;
-#endif
+extern DatabaseType LoginDatabase;
INSTANTIATE_SINGLETON_1(AccountMgr);
diff --git a/src/game/AccountMgr.h b/src/game/AccountMgr.h
index febd5c6216b..adb1bdfa6b9 100644
--- a/src/game/AccountMgr.h
+++ b/src/game/AccountMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp
new file mode 100644
index 00000000000..fe0dcc29351
--- /dev/null
+++ b/src/game/AchievementMgr.cpp
@@ -0,0 +1,1931 @@
+/*
+ * Copyright (C) 2005-2009 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 "AchievementMgr.h"
+#include "Common.h"
+#include "Player.h"
+#include "WorldPacket.h"
+#include "DBCEnums.h"
+#include "GameEventMgr.h"
+#include "ObjectMgr.h"
+#include "Guild.h"
+#include "Database/DatabaseEnv.h"
+#include "World.h"
+#include "SpellMgr.h"
+#include "ArenaTeam.h"
+#include "ProgressBar.h"
+#include "GridNotifiersImpl.h"
+#include "CellImpl.h"
+#include "Language.h"
+
+#include "Policies/SingletonImp.h"
+
+INSTANTIATE_SINGLETON_1(AchievementGlobalMgr);
+
+namespace MaNGOS
+{
+ class AchievementChatBuilder
+ {
+ public:
+ AchievementChatBuilder(Player const& pl, ChatMsg msgtype, int32 textId, uint32 ach_id)
+ : i_player(pl), i_msgtype(msgtype), i_textId(textId), i_achievementId(ach_id) {}
+ void operator()(WorldPacket& data, int32 loc_idx)
+ {
+ char const* text = objmgr.GetMangosString(i_textId,loc_idx);
+
+ data << uint8(i_msgtype);
+ data << uint32(LANG_UNIVERSAL);
+ data << uint64(i_player.GetGUID());
+ data << uint32(5);
+ data << uint64(i_player.GetGUID());
+ data << uint32(strlen(text)+1);
+ data << text;
+ data << uint8(0);
+ data << uint32(i_achievementId);
+ }
+
+ private:
+ Player const& i_player;
+ ChatMsg i_msgtype;
+ int32 i_textId;
+ uint32 i_achievementId;
+ };
+} // namespace MaNGOS
+
+
+bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
+{
+ if(dataType >= MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE)
+ {
+ sLog.outErrorDb( "Table `achievement_criteria_data` for criteria (Entry: %u) have wrong data type (%u), ignore.", criteria->ID,dataType);
+ return false;
+ }
+
+ switch(criteria->requiredType)
+ {
+ case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE:
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
+ break;
+ default:
+ sLog.outErrorDb( "Table `achievement_criteria_data` have data for not supported criteria type (Entry: %u Type: %u), ignore.", criteria->ID, criteria->requiredType);
+ return false;
+ }
+
+ switch(dataType)
+ {
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE:
+ return true;
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE:
+ if(!creature.id || !objmgr.GetCreatureTemplate(creature.id))
+ {
+ sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE (%u) have not existed creature id in value1 (%u), ignore.",
+ criteria->ID, criteria->requiredType,dataType,creature.id);
+ return false;
+ }
+ return true;
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE:
+ if(!classRace.class_id && !classRace.race_id)
+ {
+ sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE (%u) must have not 0 in one from value fields, ignore.",
+ criteria->ID, criteria->requiredType,dataType);
+ return false;
+ }
+ if(classRace.class_id && ((1 << (classRace.class_id-1)) & CLASSMASK_ALL_PLAYABLE)==0)
+ {
+ sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE (%u) have not existed class in value1 (%u), ignore.",
+ criteria->ID, criteria->requiredType,dataType,classRace.class_id);
+ return false;
+ }
+ if(classRace.race_id && ((1 << (classRace.race_id-1)) & RACEMASK_ALL_PLAYABLE)==0)
+ {
+ sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE (%u) have not existed race in value2 (%u), ignore.",
+ criteria->ID, criteria->requiredType,dataType,classRace.race_id);
+ return false;
+ }
+ return true;
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH:
+ if(health.percent < 1 || health.percent > 100)
+ {
+ sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH (%u) have wrong percent value in value1 (%u), ignore.",
+ criteria->ID, criteria->requiredType,dataType,health.percent);
+ return false;
+ }
+ return true;
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD:
+ return true;
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA:
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA:
+ {
+ SpellEntry const* spellEntry = sSpellStore.LookupEntry(aura.spell_id);
+ if(!spellEntry)
+ {
+ sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) have wrong spell id in value1 (%u), ignore.",
+ criteria->ID, criteria->requiredType,(dataType==ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"),dataType,aura.spell_id);
+ return false;
+ }
+ if(aura.effect_idx >= 3)
+ {
+ sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) have wrong spell effect index in value2 (%u), ignore.",
+ criteria->ID, criteria->requiredType,(dataType==ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"),dataType,aura.effect_idx);
+ return false;
+ }
+ if(!spellEntry->EffectApplyAuraName[aura.effect_idx])
+ {
+ sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) have non-aura spell effect (ID: %u Effect: %u), ignore.",
+ criteria->ID, criteria->requiredType,(dataType==ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"),dataType,aura.spell_id,aura.effect_idx);
+ return false;
+ }
+ return true;
+ }
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA:
+ if(!GetAreaEntryByAreaID(area.id))
+ {
+ sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA (%u) have wrong area id in value1 (%u), ignore.",
+ criteria->ID, criteria->requiredType,dataType,area.id);
+ return false;
+ }
+ return true;
+ default:
+ sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) have data for not supported data type (%u), ignore.", criteria->ID, criteria->requiredType,dataType);
+ return false;
+ }
+ return false;
+}
+
+bool AchievementCriteriaData::Meets(Player const* source, Unit const* target) const
+{
+ switch(dataType)
+ {
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE:
+ return true;
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE:
+ if (!target || target->GetTypeId()!=TYPEID_UNIT)
+ return false;
+ if (target->GetEntry() != creature.id)
+ return false;
+ return true;
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE:
+ if (!target || target->GetTypeId()!=TYPEID_PLAYER)
+ return false;
+ if(classRace.class_id && classRace.class_id != ((Player*)target)->getClass())
+ return false;
+ if(classRace.race_id && classRace.race_id != ((Player*)target)->getRace())
+ return false;
+ return true;
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH:
+ if (!target || target->GetTypeId()!=TYPEID_PLAYER)
+ return false;
+ return target->GetHealth()*100 <= health.percent*target->GetMaxHealth();
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD:
+ return target && target->GetTypeId() == TYPEID_PLAYER && !target->isAlive() && ((Player*)target)->GetDeathTimer() != 0;
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA:
+ return source->HasAuraEffect(aura.spell_id,aura.effect_idx);
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA:
+ {
+ uint32 zone_id,area_id;
+ source->GetZoneAndAreaId(zone_id,area_id);
+ return area.id==zone_id || area.id==area_id;
+ }
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA:
+ return target && target->HasAuraEffect(aura.spell_id,aura.effect_idx);
+ }
+
+ return false;
+}
+
+bool AchievementCriteriaDataSet::Meets(Player const* source, Unit const* target) const
+{
+ for(Storage::const_iterator itr = storage.begin(); itr != storage.end(); ++itr)
+ if(!itr->Meets(source,target))
+ return false;
+
+ return true;
+}
+
+AchievementMgr::AchievementMgr(Player *player)
+{
+ m_player = player;
+}
+
+AchievementMgr::~AchievementMgr()
+{
+}
+
+void AchievementMgr::Reset()
+{
+ for(CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter!=m_completedAchievements.end(); ++iter)
+ {
+ WorldPacket data(SMSG_ACHIEVEMENT_DELETED,4);
+ data << uint32(iter->first);
+ m_player->SendDirectMessage(&data);
+ }
+
+ for(CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter)
+ {
+ WorldPacket data(SMSG_CRITERIA_DELETED,4);
+ data << uint32(iter->first);
+ m_player->SendDirectMessage(&data);
+ }
+
+ m_completedAchievements.clear();
+ m_criteriaProgress.clear();
+ DeleteFromDB(m_player->GetGUIDLow());
+
+ // re-fill data
+ CheckAllAchievementCriteria();
+}
+
+void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2)
+{
+ if((sLog.getLogFilter() & LOG_FILTER_ACHIEVEMENT_UPDATES)==0)
+ sLog.outDetail("AchievementMgr::ResetAchievementCriteria(%u, %u, %u)", type, miscvalue1, miscvalue2);
+
+ if (!sWorld.getConfig(CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS) && m_player->GetSession()->GetSecurity() > SEC_PLAYER)
+ return;
+
+ AchievementCriteriaEntryList const& achievementCriteriaList = achievementmgr.GetAchievementCriteriaByType(type);
+ for(AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i!=achievementCriteriaList.end(); ++i)
+ {
+ AchievementCriteriaEntry const *achievementCriteria = (*i);
+
+ AchievementEntry const *achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement);
+ if (!achievement)
+ continue;
+
+ // don't update already completed criteria
+ if (IsCompletedCriteria(achievementCriteria,achievement))
+ continue;
+
+ switch (type)
+ {
+ case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE: // have total statistic also not expected to be reset
+ case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE: // have total statistic also not expected to be reset
+ if (achievementCriteria->healing_done.flag == miscvalue1 &&
+ achievementCriteria->healing_done.mapid == miscvalue2)
+ SetCriteriaProgress(achievementCriteria, 0, PROGRESS_SET);
+ break;
+ default: // reset all cases
+ break;
+ }
+ }
+}
+
+void AchievementMgr::DeleteFromDB(uint32 lowguid)
+{
+ CharacterDatabase.BeginTransaction ();
+ CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE guid = %u",lowguid);
+ CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE guid = %u",lowguid);
+ CharacterDatabase.CommitTransaction ();
+}
+
+void AchievementMgr::SaveToDB()
+{
+ if(!m_completedAchievements.empty())
+ {
+ bool need_execute = false;
+ std::ostringstream ssdel;
+ std::ostringstream ssins;
+ for(CompletedAchievementMap::iterator iter = m_completedAchievements.begin(); iter!=m_completedAchievements.end(); ++iter)
+ {
+ if(!iter->second.changed)
+ continue;
+
+ /// first new/changed record prefix
+ if(!need_execute)
+ {
+ ssdel << "DELETE FROM character_achievement WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND achievement IN (";
+ ssins << "INSERT INTO character_achievement (guid, achievement, date) VALUES ";
+ need_execute = true;
+ }
+ /// next new/changed record prefix
+ else
+ {
+ ssdel << ", ";
+ ssins << ", ";
+ }
+
+ // new/changed record data
+ ssdel << iter->first;
+ ssins << "("<<GetPlayer()->GetGUIDLow() << ", " << iter->first << ", " << uint64(iter->second.date) << ")";
+
+ /// mark as saved in db
+ iter->second.changed = false;
+ }
+
+ if(need_execute)
+ ssdel << ")";
+
+ if(need_execute)
+ {
+ CharacterDatabase.Execute( ssdel.str().c_str() );
+ CharacterDatabase.Execute( ssins.str().c_str() );
+ }
+ }
+
+ if(!m_criteriaProgress.empty())
+ {
+ /// prepare deleting and insert
+ bool need_execute_del = false;
+ bool need_execute_ins = false;
+ std::ostringstream ssdel;
+ std::ostringstream ssins;
+ for(CriteriaProgressMap::iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter)
+ {
+ if(!iter->second.changed)
+ continue;
+
+ // deleted data (including 0 progress state)
+ {
+ /// first new/changed record prefix (for any counter value)
+ if(!need_execute_del)
+ {
+ ssdel << "DELETE FROM character_achievement_progress WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND criteria IN (";
+ need_execute_del = true;
+ }
+ /// next new/changed record prefix
+ else
+ ssdel << ", ";
+
+ // new/changed record data
+ ssdel << iter->first;
+ }
+
+ // store data only for real progress
+ if(iter->second.counter != 0)
+ {
+ /// first new/changed record prefix
+ if(!need_execute_ins)
+ {
+ ssins << "INSERT INTO character_achievement_progress (guid, criteria, counter, date) VALUES ";
+ need_execute_ins = true;
+ }
+ /// next new/changed record prefix
+ else
+ ssins << ", ";
+
+ // new/changed record data
+ ssins << "(" << GetPlayer()->GetGUIDLow() << ", " << iter->first << ", " << iter->second.counter << ", " << iter->second.date << ")";
+ }
+
+ /// mark as updated in db
+ iter->second.changed = false;
+ }
+
+ if(need_execute_del) // DELETE ... IN (.... _)_
+ ssdel << ")";
+
+ if(need_execute_del || need_execute_ins)
+ {
+ if(need_execute_del)
+ CharacterDatabase.Execute( ssdel.str().c_str() );
+ if(need_execute_ins)
+ CharacterDatabase.Execute( ssins.str().c_str() );
+ }
+ }
+}
+
+void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *criteriaResult)
+{
+ if(achievementResult)
+ {
+ do
+ {
+ Field *fields = achievementResult->Fetch();
+ CompletedAchievementData& ca = m_completedAchievements[fields[0].GetUInt32()];
+ ca.date = time_t(fields[1].GetUInt64());
+ ca.changed = false;
+ } while(achievementResult->NextRow());
+ delete achievementResult;
+ }
+
+ if(criteriaResult)
+ {
+ do
+ {
+ Field *fields = criteriaResult->Fetch();
+
+ uint32 id = fields[0].GetUInt32();
+ uint32 counter = fields[1].GetUInt32();
+ time_t date = time_t(fields[2].GetUInt64());
+
+ AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(id);
+ if (!criteria || (criteria->timeLimit && time_t(date + criteria->timeLimit) < time(NULL)))
+ continue;
+
+ CriteriaProgress& progress = m_criteriaProgress[id];
+ progress.counter = counter;
+ progress.date = date;
+ progress.changed = false;
+ } while(criteriaResult->NextRow());
+ delete criteriaResult;
+ }
+
+}
+
+void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
+{
+ if(GetPlayer()->GetSession()->PlayerLoading())
+ return;
+
+ #ifdef MANGOS_DEBUG
+ if((sLog.getLogFilter() & LOG_FILTER_ACHIEVEMENT_UPDATES)==0)
+ sLog.outDebug("AchievementMgr::SendAchievementEarned(%u)", achievement->ID);
+ #endif
+
+ if(Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()))
+ {
+ MaNGOS::AchievementChatBuilder say_builder(*GetPlayer(), CHAT_MSG_GUILD_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED,achievement->ID);
+ MaNGOS::LocalizedPacketDo<MaNGOS::AchievementChatBuilder> say_do(say_builder);
+ guild->BroadcastWorker(say_do,GetPlayer());
+ }
+
+ if(achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_KILL|ACHIEVEMENT_FLAG_REALM_FIRST_REACH))
+ {
+ // broadcast realm first reached
+ WorldPacket data(SMSG_SERVER_FIRST_ACHIEVEMENT, strlen(GetPlayer()->GetName())+1+8+4+4);
+ data << GetPlayer()->GetName();
+ data << uint64(GetPlayer()->GetGUID());
+ data << uint32(achievement->ID);
+ data << uint32(0); // 1=link supplied string as player name, 0=display plain string
+ sWorld.SendGlobalMessage(&data);
+ }
+ else
+ {
+ CellPair p = MaNGOS::ComputeCellPair(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
+
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ MaNGOS::AchievementChatBuilder say_builder(*GetPlayer(), CHAT_MSG_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED,achievement->ID);
+ MaNGOS::LocalizedPacketDo<MaNGOS::AchievementChatBuilder> say_do(say_builder);
+ MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::AchievementChatBuilder> > say_worker(GetPlayer(),sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY),say_do);
+ TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::AchievementChatBuilder> >, WorldTypeMapContainer > message(say_worker);
+ CellLock<GridReadGuard> cell_lock(cell, p);
+ cell_lock->Visit(cell_lock, message, *GetPlayer()->GetMap());
+ }
+
+ WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8+4+8);
+ data.append(GetPlayer()->GetPackGUID());
+ data << uint32(achievement->ID);
+ data << uint32(secsToTimeBitFields(time(NULL)));
+ data << uint32(0);
+ GetPlayer()->SendMessageToSetInRange(&data, sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY), true);
+}
+
+void AchievementMgr::SendCriteriaUpdate(uint32 id, CriteriaProgress const* progress)
+{
+ WorldPacket data(SMSG_CRITERIA_UPDATE, 8+4+8);
+ data << uint32(id);
+
+ // the counter is packed like a packed Guid
+ data.appendPackGUID(progress->counter);
+
+ data.append(GetPlayer()->GetPackGUID());
+ data << uint32(0);
+ data << uint32(secsToTimeBitFields(progress->date));
+ data << uint32(0); // timer 1
+ data << uint32(0); // timer 2
+ GetPlayer()->SendDirectMessage(&data);
+}
+
+/**
+ * called at player login. The player might have fulfilled some achievements when the achievement system wasn't working yet
+ */
+void AchievementMgr::CheckAllAchievementCriteria()
+{
+ // suppress sending packets
+ for(uint32 i=0; i<ACHIEVEMENT_CRITERIA_TYPE_TOTAL; ++i)
+ UpdateAchievementCriteria(AchievementCriteriaTypes(i));
+}
+
+static const uint32 achievIdByArenaSlot[MAX_ARENA_SLOT] = { 1057, 1107, 1108 };
+static const uint32 achievIdForDangeon[][4] =
+{
+ // ach_cr_id,is_dungeon,is_raid,is_heroic_dungeon
+ { 321, true, true, true },
+ { 916, false, true, false },
+ { 917, false, true, false },
+ { 918, true, false, false },
+ { 2219, false, false, true },
+ { 0, false, false, false }
+};
+
+/**
+ * this function will be called whenever the user might have done a criteria relevant action
+ */
+void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, Unit *unit, uint32 time)
+{
+ if((sLog.getLogFilter() & LOG_FILTER_ACHIEVEMENT_UPDATES)==0)
+ sLog.outDetail("AchievementMgr::UpdateAchievementCriteria(%u, %u, %u, %u)", type, miscvalue1, miscvalue2, time);
+
+ if (!sWorld.getConfig(CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS) && m_player->GetSession()->GetSecurity() > SEC_PLAYER)
+ return;
+
+ AchievementCriteriaEntryList const& achievementCriteriaList = achievementmgr.GetAchievementCriteriaByType(type);
+ for(AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i!=achievementCriteriaList.end(); ++i)
+ {
+ AchievementCriteriaEntry const *achievementCriteria = (*i);
+
+ if (achievementCriteria->groupFlag & ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP && GetPlayer()->GetGroup())
+ continue;
+
+ AchievementEntry const *achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement);
+ if (!achievement)
+ continue;
+
+ if ((achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_HORDE && GetPlayer()->GetTeam() != HORDE) ||
+ (achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_ALLIANCE && GetPlayer()->GetTeam() != ALLIANCE))
+ continue;
+
+ // don't update already completed criteria
+ if (IsCompletedCriteria(achievementCriteria,achievement))
+ continue;
+
+ switch (type)
+ {
+ // std. case: increment at 1
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
+ // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
+ if(!miscvalue1)
+ continue;
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+ // std case: increment at miscvalue1
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS:
+ case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD:
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING:
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER:
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL:
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY:
+ case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED:
+ case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED:
+ // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
+ if(!miscvalue1)
+ continue;
+ SetCriteriaProgress(achievementCriteria, miscvalue1, PROGRESS_ACCUMULATE);
+ break;
+ // std case: high value at miscvalue1
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD: /* FIXME: for online player only currently */
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED:
+ // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
+ if(!miscvalue1)
+ continue;
+ SetCriteriaProgress(achievementCriteria, miscvalue1, PROGRESS_HIGHEST);
+ break;
+
+ // specialized cases
+
+ case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
+ // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
+ if(!miscvalue1)
+ continue;
+ if(achievementCriteria->kill_creature.creatureID != miscvalue1)
+ continue;
+
+ // LOT achievement->ID required special custom checks
+ switch(achievement->ID)
+ {
+ // Just heroic
+ case 489: case 490: case 491: case 492: case 493: case 494: case 495:
+ case 496: case 497: case 498: case 499: case 500: case 563: case 565:
+ case 567: case 569: case 573: case 575: case 577: case 623: case 625:
+ case 667: case 668: case 669: case 670: case 671: case 672: case 673:
+ case 674: case 675: case 676: case 677: case 678: case 679: case 680:
+ case 681: case 682: case 1367: case 1368: case 1378: case 1379:
+ case 1380: case 1381: case 1382: case 1383: case 1384: case 1385:
+ case 1386: case 1387: case 1388: case 1389: case 1390: case 1393:
+ case 1394: case 1400: case 1402: case 1504: case 1505: case 1506:
+ case 1507: case 1508: case 1509: case 1510: case 1511: case 1512:
+ case 1513: case 1514: case 1515: case 1721: case 1754: case 1756:
+ case 1768: case 1817: case 1865:
+ if(GetPlayer()->GetDifficulty()!=DIFFICULTY_HEROIC)
+ continue;
+ break;
+ // Heroic + other
+ case 579: case 1296: case 1297: case 1816: case 1834: case 1857: case 1859:
+ case 1860: case 1861: case 1862: case 1864: case 1866: case 1867: case 1868:
+ case 1870: case 1871: case 1872: case 1873: case 1875: case 1877: case 1919:
+ case 2036: case 2037: case 2038: case 2039: case 2040: case 2041: case 2042:
+ case 2043: case 2044: case 2045: case 2046: case 2048: case 2052: case 2053:
+ case 2054: case 2056: case 2057: case 2058: case 2139: case 2140: case 2147:
+ case 2149: case 2150: case 2151: case 2152: case 2154: case 2155: case 2156:
+ case 2157: case 2179: case 2181: case 2183: case 2185: case 2186:
+ if(GetPlayer()->GetDifficulty()!=DIFFICULTY_HEROIC)
+ continue;
+ // FIX ME: mark as fail always until implement
+ continue;
+ // Normal + other
+ case 578: case 624: case 1790: case 1856: case 1858: case 1869: case 1874:
+ case 1996: case 1997: case 2047: case 2049: case 2050: case 2051: case 2146:
+ case 2148: case 2153: case 2178: case 2180: case 2182: case 2184: case 2187:
+ if(GetPlayer()->GetDifficulty()!=DIFFICULTY_NORMAL)
+ continue;
+ // FIX ME: mark as fail always until implement
+ continue;
+ // Just Normal
+ default:
+ if(GetPlayer()->GetDifficulty()!=DIFFICULTY_NORMAL)
+ continue;
+ break;
+ };
+
+ SetCriteriaProgress(achievementCriteria, miscvalue2, PROGRESS_ACCUMULATE);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
+ SetCriteriaProgress(achievementCriteria, GetPlayer()->getLevel());
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
+ // update at loading or specific skill update
+ if(miscvalue1 && miscvalue1 != achievementCriteria->reach_skill_level.skillID)
+ continue;
+ if(uint32 skillvalue = GetPlayer()->GetBaseSkillValue(achievementCriteria->reach_skill_level.skillID))
+ SetCriteriaProgress(achievementCriteria, skillvalue);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL:
+ // update at loading or specific skill update
+ if(miscvalue1 && miscvalue1 != achievementCriteria->learn_skill_level.skillID)
+ continue;
+ if(uint32 maxSkillvalue = GetPlayer()->GetPureMaxSkillValue(achievementCriteria->learn_skill_level.skillID))
+ SetCriteriaProgress(achievementCriteria, maxSkillvalue);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
+ if(m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) != m_completedAchievements.end())
+ SetCriteriaProgress(achievementCriteria, 1);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT:
+ {
+ uint32 counter =0;
+ for(QuestStatusMap::const_iterator itr = GetPlayer()->getQuestStatusMap().begin(); itr!=GetPlayer()->getQuestStatusMap().end(); itr++)
+ if(itr->second.m_rewarded)
+ counter++;
+ SetCriteriaProgress(achievementCriteria, counter);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE:
+ {
+ // speedup for non-login case
+ if(miscvalue1 && miscvalue1 != achievementCriteria->complete_quests_in_zone.zoneID)
+ continue;
+
+ uint32 counter =0;
+ for(QuestStatusMap::const_iterator itr = GetPlayer()->getQuestStatusMap().begin(); itr!=GetPlayer()->getQuestStatusMap().end(); itr++)
+ {
+ Quest const* quest = objmgr.GetQuestTemplate(itr->first);
+ if(itr->second.m_rewarded && quest->GetZoneOrSort() >= 0 && uint32(quest->GetZoneOrSort()) == achievementCriteria->complete_quests_in_zone.zoneID)
+ counter++;
+ }
+ SetCriteriaProgress(achievementCriteria, counter);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
+ // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
+ if(!miscvalue1)
+ continue;
+ if(GetPlayer()->GetMapId() != achievementCriteria->complete_battleground.mapID)
+ continue;
+ SetCriteriaProgress(achievementCriteria, miscvalue1, PROGRESS_ACCUMULATE);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
+ // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
+ if(!miscvalue1)
+ continue;
+ if(GetPlayer()->GetMapId() != achievementCriteria->death_at_map.mapID)
+ continue;
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATH:
+ {
+ // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
+ if(!miscvalue1)
+ continue;
+ // skip wrong arena achievements, if not achievIdByArenaSlot then normal total death counter
+ bool notfit = false;
+ for(int j = 0; j < MAX_ARENA_SLOT; ++j)
+ {
+ if(achievIdByArenaSlot[j] == achievement->ID)
+ {
+ BattleGround* bg = GetPlayer()->GetBattleGround();
+ if(!bg || !bg->isArena() || ArenaTeam::GetSlotByType(bg->GetArenaType()) != j)
+ notfit = true;
+
+ break;
+ }
+ }
+ if(notfit)
+ continue;
+
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON:
+ {
+ // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
+ if(!miscvalue1)
+ continue;
+
+ Map const* map = GetPlayer()->GetMap();
+ if(!map->IsDungeon())
+ continue;
+
+ // search case
+ bool found = false;
+ for(int j = 0; achievIdForDangeon[j][0]; ++j)
+ {
+ if(achievIdForDangeon[j][0] == achievement->ID)
+ {
+ if(map->IsRaid())
+ {
+ // if raid accepted (ignore difficulty)
+ if(!achievIdForDangeon[j][2])
+ break; // for
+ }
+ else if(GetPlayer()->GetDifficulty()==DIFFICULTY_NORMAL)
+ {
+ // dungeon in normal mode accepted
+ if(!achievIdForDangeon[j][1])
+ break; // for
+ }
+ else
+ {
+ // dungeon in heroic mode accepted
+ if(!achievIdForDangeon[j][3])
+ break; // for
+ }
+
+ found = true;
+ break; // for
+ }
+ }
+ if(!found)
+ continue;
+
+ //FIXME: work only for instances where max==min for players
+ if(((InstanceMap*)map)->GetMaxPlayers() != achievementCriteria->death_in_dungeon.manLimit)
+ continue;
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE:
+ // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
+ if(!miscvalue1)
+ continue;
+ if(miscvalue1 != achievementCriteria->killed_by_creature.creatureEntry)
+ continue;
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER:
+ // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
+ if(!miscvalue1)
+ continue;
+
+ // if team check required: must kill by opposition faction
+ if(achievement->ID==318 && miscvalue2==GetPlayer()->GetTeam())
+ continue;
+
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
+ {
+ // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
+ if(!miscvalue1)
+ continue;
+ if(achievement->ID == 1260)
+ {
+ if(Player::GetDrunkenstateByValue(GetPlayer()->GetDrunkValue()) != DRUNKEN_SMASHED)
+ continue;
+ if(!IsHolidayActive(HOLIDAY_BREWFEST))
+ continue;
+ }
+ // miscvalue1 is the ingame fallheight*100 as stored in dbc
+ SetCriteriaProgress(achievementCriteria, miscvalue1);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM:
+ // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
+ if(!miscvalue1)
+ continue;
+ if(miscvalue2 != achievementCriteria->death_from.type)
+ continue;
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
+ // if miscvalues != 0, it contains the questID.
+ if (miscvalue1)
+ {
+ if (miscvalue1 == achievementCriteria->complete_quest.questID)
+ SetCriteriaProgress(achievementCriteria, 1);
+ }
+ else
+ {
+ // login case.
+ if(GetPlayer()->GetQuestRewardStatus(achievementCriteria->complete_quest.questID))
+ SetCriteriaProgress(achievementCriteria, 1);
+ }
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
+ if (!miscvalue1 || miscvalue1 != achievementCriteria->be_spell_target.spellID)
+ continue;
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
+ if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID)
+ continue;
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
+ if(miscvalue1 && miscvalue1!=achievementCriteria->learn_spell.spellID)
+ continue;
+
+ if(GetPlayer()->HasSpell(achievementCriteria->learn_spell.spellID))
+ SetCriteriaProgress(achievementCriteria, 1);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE:
+ {
+ // miscvalue1=loot_type (note: 0 = LOOT_CORSPE and then it ignored)
+ // miscvalue2=count of item loot
+ if (!miscvalue1 || !miscvalue2)
+ continue;
+ if (miscvalue1 != achievementCriteria->loot_type.lootType)
+ continue;
+
+ // zone specific
+ if(achievementCriteria->loot_type.lootTypeCount==1)
+ {
+ // those requirements couldn't be found in the dbc
+ AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria);
+ if(!data)
+ continue;
+
+ if(!data->Meets(GetPlayer(),unit))
+ continue;
+ }
+
+ SetCriteriaProgress(achievementCriteria, miscvalue2, PROGRESS_ACCUMULATE);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
+ // speedup for non-login case
+ if(miscvalue1 && achievementCriteria->own_item.itemID != miscvalue1)
+ continue;
+ SetCriteriaProgress(achievementCriteria, GetPlayer()->GetItemCount(achievementCriteria->own_item.itemID, true));
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
+ // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
+ if(!miscvalue1)
+ continue;
+ if(achievementCriteria->use_item.itemID != miscvalue1)
+ continue;
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM:
+ // You _have_ to loot that item, just owning it when logging in does _not_ count!
+ if(!miscvalue1)
+ continue;
+ if(miscvalue1 != achievementCriteria->own_item.itemID)
+ continue;
+ SetCriteriaProgress(achievementCriteria, miscvalue2, PROGRESS_ACCUMULATE);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA:
+ {
+ WorldMapOverlayEntry const* worldOverlayEntry = sWorldMapOverlayStore.LookupEntry(achievementCriteria->explore_area.areaReference);
+ if(!worldOverlayEntry)
+ break;
+
+ bool matchFound = false;
+ for (int j = 0; j < MAX_WORLD_MAP_OVERLAY_AREA_IDX; ++j)
+ {
+ uint32 area_id = worldOverlayEntry->areatableID[j];
+ if(!area_id) // array have 0 only in empty tail
+ break;
+
+ int32 exploreFlag = GetAreaFlagByAreaID(area_id);
+ if(exploreFlag < 0)
+ continue;
+
+ uint32 playerIndexOffset = uint32(exploreFlag) / 32;
+ uint32 mask = 1<< (uint32(exploreFlag) % 32);
+
+ if(GetPlayer()->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + playerIndexOffset) & mask)
+ {
+ matchFound = true;
+ break;
+ }
+ }
+
+ if(matchFound)
+ SetCriteriaProgress(achievementCriteria, 1);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
+ SetCriteriaProgress(achievementCriteria, GetPlayer()->GetByteValue(PLAYER_BYTES_2, 2)+1);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
+ {
+ // skip faction check only at loading
+ if (miscvalue1 && miscvalue1 != achievementCriteria->gain_reputation.factionID)
+ continue;
+
+ int32 reputation = GetPlayer()->GetReputationMgr().GetReputation(achievementCriteria->gain_reputation.factionID);
+ if (reputation > 0)
+ SetCriteriaProgress(achievementCriteria, reputation);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION:
+ {
+ SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetExaltedFactionCount());
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP:
+ {
+ // skip for login case
+ if(!miscvalue1)
+ continue;
+ SetCriteriaProgress(achievementCriteria, 1);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
+ {
+ // miscvalue1 = itemid
+ // miscvalue2 = diced value
+ if(!miscvalue1)
+ continue;
+ if(miscvalue2 != achievementCriteria->roll_greed_on_loot.rollValue)
+ continue;
+ ItemPrototype const *pProto = objmgr.GetItemPrototype( miscvalue1 );
+
+ uint32 requiredItemLevel = 0;
+ if (achievementCriteria->ID == 2412 || achievementCriteria->ID == 2358)
+ requiredItemLevel = 185;
+
+ if(!pProto || pProto->ItemLevel <requiredItemLevel)
+ continue;
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
+ {
+ // miscvalue1 = emote
+ if(!miscvalue1)
+ continue;
+ if(miscvalue1 != achievementCriteria->do_emote.emoteID)
+ continue;
+ if(achievementCriteria->do_emote.count)
+ {
+ // those requirements couldn't be found in the dbc
+ AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria);
+ if(!data)
+ continue;
+
+ if(!data->Meets(GetPlayer(),unit))
+ continue;
+ }
+
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE:
+ case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE:
+ {
+ if (!miscvalue1)
+ continue;
+
+ if (achievementCriteria->healing_done.flag == ACHIEVEMENT_CRITERIA_CONDITION_MAP)
+ {
+ if(GetPlayer()->GetMapId() != achievementCriteria->healing_done.mapid)
+ continue;
+
+ // map specific case (BG in fact) expected player targeted damage/heal
+ if(!unit || unit->GetTypeId()!=TYPEID_PLAYER)
+ continue;
+ }
+
+ SetCriteriaProgress(achievementCriteria, miscvalue1, PROGRESS_ACCUMULATE);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
+ // miscvalue1 = item_id
+ if(!miscvalue1)
+ continue;
+ if(miscvalue1 != achievementCriteria->equip_item.itemID)
+ continue;
+
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT:
+ // miscvalue1 = go entry
+ if(!miscvalue1)
+ continue;
+ if(miscvalue1 != achievementCriteria->use_gameobject.goEntry)
+ continue;
+
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT:
+ if (!miscvalue1)
+ continue;
+ if (miscvalue1 != achievementCriteria->fish_in_gameobject.goEntry)
+ continue;
+
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
+ {
+ if(miscvalue1 && miscvalue1 != achievementCriteria->learn_skillline_spell.skillLine)
+ continue;
+
+ uint32 spellCount = 0;
+ for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin();
+ spellIter != GetPlayer()->GetSpellMap().end();
+ ++spellIter)
+ {
+ for(SkillLineAbilityMap::const_iterator skillIter = spellmgr.GetBeginSkillLineAbilityMap(spellIter->first);
+ skillIter != spellmgr.GetEndSkillLineAbilityMap(spellIter->first);
+ ++skillIter)
+ {
+ if(skillIter->second->skillId == achievementCriteria->learn_skillline_spell.skillLine)
+ spellCount++;
+ }
+ }
+ SetCriteriaProgress(achievementCriteria, spellCount);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION:
+ SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetReveredFactionCount());
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION:
+ SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetHonoredFactionCount());
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS:
+ SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetVisibleFactionCount());
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
+ {
+ if (!miscvalue1)
+ continue;
+
+ if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID)
+ continue;
+
+ // those requirements couldn't be found in the dbc
+ AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria);
+ if(!data)
+ continue;
+
+ if(!data->Meets(GetPlayer(),unit))
+ continue;
+
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE:
+ {
+ if(miscvalue1 && miscvalue1 != achievementCriteria->learn_skill_line.skillLine)
+ continue;
+
+ uint32 spellCount = 0;
+ for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin();
+ spellIter != GetPlayer()->GetSpellMap().end();
+ ++spellIter)
+ {
+ for(SkillLineAbilityMap::const_iterator skillIter = spellmgr.GetBeginSkillLineAbilityMap(spellIter->first);
+ skillIter != spellmgr.GetEndSkillLineAbilityMap(spellIter->first);
+ ++skillIter)
+ {
+ if(skillIter->second->skillId == achievementCriteria->learn_skill_line.skillLine)
+ spellCount++;
+ }
+ }
+ SetCriteriaProgress(achievementCriteria, spellCount);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL:
+ SetCriteriaProgress(achievementCriteria, GetPlayer()->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS));
+ break;
+ // std case: not exist in DBC, not triggered in code as result
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_ARMOR:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_POWER:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_STAT:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING:
+ break;
+ // FIXME: not triggered in code as result, need to implement
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID:
+ case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE:
+ case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA:
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA:
+ case ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA:
+ case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL:
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING:
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING:
+ case ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK:
+ case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS:
+ case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE:
+ case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
+ case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS:
+ case ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS:
+ case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL:
+ case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE:
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL:
+ case ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL:
+ case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE:
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS:
+ case ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION:
+ case ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED:
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED:
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED:
+ case ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED:
+ case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN:
+ case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS:
+ case ACHIEVEMENT_CRITERIA_TYPE_TOTAL:
+ break; // Not implemented yet :(
+ }
+ if(IsCompletedCriteria(achievementCriteria,achievement))
+ CompletedCriteriaFor(achievement);
+
+ // check again the completeness for SUMM and REQ COUNT achievements,
+ // as they don't depend on the completed criteria but on the sum of the progress of each individual criteria
+ if (achievement->flags & ACHIEVEMENT_FLAG_SUMM)
+ {
+ if (IsCompletedAchievement(achievement))
+ CompletedAchievement(achievement);
+ }
+
+ if(AchievementEntryList const* achRefList = achievementmgr.GetAchievementByReferencedId(achievement->ID))
+ {
+ for(AchievementEntryList::const_iterator itr = achRefList->begin(); itr != achRefList->end(); ++itr)
+ if(IsCompletedAchievement(*itr))
+ CompletedAchievement(*itr);
+ }
+ }
+}
+
+static const uint32 achievIdByClass[MAX_CLASSES] = { 0, 459, 465 , 462, 458, 464, 461, 467, 460, 463, 0, 466 };
+static const uint32 achievIdByRace[MAX_RACES] = { 0, 1408, 1410, 1407, 1409, 1413, 1411, 1404, 1412, 0, 1405, 1406 };
+
+bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement)
+{
+ // counter can never complete
+ if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
+ return false;
+
+ if(achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_REACH | ACHIEVEMENT_FLAG_REALM_FIRST_KILL))
+ {
+ // someone on this realm has already completed that achievement
+ if(achievementmgr.IsRealmCompleted(achievement))
+ return false;
+ }
+
+ CriteriaProgressMap::const_iterator itr = m_criteriaProgress.find(achievementCriteria->ID);
+ if(itr == m_criteriaProgress.end())
+ return false;
+
+ CriteriaProgress const* progress = &itr->second;
+
+ switch(achievementCriteria->requiredType)
+ {
+ case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
+ return progress->counter >= achievementCriteria->kill_creature.creatureCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
+ {
+ // skip wrong class achievements
+ for(int i = 1; i < MAX_CLASSES; ++i)
+ if(achievIdByClass[i] == achievement->ID && i != GetPlayer()->getClass())
+ return false;
+
+ // skip wrong race achievements
+ for(int i = 1; i < MAX_RACES; ++i)
+ if(achievIdByRace[i] == achievement->ID && i != GetPlayer()->getRace())
+ return false;
+
+ // appropriate class/race or not class/race specific
+ return progress->counter >= achievementCriteria->reach_level.level;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
+ return progress->counter >= achievementCriteria->reach_skill_level.skillLevel;
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL:
+ return progress->counter >= (achievementCriteria->learn_skill_level.skillLevel * 75);
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
+ return progress->counter >= 1;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT:
+ return progress->counter >= achievementCriteria->complete_quest_count.totalQuestCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE:
+ return progress->counter >= achievementCriteria->complete_quests_in_zone.questCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
+ return progress->counter >= achievementCriteria->complete_daily_quest.questCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
+ return progress->counter >= achievementCriteria->fall_without_dying.fallHeight;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
+ return progress->counter >= 1;
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
+ return progress->counter >= achievementCriteria->be_spell_target.spellCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
+ return progress->counter >= achievementCriteria->cast_spell.castCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
+ return progress->counter >= 1;
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE:
+ return progress->counter >= achievementCriteria->loot_type.lootTypeCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
+ return progress->counter >= achievementCriteria->own_item.itemCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
+ return progress->counter >= achievementCriteria->use_item.itemCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM:
+ return progress->counter >= achievementCriteria->loot_item.itemCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA:
+ return progress->counter >= 1;
+ case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
+ return progress->counter >= achievementCriteria->buy_bank_slot.numberOfSlots;
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
+ return progress->counter >= achievementCriteria->gain_reputation.reputationAmount;
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION:
+ return progress->counter >= achievementCriteria->gain_exalted_reputation.numberOfExaltedFactions;
+ case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP:
+ return progress->counter >= achievementCriteria->visit_barber.numberOfVisits;
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
+ return progress->counter >= achievementCriteria->roll_greed_on_loot.count;
+ case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
+ return progress->counter >= achievementCriteria->do_emote.count;
+ case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE:
+ case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE:
+ return progress->counter >= achievementCriteria->healing_done.count;
+ case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
+ return progress->counter >= achievementCriteria->equip_item.count;
+ case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD:
+ return progress->counter >= achievementCriteria->quest_reward_money.goldInCopper;
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY:
+ return progress->counter >= achievementCriteria->loot_money.goldInCopper;
+ case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT:
+ return progress->counter >= achievementCriteria->use_gameobject.useCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT:
+ return progress->counter >= achievementCriteria->fish_in_gameobject.lootCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
+ return progress->counter >= achievementCriteria->learn_skillline_spell.spellCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE:
+ return progress->counter >= achievementCriteria->learn_skill_line.spellCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL:
+ return progress->counter >= achievementCriteria->honorable_kill.killCount;
+
+ // handle all statistic-only criteria here
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATH:
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON:
+ case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE:
+ case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER:
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM:
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS:
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER:
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD:
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION:
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION:
+ case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_ARMOR:
+ return false;
+ }
+ return false;
+}
+
+void AchievementMgr::CompletedCriteriaFor(AchievementEntry const* achievement)
+{
+ // counter can never complete
+ if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
+ return;
+
+ // already completed and stored
+ if (m_completedAchievements.find(achievement->ID)!=m_completedAchievements.end())
+ return;
+
+ if (IsCompletedAchievement(achievement))
+ CompletedAchievement(achievement);
+}
+
+bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry)
+{
+ // counter can never complete
+ if(entry->flags & ACHIEVEMENT_FLAG_COUNTER)
+ return false;
+
+ // for achievement with referenced achievement criterias get from referenced and counter from self
+ uint32 achievmentForTestId = entry->refAchievement ? entry->refAchievement : entry->ID;
+ uint32 achievmentForTestCount = entry->count;
+
+ AchievementCriteriaEntryList const* cList = achievementmgr.GetAchievementCriteriaByAchievement(achievmentForTestId);
+ if(!cList)
+ return false;
+ uint32 count = 0;
+
+ // For SUMM achievements, we have to count the progress of each criteria of the achievement.
+ // Oddly, the target count is NOT countained in the achievement, but in each individual criteria
+ if (entry->flags & ACHIEVEMENT_FLAG_SUMM)
+ {
+ for(AchievementCriteriaEntryList::const_iterator itr = cList->begin(); itr != cList->end(); ++itr)
+ {
+ AchievementCriteriaEntry const* criteria = *itr;
+
+ CriteriaProgressMap::const_iterator itrProgress = m_criteriaProgress.find(criteria->ID);
+ if(itrProgress == m_criteriaProgress.end())
+ continue;
+
+ CriteriaProgress const* progress = &itrProgress->second;
+ count += progress->counter;
+
+ // for counters, field4 contains the main count requirement
+ if (count >= criteria->raw.count)
+ return true;
+ }
+ return false;
+ }
+
+ // Default case - need complete all or
+ bool completed_all = true;
+ for(AchievementCriteriaEntryList::const_iterator itr = cList->begin(); itr != cList->end(); ++itr)
+ {
+ AchievementCriteriaEntry const* criteria = *itr;
+
+ bool completed = IsCompletedCriteria(criteria,entry);
+
+ // found an uncompleted criteria, but DONT return false yet - there might be a completed criteria with ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL
+ if(completed)
+ ++count;
+ else
+ completed_all = false;
+
+ // completed as have req. count of completed criterias
+ if(achievmentForTestCount > 0 && achievmentForTestCount <= count)
+ return true;
+ }
+
+ // all criterias completed requirement
+ if(completed_all && achievmentForTestCount==0)
+ return true;
+
+ return false;
+}
+
+void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype)
+{
+ if((sLog.getLogFilter() & LOG_FILTER_ACHIEVEMENT_UPDATES)==0)
+ sLog.outDetail("AchievementMgr::SetCriteriaProgress(%u, %u) for (GUID:%u)", entry->ID, changeValue, m_player->GetGUIDLow());
+
+ CriteriaProgress *progress = NULL;
+
+ CriteriaProgressMap::iterator iter = m_criteriaProgress.find(entry->ID);
+
+ if(iter == m_criteriaProgress.end())
+ {
+ // not create record for 0 counter
+ if(changeValue == 0)
+ return;
+
+ progress = &m_criteriaProgress[entry->ID];
+ progress->counter = changeValue;
+ progress->date = time(NULL);
+ }
+ else
+ {
+ progress = &iter->second;
+
+ uint32 newValue = 0;
+ switch(ptype)
+ {
+ case PROGRESS_SET:
+ newValue = changeValue;
+ break;
+ case PROGRESS_ACCUMULATE:
+ {
+ // avoid overflow
+ uint32 max_value = std::numeric_limits<uint32>::max();
+ newValue = max_value - progress->counter > changeValue ? progress->counter + changeValue : max_value;
+ break;
+ }
+ case PROGRESS_HIGHEST:
+ newValue = progress->counter < changeValue ? changeValue : progress->counter;
+ break;
+ }
+
+ // not update (not mark as changed) if counter will have same value
+ if(progress->counter == newValue)
+ return;
+
+ progress->counter = newValue;
+ }
+
+ progress->changed = true;
+
+ if(entry->timeLimit)
+ {
+ time_t now = time(NULL);
+ if(time_t(progress->date + entry->timeLimit) < now)
+ progress->counter = 1;
+
+ // also it seems illogical, the timeframe will be extended at every criteria update
+ progress->date = now;
+ }
+ SendCriteriaUpdate(entry->ID,progress);
+}
+
+void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
+{
+ sLog.outDetail("AchievementMgr::CompletedAchievement(%u)", achievement->ID);
+ if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER || m_completedAchievements.find(achievement->ID)!=m_completedAchievements.end())
+ return;
+
+ SendAchievementEarned(achievement);
+ CompletedAchievementData& ca = m_completedAchievements[achievement->ID];
+ ca.date = time(NULL);
+ ca.changed = true;
+
+ // don't insert for ACHIEVEMENT_FLAG_REALM_FIRST_KILL since otherwise only the first group member would reach that achievement
+ // TODO: where do set this instead?
+ if(!(achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL))
+ achievementmgr.SetRealmCompleted(achievement);
+
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT);
+
+ // reward items and titles if any
+ AchievementReward const* reward = achievementmgr.GetAchievementReward(achievement);
+
+ // no rewards
+ if(!reward)
+ return;
+
+ // titles
+ if(uint32 titleId = reward->titleId[GetPlayer()->GetTeam() == HORDE?0:1])
+ {
+ if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId))
+ GetPlayer()->SetTitle(titleEntry);
+ }
+
+ // mail
+ if(reward->sender)
+ {
+ Item* item = reward->itemId ? Item::CreateItem(reward->itemId,1,GetPlayer ()) : NULL;
+
+ MailItemsInfo mi;
+ if(item)
+ {
+ // save new item before send
+ item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
+
+ // item
+ mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
+ }
+
+ int loc_idx = GetPlayer()->GetSession()->GetSessionDbLocaleIndex();
+
+ // subject and text
+ std::string subject = reward->subject;
+ std::string text = reward->text;
+ if ( loc_idx >= 0 )
+ {
+ if(AchievementRewardLocale const* loc = achievementmgr.GetAchievementRewardLocale(achievement))
+ {
+ if (loc->subject.size() > size_t(loc_idx) && !loc->subject[loc_idx].empty())
+ subject = loc->subject[loc_idx];
+ if (loc->text.size() > size_t(loc_idx) && !loc->text[loc_idx].empty())
+ text = loc->text[loc_idx];
+ }
+ }
+
+ uint32 itemTextId = objmgr.CreateItemText( text );
+
+ WorldSession::SendMailTo(GetPlayer(), MAIL_CREATURE, MAIL_STATIONERY_NORMAL, reward->sender, GetPlayer()->GetGUIDLow(), subject, itemTextId , &mi, 0, 0, MAIL_CHECK_MASK_NONE);
+ }
+}
+
+void AchievementMgr::SendAllAchievementData()
+{
+ // since we don't know the exact size of the packed GUIDs this is just an approximation
+ WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, 4*2+m_completedAchievements.size()*4*2+m_completedAchievements.size()*7*4);
+ BuildAllDataPacket(&data);
+ GetPlayer()->GetSession()->SendPacket(&data);
+}
+
+void AchievementMgr::SendRespondInspectAchievements(Player* player)
+{
+ // since we don't know the exact size of the packed GUIDs this is just an approximation
+ WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 4+4*2+m_completedAchievements.size()*4*2+m_completedAchievements.size()*7*4);
+ data.append(GetPlayer()->GetPackGUID());
+ BuildAllDataPacket(&data);
+ player->GetSession()->SendPacket(&data);
+}
+
+/**
+ * used by both SMSG_ALL_ACHIEVEMENT_DATA and SMSG_RESPOND_INSPECT_ACHIEVEMENT
+ */
+void AchievementMgr::BuildAllDataPacket(WorldPacket *data)
+{
+ for(CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter!=m_completedAchievements.end(); ++iter)
+ {
+ *data << uint32(iter->first);
+ *data << uint32(secsToTimeBitFields(iter->second.date));
+ }
+ *data << int32(-1);
+
+ for(CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter)
+ {
+ *data << uint32(iter->first);
+ data->appendPackGUID(iter->second.counter);
+ data->append(GetPlayer()->GetPackGUID());
+ *data << uint32(0);
+ *data << uint32(secsToTimeBitFields(iter->second.date));
+ *data << uint32(0);
+ *data << uint32(0);
+ }
+
+ *data << int32(-1);
+}
+
+//==========================================================
+AchievementCriteriaEntryList const& AchievementGlobalMgr::GetAchievementCriteriaByType(AchievementCriteriaTypes type)
+{
+ return m_AchievementCriteriasByType[type];
+}
+
+void AchievementGlobalMgr::LoadAchievementCriteriaList()
+{
+ if(sAchievementCriteriaStore.GetNumRows()==0)
+ {
+ barGoLink bar(1);
+ bar.step();
+
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded 0 achievement criteria.");
+ return;
+ }
+
+ barGoLink bar( sAchievementCriteriaStore.GetNumRows() );
+ for (uint32 entryId = 0; entryId < sAchievementCriteriaStore.GetNumRows(); ++entryId)
+ {
+ bar.step();
+
+ AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId);
+ if(!criteria)
+ continue;
+
+ m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria);
+ m_AchievementCriteriaListByAchievement[criteria->referredAchievement].push_back(criteria);
+ }
+
+ sLog.outString();
+ sLog.outString(">> Loaded %lu achievement criteria.",(unsigned long)m_AchievementCriteriasByType->size());
+}
+
+void AchievementGlobalMgr::LoadAchievementReferenceList()
+{
+ if(sAchievementStore.GetNumRows()==0)
+ {
+ barGoLink bar(1);
+ bar.step();
+
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded 0 achievement references.");
+ return;
+ }
+
+ uint32 count = 0;
+ barGoLink bar( sAchievementStore.GetNumRows() );
+ for (uint32 entryId = 0; entryId < sAchievementStore.GetNumRows(); ++entryId)
+ {
+ bar.step();
+
+ AchievementEntry const* achievement = sAchievementStore.LookupEntry(entryId);
+ if(!achievement || !achievement->refAchievement)
+ continue;
+
+ m_AchievementListByReferencedId[achievement->refAchievement].push_back(achievement);
+ ++count;
+ }
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u achievement references.",count);
+}
+
+void AchievementGlobalMgr::LoadAchievementCriteriaData()
+{
+ m_criteriaDataMap.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query("SELECT criteria_id, type, value1, value2 FROM achievement_criteria_data");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+ bar.step();
+
+ sLog.outString();
+ sLog.outString(">> Loaded 0 additional achievement criteria data. DB table `achievement_criteria_data` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+ barGoLink bar(result->GetRowCount());
+ do
+ {
+ bar.step();
+ Field *fields = result->Fetch();
+ uint32 criteria_id = fields[0].GetUInt32();
+
+ AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(criteria_id);
+
+ if (!criteria)
+ {
+ sLog.outErrorDb( "Table `achievement_criteria_data` have data for not existed criteria (Entry: %u), ignore.", criteria_id);
+ continue;
+ }
+
+ AchievementCriteriaData data(fields[1].GetUInt32(),fields[2].GetUInt32(),fields[3].GetUInt32());
+
+ if(!data.IsValid(criteria))
+ continue;
+
+ // this will allocate empty data set storage
+ AchievementCriteriaDataSet& dataSet = m_criteriaDataMap[criteria_id];
+
+ // add real data only for not NONE data types
+ if(data.dataType!=ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE)
+ dataSet.Add(data);
+
+ // counting data by and data types
+ ++count;
+ } while(result->NextRow());
+
+ delete result;
+
+ // post loading checks
+ for (uint32 entryId = 0; entryId < sAchievementCriteriaStore.GetNumRows(); ++entryId)
+ {
+ AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId);
+ if(!criteria)
+ continue;
+
+ switch(criteria->requiredType)
+ {
+ case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE: // need skip generic cases
+ if(criteria->do_emote.count==0)
+ continue;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: // any cases
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: // need skip generic cases
+ if(criteria->loot_type.lootTypeCount!=1)
+ continue;
+ break;
+ default: // type not use DB data, ignore
+ continue;
+ }
+
+ if(!GetCriteriaDataSet(criteria))
+ sLog.outErrorDb( "Table `achievement_criteria_data` not have expected data for for criteria (Entry: %u Type: %u).", criteria->ID, criteria->requiredType);
+ }
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u additional achievement criteria data.",count);
+}
+
+void AchievementGlobalMgr::LoadCompletedAchievements()
+{
+ QueryResult *result = CharacterDatabase.Query("SELECT achievement FROM character_achievement GROUP BY achievement");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+ bar.step();
+
+ sLog.outString();
+ sLog.outString(">> Loaded 0 realm completed achievements . DB table `character_achievement` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+ do
+ {
+ bar.step();
+ Field *fields = result->Fetch();
+ m_allCompletedAchievements.insert(fields[0].GetUInt32());
+ } while(result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString(">> Loaded %lu realm completed achievements.",(unsigned long)m_allCompletedAchievements.size());
+}
+
+void AchievementGlobalMgr::LoadRewards()
+{
+ m_achievementRewards.clear(); // need for reload case
+
+ // 0 1 2 3 4 5 6
+ QueryResult *result = WorldDatabase.Query("SELECT entry, title_A, title_H, item, sender, subject, text FROM achievement_reward");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded 0 achievement rewards. DB table `achievement_reward` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ bar.step();
+
+ Field *fields = result->Fetch();
+ uint32 entry = fields[0].GetUInt32();
+ if (!sAchievementStore.LookupEntry(entry))
+ {
+ sLog.outErrorDb( "Table `achievement_reward` has wrong achievement (Entry: %u), ignore", entry);
+ continue;
+ }
+
+ AchievementReward reward;
+ reward.titleId[0] = fields[1].GetUInt32();
+ reward.titleId[1] = fields[2].GetUInt32();
+ reward.itemId = fields[3].GetUInt32();
+ reward.sender = fields[4].GetUInt32();
+ reward.subject = fields[5].GetCppString();
+ reward.text = fields[6].GetCppString();
+
+ if ((reward.titleId[0]==0)!=(reward.titleId[1]==0))
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has title (A: %u H: %u) only for one from teams.", entry, reward.titleId[0], reward.titleId[1]);
+
+ // must be title or mail at least
+ if (!reward.titleId[0] && !reward.titleId[1] && !reward.sender)
+ {
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) not have title or item reward data, ignore.", entry);
+ continue;
+ }
+
+ if (reward.titleId[0])
+ {
+ CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(reward.titleId[0]);
+ if (!titleEntry)
+ {
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has invalid title id (%u) in `title_A`, set to 0", entry, reward.titleId[0]);
+ reward.titleId[0] = 0;
+ }
+ }
+
+ if (reward.titleId[1])
+ {
+ CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(reward.titleId[1]);
+ if (!titleEntry)
+ {
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has invalid title id (%u) in `title_A`, set to 0", entry, reward.titleId[1]);
+ reward.titleId[1] = 0;
+ }
+ }
+
+ //check mail data before item for report including wrong item case
+ if (reward.sender)
+ {
+ if (!objmgr.GetCreatureTemplate(reward.sender))
+ {
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has invalid creature entry %u as sender, mail reward skipped.", entry, reward.sender);
+ reward.sender = 0;
+ }
+ }
+ else
+ {
+ if (reward.itemId)
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) not have sender data but have item reward, item will not rewarded", entry);
+
+ if (!reward.subject.empty())
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) not have sender data but have mail subject.", entry);
+
+ if (!reward.text.empty())
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) not have sender data but have mail text.", entry);
+ }
+
+ if (reward.itemId)
+ {
+ if (!objmgr.GetItemPrototype(reward.itemId))
+ {
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has invalid item id %u, reward mail will be without item.", entry, reward.itemId);
+ reward.itemId = 0;
+ }
+ }
+
+ m_achievementRewards[entry] = reward;
+ ++count;
+
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u achievement rewards", count );
+}
+
+void AchievementGlobalMgr::LoadRewardLocales()
+{
+ m_achievementRewardLocales.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query("SELECT entry,subject_loc1,text_loc1,subject_loc2,text_loc2,subject_loc3,text_loc3,subject_loc4,text_loc4,subject_loc5,text_loc5,subject_loc6,text_loc6,subject_loc7,text_loc7,subject_loc8,text_loc8 FROM locales_achievement_reward");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outString(">> Loaded 0 achievement reward locale strings. DB table `locales_achievement_reward` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 entry = fields[0].GetUInt32();
+
+ if(m_achievementRewards.find(entry)==m_achievementRewards.end())
+ {
+ sLog.outErrorDb( "Table `locales_achievement_reward` (Entry: %u) has locale strings for not existed achievement reward .", entry);
+ continue;
+ }
+
+ AchievementRewardLocale& data = m_achievementRewardLocales[entry];
+
+ for(int i = 1; i < MAX_LOCALE; ++i)
+ {
+ std::string str = fields[1+2*(i-1)].GetCppString();
+ if(!str.empty())
+ {
+ int idx = objmgr.GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.subject.size() <= size_t(idx))
+ data.subject.resize(idx+1);
+
+ data.subject[idx] = str;
+ }
+ }
+ str = fields[1+2*(i-1)+1].GetCppString();
+ if(!str.empty())
+ {
+ int idx = objmgr.GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.text.size() <= size_t(idx))
+ data.text.resize(idx+1);
+
+ data.text[idx] = str;
+ }
+ }
+ }
+ } while (result->NextRow());
+
+ delete result;
+
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %lu achievement reward locale strings", (unsigned long)m_achievementRewardLocales.size() );
+}
diff --git a/src/game/AchievementMgr.h b/src/game/AchievementMgr.h
new file mode 100644
index 00000000000..b00dc6a107f
--- /dev/null
+++ b/src/game/AchievementMgr.h
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2005-2009 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 __MANGOS_ACHIEVEMENTMGR_H
+#define __MANGOS_ACHIEVEMENTMGR_H
+
+#include "Common.h"
+#include "Policies/Singleton.h"
+#include "Database/DatabaseEnv.h"
+#include "DBCEnums.h"
+#include "DBCStores.h"
+
+#include <map>
+#include <string>
+
+typedef std::list<AchievementCriteriaEntry const*> AchievementCriteriaEntryList;
+typedef std::list<AchievementEntry const*> AchievementEntryList;
+
+typedef std::map<uint32,AchievementCriteriaEntryList> AchievementCriteriaListByAchievement;
+typedef std::map<uint32,AchievementEntryList> AchievementListByReferencedId;
+
+struct CriteriaProgress
+{
+ uint32 counter;
+ time_t date;
+ bool changed;
+};
+
+enum AchievementCriteriaDataType
+{ // value1 value2 comment
+ ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE = 0, // 0 0
+ ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE = 1, // creature_id 0
+ ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE = 2, // class_id race_id
+ ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH= 3, // health_percent 0
+ ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD = 4, // 0 0 not corpse (not released body)
+ ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA = 5, // spell_id effect_idx
+ ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA = 6, // area id 0
+ ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA = 7, // spell_id effect_idx
+};
+
+#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 8 // maximum value in AchievementCriteriaDataType enum
+
+class Player;
+class Unit;
+
+struct AchievementCriteriaData
+{
+ AchievementCriteriaDataType dataType;
+ union
+ {
+ // ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE
+ struct
+ {
+ uint32 id;
+ } creature;
+ // ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE
+ struct
+ {
+ uint32 class_id;
+ uint32 race_id;
+ } classRace;
+ // ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH
+ struct
+ {
+ uint32 percent;
+ } health;
+ // ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA
+ // ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA
+ struct
+ {
+ uint32 spell_id;
+ uint32 effect_idx;
+ } aura;
+ // ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA
+ struct
+ {
+ uint32 id;
+ } area;
+ // ...
+ struct
+ {
+ uint32 value1;
+ uint32 value2;
+ } raw;
+ };
+
+ AchievementCriteriaData() : dataType(ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE)
+ {
+ raw.value1 = 0;
+ raw.value2 = 0;
+ }
+
+ AchievementCriteriaData(uint32 _dataType, uint32 _value1, uint32 _value2) : dataType(AchievementCriteriaDataType(_dataType))
+ {
+ raw.value1 = _value1;
+ raw.value2 = _value2;
+ }
+
+ bool IsValid(AchievementCriteriaEntry const* criteria);
+ bool Meets(Player const* source, Unit const* target) const;
+};
+
+struct AchievementCriteriaDataSet
+{
+ typedef std::vector<AchievementCriteriaData> Storage;
+ void Add(AchievementCriteriaData const& data) { storage.push_back(data); }
+ bool Meets(Player const* source, Unit const* target) const;
+ private:
+ Storage storage;
+};
+
+
+typedef std::map<uint32,AchievementCriteriaDataSet> AchievementCriteriaDataMap;
+
+struct AchievementReward
+{
+ uint32 titleId[2];
+ uint32 itemId;
+ uint32 sender;
+ std::string subject;
+ std::string text;
+};
+
+typedef std::map<uint32,AchievementReward> AchievementRewards;
+
+struct AchievementRewardLocale
+{
+ std::vector<std::string> subject;
+ std::vector<std::string> text;
+};
+
+typedef std::map<uint32,AchievementRewardLocale> AchievementRewardLocales;
+
+
+struct CompletedAchievementData
+{
+ time_t date;
+ bool changed;
+};
+
+typedef UNORDERED_MAP<uint32, CriteriaProgress> CriteriaProgressMap;
+typedef UNORDERED_MAP<uint32, CompletedAchievementData> CompletedAchievementMap;
+
+class Unit;
+class Player;
+class WorldPacket;
+
+class AchievementMgr
+{
+ public:
+ AchievementMgr(Player* pl);
+ ~AchievementMgr();
+
+ void Reset();
+ static void DeleteFromDB(uint32 lowguid);
+ void LoadFromDB(QueryResult *achievementResult, QueryResult *criteriaResult);
+ void SaveToDB();
+ void ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1=0, uint32 miscvalue2=0);
+ void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1=0, uint32 miscvalue2=0, Unit *unit=NULL, uint32 time=0);
+ void CheckAllAchievementCriteria();
+ void SendAllAchievementData();
+ void SendRespondInspectAchievements(Player* player);
+ Player* GetPlayer() { return m_player;}
+
+ private:
+ enum ProgressType { PROGRESS_SET, PROGRESS_ACCUMULATE, PROGRESS_HIGHEST };
+ void SendAchievementEarned(AchievementEntry const* achievement);
+ void SendCriteriaUpdate(uint32 id, CriteriaProgress const* progress);
+ void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype = PROGRESS_SET);
+ void CompletedCriteriaFor(AchievementEntry const* achievement);
+ void CompletedAchievement(AchievementEntry const* entry);
+ bool IsCompletedCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement);
+ bool IsCompletedAchievement(AchievementEntry const* entry);
+ void CompleteAchievementsWithRefs(AchievementEntry const* entry);
+ void BuildAllDataPacket(WorldPacket *data);
+
+ Player* m_player;
+ CriteriaProgressMap m_criteriaProgress;
+ CompletedAchievementMap m_completedAchievements;
+};
+
+class AchievementGlobalMgr
+{
+ public:
+ AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type);
+ AchievementCriteriaEntryList const* GetAchievementCriteriaByAchievement(uint32 id)
+ {
+ AchievementCriteriaListByAchievement::const_iterator itr = m_AchievementCriteriaListByAchievement.find(id);
+ return itr != m_AchievementCriteriaListByAchievement.end() ? &itr->second : NULL;
+ }
+
+ AchievementEntryList const* GetAchievementByReferencedId(uint32 id) const
+ {
+ AchievementListByReferencedId::const_iterator itr = m_AchievementListByReferencedId.find(id);
+ return itr != m_AchievementListByReferencedId.end() ? &itr->second : NULL;
+ }
+
+ AchievementReward const* GetAchievementReward(AchievementEntry const* achievement) const
+ {
+ AchievementRewards::const_iterator iter = m_achievementRewards.find(achievement->ID);
+ return iter!=m_achievementRewards.end() ? &iter->second : NULL;
+ }
+
+ AchievementRewardLocale const* GetAchievementRewardLocale(AchievementEntry const* achievement) const
+ {
+ AchievementRewardLocales::const_iterator iter = m_achievementRewardLocales.find(achievement->ID);
+ return iter!=m_achievementRewardLocales.end() ? &iter->second : NULL;
+ }
+
+ AchievementCriteriaDataSet const* GetCriteriaDataSet(AchievementCriteriaEntry const *achievementCriteria)
+ {
+ AchievementCriteriaDataMap::const_iterator iter = m_criteriaDataMap.find(achievementCriteria->ID);
+ return iter!=m_criteriaDataMap.end() ? &iter->second : NULL;
+ }
+
+ bool IsRealmCompleted(AchievementEntry const* achievement) const
+ {
+ return m_allCompletedAchievements.find(achievement->ID) != m_allCompletedAchievements.end();
+ }
+
+ void SetRealmCompleted(AchievementEntry const* achievement)
+ {
+ m_allCompletedAchievements.insert(achievement->ID);
+ }
+
+ void LoadAchievementCriteriaList();
+ void LoadAchievementCriteriaData();
+ void LoadAchievementReferenceList();
+ void LoadCompletedAchievements();
+ void LoadRewards();
+ void LoadRewardLocales();
+ private:
+ AchievementCriteriaDataMap m_criteriaDataMap;
+
+ // store achievement criterias by type to speed up lookup
+ AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
+ // store achievement criterias by achievement to speed up lookup
+ AchievementCriteriaListByAchievement m_AchievementCriteriaListByAchievement;
+ // store achievements by referenced achievement id to speed up lookup
+ AchievementListByReferencedId m_AchievementListByReferencedId;
+
+ typedef std::set<uint32> AllCompletedAchievements;
+ AllCompletedAchievements m_allCompletedAchievements;
+
+ AchievementRewards m_achievementRewards;
+ AchievementRewardLocales m_achievementRewardLocales;
+};
+
+#define achievementmgr Trinity::Singleton<AchievementGlobalMgr>::Instance()
+
+#endif
diff --git a/src/game/AddonHandler.cpp b/src/game/AddonHandler.cpp
index 63582113914..4dd25c56b26 100644
--- a/src/game/AddonHandler.cpp
+++ b/src/game/AddonHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -66,63 +66,84 @@ bool AddonHandler::BuildAddonPacket(WorldPacket *Source, WorldPacket *Target)
if (Source->rpos() + 4 > Source->size())
return false;
- *Source >> TempValue; //get real size of the packed structure
+ *Source >> TempValue; // get real size of the packed structure
// empty addon packet, nothing process, can't be received from real client
if(!TempValue)
return false;
- AddonRealSize = TempValue; //temp value because ZLIB only excepts uLongf
+ AddonRealSize = TempValue; // temp value because ZLIB only excepts uLongf
- CurrentPosition = Source->rpos(); //get the position of the pointer in the structure
+ CurrentPosition = Source->rpos(); // get the position of the pointer in the structure
- AddOnPacked.resize(AddonRealSize); //resize target for zlib action
+ AddOnPacked.resize(AddonRealSize); // resize target for zlib action
if (!uncompress(const_cast<uint8*>(AddOnPacked.contents()), &AddonRealSize, const_cast<uint8*>((*Source).contents() + CurrentPosition), (*Source).size() - CurrentPosition)!= Z_OK)
{
Target->Initialize(SMSG_ADDON_INFO);
- while(AddOnPacked.rpos() < AddOnPacked.size())
+ uint32 addonsCount;
+ AddOnPacked >> addonsCount; // addons count?
+
+ for(uint32 i = 0; i < addonsCount; ++i)
{
- std::string AddonNames;
- uint8 unk6;
- uint32 crc, unk7;
+ std::string addonName;
+ uint8 enabled;
+ uint32 crc, unk2;
// check next addon data format correctness
- if(AddOnPacked.rpos()+1+4+4+1 > AddOnPacked.size())
+ if(AddOnPacked.rpos()+1 > AddOnPacked.size())
return false;
- AddOnPacked >> AddonNames;
+ AddOnPacked >> addonName;
// recheck next addon data format correctness
- if(AddOnPacked.rpos()+4+4+1 > AddOnPacked.size())
+ if(AddOnPacked.rpos()+1+4+4 > AddOnPacked.size())
return false;
- AddOnPacked >> crc >> unk7 >> unk6;
+ AddOnPacked >> enabled >> crc >> unk2;
- //sLog.outDebug("ADDON: Name:%s CRC:%x Unknown1 :%x Unknown2 :%x", AddonNames.c_str(), crc, unk7, unk6);
+ sLog.outDebug("ADDON: Name: %s, Enabled: 0x%x, CRC: 0x%x, Unknown2: 0x%x", addonName.c_str(), enabled, crc, unk2);
- *Target << (uint8)2;
+ uint8 state = (enabled ? 2 : 1);
+ *Target << uint8(state);
- uint8 unk1 = 1;
- *Target << (uint8)unk1;
+ uint8 unk1 = (enabled ? 1 : 0);
+ *Target << uint8(unk1);
if (unk1)
{
- uint8 unk2 = crc != 0x1c776d01LL; //If addon is Standard addon CRC
- *Target << (uint8)unk2;
+ uint8 unk2 = (crc != 0x4c1c776d); // If addon is Standard addon CRC
+ *Target << uint8(unk2);
if (unk2)
Target->append(tdata, sizeof(tdata));
- *Target << (uint32)0;
+ *Target << uint32(0);
}
- uint8 unk3 = 0;
- *Target << (uint8)unk3;
+ uint8 unk3 = (enabled ? 0 : 1);
+ *Target << uint8(unk3);
if (unk3)
{
- // String, 256
+ // String, 256 (null terminated?)
+ *Target << uint8(0);
}
}
+
+ uint32 unk4;
+ AddOnPacked >> unk4;
+
+ uint32 count = 0;
+ *Target << uint32(count);
+ /*for(uint32 i = 0; i < count; ++i)
+ {
+ uint32
+ string (16 bytes)
+ string (16 bytes)
+ uint32
+ }*/
+
+ if(AddOnPacked.rpos() != AddOnPacked.size())
+ sLog.outDebug("packet under read!");
}
else
{
diff --git a/src/game/AddonHandler.h b/src/game/AddonHandler.h
index 6255bd551e2..fd9ad395924 100644
--- a/src/game/AddonHandler.h
+++ b/src/game/AddonHandler.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp
index a001ea5af22..a637e7e40f0 100644
--- a/src/game/AggressorAI.cpp
+++ b/src/game/AggressorAI.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,7 +21,6 @@
#include "AggressorAI.h"
#include "Errors.h"
#include "Creature.h"
-#include "Player.h"
#include "ObjectAccessor.h"
#include "VMapFactory.h"
#include "World.h"
@@ -38,78 +37,78 @@ AggressorAI::Permissible(const Creature *creature)
return PERMIT_BASE_NO;
}
-AggressorAI::AggressorAI(Creature *c) : CreatureAI(c), i_creature(*c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
+AggressorAI::AggressorAI(Creature *c) : CreatureAI(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
{
}
void AggressorAI::EnterEvadeMode()
{
- if( !i_creature.isAlive() )
+ if( !m_creature->isAlive() )
{
- DEBUG_LOG("Creature stopped attacking cuz his dead [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow());
i_victimGuid = 0;
- i_creature.CombatStop();
- i_creature.DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->DeleteThreatList();
return;
}
- Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid );
+ Unit* victim = ObjectAccessor::GetUnit(*m_creature, i_victimGuid );
if( !victim )
{
- DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", m_creature->GetGUIDLow());
}
else if( !victim->isAlive() )
{
- DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", m_creature->GetGUIDLow());
}
else if( victim->HasStealthAura() )
{
- DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", m_creature->GetGUIDLow());
}
else if( victim->isInFlight() )
{
- DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", m_creature->GetGUIDLow());
}
else
{
- DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", m_creature->GetGUIDLow());
//i_state = STATE_LOOK_AT_VICTIM;
//i_tracker.Reset(TIME_INTERVAL_LOOK);
}
- if(!i_creature.GetCharmerOrOwner())
+ if(!m_creature->GetCharmerOrOwner())
{
- i_creature.RemoveAllAuras();
+ m_creature->RemoveAllAuras();
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
- if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
- i_creature.GetMotionMaster()->MoveTargetedHome();
+ if( m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
+ m_creature->GetMotionMaster()->MoveTargetedHome();
}
- else if (i_creature.GetOwner() && i_creature.GetOwner()->isAlive())
- i_creature.GetMotionMaster()->MoveFollow(i_creature.GetOwner(),PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
+ else if (m_creature->GetOwner() && m_creature->GetOwner()->isAlive())
+ m_creature->GetMotionMaster()->MoveFollow(m_creature->GetOwner(),PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
- i_creature.DeleteThreatList();
+ m_creature->DeleteThreatList();
i_victimGuid = 0;
- i_creature.CombatStop();
- i_creature.SetLootRecipient(NULL);
+ m_creature->CombatStop(true);
+ m_creature->SetLootRecipient(NULL);
}
void
AggressorAI::UpdateAI(const uint32 /*diff*/)
{
- // update i_victimGuid if i_creature.getVictim() !=0 and changed
+ // update i_victimGuid if m_creature->getVictim() !=0 and changed
if(!UpdateVictim())
return;
- i_victimGuid = i_creature.getVictim()->GetGUID();
+ i_victimGuid = m_creature->getVictim()->GetGUID();
- if( i_creature.isAttackReady() )
+ if( m_creature->isAttackReady() )
{
- if( i_creature.IsWithinMeleeRange(i_creature.getVictim()))
+ if( m_creature->IsWithinMeleeRange(m_creature->getVictim()))
{
- i_creature.AttackerStateUpdate(i_creature.getVictim());
- i_creature.resetAttackTimer();
+ m_creature->AttackerStateUpdate(m_creature->getVictim());
+ m_creature->resetAttackTimer();
}
}
}
diff --git a/src/game/AggressorAI.h b/src/game/AggressorAI.h
index 97dccbcd329..983498716e6 100644
--- a/src/game/AggressorAI.h
+++ b/src/game/AggressorAI.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -36,7 +36,7 @@ class TRINITY_DLL_DECL AggressorAI : public CreatureAI
public:
- AggressorAI(Creature *c);
+ explicit AggressorAI(Creature *c);
void EnterEvadeMode();
@@ -44,7 +44,6 @@ class TRINITY_DLL_DECL AggressorAI : public CreatureAI
static int Permissible(const Creature *);
private:
- Creature &i_creature;
uint64 i_victimGuid;
AggressorState i_state;
TimeTracker i_tracker;
diff --git a/src/game/AnimalRandomMovementGenerator.h b/src/game/AnimalRandomMovementGenerator.h
index c24162d2708..9c64edcaa44 100644
--- a/src/game/AnimalRandomMovementGenerator.h
+++ b/src/game/AnimalRandomMovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/ArenaTeam.cpp b/src/game/ArenaTeam.cpp
index 747ad811b85..c00a103b1ca 100644
--- a/src/game/ArenaTeam.cpp
+++ b/src/game/ArenaTeam.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
+ * Copyright (C) 2005-2009 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
@@ -304,8 +304,11 @@ void ArenaTeam::Roster(WorldSession *session)
{
Player *pl = NULL;
+ uint8 unk308 = 0;
+
WorldPacket data(SMSG_ARENA_TEAM_ROSTER, 100);
data << uint32(GetId()); // arena team id
+ data << uint8(unk308); // 308 unknown value but affect packet structure
data << uint32(GetMembersSize()); // members count
data << uint32(GetType()); // arena team type?
@@ -313,18 +316,24 @@ void ArenaTeam::Roster(WorldSession *session)
{
pl = objmgr.GetPlayer(itr->guid);
- data << uint64(itr->guid); // guid
- data << uint8((pl ? 1 : 0)); // online flag
- data << itr->name; // member name
+ data << uint64(itr->guid); // guid
+ data << uint8((pl ? 1 : 0)); // online flag
+ data << itr->name; // member name
data << uint32((itr->guid == GetCaptain() ? 0 : 1));// captain flag 0 captain 1 member
- data << uint8((pl ? pl->getLevel() : 0)); // unknown, level?
- data << uint8(itr->Class); // class
- data << uint32(itr->games_week); // played this week
- data << uint32(itr->wins_week); // wins this week
- data << uint32(itr->games_season); // played this season
- data << uint32(itr->wins_season); // wins this season
- data << uint32(itr->personal_rating); // personal rating
+ data << uint8((pl ? pl->getLevel() : 0)); // unknown, level?
+ data << uint8(itr->Class); // class
+ data << uint32(itr->games_week); // played this week
+ data << uint32(itr->wins_week); // wins this week
+ data << uint32(itr->games_season); // played this season
+ data << uint32(itr->wins_season); // wins this season
+ data << uint32(itr->personal_rating); // personal rating
+ if(unk308)
+ {
+ data << float(0.0); // 308 unk
+ data << float(0.0); // 308 unk
+ }
}
+
session->SendPacket(&data);
sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_ROSTER");
}
@@ -508,7 +517,7 @@ int32 ArenaTeam::WonAgainst(uint32 againstRating)
stats.wins_season += 1;
//update team's rank
stats.rank = 1;
- ObjectMgr::ArenaTeamMap::iterator i = objmgr.GetArenaTeamMapBegin();
+ ObjectMgr::ArenaTeamMap::const_iterator i = objmgr.GetArenaTeamMapBegin();
for ( ; i != objmgr.GetArenaTeamMapEnd(); ++i)
{
if (i->second->GetType() == this->Type && i->second->GetStats().rating > stats.rating)
@@ -533,7 +542,7 @@ int32 ArenaTeam::LostAgainst(uint32 againstRating)
//update team's rank
stats.rank = 1;
- ObjectMgr::ArenaTeamMap::iterator i = objmgr.GetArenaTeamMapBegin();
+ ObjectMgr::ArenaTeamMap::const_iterator i = objmgr.GetArenaTeamMapBegin();
for ( ; i != objmgr.GetArenaTeamMapEnd(); ++i)
{
if (i->second->GetType() == this->Type && i->second->GetStats().rating > stats.rating)
@@ -566,6 +575,28 @@ void ArenaTeam::MemberLost(Player * plr, uint32 againstRating)
}
}
+void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstRating)
+{
+ // called for offline player after ending rated arena match!
+ for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
+ {
+ if(itr->guid == guid)
+ {
+ // update personal rating
+ float chance = GetChanceAgainst(itr->personal_rating, againstRating);
+ int32 mod = (int32)ceil(32.0f * (0.0f - chance));
+ if (int32(itr->personal_rating) + mod < 0)
+ itr->personal_rating = 0;
+ else
+ itr->personal_rating += mod;
+ // update personal played stats
+ itr->games_week +=1;
+ itr->games_season +=1;
+ return;
+ }
+ }
+}
+
void ArenaTeam::MemberWon(Player * plr, uint32 againstRating)
{
// called for each participant after winning a match
@@ -599,7 +630,7 @@ void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& PlayerPoints)
return;
// to get points, a player has to participate in at least 30% of the matches
uint32 min_plays = (uint32) ceil(stats.games_week * 0.3);
- for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
+ for(MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
{
// the player participated in enough games, update his points
uint32 points_to_add = 0;
@@ -623,11 +654,13 @@ void ArenaTeam::SaveToDB()
{
// save team and member stats to db
// called after a match has ended, or when calculating arena_points
+ CharacterDatabase.BeginTransaction();
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_week, stats.games_season, stats.rank, stats.wins_week, stats.wins_season, GetId());
- for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
+ for(MemberList::const_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', personal_rating = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->games_week, itr->wins_week, itr->games_season, itr->wins_season, itr->personal_rating, Id, itr->guid);
+ CharacterDatabase.PExecute("UPDATE arena_team_member SET played_week = '%u', wons_week = '%u', played_season = '%u', wons_season = '%u', personal_rating = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->games_week, itr->wins_week, itr->games_season, itr->wins_season, itr->personal_rating, Id, GUID_LOPART(itr->guid));
}
+ CharacterDatabase.CommitTransaction();
}
void ArenaTeam::FinishWeek()
@@ -641,6 +674,19 @@ void ArenaTeam::FinishWeek()
}
}
+bool ArenaTeam::IsFighting() const
+{
+ for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
+ {
+ if (Player *p = objmgr.GetPlayer(itr->guid))
+ {
+ if (p->GetMap()->IsBattleArena())
+ return true;
+ }
+ }
+ return false;
+}
+
/*
arenateam fields (id from 2.3.3 client):
1414 - arena team id 2v2
diff --git a/src/game/ArenaTeam.h b/src/game/ArenaTeam.h
index 9641c1e5992..60c80f972d2 100644
--- a/src/game/ArenaTeam.h
+++ b/src/game/ArenaTeam.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -98,7 +98,7 @@ struct ArenaTeamMember
void ModifyPersonalRating(Player* plr, int32 mod, uint32 slot)
{
- if (personal_rating + mod < 0)
+ if (int32(personal_rating) + mod < 0)
personal_rating = 0;
else
personal_rating += mod;
@@ -179,18 +179,7 @@ class ArenaTeam
return NULL;
}
- bool IsFighting() const
- {
- for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
- {
- if (Player *p = objmgr.GetPlayer(itr->guid))
- {
- if (p->GetMap()->IsBattleArena())
- return true;
- }
- }
- return false;
- }
+ bool IsFighting() const;
bool LoadArenaTeamFromDB(uint32 ArenaTeamId);
void LoadMembersFromDB(uint32 ArenaTeamId);
@@ -211,6 +200,7 @@ class ArenaTeam
void MemberWon(Player * plr, uint32 againstRating);
int32 LostAgainst(uint32 againstRating);
void MemberLost(Player * plr, uint32 againstRating);
+ void OfflineMemberLost(uint64 guid, uint32 againstRating);
void UpdateArenaPointsHelper(std::map<uint32, uint32> & PlayerPoints);
diff --git a/src/game/ArenaTeamHandler.cpp b/src/game/ArenaTeamHandler.cpp
index 9ba2e65ec92..f195ccc93c3 100644
--- a/src/game/ArenaTeamHandler.cpp
+++ b/src/game/ArenaTeamHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -27,7 +27,6 @@
#include "ArenaTeam.h"
#include "World.h"
#include "SocialMgr.h"
-#include "Language.h"
void WorldSession::HandleInspectArenaStatsOpcode(WorldPacket & recv_data)
{
@@ -41,7 +40,7 @@ void WorldSession::HandleInspectArenaStatsOpcode(WorldPacket & recv_data)
if(Player *plr = objmgr.GetPlayer(guid))
{
- for (uint8 i = 0; i < MAX_ARENA_SLOT; i++)
+ for (uint8 i = 0; i < MAX_ARENA_SLOT; ++i)
{
if(uint32 a_id = plr->GetArenaTeamId(i))
{
@@ -173,7 +172,7 @@ void WorldSession::HandleArenaTeamInviteAcceptOpcode(WorldPacket & /*recv_data*/
if(!at)
return;
- if(_player->GetArenaTeamIdFromDB(_player->GetGUIDLow(), at->GetType()))
+ if(_player->GetArenaTeamId(at->GetSlot()))
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,"","",ERR_ALREADY_IN_ARENA_TEAM); // already in arena team that size
return;
diff --git a/src/game/AuctionHouseBot.cpp b/src/game/AuctionHouseBot.cpp
index a212feb826d..08b4695125f 100644
--- a/src/game/AuctionHouseBot.cpp
+++ b/src/game/AuctionHouseBot.cpp
@@ -4,8 +4,8 @@
#include "Database/DatabaseEnv.h"
#include "Item.h"
#include "Log.h"
-#include "AuctionHouseMgr.h"
#include "ObjectMgr.h"
+#include "AuctionHouseMgr.h"
#include "Player.h"
#include "World.h"
#include "WorldSession.h"
@@ -15,7 +15,7 @@
using namespace std;
-static bool debug_Out = sConfig.GetIntDefault("AuctionHouseBot.DEBUG", 0);
+static bool debug_Out = sConfig.GetBoolDefault("AuctionHouseBot.DEBUG", false);
static vector<uint32> npcItems;
static vector<uint32> lootItems;
@@ -782,7 +782,7 @@ void AuctionHouseBot()
if ((!AHBSeller) && (!AHBBuyer))
return;
- WorldSession _session(AHBplayerAccount, NULL, 0, true, 0, LOCALE_enUS);
+ WorldSession _session(AHBplayerAccount, NULL, SEC_PLAYER, true, 0, LOCALE_enUS);
Player _AHBplayer(&_session);
_AHBplayer.MinimalLoadFromDB(NULL, AHBplayerGUID);
ObjectAccessor::Instance().AddObject(&_AHBplayer);
@@ -815,13 +815,13 @@ void AuctionHouseBot()
///////////////////////////////////////////////////////////////////////////////
void AuctionHouseBotInit()
{
- AHBSeller = sConfig.GetBoolDefault("AuctionHouseBot.EnableSeller", 0);
- AHBBuyer = sConfig.GetBoolDefault("AuctionHouseBot.EnableBuyer", 0);
- No_Bind = sConfig.GetBoolDefault("AuctionHouseBot.No_Bind", 1);
- Bind_When_Picked_Up = sConfig.GetBoolDefault("AuctionHouseBot.Bind_When_Picked_Up", 0);
- Bind_When_Equipped = sConfig.GetBoolDefault("AuctionHouseBot.Bind_When_Equipped", 1);
- Bind_When_Use = sConfig.GetBoolDefault("AuctionHouseBot.Bind_When_Use", 1);
- Bind_Quest_Item = sConfig.GetBoolDefault("AuctionHouseBot.Bind_Quest_Item", 0);
+ AHBSeller = sConfig.GetBoolDefault("AuctionHouseBot.EnableSeller", false);
+ AHBBuyer = sConfig.GetBoolDefault("AuctionHouseBot.EnableBuyer", false);
+ No_Bind = sConfig.GetBoolDefault("AuctionHouseBot.No_Bind", true);
+ Bind_When_Picked_Up = sConfig.GetBoolDefault("AuctionHouseBot.Bind_When_Picked_Up", false);
+ Bind_When_Equipped = sConfig.GetBoolDefault("AuctionHouseBot.Bind_When_Equipped", true);
+ Bind_When_Use = sConfig.GetBoolDefault("AuctionHouseBot.Bind_When_Use", true);
+ Bind_Quest_Item = sConfig.GetBoolDefault("AuctionHouseBot.Bind_Quest_Item", false);
if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
{
@@ -832,9 +832,9 @@ void AuctionHouseBotInit()
if (AHBSeller)
{
- Vendor_Items = sConfig.GetBoolDefault("AuctionHouseBot.VendorItems", 0);
- Loot_Items = sConfig.GetBoolDefault("AuctionHouseBot.LootItems", 1);
- Other_Items = sConfig.GetBoolDefault("AuctionHouseBot.OtherItems", 0);
+ Vendor_Items = sConfig.GetBoolDefault("AuctionHouseBot.VendorItems", false);
+ Loot_Items = sConfig.GetBoolDefault("AuctionHouseBot.LootItems", true);
+ Other_Items = sConfig.GetBoolDefault("AuctionHouseBot.OtherItems", false);
QueryResult* results = (QueryResult*) NULL;
char npcQuery[] = "SELECT distinct `item` FROM `npc_vendor`";
@@ -1055,20 +1055,20 @@ void AuctionHouseBotInit()
}
sLog.outString("AuctionHouseBot:");
- sLog.outString("loaded %d grey trade goods", greyTradeGoodsBin.size());
- sLog.outString("loaded %d white trade goods", whiteTradeGoodsBin.size());
- sLog.outString("loaded %d green trade goods", greenTradeGoodsBin.size());
- sLog.outString("loaded %d blue trade goods", blueTradeGoodsBin.size());
- sLog.outString("loaded %d purple trade goods", purpleTradeGoodsBin.size());
- sLog.outString("loaded %d orange trade goods", orangeTradeGoodsBin.size());
- sLog.outString("loaded %d yellow trade goods", yellowTradeGoodsBin.size());
- sLog.outString("loaded %d grey items", greyItemsBin.size());
- sLog.outString("loaded %d white items", whiteItemsBin.size());
- sLog.outString("loaded %d green items", greenItemsBin.size());
- sLog.outString("loaded %d blue items", blueItemsBin.size());
- sLog.outString("loaded %d purple items", purpleItemsBin.size());
- sLog.outString("loaded %d orange items", orangeItemsBin.size());
- sLog.outString("loaded %d yellow items", yellowItemsBin.size());
+ sLog.outString("loaded %u grey trade goods", greyTradeGoodsBin.size());
+ sLog.outString("loaded %u white trade goods", whiteTradeGoodsBin.size());
+ sLog.outString("loaded %u green trade goods", greenTradeGoodsBin.size());
+ sLog.outString("loaded %u blue trade goods", blueTradeGoodsBin.size());
+ sLog.outString("loaded %u purple trade goods", purpleTradeGoodsBin.size());
+ sLog.outString("loaded %u orange trade goods", orangeTradeGoodsBin.size());
+ sLog.outString("loaded %u yellow trade goods", yellowTradeGoodsBin.size());
+ sLog.outString("loaded %u grey items", greyItemsBin.size());
+ sLog.outString("loaded %u white items", whiteItemsBin.size());
+ sLog.outString("loaded %u green items", greenItemsBin.size());
+ sLog.outString("loaded %u blue items", blueItemsBin.size());
+ sLog.outString("loaded %u purple items", purpleItemsBin.size());
+ sLog.outString("loaded %u orange items", orangeItemsBin.size());
+ sLog.outString("loaded %u yellow items", yellowItemsBin.size());
}
sLog.outString("AuctionHouseBot by Paradox (original by ChrisK) has been loaded.");
sLog.outString("AuctionHouseBot now includes AHBuyer by Kerbe and Paradox");
diff --git a/src/game/AuctionHouseHandler.cpp b/src/game/AuctionHouseHandler.cpp
index b36d1870b86..921db551508 100644
--- a/src/game/AuctionHouseHandler.cpp
+++ b/src/game/AuctionHouseHandler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
@@ -41,7 +41,7 @@ void WorldSession::HandleAuctionHelloOpcode( WorldPacket & recv_data )
uint64 guid; //NPC guid
recv_data >> guid;
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_AUCTIONEER);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
if (!unit)
{
sLog.outDebug( "WORLD: HandleAuctionHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
@@ -50,7 +50,7 @@ void WorldSession::HandleAuctionHelloOpcode( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
SendAuctionHello(guid, unit);
}
@@ -168,7 +168,7 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data )
if (!item || !bid || !etime)
return; //check for cheaters
- Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, auctioneer,UNIT_NPC_FLAG_AUCTIONEER);
+ Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER);
if (!pCreature)
{
sLog.outDebug( "WORLD: HandleAuctionSellItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)) );
@@ -199,7 +199,7 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
Item *it = pl->GetItemByGuid( item );
//do not allow to sell already auctioned items
@@ -295,7 +295,7 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data )
if (!auctionId || !price)
return; //check for cheaters
- Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, auctioneer,UNIT_NPC_FLAG_AUCTIONEER);
+ Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER);
if (!pCreature)
{
sLog.outDebug( "WORLD: HandleAuctionPlaceBid - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)) );
@@ -304,7 +304,7 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() );
@@ -367,6 +367,7 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data )
}
auction->bidder = pl->GetGUIDLow();
auction->bid = price;
+ GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price);
// after this update we should save player's money ...
CharacterDatabase.PExecute("UPDATE auctionhouse SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id);
@@ -390,6 +391,7 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data )
}
auction->bidder = pl->GetGUIDLow();
auction->bid = auction->buyout;
+ GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout);
auctionmgr.SendAuctionSalePendingMail( auction );
auctionmgr.SendAuctionSuccessfulMail( auction );
@@ -419,7 +421,7 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data )
recv_data >> auctionId;
//sLog.outDebug( "Cancel AUCTION AuctionID: %u", auctionId);
- Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, auctioneer,UNIT_NPC_FLAG_AUCTIONEER);
+ Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER);
if (!pCreature)
{
sLog.outDebug( "WORLD: HandleAuctionRemoveItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)) );
@@ -428,7 +430,7 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() );
@@ -500,11 +502,11 @@ void WorldSession::HandleAuctionListBidderItems( WorldPacket & recv_data )
recv_data >> outbiddedCount;
if (recv_data.size() != (16 + outbiddedCount * 4 ))
{
- sLog.outError("Client sent bad opcode!!! with count: %u and size : %d (mustbe: %d", outbiddedCount, recv_data.size(),(16 + outbiddedCount * 4 ));
+ sLog.outError("Client sent bad opcode!!! with count: %u and size : %lu (must be: %u)", outbiddedCount, (unsigned long)recv_data.size(),(16 + outbiddedCount * 4 ));
outbiddedCount = 0;
}
- Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_AUCTIONEER);
+ Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
if (!pCreature)
{
sLog.outDebug( "WORLD: HandleAuctionListBidderItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
@@ -513,7 +515,7 @@ void WorldSession::HandleAuctionListBidderItems( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() );
@@ -553,7 +555,7 @@ void WorldSession::HandleAuctionListOwnerItems( WorldPacket & recv_data )
recv_data >> guid;
recv_data >> listfrom; // not used in fact (this list not have page control in client)
- Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_AUCTIONEER);
+ Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
if (!pCreature)
{
sLog.outDebug( "WORLD: HandleAuctionListOwnerItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
@@ -562,7 +564,7 @@ void WorldSession::HandleAuctionListOwnerItems( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() );
@@ -600,7 +602,7 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data )
recv_data >> auctionSlotID >> auctionMainCategory >> auctionSubCategory;
recv_data >> quality >> usable;
- Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_AUCTIONEER);
+ Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
if (!pCreature)
{
sLog.outDebug( "WORLD: HandleAuctionListItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
@@ -609,7 +611,7 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() );
@@ -638,3 +640,22 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data )
SendPacket(&data);
}
+void WorldSession::HandleAuctionListPendingSales( WorldPacket & recv_data )
+{
+ sLog.outDebug("CMSG_AUCTION_LIST_PENDING_SALES");
+ recv_data.hexlike();
+
+ uint32 count = 0;
+
+ WorldPacket data(SMSG_AUCTION_LIST_PENDING_SALES, 4);
+ data << uint32(count); // count
+ /*for(uint32 i = 0; i < count; ++i)
+ {
+ data << ""; // string
+ data << ""; // string
+ data << uint32(0);
+ data << uint32(0);
+ data << float(0);
+ }*/
+ SendPacket(&data);
+}
diff --git a/src/game/AuctionHouseMgr.cpp b/src/game/AuctionHouseMgr.cpp
index 1554013af99..e34795c9ecd 100644
--- a/src/game/AuctionHouseMgr.cpp
+++ b/src/game/AuctionHouseMgr.cpp
@@ -1,25 +1,25 @@
/*
-* Copyright (C) 2005-2009 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
-*/
+ * Copyright (C) 2005-2009 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 "Common.h"
#include "Database/DatabaseEnv.h"
-#include "Database/DBCStores.h"
#include "Database/SQLStorage.h"
+#include "DBCStores.h"
#include "ProgressBar.h"
#include "AccountMgr.h"
@@ -43,7 +43,7 @@ AuctionHouseMgr::AuctionHouseMgr()
AuctionHouseMgr::~AuctionHouseMgr()
{
- for(ItemMap::iterator itr = mAitems.begin(); itr != mAitems.end(); ++itr)
+ for(ItemMap::const_iterator itr = mAitems.begin(); itr != mAitems.end(); ++itr)
delete itr->second;
}
@@ -223,6 +223,8 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail( AuctionEntry * auction )
if (owner)
{
+ //FIXME: what do if owner offline
+ owner->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD, auction->bid);
//send auction owner notification, bidder must be current!
owner->GetSession()->SendAuctionOwnerNotification( auction );
}
@@ -257,7 +259,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail( AuctionEntry * auction )
if ( owner )
owner->GetSession()->SendAuctionOwnerNotification( auction );
else
- RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
+ RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
MailItemsInfo mi;
mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
@@ -283,7 +285,7 @@ void AuctionHouseMgr::LoadAuctionItems()
{
barGoLink bar(1);
bar.step();
- sLog.outString("");
+ sLog.outString();
sLog.outString(">> Loaded 0 auction items");
return;
}
@@ -298,8 +300,8 @@ void AuctionHouseMgr::LoadAuctionItems()
bar.step();
fields = result->Fetch();
- uint32 item_guid = fields[1].GetUInt32();
- uint32 item_template = fields[2].GetUInt32();
+ uint32 item_guid = fields[1].GetUInt32();
+ uint32 item_template = fields[2].GetUInt32();
ItemPrototype const *proto = objmgr.GetItemPrototype(item_template);
@@ -334,7 +336,7 @@ void AuctionHouseMgr::LoadAuctions()
{
barGoLink bar(1);
bar.step();
- sLog.outString("");
+ sLog.outString();
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
return;
}
@@ -347,7 +349,7 @@ void AuctionHouseMgr::LoadAuctions()
{
barGoLink bar(1);
bar.step();
- sLog.outString("");
+ sLog.outString();
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
return;
}
@@ -357,7 +359,7 @@ void AuctionHouseMgr::LoadAuctions()
{
barGoLink bar(1);
bar.step();
- sLog.outString("");
+ sLog.outString();
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
return;
}
@@ -468,17 +470,17 @@ AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTem
// but no easy way convert creature faction to player race faction for specific city
switch(factionTemplateId)
{
- case 12: houseid = 1; break; // human
- case 29: houseid = 6; break; // orc, and generic for horde
- case 55: houseid = 2; break; // dwarf, and generic for alliance
- case 68: houseid = 4; break; // undead
- case 80: houseid = 3; break; // n-elf
- case 104: houseid = 5; break; // trolls
- case 120: houseid = 7; break; // booty bay, neutral
- case 474: houseid = 7; break; // gadgetzan, neutral
- case 855: houseid = 7; break; // everlook, neutral
+ case 12: houseid = 1; break; // human
+ case 29: houseid = 6; break; // orc, and generic for horde
+ case 55: houseid = 2; break; // dwarf, and generic for alliance
+ case 68: houseid = 4; break; // undead
+ case 80: houseid = 3; break; // n-elf
+ case 104: houseid = 5; break; // trolls
+ case 120: houseid = 7; break; // booty bay, neutral
+ case 474: houseid = 7; break; // gadgetzan, neutral
+ case 855: houseid = 7; break; // everlook, neutral
case 1604: houseid = 6; break; // b-elfs,
- default: // for unknown case
+ default: // for unknown case
{
FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(factionTemplateId);
if(!u_entry)
@@ -576,22 +578,22 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player
ItemPrototype const *proto = item->GetProto();
- if (itemClass != (0xffffffff) && proto->Class != itemClass)
+ if (itemClass != 0xffffffff && proto->Class != itemClass)
continue;
- if (itemSubClass != (0xffffffff) && proto->SubClass != itemSubClass)
+ if (itemSubClass != 0xffffffff && proto->SubClass != itemSubClass)
continue;
- if (inventoryType != (0xffffffff) && proto->InventoryType != inventoryType)
+ if (inventoryType != 0xffffffff && proto->InventoryType != inventoryType)
continue;
- if (quality != (0xffffffff) && proto->Quality != quality)
+ if (quality != 0xffffffff && proto->Quality != quality)
continue;
- if( levelmin != (0x00) && (proto->RequiredLevel < levelmin || levelmax != (0x00) && proto->RequiredLevel > levelmax ) )
+ if (levelmin != 0x00 && (proto->RequiredLevel < levelmin || (levelmax != 0x00 && proto->RequiredLevel > levelmax)))
continue;
- if( usable != (0x00) && player->CanUseItem( item ) != EQUIP_ERR_OK )
+ if (usable != 0x00 && player->CanUseItem( item ) != EQUIP_ERR_OK)
continue;
std::string name = proto->Name1;
@@ -609,10 +611,10 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player
}
}
- if( !wsearchedname.empty() && !Utf8FitTo(name, wsearchedname) )
+ if (!wsearchedname.empty() && !Utf8FitTo(name, wsearchedname) )
continue;
- if ((count < 50) && (totalcount >= listfrom))
+ if (count < 50 && totalcount >= listfrom)
{
++count;
Aentry->BuildAuctionInfo(data);
@@ -630,29 +632,29 @@ bool AuctionEntry::BuildAuctionInfo(WorldPacket & data) const
sLog.outError("auction to item, that doesn't exist !!!!");
return false;
}
- data << (uint32) Id;
- data << (uint32) pItem->GetEntry();
+ data << uint32(Id);
+ data << uint32(pItem->GetEntry());
- for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; i++)
+ for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; ++i)
{
- data << (uint32) pItem->GetEnchantmentId(EnchantmentSlot(i));
- data << (uint32) pItem->GetEnchantmentDuration(EnchantmentSlot(i));
- data << (uint32) pItem->GetEnchantmentCharges(EnchantmentSlot(i));
+ data << uint32(pItem->GetEnchantmentId(EnchantmentSlot(i)));
+ data << uint32(pItem->GetEnchantmentDuration(EnchantmentSlot(i)));
+ data << uint32(pItem->GetEnchantmentCharges(EnchantmentSlot(i)));
}
- data << (uint32) pItem->GetItemRandomPropertyId(); //random item property id
- data << (uint32) pItem->GetItemSuffixFactor(); //SuffixFactor
- data << (uint32) pItem->GetCount(); //item->count
- data << (uint32) pItem->GetSpellCharges(); //item->charge FFFFFFF
- data << (uint32) 0; //Unknown
- data << (uint64) owner; //Auction->owner
- data << (uint32) startbid; //Auction->startbid (not sure if useful)
- data << (uint32) (bid ? GetAuctionOutBid() : 0);
+ data << uint32(pItem->GetItemRandomPropertyId()); //random item property id
+ data << uint32(pItem->GetItemSuffixFactor()); //SuffixFactor
+ data << uint32(pItem->GetCount()); //item->count
+ data << uint32(pItem->GetSpellCharges()); //item->charge FFFFFFF
+ data << uint32(0); //Unknown
+ data << uint64(owner); //Auction->owner
+ data << uint32(startbid); //Auction->startbid (not sure if useful)
+ data << uint32(bid ? GetAuctionOutBid() : 0);
//minimal outbid
- data << (uint32) buyout; //auction->buyout
- data << (uint32) (expire_time - time(NULL))* 1000; //time left
- data << (uint64) bidder; //auction->bidder current
- data << (uint32) bid; //current bid
+ data << uint32(buyout); //auction->buyout
+ data << uint32((expire_time-time(NULL))*IN_MILISECONDS);//time left
+ data << uint64(bidder) ; //auction->bidder current
+ data << uint32(bid); //current bid
return true;
}
diff --git a/src/game/Bag.cpp b/src/game/Bag.cpp
index 331b12acde5..1edbc06474d 100644
--- a/src/game/Bag.cpp
+++ b/src/game/Bag.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -23,9 +23,7 @@
#include "ObjectMgr.h"
#include "Database/DatabaseEnv.h"
#include "Log.h"
-#include "WorldPacket.h"
#include "UpdateData.h"
-#include "WorldSession.h"
Bag::Bag( ): Item()
{
@@ -34,7 +32,7 @@ Bag::Bag( ): Item()
m_valuesCount = CONTAINER_END;
- memset(m_bagslot, 0, sizeof(Item *) * MAX_BAG_SIZE); // Maximum 20 Slots
+ memset(m_bagslot, 0, sizeof(Item *) * MAX_BAG_SIZE);
}
Bag::~Bag()
@@ -86,7 +84,7 @@ bool Bag::Create(uint32 guidlow, uint32 itemid, Player const* owner)
SetUInt32Value(CONTAINER_FIELD_NUM_SLOTS, itemProto->ContainerSlots);
// Cleaning 20 slots
- for (uint8 i = 0; i < MAX_BAG_SIZE; i++)
+ for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
{
SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (i*2), 0);
m_bagslot[i] = NULL;
@@ -121,7 +119,7 @@ bool Bag::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result)
void Bag::DeleteFromDB()
{
- for (int i = 0; i < MAX_BAG_SIZE; i++)
+ for (int i = 0; i < MAX_BAG_SIZE; ++i)
if (m_bagslot[i])
m_bagslot[i]->DeleteFromDB();
@@ -131,7 +129,7 @@ void Bag::DeleteFromDB()
uint32 Bag::GetFreeSlots() const
{
uint32 slots = 0;
- for (uint32 i=0; i < GetBagSize(); i++)
+ for (uint32 i=0; i < GetBagSize(); ++i)
if (!m_bagslot[i])
++slots;
diff --git a/src/game/Bag.h b/src/game/Bag.h
index d930809cf4a..1c341b5611d 100644
--- a/src/game/Bag.h
+++ b/src/game/Bag.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -24,10 +24,7 @@
// Maximum 36 Slots ( (CONTAINER_END - CONTAINER_FIELD_SLOT_1)/2
#define MAX_BAG_SIZE 36 // 2.0.12
-#include "Object.h"
#include "ItemPrototype.h"
-#include "Unit.h"
-#include "Creature.h"
#include "Item.h"
class Bag : public Item
diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp
index c0ec88b78fb..d179ec33691 100644
--- a/src/game/BattleGround.cpp
+++ b/src/game/BattleGround.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,23 +21,119 @@
#include "Object.h"
#include "Player.h"
#include "BattleGround.h"
+#include "BattleGroundMgr.h"
#include "Creature.h"
#include "MapManager.h"
#include "Language.h"
-#include "Chat.h"
#include "SpellAuras.h"
#include "ArenaTeam.h"
#include "World.h"
+#include "Group.h"
+#include "ObjectMgr.h"
+#include "WorldPacket.h"
#include "Util.h"
+#include "Formulas.h"
+#include "GridNotifiersImpl.h"
+
+namespace MaNGOS
+{
+ class BattleGroundChatBuilder
+ {
+ public:
+ BattleGroundChatBuilder(ChatMsg msgtype, int32 textId, Player const* source, va_list* args = NULL)
+ : i_msgtype(msgtype), i_textId(textId), i_source(source), i_args(args) {}
+ void operator()(WorldPacket& data, int32 loc_idx)
+ {
+ char const* text = objmgr.GetMangosString(i_textId,loc_idx);
+
+ if (i_args)
+ {
+ // we need copy va_list before use or original va_list will corrupted
+ va_list ap;
+ va_copy(ap,*i_args);
+
+ char str [2048];
+ vsnprintf(str,2048,text, ap );
+ va_end(ap);
+
+ do_helper(data,&str[0]);
+ }
+ else
+ do_helper(data,text);
+ }
+ private:
+ void do_helper(WorldPacket& data, char const* text)
+ {
+ uint64 target_guid = i_source ? i_source ->GetGUID() : 0;
+
+ data << uint8(i_msgtype);
+ data << uint32(LANG_UNIVERSAL);
+ data << uint64(target_guid); // there 0 for BG messages
+ data << uint32(0); // can be chat msg group or something
+ data << uint64(target_guid);
+ data << uint32(strlen(text)+1);
+ data << text;
+ data << uint8(i_source ? i_source->chatTag() : uint8(0));
+ }
+
+ ChatMsg i_msgtype;
+ int32 i_textId;
+ Player const* i_source;
+ va_list* i_args;
+ };
+
+ class BattleGround2ChatBuilder
+ {
+ public:
+ BattleGround2ChatBuilder(ChatMsg msgtype, int32 textId, Player const* source, int32 arg1, int32 arg2)
+ : i_msgtype(msgtype), i_textId(textId), i_source(source), i_arg1(arg1), i_arg2(arg2) {}
+ void operator()(WorldPacket& data, int32 loc_idx)
+ {
+ char const* text = objmgr.GetMangosString(i_textId,loc_idx);
+ char const* arg1str = i_arg1 ? objmgr.GetMangosString(i_arg1,loc_idx) : "";
+ char const* arg2str = i_arg2 ? objmgr.GetMangosString(i_arg2,loc_idx) : "";
+
+ char str [2048];
+ snprintf(str,2048,text, arg1str, arg2str );
+
+ uint64 target_guid = i_source ? i_source ->GetGUID() : 0;
+
+ data << uint8(i_msgtype);
+ data << uint32(LANG_UNIVERSAL);
+ data << uint64(target_guid); // there 0 for BG messages
+ data << uint32(0); // can be chat msg group or something
+ data << uint64(target_guid);
+ data << uint32(strlen(str)+1);
+ data << str;
+ data << uint8(i_source ? i_source->chatTag() : uint8(0));
+ }
+ private:
+
+ ChatMsg i_msgtype;
+ int32 i_textId;
+ Player const* i_source;
+ int32 i_arg1;
+ int32 i_arg2;
+ };
+} // namespace MaNGOS
+
+template<class Do>
+void BattleGround::BroadcastWorker(Do& _do)
+{
+ for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
+ if (Player *plr = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)))
+ _do(plr);
+}
BattleGround::BattleGround()
{
- m_TypeID = 0;
+ m_TypeID = BattleGroundTypeId(0);
m_InstanceID = 0;
- m_Status = 0;
+ m_Status = STATUS_NONE;
+ m_ClientInstanceID = 0;
m_EndTime = 0;
m_LastResurrectTime = 0;
- m_Queue_type = MAX_BATTLEGROUND_QUEUES;
+ m_QueueId = QUEUE_ID_MAX_LEVEL_19;
m_InvitedAlliance = 0;
m_InvitedHorde = 0;
m_ArenaType = 0;
@@ -88,6 +184,16 @@ BattleGround::BattleGround()
m_PrematureCountDown = 0;
m_HonorMode = BG_NORMAL;
+
+ m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_2M;
+ m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_1M;
+ m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_30S;
+ m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
+ //we must set to some default existing values
+ m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_WS_START_TWO_MINUTES;
+ m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN;
}
BattleGround::~BattleGround()
@@ -105,97 +211,68 @@ BattleGround::~BattleGround()
DelObject(i);
}
- // delete creature and go respawn times
- WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE instance = '%u'",GetInstanceID());
- WorldDatabase.PExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'",GetInstanceID());
- // delete instance from db
- CharacterDatabase.PExecute("DELETE FROM instance WHERE id = '%u'",GetInstanceID());
- // remove from battlegrounds
- sBattleGroundMgr.RemoveBattleGround(GetInstanceID());
+ if(GetInstanceID()) // not spam by useless queries in case BG templates
+ {
+ // delete creature and go respawn times
+ WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE instance = '%u'",GetInstanceID());
+ WorldDatabase.PExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'",GetInstanceID());
+ // delete instance from db
+ CharacterDatabase.PExecute("DELETE FROM instance WHERE id = '%u'",GetInstanceID());
+ // remove from battlegrounds
+ }
+
+ sBattleGroundMgr.RemoveBattleGround(GetInstanceID(), GetTypeID());
// unload map
- if(Map * map = MapManager::Instance().FindMap(GetMapId(), GetInstanceID()))
- if(map->IsBattleGroundOrArena())
+ if (Map * map = MapManager::Instance().FindMap(GetMapId(), GetInstanceID()))
+ if (map->IsBattleGroundOrArena())
((BattleGroundMap*)map)->SetUnload();
// remove from bg free slot queue
this->RemoveFromBGFreeSlotQueue();
}
-void BattleGround::Update(time_t diff)
+void BattleGround::Update(uint32 diff)
{
- if(!GetPlayersSize() && !GetRemovedPlayersSize() && !GetReviveQueueSize())
+ if (!GetPlayersSize() && !GetReviveQueueSize())
//BG is empty
return;
- WorldPacket data;
-
- if(GetRemovedPlayersSize())
+ // remove offline players from bg after 5 minutes
+ if (!m_OfflineQueue.empty())
{
- for(std::map<uint64, uint8>::iterator itr = m_RemovedPlayers.begin(); itr != m_RemovedPlayers.end(); ++itr)
+ BattleGroundPlayerMap::iterator itr = m_Players.find(*(m_OfflineQueue.begin()));
+ if (itr != m_Players.end())
{
- Player *plr = objmgr.GetPlayer(itr->first);
- switch(itr->second)
+ if (itr->second.OfflineRemoveTime <= sWorld.GetGameTime())
{
- //following code is handled by event:
- /*case 0:
- sBattleGroundMgr.m_BattleGroundQueues[GetTypeID()].RemovePlayer(itr->first);
- //RemovePlayerFromQueue(itr->first);
- if(plr)
- {
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(m_TypeID), STATUS_NONE, 0, 0);
- plr->GetSession()->SendPacket(&data);
- }
- break;*/
- case 1: // currently in bg and was removed from bg
- if(plr)
- RemovePlayerAtLeave(itr->first, true, true);
- else
- RemovePlayerAtLeave(itr->first, false, false);
- break;
- case 2: // revive queue
- RemovePlayerFromResurrectQueue(itr->first);
- break;
- default:
- sLog.outError("BattleGround: Unknown remove player case!");
+ RemovePlayerAtLeave(itr->first, true, true);// remove player from BG
+ m_OfflineQueue.pop_front(); // remove from offline queue
+ //do not use itr for anything, because it is erased in RemovePlayerAtLeave()
}
}
- m_RemovedPlayers.clear();
}
- // this code isn't efficient and its idea isn't implemented yet
- /* offline players are removed from battleground in worldsession::LogoutPlayer()
- // remove offline players from bg after ~5 minutes
- if(GetPlayersSize())
- {
- for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
- {
- Player *plr = objmgr.GetPlayer(itr->first);
- itr->second.LastOnlineTime += diff;
-
- if(plr)
- itr->second.LastOnlineTime = 0; // update last online time
- else
- if(itr->second.LastOnlineTime >= MAX_OFFLINE_TIME) // 5 minutes
- m_RemovedPlayers[itr->first] = 1; // add to remove list (BG)
- }
- }*/
+ /*********************************************************/
+ /*** BATTLEGROUND RESSURECTION SYSTEM ***/
+ /*********************************************************/
+ //this should be handled by spell system
m_LastResurrectTime += diff;
if (m_LastResurrectTime >= RESURRECTION_INTERVAL)
{
- if(GetReviveQueueSize())
+ if (GetReviveQueueSize())
{
for(std::map<uint64, std::vector<uint64> >::iterator itr = m_ReviveQueue.begin(); itr != m_ReviveQueue.end(); ++itr)
{
Creature *sh = NULL;
- for(std::vector<uint64>::iterator itr2 = (itr->second).begin(); itr2 != (itr->second).end(); ++itr2)
+ for(std::vector<uint64>::const_iterator itr2 = (itr->second).begin(); itr2 != (itr->second).end(); ++itr2)
{
Player *plr = objmgr.GetPlayer(*itr2);
- if(!plr)
+ if (!plr)
continue;
- if (!sh)
+ if (!sh && plr->IsInWorld())
{
- sh = ObjectAccessor::GetCreature(*plr, itr->first);
+ sh = plr->GetMap()->GetCreature(itr->first);
// only for visual effect
if (sh)
sh->CastSpell(sh, SPELL_SPIRIT_HEAL, true); // Spirit Heal, effect 117
@@ -216,10 +293,10 @@ void BattleGround::Update(time_t diff)
}
else if (m_LastResurrectTime > 500) // Resurrect players only half a second later, to see spirit heal effect on NPC
{
- for(std::vector<uint64>::iterator itr = m_ResurrectQueue.begin(); itr != m_ResurrectQueue.end(); ++itr)
+ for(std::vector<uint64>::const_iterator itr = m_ResurrectQueue.begin(); itr != m_ResurrectQueue.end(); ++itr)
{
Player *plr = objmgr.GetPlayer(*itr);
- if(!plr)
+ if (!plr)
continue;
plr->ResurrectPlayer(1.0f);
plr->CastSpell(plr, SPELL_SPIRIT_HEAL_MANA, true);
@@ -228,46 +305,151 @@ void BattleGround::Update(time_t diff)
m_ResurrectQueue.clear();
}
+ /*********************************************************/
+ /*** BATTLEGROUND BALLANCE SYSTEM ***/
+ /*********************************************************/
+
// if less then minimum players are in on one side, then start premature finish timer
- if(GetStatus() == STATUS_IN_PROGRESS && !isArena() && sBattleGroundMgr.GetPrematureFinishTime() && (GetPlayersCountByTeam(ALLIANCE) < GetMinPlayersPerTeam() || GetPlayersCountByTeam(HORDE) < GetMinPlayersPerTeam()))
+ if (GetStatus() == STATUS_IN_PROGRESS && !isArena() && sBattleGroundMgr.GetPrematureFinishTime() && (GetPlayersCountByTeam(ALLIANCE) < GetMinPlayersPerTeam() || GetPlayersCountByTeam(HORDE) < GetMinPlayersPerTeam()))
{
- if(!m_PrematureCountDown)
+ if (!m_PrematureCountDown)
{
m_PrematureCountDown = true;
m_PrematureCountDownTimer = sBattleGroundMgr.GetPrematureFinishTime();
- SendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING);
}
- else if(m_PrematureCountDownTimer < diff)
+ else if (m_PrematureCountDownTimer < diff)
{
// time's up!
- EndBattleGround(0); // noone wins
+ uint32 winner = 0;
+ if (GetPlayersCountByTeam(ALLIANCE) >= GetMinPlayersPerTeam())
+ winner = ALLIANCE;
+ else if (GetPlayersCountByTeam(HORDE) >= GetMinPlayersPerTeam())
+ winner = HORDE;
+
+ EndBattleGround(winner);
m_PrematureCountDown = false;
}
else
{
uint32 newtime = m_PrematureCountDownTimer - diff;
// announce every minute
- if(m_PrematureCountDownTimer != sBattleGroundMgr.GetPrematureFinishTime() && newtime / 60000 != m_PrematureCountDownTimer / 60000)
- SendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING);
+ if (newtime > (MINUTE * IN_MILISECONDS))
+ {
+ if (newtime / (MINUTE * IN_MILISECONDS) != m_PrematureCountDownTimer / (MINUTE * IN_MILISECONDS))
+ PSendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING, CHAT_MSG_SYSTEM, NULL, (uint32)(m_PrematureCountDownTimer / (MINUTE * IN_MILISECONDS)));
+ }
+ else
+ {
+ //announce every 15 seconds
+ if (newtime / (15 * IN_MILISECONDS) != m_PrematureCountDownTimer / (15 * IN_MILISECONDS))
+ PSendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING_SECS, CHAT_MSG_SYSTEM, NULL, (uint32)(m_PrematureCountDownTimer / IN_MILISECONDS));
+ }
m_PrematureCountDownTimer = newtime;
}
}
else if (m_PrematureCountDown)
m_PrematureCountDown = false;
- if(GetStatus() == STATUS_WAIT_LEAVE)
+ /*********************************************************/
+ /*** BATTLEGROUND STARTING SYSTEM ***/
+ /*********************************************************/
+
+ if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
+ {
+ ModifyStartDelayTime(diff);
+
+ if (!(m_Events & BG_STARTING_EVENT_1))
+ {
+ m_Events |= BG_STARTING_EVENT_1;
+
+ // setup here, only when at least one player has ported to the map
+ if (!SetupBattleGround())
+ {
+ EndNow();
+ return;
+ }
+
+ StartingEventCloseDoors();
+ SetStartDelayTime(m_StartDelayTimes[BG_STARTING_EVENT_FIRST]);
+ //first start warning - 2 or 1 minute
+ SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_FIRST], CHAT_MSG_BG_SYSTEM_NEUTRAL);
+ }
+ // After 1 minute or 30 seconds, warning is signalled
+ else if (GetStartDelayTime() <= m_StartDelayTimes[BG_STARTING_EVENT_SECOND] && !(m_Events & BG_STARTING_EVENT_2))
+ {
+ m_Events |= BG_STARTING_EVENT_2;
+ SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_SECOND], CHAT_MSG_BG_SYSTEM_NEUTRAL);
+ }
+ // After 30 or 15 seconds, warning is signalled
+ else if (GetStartDelayTime() <= m_StartDelayTimes[BG_STARTING_EVENT_THIRD] && !(m_Events & BG_STARTING_EVENT_3))
+ {
+ m_Events |= BG_STARTING_EVENT_3;
+ SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_THIRD], CHAT_MSG_BG_SYSTEM_NEUTRAL);
+ }
+ // delay expired (atfer 2 or 1 minute)
+ else if (GetStartDelayTime() <= 0 && !(m_Events & BG_STARTING_EVENT_4))
+ {
+ m_Events |= BG_STARTING_EVENT_4;
+
+ StartingEventOpenDoors();
+
+ SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_FOURTH], CHAT_MSG_BG_SYSTEM_NEUTRAL);
+ SetStatus(STATUS_IN_PROGRESS);
+ SetStartDelayTime(m_StartDelayTimes[BG_STARTING_EVENT_FOURTH]);
+
+ //remove preparation
+ if (isArena())
+ {
+ //TODO : add arena sound PlaySoundToAll(SOUND_ARENA_START);
+
+ for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
+ if (Player *plr = objmgr.GetPlayer(itr->first))
+ plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
+
+ CheckArenaWinConditions();
+ }
+ else
+ {
+
+ PlaySoundToAll(SOUND_BG_START);
+
+ for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
+ if (Player* plr = objmgr.GetPlayer(itr->first))
+ plr->RemoveAurasDueToSpell(SPELL_PREPARATION);
+ //Announce BG starting
+ if (sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE))
+ {
+ sWorld.SendWorldText(LANG_BG_STARTED_ANNOUNCE_WORLD, GetName(), GetMinLevel(), GetMaxLevel());
+ }
+ }
+ }
+ }
+
+ /*********************************************************/
+ /*** BATTLEGROUND ENDING SYSTEM ***/
+ /*********************************************************/
+
+ if (GetStatus() == STATUS_WAIT_LEAVE)
{
// remove all players from battleground after 2 minutes
- m_EndTime += diff;
- if(m_EndTime >= TIME_TO_AUTOREMOVE) // 2 minutes
+ m_EndTime -= diff;
+ if (m_EndTime <= 0)
{
- for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
+ m_EndTime = 0;
+ BattleGroundPlayerMap::iterator itr, next;
+ for(itr = m_Players.begin(); itr != m_Players.end(); itr = next)
{
- m_RemovedPlayers[itr->first] = 1; // add to remove list (BG)
+ next = itr;
+ ++next;
+ //itr is erased here!
+ RemovePlayerAtLeave(itr->first, true, true);// remove player from BG
+ // do not change any battleground's private variables
}
- // do not change any battleground's private variables
}
}
+
+ //update start time
+ m_StartTime += diff;
}
void BattleGround::SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O)
@@ -281,10 +463,10 @@ void BattleGround::SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, flo
void BattleGround::SendPacketToAll(WorldPacket *packet)
{
- for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
+ for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
Player *plr = objmgr.GetPlayer(itr->first);
- if(plr)
+ if (plr)
plr->GetSession()->SendPacket(packet);
else
sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first);
@@ -293,23 +475,23 @@ void BattleGround::SendPacketToAll(WorldPacket *packet)
void BattleGround::SendPacketToTeam(uint32 TeamID, WorldPacket *packet, Player *sender, bool self)
{
- for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
+ for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
Player *plr = objmgr.GetPlayer(itr->first);
- if(!plr)
+ if (!plr)
{
sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first);
continue;
}
- if(!self && sender == plr)
+ if (!self && sender == plr)
continue;
- uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
+ uint32 team = itr->second.Team;
if(!team) team = plr->GetTeam();
- if(team == TeamID)
+ if (team == TeamID)
plr->GetSession()->SendPacket(packet);
}
}
@@ -325,20 +507,20 @@ void BattleGround::PlaySoundToTeam(uint32 SoundID, uint32 TeamID)
{
WorldPacket data;
- for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
+ for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
Player *plr = objmgr.GetPlayer(itr->first);
- if(!plr)
+ if (!plr)
{
sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first);
continue;
}
- uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
+ uint32 team = itr->second.Team;
if(!team) team = plr->GetTeam();
- if(team == TeamID)
+ if (team == TeamID)
{
sBattleGroundMgr.BuildPlaySoundPacket(&data, SoundID);
plr->GetSession()->SendPacket(&data);
@@ -348,20 +530,20 @@ void BattleGround::PlaySoundToTeam(uint32 SoundID, uint32 TeamID)
void BattleGround::CastSpellOnTeam(uint32 SpellID, uint32 TeamID)
{
- for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
+ for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
Player *plr = objmgr.GetPlayer(itr->first);
- if(!plr)
+ if (!plr)
{
sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first);
continue;
}
- uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
+ uint32 team = itr->second.Team;
if(!team) team = plr->GetTeam();
- if(team == TeamID)
+ if (team == TeamID)
plr->CastSpell(plr, SpellID, true);
}
}
@@ -385,20 +567,20 @@ void BattleGround::YellToAll(Creature* creature, const char* text, uint32 langua
void BattleGround::RewardHonorToTeam(uint32 Honor, uint32 TeamID)
{
- for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
+ for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
Player *plr = objmgr.GetPlayer(itr->first);
- if(!plr)
+ if (!plr)
{
sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first);
continue;
}
- uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
+ uint32 team = itr->second.Team;
if(!team) team = plr->GetTeam();
- if(team == TeamID)
+ if (team == TeamID)
UpdatePlayerScore(plr, SCORE_BONUS_HONOR, Honor);
}
}
@@ -407,24 +589,24 @@ void BattleGround::RewardReputationToTeam(uint32 faction_id, uint32 Reputation,
{
FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id);
- if(!factionEntry)
+ if (!factionEntry)
return;
- for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
+ for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
Player *plr = objmgr.GetPlayer(itr->first);
- if(!plr)
+ if (!plr)
{
sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first);
continue;
}
- uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
+ uint32 team = itr->second.Team;
if(!team) team = plr->GetTeam();
- if(team == TeamID)
- plr->ModifyFactionReputation(factionEntry, Reputation);
+ if (team == TeamID)
+ plr->GetReputationMgr().ModifyReputation(factionEntry, Reputation);
}
}
@@ -445,32 +627,25 @@ void BattleGround::UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player
void BattleGround::EndBattleGround(uint32 winner)
{
this->RemoveFromBGFreeSlotQueue();
- uint32 almost_winning_team = HORDE;
+
ArenaTeam * winner_arena_team = NULL;
ArenaTeam * loser_arena_team = NULL;
uint32 loser_rating = 0;
uint32 winner_rating = 0;
WorldPacket data;
- Player *Source = NULL;
- const char *winmsg = "";
+ int32 winmsg_id = 0;
- if(winner == ALLIANCE)
+ if (winner == ALLIANCE)
{
- if(isBattleGround())
- winmsg = GetTrinityString(LANG_BG_A_WINS);
- else
- winmsg = GetTrinityString(LANG_ARENA_GOLD_WINS);
+ winmsg_id = isBattleGround() ? LANG_BG_A_WINS : LANG_ARENA_GOLD_WINS;
PlaySoundToAll(SOUND_ALLIANCE_WINS); // alliance wins sound
SetWinner(WINNER_ALLIANCE);
}
- else if(winner == HORDE)
+ else if (winner == HORDE)
{
- if(isBattleGround())
- winmsg = GetTrinityString(LANG_BG_H_WINS);
- else
- winmsg = GetTrinityString(LANG_ARENA_GREEN_WINS);
+ winmsg_id = isBattleGround() ? LANG_BG_H_WINS : LANG_ARENA_GREEN_WINS;
PlaySoundToAll(SOUND_HORDE_WINS); // horde wins sound
@@ -482,38 +657,23 @@ void BattleGround::EndBattleGround(uint32 winner)
}
SetStatus(STATUS_WAIT_LEAVE);
- m_EndTime = 0;
+ //we must set it this way, because end time is sent in packet!
+ m_EndTime = TIME_TO_AUTOREMOVE;
// arena rating calculation
- if(isArena() && isRated())
+ if (isArena() && isRated())
{
- if(winner == ALLIANCE)
- {
- winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE));
- loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE));
- }
- else if(winner == HORDE)
- {
- winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE));
- loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE));
- }
- if(winner_arena_team && loser_arena_team)
+ winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(winner));
+ loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(winner)));
+ if (winner_arena_team && loser_arena_team)
{
loser_rating = loser_arena_team->GetStats().rating;
winner_rating = winner_arena_team->GetStats().rating;
int32 winner_change = winner_arena_team->WonAgainst(loser_rating);
int32 loser_change = loser_arena_team->LostAgainst(winner_rating);
sLog.outDebug("--- Winner rating: %u, Loser rating: %u, Winner change: %u, Losser change: %u ---", winner_rating, loser_rating, winner_change, loser_change);
- if(winner == ALLIANCE)
- {
- SetArenaTeamRatingChangeForTeam(ALLIANCE, winner_change);
- SetArenaTeamRatingChangeForTeam(HORDE, loser_change);
- }
- else
- {
- SetArenaTeamRatingChangeForTeam(HORDE, winner_change);
- SetArenaTeamRatingChangeForTeam(ALLIANCE, loser_change);
- }
+ SetArenaTeamRatingChangeForTeam(winner, winner_change);
+ SetArenaTeamRatingChangeForTeam(GetOtherTeam(winner), loser_change);
}
else
{
@@ -522,69 +682,56 @@ void BattleGround::EndBattleGround(uint32 winner)
}
}
- if(!isArena()){
-
- if(m_score[GetTeamIndexByTeamId(ALLIANCE)] == m_score[GetTeamIndexByTeamId(HORDE)])
- almost_winning_team = 0; //no real winner
- if(m_score[GetTeamIndexByTeamId(ALLIANCE)] > m_score[GetTeamIndexByTeamId(HORDE)])
- almost_winning_team = ALLIANCE;
-
- }
-
- for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
+ for(BattleGroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
Player *plr = objmgr.GetPlayer(itr->first);
- if(!plr)
+ uint32 team = itr->second.Team;
+
+ if (!plr)
{
+ //if rated arena match - make member lost!
+ if (isArena() && isRated() && winner_arena_team && loser_arena_team)
+ {
+ if (team == winner)
+ winner_arena_team->OfflineMemberLost(itr->first, loser_rating);
+ else
+ loser_arena_team->OfflineMemberLost(itr->first, winner_rating);
+ }
sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first);
continue;
}
// should remove spirit of redemption
if(plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
- plr->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT);
+ plr->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT);
- if(!plr->isAlive())
+ if (!plr->isAlive())
{
plr->ResurrectPlayer(1.0f);
plr->SpawnCorpseBones();
}
- uint32 team = itr->second.Team;
- if(!team) team = plr->GetTeam();
+ //this line is obsolete - team is set ALWAYS
+ //if(!team) team = plr->GetTeam();
// per player calculation
- if(isArena() && isRated() && winner_arena_team && loser_arena_team)
+ if (isArena() && isRated() && winner_arena_team && loser_arena_team)
{
- if(team == winner)
+ if (team == winner)
winner_arena_team->MemberWon(plr,loser_rating);
else
loser_arena_team->MemberLost(plr,winner_rating);
}
- if(team == winner)
+ if (team == winner)
{
- if(!Source)
- Source = plr;
RewardMark(plr,ITEM_WINNER_COUNT);
- UpdatePlayerScore(plr, SCORE_BONUS_HONOR, 20);
RewardQuest(plr);
}
else if(winner !=0)
{
- RewardMark(plr,ITEM_LOSER_COUNT);
- }
- else if(winner == 0)
- {
- if(sWorld.getConfig(CONFIG_PREMATURE_BG_REWARD)) // We're feeling generous, giving rewards to people who not earned them ;)
- { //nested ifs for the win! its boring writing that, forgive me my unfunniness
-
- if(almost_winning_team == team) //player's team had more points
- RewardMark(plr,ITEM_WINNER_COUNT);
- else
- RewardMark(plr,ITEM_LOSER_COUNT); // if scores were the same, each team gets 1 mark.
+ RewardMark(plr,ITEM_LOSER_COUNT);
}
- }
plr->CombatStopWithPets(true);
@@ -593,12 +740,13 @@ void BattleGround::EndBattleGround(uint32 winner)
sBattleGroundMgr.BuildPvpLogDataPacket(&data, this);
plr->GetSession()->SendPacket(&data);
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType());
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime());
+ BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType());
plr->GetSession()->SendPacket(&data);
+ plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1);
}
- if(isArena() && isRated() && winner_arena_team && loser_arena_team)
+ if (isArena() && isRated() && winner_arena_team && loser_arena_team)
{
// update arena points only after increasing the player's match count!
//obsolete: winner_arena_team->UpdateArenaPointsHelper();
@@ -610,17 +758,16 @@ void BattleGround::EndBattleGround(uint32 winner)
// this way all arena team members will get notified, not only the ones who participated in this match
winner_arena_team->NotifyStatsChanged();
loser_arena_team->NotifyStatsChanged();
- sLog.outDebug("Rated arena match between %s and %s finished, winner: %s", loser_arena_team->GetName().c_str(),winner_arena_team->GetName().c_str(),winner_arena_team->GetName().c_str());
}
- // inform invited players about the removal
- sBattleGroundMgr.m_BattleGroundQueues[sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this);
+ if (winmsg_id)
+ SendMessageToAll(winmsg_id, CHAT_MSG_BG_SYSTEM_NEUTRAL);
+}
- if(Source)
- {
- ChatHandler(Source).FillMessageData(&data, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, Source->GetGUID(), winmsg);
- SendPacketToAll(&data);
- }
+uint32 BattleGround::GetBonusHonorFromKill(uint32 kills) const
+{
+ //variable kills means how many honorable kills you scored (so we need kills * honor_for_one_kill)
+ return MaNGOS::Honor::hk_honor_at_level(GetMaxLevel(), kills);
}
uint32 BattleGround::GetBattlemasterEntry() const
@@ -639,13 +786,13 @@ uint32 BattleGround::GetBattlemasterEntry() const
void BattleGround::RewardMark(Player *plr,uint32 count)
{
// 'Inactive' this aura prevents the player from gaining honor points and battleground tokens
- if(plr->GetDummyAura(SPELL_AURA_PLAYER_INACTIVE))
+ if (plr->GetDummyAura(SPELL_AURA_PLAYER_INACTIVE))
return;
if(!plr || !count)
return;
- BattleGroundMarks mark;
+ BattleGroundMarks mark;
switch(GetTypeID())
{
case BATTLEGROUND_AV:
@@ -657,7 +804,7 @@ void BattleGround::RewardMark(Player *plr,uint32 count)
case BATTLEGROUND_AB:
mark = ITEM_AB_MARK_OF_HONOR;
break;
- case BATTLEGROUND_EY:
+ case BATTLEGROUND_EY:
mark = ITEM_EY_MARK_OF_HONOR;
break;
default:
@@ -676,7 +823,7 @@ void BattleGround::RewardMark(Player *plr,uint32 count)
if(Item* item = plr->StoreNewItem( dest, mark, true, 0))
plr->SendNewItem(item,count,false,true);
- if(no_space_count > 0)
+ if (no_space_count > 0)
SendRewardMarkByMail(plr,mark,no_space_count);
}
}
@@ -684,14 +831,14 @@ void BattleGround::RewardMark(Player *plr,uint32 count)
void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count)
{
uint32 bmEntry = GetBattlemasterEntry();
- if(!bmEntry)
+ if (!bmEntry)
return;
ItemPrototype const* markProto = objmgr.GetItemPrototype(mark);
- if(!markProto)
+ if (!markProto)
return;
- if(Item* markItem = Item::CreateItem(mark,count,plr))
+ if (Item* markItem = Item::CreateItem(mark,count,plr))
{
// save new item before send
markItem->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
@@ -703,8 +850,8 @@ void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count)
// subject: item name
std::string subject = markProto->Name1;
int loc_idx = plr->GetSession()->GetSessionDbLocaleIndex();
- if ( loc_idx >= 0 )
- if(ItemLocale const *il = objmgr.GetItemLocale(markProto->ItemId))
+ if (loc_idx >= 0 )
+ if (ItemLocale const *il = objmgr.GetItemLocale(markProto->ItemId))
if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty())
subject = il->Name[loc_idx];
@@ -721,7 +868,7 @@ void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count)
void BattleGround::RewardQuest(Player *plr)
{
// 'Inactive' this aura prevents the player from gaining honor points and battleground tokens
- if(plr->GetDummyAura(SPELL_AURA_PLAYER_INACTIVE))
+ if (plr->GetDummyAura(SPELL_AURA_PLAYER_INACTIVE))
return;
uint32 quest;
@@ -756,17 +903,17 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
uint32 team = GetPlayerTeam(guid);
bool participant = false;
// Remove from lists/maps
- std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.find(guid);
- if(itr != m_Players.end())
+ BattleGroundPlayerMap::iterator itr = m_Players.find(guid);
+ if (itr != m_Players.end())
{
- UpdatePlayersCountByTeam(team, true); // -1 player
+ UpdatePlayersCountByTeam(team, true); // -1 player
m_Players.erase(itr);
// check if the player was a participant of the match, or only entered through gm command (goname)
participant = true;
}
std::map<uint64, BattleGroundScore*>::iterator itr2 = m_PlayerScores.find(guid);
- if(itr2 != m_PlayerScores.end())
+ if (itr2 != m_PlayerScores.end())
{
delete itr2->second; // delete player's score
m_PlayerScores.erase(itr2);
@@ -778,7 +925,7 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
// should remove spirit of redemption
if(plr && plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
- plr->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT);
+ plr->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT);
if(plr && !plr->isAlive()) // resurrect on exit
{
@@ -788,100 +935,91 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
RemovePlayer(plr, guid); // BG subclass specific code
- if(plr)
+ if(participant) // if the player was a match participant, remove auras, calc rating, update queue
{
- plr->ClearAfkReports();
-
- if(participant) // if the player was a match participant, remove auras, calc rating, update queue
+ BattleGroundTypeId bgTypeId = GetTypeID();
+ BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
+ if (plr)
{
+ plr->ClearAfkReports();
+
if(!team) team = plr->GetTeam();
- uint32 bgTypeId = GetTypeID();
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType());
// if arena, remove the specific arena auras
- if(isArena())
+ if (isArena())
{
- plr->RemoveArenaAuras(true); // removes debuffs / dots etc., we don't want the player to die after porting out
- bgTypeId=BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing)
+ plr->RemoveArenaAuras(true); // removes debuffs / dots etc., we don't want the player to die after porting out
+ bgTypeId=BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing)
- // summon old pet if there was one and there isn't a current pet
- if(!plr->GetPet() && plr->GetTemporaryUnsummonedPetNumber())
- {
- Pet* NewPet = new Pet;
- if(!NewPet->LoadPetFromDB(plr, 0, (plr)->GetTemporaryUnsummonedPetNumber(), true))
- delete NewPet;
-
- (plr)->SetTemporaryUnsummonedPetNumber(0);
- }
+ // unsummon current and summon old pet if there was one and there isn't a current pet
+ plr->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT);
+ plr->ResummonPetTemporaryUnSummonedIfAny();
- if(isRated() && GetStatus() == STATUS_IN_PROGRESS)
+ if (isRated() && GetStatus() == STATUS_IN_PROGRESS)
{
//left a rated match while the encounter was in progress, consider as loser
- ArenaTeam * winner_arena_team = 0;
- ArenaTeam * loser_arena_team = 0;
- if(team == HORDE)
- {
- winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE));
- loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE));
- }
- else
- {
- winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE));
- loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE));
- }
- if(winner_arena_team && loser_arena_team)
- {
+ ArenaTeam * winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(team)));
+ ArenaTeam * loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(team));
+ if (winner_arena_team && loser_arena_team)
loser_arena_team->MemberLost(plr,winner_arena_team->GetRating());
- }
}
}
-
- WorldPacket data;
- if(SendPacket)
+ if (SendPacket)
{
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, team, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_NONE, 0, 0);
+ WorldPacket data;
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_NONE, 0, 0, 0);
plr->GetSession()->SendPacket(&data);
}
// this call is important, because player, when joins to battleground, this method is not called, so it must be called when leaving bg
plr->RemoveBattleGroundQueueId(bgQueueTypeId);
-
- DecreaseInvitedCount(team);
- //we should update battleground queue, but only if bg isn't ending
- if (GetQueueType() < MAX_BATTLEGROUND_QUEUES)
- sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, GetQueueType());
-
- Group * group = plr->GetGroup();
- // remove from raid group if exist
- if(group && group == GetBgRaid(team))
+ }
+ else
+ // removing offline participant
+ {
+ if (isRated() && GetStatus() == STATUS_IN_PROGRESS)
{
- if(!group->RemoveMember(guid, 0)) // group was disbanded
- {
- SetBgRaid(team, NULL);
- delete group;
- }
+ //left a rated match while the encounter was in progress, consider as loser
+ ArenaTeam * others_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(team)));
+ ArenaTeam * players_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(team));
+ if (others_arena_team && players_arena_team)
+ players_arena_team->OfflineMemberLost(guid, others_arena_team->GetRating());
}
+ }
- // Let others know
- sBattleGroundMgr.BuildPlayerLeftBattleGroundPacket(&data, plr);
- SendPacketToTeam(team, &data, plr, false);
+ // remove from raid group if player is member
+ if (Group *group = GetBgRaid(team))
+ {
+ if( !group->RemoveMember(guid, 0) ) // group was disbanded
+ {
+ SetBgRaid(team, NULL);
+ delete group;
+ }
}
+ DecreaseInvitedCount(team);
+ //we should update battleground queue, but only if bg isn't ending
+ if (isBattleGround() && GetStatus() < STATUS_WAIT_LEAVE)
+ sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, GetQueueId());
+ // Let others know
+ WorldPacket data;
+ sBattleGroundMgr.BuildPlayerLeftBattleGroundPacket(&data, guid);
+ SendPacketToTeam(team, &data, plr, false);
+ }
+ if (plr)
+ {
// Do next only if found in battleground
- plr->SetBattleGroundId(0); // We're not in BG.
+ plr->SetBattleGroundId(0, BATTLEGROUND_TYPE_NONE); // We're not in BG.
// reset destination bg team
plr->SetBGTeam(0);
- if(Transport)
- {
- plr->TeleportTo(plr->GetBattleGroundEntryPointMap(), plr->GetBattleGroundEntryPointX(), plr->GetBattleGroundEntryPointY(), plr->GetBattleGroundEntryPointZ(), plr->GetBattleGroundEntryPointO());
- }
+ if (Transport)
+ plr->TeleportTo(plr->GetBattleGroundEntryPoint());
- // Log
sLog.outDetail("BATTLEGROUND: Removed player %s from BattleGround.", plr->GetName());
}
- if(!GetPlayersSize() && !GetInvitedCount(HORDE) && !GetInvitedCount(ALLIANCE))
+ if (!GetPlayersSize() && !GetInvitedCount(HORDE) && !GetInvitedCount(ALLIANCE))
{
// if no players left AND no invitees left, set this bg to delete in next update
// direct deletion could cause crashes
@@ -897,7 +1035,7 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
// this method is called when no players remains in battleground
void BattleGround::Reset()
{
- SetQueueType(MAX_BATTLEGROUND_QUEUES);
+ SetQueueId(QUEUE_ID_MAX_LEVEL_19);
SetWinner(WINNER_NONE);
SetStatus(STATUS_WAIT_QUEUE);
SetStartTime(0);
@@ -909,7 +1047,7 @@ void BattleGround::Reset()
m_Events = 0;
if (m_InvitedAlliance > 0 || m_InvitedHorde > 0)
- sLog.outError("BattleGround system ERROR: bad counter, m_InvitedAlliance: %d, m_InvitedHorde: %d", m_InvitedAlliance, m_InvitedHorde);
+ sLog.outError("BattleGround system: bad counter, m_InvitedAlliance: %d, m_InvitedHorde: %d", m_InvitedAlliance, m_InvitedHorde);
m_InvitedAlliance = 0;
m_InvitedHorde = 0;
@@ -917,9 +1055,6 @@ void BattleGround::Reset()
m_Players.clear();
m_PlayerScores.clear();
-
- // reset BGSubclass
- ResetBGSubclass();
}
void BattleGround::StartBattleGround()
@@ -938,7 +1073,7 @@ void BattleGround::AddPlayer(Player *plr)
uint32 team = plr->GetBGTeam();
BattleGroundPlayer bp;
- bp.LastOnlineTime = 0;
+ bp.OfflineRemoveTime = 0;
bp.Team = team;
// Add to list/maps
@@ -951,40 +1086,28 @@ void BattleGround::AddPlayer(Player *plr)
SendPacketToTeam(team, &data, plr, false);
// add arena specific auras
- if(isArena())
+ if (isArena())
{
plr->RemoveArenaSpellCooldowns();
plr->RemoveArenaAuras();
plr->RemoveAllEnchantments(TEMP_ENCHANTMENT_SLOT);
if(team == ALLIANCE) // gold
{
- if(plr->GetTeam() == HORDE)
+ if (plr->GetTeam() == HORDE)
plr->CastSpell(plr, SPELL_HORDE_GOLD_FLAG,true);
else
plr->CastSpell(plr, SPELL_ALLIANCE_GOLD_FLAG,true);
}
else // green
{
- if(plr->GetTeam() == HORDE)
+ if (plr->GetTeam() == HORDE)
plr->CastSpell(plr, SPELL_HORDE_GREEN_FLAG,true);
else
plr->CastSpell(plr, SPELL_ALLIANCE_GREEN_FLAG,true);
}
plr->DestroyConjuredItems(true);
-
- Pet* pet = plr->GetPet();
- if(pet)
- {
- if(pet->getPetType() == SUMMON_PET || pet->getPetType() == HUNTER_PET)
- {
- (plr)->SetTemporaryUnsummonedPetNumber(pet->GetCharmInfo()->GetPetNumber());
- (plr)->SetOldPetSpell(pet->GetUInt32Value(UNIT_CREATED_BY_SPELL));
- }
- (plr)->RemovePet(NULL,PET_SAVE_NOT_IN_SLOT);
- }
- else
- (plr)->SetTemporaryUnsummonedPetNumber(0);
+ plr->UnsummonPetTemporaryIfAny();
if(GetStatus() == STATUS_WAIT_JOIN) // not started yet
{
@@ -1000,15 +1123,86 @@ void BattleGround::AddPlayer(Player *plr)
plr->CastSpell(plr, SPELL_PREPARATION, true); // reduces all mana cost of spells.
}
+ plr->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, ACHIEVEMENT_CRITERIA_CONDITION_MAP, GetMapId());
+ plr->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE, ACHIEVEMENT_CRITERIA_CONDITION_MAP, GetMapId());
+
+ // setup BG group membership
+ PlayerAddedToBGCheckIfBGIsRunning(plr);
+ AddOrSetPlayerToCorrectBgGroup(plr, guid, team);
+
// Log
sLog.outDetail("BATTLEGROUND: Player %s joined the battle.", plr->GetName());
}
+/* this method adds player to his team's bg group, or sets his correct group if player is already in bg group */
+void BattleGround::AddOrSetPlayerToCorrectBgGroup(Player *plr, uint64 plr_guid, uint32 team)
+{
+ Group* group = GetBgRaid(team);
+ if(!group) // first player joined
+ {
+ group = new Group;
+ SetBgRaid(team, group);
+ group->Create(plr_guid, plr->GetName());
+ }
+ else // raid already exist
+ {
+ if (group->IsMember(plr_guid))
+ {
+ uint8 subgroup = group->GetMemberGroup(plr_guid);
+ plr->SetBattleGroundRaid(group, subgroup);
+ }
+ else
+ {
+ group->AddMember(plr_guid, plr->GetName());
+ if (Group* originalGroup = plr->GetOriginalGroup())
+ if (originalGroup->IsLeader(plr_guid))
+ group->ChangeLeader(plr_guid);
+ }
+ }
+}
+
+// This method should be called when player logs into running battleground
+void BattleGround::EventPlayerLoggedIn(Player* player, uint64 plr_guid)
+{
+ // player is correct pointer
+ for(std::deque<uint64>::iterator itr = m_OfflineQueue.begin(); itr != m_OfflineQueue.end(); ++itr)
+ {
+ if (*itr == plr_guid)
+ {
+ m_OfflineQueue.erase(itr);
+ break;
+ }
+ }
+ m_Players[plr_guid].OfflineRemoveTime = 0;
+ PlayerAddedToBGCheckIfBGIsRunning(player);
+ // if battleground is starting, then add preparation aura
+ // we don't have to do that, because preparation aura isn't removed when player logs out
+}
+
+// This method should be called when player logs out from running battleground
+void BattleGround::EventPlayerLoggedOut(Player* player)
+{
+ // player is correct pointer, it is checked in WorldSession::LogoutPlayer()
+ m_OfflineQueue.push_back(player->GetGUID());
+ m_Players[player->GetGUID()].OfflineRemoveTime = sWorld.GetGameTime() + MAX_OFFLINE_TIME;
+ if (GetStatus() == STATUS_IN_PROGRESS)
+ {
+ if (isBattleGround())
+ EventPlayerDroppedFlag(player);
+ else
+ {
+ //1 player is logging out, if it is the last, then end arena!
+ if (GetAlivePlayersCountByTeam(player->GetTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player->GetTeam())))
+ EndBattleGround(GetOtherTeam(player->GetTeam()));
+ }
+ }
+}
+
/* This method should be called only once ... it adds pointer to queue */
void BattleGround::AddToBGFreeSlotQueue()
{
// make sure to add only once
- if(!m_InBGFreeSlotQueue)
+ if (!m_InBGFreeSlotQueue && isBattleGround())
{
sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].push_front(this);
m_InBGFreeSlotQueue = true;
@@ -1021,7 +1215,7 @@ void BattleGround::RemoveFromBGFreeSlotQueue()
// set to be able to re-add if needed
m_InBGFreeSlotQueue = false;
// uncomment this code when battlegrounds will work like instances
- for (std::deque<BattleGround*>::iterator itr = sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].end(); ++itr)
+ for (BGFreeSlotQueueType::iterator itr = sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].end(); ++itr)
{
if ((*itr)->GetInstanceID() == m_InstanceID)
{
@@ -1032,61 +1226,12 @@ void BattleGround::RemoveFromBGFreeSlotQueue()
}
// get the number of free slots for team
-// works in similar way that HasFreeSlotsForTeam did, but this is needed for join as group
+// returns the number how many players can join battleground to MaxPlayersPerTeam
uint32 BattleGround::GetFreeSlotsForTeam(uint32 Team) const
{
- //if BG is starting ... invite anyone
- if (GetStatus() == STATUS_WAIT_JOIN)
+ //return free slot count to MaxPlayerPerTeam
+ if (GetStatus() == STATUS_WAIT_JOIN || GetStatus() == STATUS_IN_PROGRESS)
return (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0;
- //if BG is already started .. do not allow to join too much players of one faction
- uint32 otherTeam;
- uint32 otherIn;
- if (Team == ALLIANCE)
- {
- otherTeam = GetInvitedCount(HORDE);
- otherIn = GetPlayersCountByTeam(HORDE);
- }
- else
- {
- otherTeam = GetInvitedCount(ALLIANCE);
- otherIn = GetPlayersCountByTeam(ALLIANCE);
- }
- if (GetStatus() == STATUS_IN_PROGRESS)
- {
- // difference based on ppl invited (not necessarily entered battle)
- // default: allow 0
- uint32 diff = 0;
- // allow join one person if the sides are equal (to fill up bg to minplayersperteam)
- if (otherTeam == GetInvitedCount(Team))
- diff = 1;
- // allow join more ppl if the other side has more players
- else if(otherTeam > GetInvitedCount(Team))
- diff = otherTeam - GetInvitedCount(Team);
-
- // difference based on max players per team (don't allow inviting more)
- uint32 diff2 = (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0;
-
- // difference based on players who already entered
- // default: allow 0
- uint32 diff3 = 0;
- // allow join one person if the sides are equal (to fill up bg minplayersperteam)
- if (otherIn == GetPlayersCountByTeam(Team))
- diff3 = 1;
- // allow join more ppl if the other side has more players
- else if (otherIn > GetPlayersCountByTeam(Team))
- diff3 = otherIn - GetPlayersCountByTeam(Team);
- // or other side has less than minPlayersPerTeam
- else if (GetInvitedCount(Team) <= GetMinPlayersPerTeam())
- diff3 = GetMinPlayersPerTeam() - GetInvitedCount(Team) + 1;
-
- // return the minimum of the 3 differences
-
- // min of diff and diff 2
- diff = diff < diff2 ? diff : diff2;
-
- // min of diff, diff2 and diff3
- return diff < diff3 ? diff : diff3 ;
- }
return 0;
}
@@ -1099,7 +1244,7 @@ bool BattleGround::HasFreeSlots() const
void BattleGround::UpdatePlayerScore(Player *Source, uint32 type, uint32 value)
{
//this procedure is called from virtual function implemented in bg subclass
- std::map<uint64, BattleGroundScore*>::iterator itr = m_PlayerScores.find(Source->GetGUID());
+ std::map<uint64, BattleGroundScore*>::const_iterator itr = m_PlayerScores.find(Source->GetGUID());
if(itr == m_PlayerScores.end()) // player not found...
return;
@@ -1117,10 +1262,10 @@ void BattleGround::UpdatePlayerScore(Player *Source, uint32 type, uint32 value)
break;
case SCORE_BONUS_HONOR: // Honor bonus
// do not add honor in arenas
- if(isBattleGround())
+ if (isBattleGround())
{
// reward honor instantly
- if(Source->RewardHonor(NULL, 1, value))
+ if (Source->RewardHonor(NULL, 1, value))
itr->second->BonusHonor += value;
}
break;
@@ -1142,14 +1287,13 @@ void BattleGround::AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid
m_ReviveQueue[npc_guid].push_back(player_guid);
Player *plr = objmgr.GetPlayer(player_guid);
- if(!plr)
+ if (!plr)
return;
- plr->CastSpell(plr, SPELL_WAITING_FOR_RESURRECT, true);
SpellEntry const *spellInfo = sSpellStore.LookupEntry( SPELL_WAITING_FOR_RESURRECT );
- if(spellInfo)
+ if (spellInfo)
{
- Aura *Aur = CreateAura(spellInfo, 0, NULL, plr);
+ Aura *Aur = new Aura(spellInfo, 1, NULL, plr);
plr->AddAura(Aur);
}
}
@@ -1160,12 +1304,12 @@ void BattleGround::RemovePlayerFromResurrectQueue(uint64 player_guid)
{
for(std::vector<uint64>::iterator itr2 =(itr->second).begin(); itr2 != (itr->second).end(); ++itr2)
{
- if(*itr2 == player_guid)
+ if (*itr2 == player_guid)
{
(itr->second).erase(itr2);
Player *plr = objmgr.GetPlayer(player_guid);
- if(!plr)
+ if (!plr)
return;
plr->RemoveAurasDueToSpell(SPELL_WAITING_FOR_RESURRECT);
@@ -1179,14 +1323,15 @@ void BattleGround::RemovePlayerFromResurrectQueue(uint64 player_guid)
bool BattleGround::AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime)
{
Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceID());
- if(!map)
+ if (!map)
return false;
// must be created this way, adding to godatamap would add it to the base map of the instance
// and when loading it (in go::LoadFromDB()), a new guid would be assigned to the object, and a new object would be created
// so we must create it specific for this instance
GameObject * go = new GameObject;
- if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),entry, map,x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1))
+ if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),entry, map,
+ PHASEMASK_NORMAL, x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,GO_STATE_READY))
{
sLog.outErrorDb("Gameobject template %u not found in database! BattleGround not created!", entry);
sLog.outError("Cannot create gameobject template %u! BattleGround not created!", entry);
@@ -1226,10 +1371,10 @@ bool BattleGround::AddObject(uint32 type, uint32 entry, float x, float y, float
void BattleGround::DoorClose(uint32 type)
{
GameObject *obj = HashMapHolder<GameObject>::Find(m_BgObjects[type]);
- if(obj)
+ if (obj)
{
//if doors are open, close it
- if( obj->getLootState() == GO_ACTIVATED && !obj->GetGoState() )
+ if (obj->getLootState() == GO_ACTIVATED && obj->GetGoState() != GO_STATE_READY)
{
//change state to allow door to be closed
obj->SetLootState(GO_READY);
@@ -1245,7 +1390,7 @@ void BattleGround::DoorClose(uint32 type)
void BattleGround::DoorOpen(uint32 type)
{
GameObject *obj = HashMapHolder<GameObject>::Find(m_BgObjects[type]);
- if(obj)
+ if (obj)
{
//change state to be sure they will be opened
obj->SetLootState(GO_READY);
@@ -1276,15 +1421,15 @@ Creature* BattleGround::GetBGCreature(uint32 type)
void BattleGround::SpawnBGObject(uint32 type, uint32 respawntime)
{
Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceID());
- if(!map)
+ if (!map)
return;
- if( respawntime == 0 )
+ if (respawntime == 0)
{
GameObject *obj = HashMapHolder<GameObject>::Find(m_BgObjects[type]);
- if(obj)
+ if (obj)
{
//we need to change state from GO_JUST_DEACTIVATED to GO_READY in case battleground is starting again
- if( obj->getLootState() == GO_JUST_DEACTIVATED )
+ if (obj->getLootState() == GO_JUST_DEACTIVATED)
obj->SetLootState(GO_READY);
obj->SetRespawnTime(0);
map->Add(obj);
@@ -1293,7 +1438,7 @@ void BattleGround::SpawnBGObject(uint32 type, uint32 respawntime)
else
{
GameObject *obj = HashMapHolder<GameObject>::Find(m_BgObjects[type]);
- if(obj)
+ if (obj)
{
map->Add(obj);
obj->SetRespawnTime(respawntime);
@@ -1305,11 +1450,11 @@ void BattleGround::SpawnBGObject(uint32 type, uint32 respawntime)
Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o, uint32 respawntime)
{
Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceID());
- if(!map)
+ if (!map)
return NULL;
Creature* pCreature = new Creature;
- if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, entry, teamval))
+ if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, PHASEMASK_NORMAL, entry, teamval))
{
sLog.outError("Can't create creature entry: %u",entry);
delete pCreature;
@@ -1318,14 +1463,14 @@ Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, f
pCreature->Relocate(x, y, z, o);
- if(!pCreature->IsPositionValid())
+ if (!pCreature->IsPositionValid())
{
- sLog.outError("ERROR: Creature (guidlow %d, entry %d) not added to battleground. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
+ sLog.outError("Creature (guidlow %d, entry %d) not added to battleground. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
+ delete pCreature;
return NULL;
}
pCreature->SetHomePosition(x, y, z, o);
- pCreature->AIM_Initialize();
//pCreature->SetDungeonDifficulty(0);
@@ -1338,13 +1483,13 @@ Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, f
void BattleGround::SpawnBGCreature(uint32 type, uint32 respawntime)
{
Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceId());
- if(!map)
+ if (!map)
return false;
- if(respawntime == 0)
+ if (respawntime == 0)
{
Creature *obj = HashMapHolder<Creature>::Find(m_BgCreatures[type]);
- if(obj)
+ if (obj)
{
//obj->Respawn(); // bugged
obj->SetRespawnTime(0);
@@ -1355,7 +1500,7 @@ void BattleGround::SpawnBGCreature(uint32 type, uint32 respawntime)
else
{
Creature *obj = HashMapHolder<Creature>::Find(m_BgCreatures[type]);
- if(obj)
+ if (obj)
{
obj->setDeathState(DEAD);
obj->SetRespawnTime(respawntime);
@@ -1366,8 +1511,11 @@ void BattleGround::SpawnBGCreature(uint32 type, uint32 respawntime)
*/
bool BattleGround::DelCreature(uint32 type)
{
+ if (!m_BgCreatures[type])
+ return true;
+
Creature *cr = HashMapHolder<Creature>::Find(m_BgCreatures[type]);
- if(!cr)
+ if (!cr)
{
sLog.outError("Can't find creature guid: %u",GUID_LOPART(m_BgCreatures[type]));
return false;
@@ -1381,8 +1529,11 @@ bool BattleGround::DelCreature(uint32 type)
bool BattleGround::DelObject(uint32 type)
{
+ if (!m_BgObjects[type])
+ return true;
+
GameObject *obj = HashMapHolder<GameObject>::Find(m_BgObjects[type]);
- if(!obj)
+ if (!obj)
{
sLog.outError("Can't find gobject guid: %u",GUID_LOPART(m_BgObjects[type]));
return false;
@@ -1397,13 +1548,13 @@ bool BattleGround::AddSpiritGuide(uint32 type, float x, float y, float z, float
{
uint32 entry = 0;
- if(team == ALLIANCE)
+ if (team == ALLIANCE)
entry = 13116;
else
entry = 13117;
Creature* pCreature = AddCreature(entry,type,team,x,y,z,o);
- if(!pCreature)
+ if (!pCreature)
{
sLog.outError("Can't create Spirit guide. BattleGround not created!");
EndNow();
@@ -1414,10 +1565,12 @@ bool BattleGround::AddSpiritGuide(uint32 type, float x, float y, float z, float
pCreature->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, pCreature->GetGUID());
// aura
- pCreature->SetUInt32Value(UNIT_FIELD_AURA, SPELL_SPIRIT_HEAL_CHANNEL);
- pCreature->SetUInt32Value(UNIT_FIELD_AURAFLAGS, 0x00000009);
- pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x0000003C);
- pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0x000000FF);
+ //TODO: Fix display here
+ //pCreature->SetVisibleAura(0, SPELL_SPIRIT_HEAL_CHANNEL);
+
+ //pCreature->SetUInt32Value(UNIT_FIELD_AURAFLAGS, 0x00000009);
+ //pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x0000003C);
+ //pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0x000000FF);
// casting visual effect
pCreature->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SPIRIT_HEAL_CHANNEL);
// correct cast speed
@@ -1428,31 +1581,40 @@ bool BattleGround::AddSpiritGuide(uint32 type, float x, float y, float z, float
return true;
}
-void BattleGround::SendMessageToAll(char const* text)
+void BattleGround::SendMessageToAll(int32 entry, ChatMsg type, Player const* source)
{
- WorldPacket data;
- ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, text, NULL);
- SendPacketToAll(&data);
+ MaNGOS::BattleGroundChatBuilder bg_builder(type, entry, source);
+ MaNGOS::LocalizedPacketDo<MaNGOS::BattleGroundChatBuilder> bg_do(bg_builder);
+ BroadcastWorker(bg_do);
}
-void BattleGround::SendMessageToAll(int32 entry)
+void BattleGround::PSendMessageToAll(int32 entry, ChatMsg type, Player const* source, ...)
{
- char const* text = GetTrinityString(entry);
- WorldPacket data;
- ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, text, NULL);
- SendPacketToAll(&data);
+ va_list ap;
+ va_start(ap, source);
+
+ MaNGOS::BattleGroundChatBuilder bg_builder(type, entry, source, &ap);
+ MaNGOS::LocalizedPacketDo<MaNGOS::BattleGroundChatBuilder> bg_do(bg_builder);
+ BroadcastWorker(bg_do);
+
+ va_end(ap);
+}
+
+void BattleGround::SendMessage2ToAll(int32 entry, ChatMsg type, Player const* source, int32 arg1, int32 arg2)
+{
+ MaNGOS::BattleGround2ChatBuilder bg_builder(type, entry, source, arg1, arg2);
+ MaNGOS::LocalizedPacketDo<MaNGOS::BattleGround2ChatBuilder> bg_do(bg_builder);
+ BroadcastWorker(bg_do);
}
void BattleGround::EndNow()
{
RemoveFromBGFreeSlotQueue();
SetStatus(STATUS_WAIT_LEAVE);
- SetEndTime(TIME_TO_AUTOREMOVE);
- // inform invited players about the removal
- sBattleGroundMgr.m_BattleGroundQueues[sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this);
+ SetEndTime(0);
}
-// Battleground messages are localized using the dbc lang, they are not client language dependent
+//to be removed
const char *BattleGround::GetTrinityString(int32 entry)
{
// FIXME: now we have different DBC locales and need localized message for each target client
@@ -1467,7 +1629,7 @@ buffs are in their positions when battleground starts
void BattleGround::HandleTriggerBuff(uint64 const& go_guid)
{
GameObject *obj = HashMapHolder<GameObject>::Find(go_guid);
- if(!obj || obj->GetGoType() != GAMEOBJECT_TYPE_TRAP || !obj->isSpawned())
+ if (!obj || obj->GetGoType() != GAMEOBJECT_TYPE_TRAP || !obj->isSpawned())
return;
//change buff type, when buff is used:
@@ -1483,13 +1645,13 @@ void BattleGround::HandleTriggerBuff(uint64 const& go_guid)
//randomly select new buff
uint8 buff = urand(0, 2);
uint32 entry = obj->GetEntry();
- if( m_BuffChange && entry != Buff_Entries[buff] )
+ if (m_BuffChange && entry != Buff_Entries[buff])
{
//despawn current buff
SpawnBGObject(index, RESPAWN_ONE_DAY);
//set index for new one
for (uint8 currBuffTypeIndex = 0; currBuffTypeIndex < 3; ++currBuffTypeIndex)
- if( entry == Buff_Entries[currBuffTypeIndex] )
+ if (entry == Buff_Entries[currBuffTypeIndex])
{
index -= currBuffTypeIndex;
index += buff;
@@ -1507,46 +1669,77 @@ void BattleGround::HandleKillPlayer( Player *player, Player *killer )
UpdatePlayerScore(player, SCORE_DEATHS, 1);
// add +1 kills to group and +1 killing_blows to killer
- if( killer )
+ if (killer)
{
UpdatePlayerScore(killer, SCORE_HONORABLE_KILLS, 1);
UpdatePlayerScore(killer, SCORE_KILLING_BLOWS, 1);
- for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
+ for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
Player *plr = objmgr.GetPlayer(itr->first);
- if(!plr || plr == killer)
+ if (!plr || plr == killer)
continue;
- if( plr->GetTeam() == killer->GetTeam() && plr->IsAtGroupRewardDistance(player) )
+ if (plr->GetTeam() == killer->GetTeam() && plr->IsAtGroupRewardDistance(player))
UpdatePlayerScore(plr, SCORE_HONORABLE_KILLS, 1);
}
}
- // to be able to remove insignia
- player->SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE );
+ // to be able to remove insignia -- ONLY IN BattleGrounds
+ if (!isArena())
+ player->SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE );
}
// return the player's team based on battlegroundplayer info
// used in same faction arena matches mainly
uint32 BattleGround::GetPlayerTeam(uint64 guid)
{
- std::map<uint64, BattleGroundPlayer>::const_iterator itr = m_Players.find(guid);
- if(itr!=m_Players.end())
+ BattleGroundPlayerMap::const_iterator itr = m_Players.find(guid);
+ if (itr!=m_Players.end())
return itr->second.Team;
return 0;
}
+uint32 BattleGround::GetOtherTeam(uint32 teamId)
+{
+ return (teamId) ? ((teamId == ALLIANCE) ? HORDE : ALLIANCE) : 0;
+}
+
+bool BattleGround::IsPlayerInBattleGround(uint64 guid)
+{
+ BattleGroundPlayerMap::const_iterator itr = m_Players.find(guid);
+ if (itr != m_Players.end())
+ return true;
+ return false;
+}
+
+void BattleGround::PlayerAddedToBGCheckIfBGIsRunning(Player* plr)
+{
+ if (GetStatus() != STATUS_WAIT_LEAVE)
+ return;
+
+ WorldPacket data;
+ BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
+
+ BlockMovement(plr);
+
+ sBattleGroundMgr.BuildPvpLogDataPacket(&data, this);
+ plr->GetSession()->SendPacket(&data);
+
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType());
+ plr->GetSession()->SendPacket(&data);
+}
+
uint32 BattleGround::GetAlivePlayersCountByTeam(uint32 Team) const
{
int count = 0;
- for(std::map<uint64, BattleGroundPlayer>::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
+ for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
- if(itr->second.Team == Team)
+ if (itr->second.Team == Team)
{
Player * pl = objmgr.GetPlayer(itr->first);
- if(pl && pl->isAlive())
+ if (pl && pl->isAlive())
++count;
}
}
@@ -1574,3 +1767,23 @@ void BattleGround::HandleKillUnit(Creature *creature, Player *killer)
{
}
+void BattleGround::CheckArenaWinConditions()
+{
+ if (!GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
+ EndBattleGround(HORDE);
+ else if (GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE))
+ EndBattleGround(ALLIANCE);
+}
+
+void BattleGround::SetBgRaid( uint32 TeamID, Group *bg_raid )
+{
+ Group* &old_raid = TeamID == ALLIANCE ? m_BgRaids[BG_TEAM_ALLIANCE] : m_BgRaids[BG_TEAM_HORDE];
+ if(old_raid) old_raid->SetBattlegroundGroup(NULL);
+ if(bg_raid) bg_raid->SetBattlegroundGroup(this);
+ old_raid = bg_raid;
+}
+
+WorldSafeLocsEntry const* BattleGround::GetClosestGraveYard( Player* player )
+{
+ return objmgr.GetClosestGraveYard( player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetTeam() );
+}
diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h
index e03e36cbd1e..9788f264502 100644
--- a/src/game/BattleGround.h
+++ b/src/game/BattleGround.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,13 +22,16 @@
#define __BATTLEGROUND_H
#include "Common.h"
-#include "WorldPacket.h"
-#include "WorldSession.h"
-#include "Opcodes.h"
-#include "ObjectMgr.h"
-#include "BattleGroundMgr.h"
#include "SharedDefines.h"
+class Creature;
+class GameObject;
+class Group;
+class Player;
+class WorldPacket;
+
+struct WorldSafeLocsEntry;
+
enum BattleGroundSounds
{
SOUND_HORDE_WINS = 8454,
@@ -83,17 +86,22 @@ enum BattleGroundTimeIntervals
{
RESURRECTION_INTERVAL = 30000, // ms
REMIND_INTERVAL = 30000, // ms
+ INVITATION_REMIND_TIME = 60000, // ms
INVITE_ACCEPT_WAIT_TIME = 80000, // ms
TIME_TO_AUTOREMOVE = 120000, // ms
- MAX_OFFLINE_TIME = 300000, // ms
- START_DELAY0 = 120000, // ms
- START_DELAY1 = 60000, // ms
- START_DELAY2 = 30000, // ms
- START_DELAY3 = 15000, // ms used only in arena
+ MAX_OFFLINE_TIME = 300, // secs
RESPAWN_ONE_DAY = 86400, // secs
RESPAWN_IMMEDIATELY = 0, // secs
BUFF_RESPAWN_TIME = 180, // secs
- BG_HONOR_SCORE_TICKS = 330 // points
+};
+
+enum BattleGroundStartTimeIntervals
+{
+ BG_START_DELAY_2M = 120000, // ms (2 minutes)
+ BG_START_DELAY_1M = 60000, // ms (1 minute)
+ BG_START_DELAY_30S = 30000, // ms (30 seconds)
+ BG_START_DELAY_15S = 15000, // ms (15 seconds) Used only in arena
+ BG_START_DELAY_NONE = 0, // ms
};
enum BattleGroundBuffObjects
@@ -107,16 +115,16 @@ const uint32 Buff_Entries[3] = { BG_OBJECTID_SPEEDBUFF_ENTRY, BG_OBJECTID_REGENB
enum BattleGroundStatus
{
- STATUS_NONE = 0,
- STATUS_WAIT_QUEUE = 1,
- STATUS_WAIT_JOIN = 2,
- STATUS_IN_PROGRESS = 3,
- STATUS_WAIT_LEAVE = 4 // custom
+ STATUS_NONE = 0, // first status, should mean bg is not instance
+ STATUS_WAIT_QUEUE = 1, // means bg is empty and waiting for queue
+ STATUS_WAIT_JOIN = 2, // this means, that BG has already started and it is waiting for more players
+ STATUS_IN_PROGRESS = 3, // means bg is running
+ STATUS_WAIT_LEAVE = 4 // means some faction has won BG and it is ending
};
struct BattleGroundPlayer
{
- uint32 LastOnlineTime; // for tracking and removing offline players from queue after 5 minutes
+ time_t OfflineRemoveTime; // for tracking and removing offline players from queue after 5 minutes
uint32 Team; // Player's team
};
@@ -129,31 +137,33 @@ struct BattleGroundObjectInfo
uint32 spellid;
};
-#define MAX_QUEUED_PLAYERS_MAP 7
-
-enum BattleGroundTypeId
+// handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time
+enum BattleGroundQueueTypeId
{
- BATTLEGROUND_AV = 1,
- BATTLEGROUND_WS = 2,
- BATTLEGROUND_AB = 3,
- BATTLEGROUND_NA = 4,
- BATTLEGROUND_BE = 5,
- BATTLEGROUND_AA = 6,
- BATTLEGROUND_EY = 7,
- BATTLEGROUND_RL = 8
+ BATTLEGROUND_QUEUE_NONE = 0,
+ BATTLEGROUND_QUEUE_AV = 1,
+ BATTLEGROUND_QUEUE_WS = 2,
+ BATTLEGROUND_QUEUE_AB = 3,
+ BATTLEGROUND_QUEUE_EY = 4,
+ BATTLEGROUND_QUEUE_SA = 5,
+ BATTLEGROUND_QUEUE_2v2 = 6,
+ BATTLEGROUND_QUEUE_3v3 = 7,
+ BATTLEGROUND_QUEUE_5v5 = 8
};
+#define MAX_BATTLEGROUND_QUEUE_TYPES 9
-// handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time
-enum BattleGroundQueueTypeId
+enum BGQueueIdBasedOnLevel // queue_id for level ranges
{
- BATTLEGROUND_QUEUE_AV = 1,
- BATTLEGROUND_QUEUE_WS = 2,
- BATTLEGROUND_QUEUE_AB = 3,
- BATTLEGROUND_QUEUE_EY = 4,
- BATTLEGROUND_QUEUE_2v2 = 5,
- BATTLEGROUND_QUEUE_3v3 = 6,
- BATTLEGROUND_QUEUE_5v5 = 7,
+ QUEUE_ID_MAX_LEVEL_19 = 0,
+ QUEUE_ID_MAX_LEVEL_29 = 1,
+ QUEUE_ID_MAX_LEVEL_39 = 2,
+ QUEUE_ID_MAX_LEVEL_49 = 3,
+ QUEUE_ID_MAX_LEVEL_59 = 4,
+ QUEUE_ID_MAX_LEVEL_69 = 5,
+ QUEUE_ID_MAX_LEVEL_79 = 6,
+ QUEUE_ID_MAX_LEVEL_80 = 7
};
+#define MAX_BATTLEGROUND_QUEUES 8
enum ScoreType
{
@@ -206,6 +216,25 @@ enum BattleGroundTeamId
BG_TEAM_ALLIANCE = 0,
BG_TEAM_HORDE = 1
};
+#define BG_TEAMS_COUNT 2
+
+enum BattleGroundStartingEvents
+{
+ BG_STARTING_EVENT_NONE = 0x00,
+ BG_STARTING_EVENT_1 = 0x01,
+ BG_STARTING_EVENT_2 = 0x02,
+ BG_STARTING_EVENT_3 = 0x04,
+ BG_STARTING_EVENT_4 = 0x08
+};
+
+enum BattleGroundStartingEventsIds
+{
+ BG_STARTING_EVENT_FIRST = 0,
+ BG_STARTING_EVENT_SECOND = 1,
+ BG_STARTING_EVENT_THIRD = 2,
+ BG_STARTING_EVENT_FOURTH = 3
+};
+#define BG_STARTING_EVENT_COUNT 4
enum BattleGroundJoinError
{
@@ -224,10 +253,11 @@ enum BattleGroundJoinError
class BattleGroundScore
{
public:
- BattleGroundScore() : KillingBlows(0), HonorableKills(0), Deaths(0), DamageDone(0), HealingDone(0), BonusHonor(0) {};
- virtual ~BattleGroundScore() //virtual destructor is used when deleting score from scores map
- {
- };
+ BattleGroundScore() : KillingBlows(0), Deaths(0), HonorableKills(0),
+ BonusHonor(0), DamageDone(0), HealingDone(0)
+ {}
+ virtual ~BattleGroundScore() {} //virtual destructor is used when deleting score from scores map
+
uint32 KillingBlows;
uint32 Deaths;
uint32 HonorableKills;
@@ -259,23 +289,23 @@ class BattleGround
BattleGround();
/*BattleGround(const BattleGround& bg);*/
virtual ~BattleGround();
- virtual void Update(time_t diff); // must be implemented in BG subclass of BG specific update code, but must in begginning call parent version
+ virtual void Update(uint32 diff); // must be implemented in BG subclass of BG specific update code, but must in begginning call parent version
virtual bool SetupBattleGround() // must be implemented in BG subclass
{
return true;
}
- void Reset(); // resets all common properties for battlegrounds
- virtual void ResetBGSubclass() // must be implemented in BG subclass
- {
- }
+ virtual void Reset(); // resets all common properties for battlegrounds, must be implemented and called in BG subclass
+ virtual void StartingEventCloseDoors() {}
+ virtual void StartingEventOpenDoors() {}
/* Battleground */
// Get methods:
char const* GetName() const { return m_Name; }
- uint32 GetTypeID() const { return m_TypeID; }
- uint32 GetQueueType() const { return m_Queue_type; }
+ BattleGroundTypeId GetTypeID() const { return m_TypeID; }
+ BGQueueIdBasedOnLevel GetQueueId() const { return m_QueueId; }
uint32 GetInstanceID() const { return m_InstanceID; }
- uint32 GetStatus() const { return m_Status; }
+ BattleGroundStatus GetStatus() const { return m_Status; }
+ uint32 GetClientInstanceID() const { return m_ClientInstanceID; }
uint32 GetStartTime() const { return m_StartTime; }
uint32 GetEndTime() const { return m_EndTime; }
uint32 GetLastResurrectTime() const { return m_LastResurrectTime; }
@@ -288,17 +318,25 @@ class BattleGround
uint32 GetMaxPlayersPerTeam() const { return m_MaxPlayersPerTeam; }
uint32 GetMinPlayersPerTeam() const { return m_MinPlayersPerTeam; }
- int GetStartDelayTime() const { return m_StartDelayTime; }
+ int32 GetStartDelayTime() const { return m_StartDelayTime; }
uint8 GetArenaType() const { return m_ArenaType; }
uint8 GetWinner() const { return m_Winner; }
uint32 GetBattlemasterEntry() const;
+ uint32 GetBonusHonorFromKill(uint32 kills) const;
// Set methods:
void SetName(char const* Name) { m_Name = Name; }
- void SetTypeID(uint32 TypeID) { m_TypeID = TypeID; }
- void SetQueueType(uint32 ID) { m_Queue_type = ID; }
+ void SetTypeID(BattleGroundTypeId TypeID) { m_TypeID = TypeID; }
+ //here we can count minlevel and maxlevel for players
+ void SetQueueId(BGQueueIdBasedOnLevel ID)
+ {
+ m_QueueId = ID;
+ uint8 diff = (m_TypeID == BATTLEGROUND_AV) ? 1 : 0;
+ this->SetLevelRange((ID + 1) * 10 + diff, (ID + 2) * 10 - ((diff + 1) % 2));
+ }
void SetInstanceID(uint32 InstanceID) { m_InstanceID = InstanceID; }
- void SetStatus(uint32 Status) { m_Status = Status; }
+ void SetStatus(BattleGroundStatus Status) { m_Status = Status; }
+ void SetClientInstanceID(uint32 InstanceID) { m_ClientInstanceID = InstanceID; }
void SetStartTime(uint32 Time) { m_StartTime = Time; }
void SetEndTime(uint32 Time) { m_EndTime = Time; }
void SetLastResurrectTime(uint32 Time) { m_LastResurrectTime = Time; }
@@ -323,12 +361,11 @@ class BattleGround
void IncreaseInvitedCount(uint32 team) { (team == ALLIANCE) ? ++m_InvitedAlliance : ++m_InvitedHorde; }
uint32 GetInvitedCount(uint32 team) const
{
- if( team == ALLIANCE )
+ if (team == ALLIANCE)
return m_InvitedAlliance;
else
return m_InvitedHorde;
}
- bool HasFreeSlotsForTeam(uint32 Team) const;
bool HasFreeSlots() const;
uint32 GetFreeSlotsForTeam(uint32 Team) const;
@@ -339,7 +376,6 @@ class BattleGround
typedef std::map<uint64, BattleGroundPlayer> BattleGroundPlayerMap;
BattleGroundPlayerMap const& GetPlayers() const { return m_Players; }
uint32 GetPlayersSize() const { return m_Players.size(); }
- uint32 GetRemovedPlayersSize() const { return m_RemovedPlayers.size(); }
std::map<uint64, BattleGroundScore*>::const_iterator GetPlayerScoresBegin() const { return m_PlayerScores.begin(); }
std::map<uint64, BattleGroundScore*>::const_iterator GetPlayerScoresEnd() const { return m_PlayerScores.end(); }
@@ -374,6 +410,10 @@ class BattleGround
void SendPacketToTeam(uint32 TeamID, WorldPacket *packet, Player *sender = NULL, bool self = true);
void SendPacketToAll(WorldPacket *packet);
void YellToAll(Creature* creature, const char* text, uint32 language);
+
+ template<class Do>
+ void BroadcastWorker(Do& _do);
+
void PlaySoundToTeam(uint32 SoundID, uint32 TeamID);
void PlaySoundToAll(uint32 SoundID);
void CastSpellOnTeam(uint32 SpellID, uint32 TeamID);
@@ -387,18 +427,15 @@ class BattleGround
void EndBattleGround(uint32 winner);
void BlockMovement(Player *plr);
- void SendMessageToAll(char const* text);
- void SendMessageToAll(int32 entry);
+ void SendMessageToAll(int32 entry, ChatMsg type, Player const* source = NULL);
+ void PSendMessageToAll(int32 entry, ChatMsg type, Player const* source, ... );
+
+ // specialized version with 2 string id args
+ void SendMessage2ToAll(int32 entry, ChatMsg type, Player const* source, int32 strId1 = 0, int32 strId2 = 0);
/* Raid Group */
Group *GetBgRaid(uint32 TeamID) const { return TeamID == ALLIANCE ? m_BgRaids[BG_TEAM_ALLIANCE] : m_BgRaids[BG_TEAM_HORDE]; }
- void SetBgRaid(uint32 TeamID, Group *bg_raid)
- {
- Group* &old_raid = TeamID == ALLIANCE ? m_BgRaids[BG_TEAM_ALLIANCE] : m_BgRaids[BG_TEAM_HORDE];
- if(old_raid) old_raid->SetBattlegroundGroup(NULL);
- if(bg_raid) bg_raid->SetBattlegroundGroup(this);
- old_raid = bg_raid;
- }
+ void SetBgRaid(uint32 TeamID, Group *bg_raid);
virtual void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
@@ -407,7 +444,7 @@ class BattleGround
uint32 GetAlivePlayersCountByTeam(uint32 Team) const; // used in arenas to correctly handle death in spirit of redemption / last stand etc. (killer = killed) cases
void UpdatePlayersCountByTeam(uint32 Team, bool remove)
{
- if(remove)
+ if (remove)
--m_PlayersCount[GetTeamIndexByTeamId(Team)];
else
++m_PlayersCount[GetTeamIndexByTeamId(Team)];
@@ -415,9 +452,10 @@ class BattleGround
// used for rated arena battles
void SetArenaTeamIdForTeam(uint32 Team, uint32 ArenaTeamId) { m_ArenaTeamIds[GetTeamIndexByTeamId(Team)] = ArenaTeamId; }
- uint32 GetArenaTeamIdForTeam(uint32 Team) const { return m_ArenaTeamIds[GetTeamIndexByTeamId(Team)]; }
+ uint32 GetArenaTeamIdForTeam(uint32 Team) const { return m_ArenaTeamIds[GetTeamIndexByTeamId(Team)]; }
void SetArenaTeamRatingChangeForTeam(uint32 Team, int32 RatingChange) { m_ArenaTeamRatingChanges[GetTeamIndexByTeamId(Team)] = RatingChange; }
- int32 GetArenaTeamRatingChangeForTeam(uint32 Team) const { return m_ArenaTeamRatingChanges[GetTeamIndexByTeamId(Team)]; }
+ int32 GetArenaTeamRatingChangeForTeam(uint32 Team) const { return m_ArenaTeamRatingChanges[GetTeamIndexByTeamId(Team)]; }
+ void CheckArenaWinConditions();
/* Triggers handle */
// must be implemented in BG subclass
@@ -427,16 +465,19 @@ class BattleGround
virtual void HandleKillUnit(Creature* /*unit*/, Player* /*killer*/);
/* Battleground events */
- /* these functions will return true event is possible, but false if player is bugger */
virtual void EventPlayerDroppedFlag(Player* /*player*/) {}
virtual void EventPlayerClickedOnFlag(Player* /*player*/, GameObject* /*target_obj*/) {}
virtual void EventPlayerCapturedFlag(Player* /*player*/) {}
+ void EventPlayerLoggedIn(Player* player, uint64 plr_guid);
+ void EventPlayerLoggedOut(Player* player);
/* Death related */
- virtual WorldSafeLocsEntry const* GetClosestGraveYard(float /*x*/, float /*y*/, float /*z*/, uint32 /*team*/) { return NULL; }
+ virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
virtual void AddPlayer(Player *plr); // must be implemented in BG subclass
+ void AddOrSetPlayerToCorrectBgGroup(Player *plr, uint64 plr_guid, uint32 team);
+
virtual void RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket);
// can be extended in in BG subclass
@@ -459,18 +500,22 @@ class BattleGround
void DoorOpen(uint32 type);
void DoorClose(uint32 type);
+ //to be removed
const char *GetTrinityString(int32 entry);
- virtual bool HandlePlayerUnderMap(Player * plr) {return false;}
+ virtual bool HandlePlayerUnderMap(Player * /*plr*/) { return false; }
// since arenas can be AvA or Hvh, we have to get the "temporary" team of a player
uint32 GetPlayerTeam(uint64 guid);
+ uint32 GetOtherTeam(uint32 teamId);
+ bool IsPlayerInBattleGround(uint64 guid);
void SetDeleteThis() {m_SetDeleteThis = true;}
protected:
//this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends BattleGround
void EndNow();
+ void PlayerAddedToBGCheckIfBGIsRunning(Player* plr);
/* Scorekeeping */
// Player scores
@@ -484,29 +529,29 @@ class BattleGround
std::map<uint64, std::vector<uint64> > m_ReviveQueue;
/*
- this is important variable used for invitation messages
+ these are important variables used for starting messages
*/
uint8 m_Events;
+ BattleGroundStartTimeIntervals m_StartDelayTimes[BG_STARTING_EVENT_COUNT];
+ //this must be filled in constructors!
+ uint32 m_StartMessageIds[BG_STARTING_EVENT_COUNT];
bool m_BuffChange;
- uint32 m_score[2]; //array that keeps general team scores, used to determine who gets most marks when bg ends prematurely
BGHonorMode m_HonorMode;
private:
/* Battleground */
- uint32 m_TypeID; //Battleground type, defined in enum BattleGroundTypeId
+ BattleGroundTypeId m_TypeID;
uint32 m_InstanceID; //BattleGround Instance's GUID!
- uint32 m_Status;
+ BattleGroundStatus m_Status;
+ uint32 m_ClientInstanceID; //the instance-id which is sent to the client and without any other internal use
uint32 m_StartTime;
- uint32 m_EndTime;
+ int32 m_EndTime; // it is set to 120000 when bg is ending and it decreases itself
uint32 m_LastResurrectTime;
- uint32 m_Queue_type;
+ BGQueueIdBasedOnLevel m_QueueId;
uint8 m_ArenaType; // 2=2v2, 3=3v3, 5=5v5
bool m_InBGFreeSlotQueue; // used to make sure that BG is only once inserted into the BattleGroundMgr.BGFreeSlotQueue[bgTypeId] deque
bool m_SetDeleteThis; // used for safe deletion of the bg after end / all players leave
- // this variable is not used .... it can be found in many other ways... but to store it in BG object instance is useless
- //uint8 m_BattleGroundType; // 3=BG, 4=arena
- //instead of uint8 (in previous line) is bool used
bool m_IsArena;
uint8 m_Winner; // 0=alliance, 1=horde, 2=none
int32 m_StartDelayTime;
@@ -514,11 +559,10 @@ class BattleGround
bool m_PrematureCountDown;
uint32 m_PrematureCountDownTimer;
char const *m_Name;
-
/* Player lists */
std::vector<uint64> m_ResurrectQueue; // Player GUID
- std::map<uint64, uint8> m_RemovedPlayers; // uint8 is remove type (0 - bgqueue, 1 - bg, 2 - resurrect queue)
+ std::deque<uint64> m_OfflineQueue; // Player GUID
/* Invited counters are useful for player invitation to BG - do not allow, if BG is started to one faction to have 2 more players than another faction */
/* Invited counters will be changed only when removing already invited player from queue, removing player from battleground and inviting player to BG */
@@ -527,15 +571,15 @@ class BattleGround
uint32 m_InvitedHorde;
/* Raid Group */
- Group *m_BgRaids[2]; // 0 - alliance, 1 - horde
+ Group *m_BgRaids[BG_TEAMS_COUNT]; // 0 - alliance, 1 - horde
/* Players count by team */
- uint32 m_PlayersCount[2];
+ uint32 m_PlayersCount[BG_TEAMS_COUNT];
/* Arena team ids by team */
- uint32 m_ArenaTeamIds[2];
+ uint32 m_ArenaTeamIds[BG_TEAMS_COUNT];
- int32 m_ArenaTeamRatingChanges[2];
+ int32 m_ArenaTeamRatingChanges[BG_TEAMS_COUNT];
/* Limits */
uint32 m_LevelMin;
@@ -545,12 +589,12 @@ class BattleGround
uint32 m_MinPlayersPerTeam;
uint32 m_MinPlayers;
- /* Location */
+ /* Start location */
uint32 m_MapId;
- float m_TeamStartLocX[2];
- float m_TeamStartLocY[2];
- float m_TeamStartLocZ[2];
- float m_TeamStartLocO[2];
+ float m_TeamStartLocX[BG_TEAMS_COUNT];
+ float m_TeamStartLocY[BG_TEAMS_COUNT];
+ float m_TeamStartLocZ[BG_TEAMS_COUNT];
+ float m_TeamStartLocO[BG_TEAMS_COUNT];
};
#endif
diff --git a/src/game/BattleGroundAA.cpp b/src/game/BattleGroundAA.cpp
index ad9720ad5fe..2aac2dde3eb 100644
--- a/src/game/BattleGroundAA.cpp
+++ b/src/game/BattleGroundAA.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,10 +21,20 @@
#include "Player.h"
#include "BattleGround.h"
#include "BattleGroundAA.h"
+#include "Language.h"
BattleGroundAA::BattleGroundAA()
{
+ m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
+ m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
+ m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
+ m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
+ //we must set messageIds
+ m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
+ m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
+ m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
}
BattleGroundAA::~BattleGroundAA()
@@ -32,11 +42,19 @@ BattleGroundAA::~BattleGroundAA()
}
-void BattleGroundAA::Update(time_t diff)
+void BattleGroundAA::Update(uint32 diff)
{
BattleGround::Update(diff);
}
+void BattleGroundAA::StartingEventCloseDoors()
+{
+}
+
+void BattleGroundAA::StartingEventOpenDoors()
+{
+}
+
void BattleGroundAA::AddPlayer(Player *plr)
{
BattleGround::AddPlayer(plr);
diff --git a/src/game/BattleGroundAA.h b/src/game/BattleGroundAA.h
index 8a07831eb38..06793ea38e0 100644
--- a/src/game/BattleGroundAA.h
+++ b/src/game/BattleGroundAA.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -37,10 +37,13 @@ class BattleGroundAA : public BattleGround
public:
BattleGroundAA();
~BattleGroundAA();
- void Update(time_t diff);
+ void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
+ virtual void StartingEventCloseDoors();
+ virtual void StartingEventOpenDoors();
+
void RemovePlayer(Player *plr, uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
bool SetupBattleGround();
diff --git a/src/game/BattleGroundAB.cpp b/src/game/BattleGroundAB.cpp
index bbaef37152f..40f60960377 100644
--- a/src/game/BattleGroundAB.cpp
+++ b/src/game/BattleGroundAB.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -23,12 +23,11 @@
#include "BattleGround.h"
#include "BattleGroundAB.h"
#include "Creature.h"
-#include "Chat.h"
#include "ObjectMgr.h"
-#include "MapManager.h"
#include "Language.h"
#include "World.h"
#include "Util.h"
+#include "WorldPacket.h"
// these variables aren't used outside of this file, so declare them only here
uint32 BG_AB_HonorScoreTicks[BG_HONOR_MODE_NUM] = {
@@ -46,102 +45,31 @@ BattleGroundAB::BattleGroundAB()
m_BuffChange = true;
m_BgObjects.resize(BG_AB_OBJECT_MAX);
m_BgCreatures.resize(BG_AB_ALL_NODES_COUNT);
+
+ m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_AB_START_TWO_MINUTES;
+ m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_AB_START_ONE_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_AB_START_HALF_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_AB_HAS_BEGUN;
}
BattleGroundAB::~BattleGroundAB()
{
}
-void BattleGroundAB::Update(time_t diff)
+void BattleGroundAB::Update(uint32 diff)
{
BattleGround::Update(diff);
- if( GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize() )
+ if (GetStatus() == STATUS_IN_PROGRESS)
{
- ModifyStartDelayTime(diff);
-
- if( !(m_Events & 0x01) )
- {
- m_Events |= 0x01;
-
- // setup here, only when at least one player has ported to the map
- if(!SetupBattleGround())
- {
- EndNow();
- return;
- }
-
- sLog.outDebug("Arathi Basin: entering state STATUS_WAIT_JOIN ...");
-
- // despawn banners, auras and buffs
- for (int obj = BG_AB_OBJECT_BANNER_NEUTRAL; obj < BG_AB_DYNAMIC_NODES_COUNT * 8; ++obj)
- SpawnBGObject(obj, RESPAWN_ONE_DAY);
- for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT * 3; ++i)
- SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + i, RESPAWN_ONE_DAY);
-
- // Starting doors
- SpawnBGObject(BG_AB_OBJECT_GATE_A, RESPAWN_IMMEDIATELY);
- SpawnBGObject(BG_AB_OBJECT_GATE_H, RESPAWN_IMMEDIATELY);
- DoorClose(BG_AB_OBJECT_GATE_A);
- DoorClose(BG_AB_OBJECT_GATE_H);
-
- // Starting base spirit guides
- _NodeOccupied(BG_AB_SPIRIT_ALIANCE,ALLIANCE);
- _NodeOccupied(BG_AB_SPIRIT_HORDE,HORDE);
-
- SetStartDelayTime(START_DELAY0);
- }
- // After 1 minute, warning is signalled
- else if( GetStartDelayTime() <= START_DELAY1 && !(m_Events & 0x04) )
- {
- m_Events |= 0x04;
- SendMessageToAll(GetTrinityString(LANG_BG_AB_ONEMINTOSTART));
- }
- // After 1,5 minute, warning is signalled
- else if( GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x08) )
- {
- m_Events |= 0x08;
- SendMessageToAll(GetTrinityString(LANG_BG_AB_HALFMINTOSTART));
- }
- // After 2 minutes, gates OPEN ! x)
- else if( GetStartDelayTime() < 0 && !(m_Events & 0x10) )
- {
- m_Events |= 0x10;
- SendMessageToAll(GetTrinityString(LANG_BG_AB_STARTED));
-
- // spawn neutral banners
- for (int banner = BG_AB_OBJECT_BANNER_NEUTRAL, i = 0; i < 5; banner += 8, ++i)
- SpawnBGObject(banner, RESPAWN_IMMEDIATELY);
- for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
- {
- //randomly select buff to spawn
- uint8 buff = urand(0, 2);
- SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + buff + i * 3, RESPAWN_IMMEDIATELY);
- }
- DoorOpen(BG_AB_OBJECT_GATE_A);
- DoorOpen(BG_AB_OBJECT_GATE_H);
-
- PlaySoundToAll(SOUND_BG_START);
- if(sWorld.getConfig(CONFIG_BG_START_MUSIC))
- PlaySoundToAll(SOUND_BG_START_L70ETC); //MUSIC
- SetStatus(STATUS_IN_PROGRESS);
-
- for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
- if(Player* plr = objmgr.GetPlayer(itr->first))
- plr->RemoveAurasDueToSpell(SPELL_PREPARATION);
- }
-
- }
- else if( GetStatus() == STATUS_IN_PROGRESS )
- {
- int team_points[2] = { 0, 0 };
+ int team_points[BG_TEAMS_COUNT] = { 0, 0 };
for (int node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node)
{
// 3 sec delay to spawn new banner instead previous despawned one
- if( m_BannerTimers[node].timer )
+ if (m_BannerTimers[node].timer)
{
- if( m_BannerTimers[node].timer > diff )
+ if (m_BannerTimers[node].timer > diff)
m_BannerTimers[node].timer -= diff;
else
{
@@ -151,9 +79,9 @@ void BattleGroundAB::Update(time_t diff)
}
// 1-minute to occupy a node from contested state
- if( m_NodeTimers[node] )
+ if (m_NodeTimers[node])
{
- if( m_NodeTimers[node] > diff )
+ if (m_NodeTimers[node] > diff)
m_NodeTimers[node] -= diff;
else
{
@@ -169,72 +97,111 @@ void BattleGroundAB::Update(time_t diff)
_SendNodeUpdate(node);
_NodeOccupied(node,(teamIndex == 0) ? ALLIANCE:HORDE);
// Message to chatlog
- char buf[256];
- uint8 type = (teamIndex == 0) ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE;
- sprintf(buf, GetTrinityString(LANG_BG_AB_NODE_TAKEN), (teamIndex == 0) ? GetTrinityString(LANG_BG_AB_ALLY) : GetTrinityString(LANG_BG_AB_HORDE), _GetNodeName(node));
- WorldPacket data;
- ChatHandler::FillMessageData(&data, NULL, type, LANG_UNIVERSAL, NULL, 0, buf, NULL);
- SendPacketToAll(&data);
- PlaySoundToAll((teamIndex == 0) ? SOUND_NODE_CAPTURED_ALLIANCE : SOUND_NODE_CAPTURED_HORDE);
+
+ if (teamIndex == 0)
+ {
+ // FIXME: team and node names not localized
+ SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN,CHAT_MSG_BG_SYSTEM_ALLIANCE,NULL,LANG_BG_AB_ALLY,_GetNodeNameId(node));
+ PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
+ }
+ else
+ {
+ // FIXME: team and node names not localized
+ SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN,CHAT_MSG_BG_SYSTEM_HORDE,NULL,LANG_BG_AB_HORDE,_GetNodeNameId(node));
+ PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
+ }
}
}
- for (int team = 0; team < 2; ++team)
- if( m_Nodes[node] == team + BG_AB_NODE_TYPE_OCCUPIED )
+ for (int team = 0; team < BG_TEAMS_COUNT; ++team)
+ if (m_Nodes[node] == team + BG_AB_NODE_TYPE_OCCUPIED)
++team_points[team];
}
// Accumulate points
- for (int team = 0; team < 2; ++team)
+ for (int team = 0; team < BG_TEAMS_COUNT; ++team)
{
int points = team_points[team];
- if( !points )
+ if (!points)
continue;
m_lastTick[team] += diff;
- if( m_lastTick[team] > BG_AB_TickIntervals[points] )
+ if (m_lastTick[team] > BG_AB_TickIntervals[points])
{
m_lastTick[team] -= BG_AB_TickIntervals[points];
m_TeamScores[team] += BG_AB_TickPoints[points];
- m_score[team] = m_TeamScores[team];
m_HonorScoreTics[team] += BG_AB_TickPoints[points];
m_ReputationScoreTics[team] += BG_AB_TickPoints[points];
- if( m_ReputationScoreTics[team] >= BG_AB_ReputationScoreTicks[m_HonorMode] )
+ if (m_ReputationScoreTics[team] >= m_ReputationTics)
{
(team == BG_TEAM_ALLIANCE) ? RewardReputationToTeam(509, 10, ALLIANCE) : RewardReputationToTeam(510, 10, HORDE);
- m_ReputationScoreTics[team] -= BG_AB_ReputationScoreTicks[m_HonorMode];
+ m_ReputationScoreTics[team] -= m_ReputationTics;
}
- if( m_HonorScoreTics[team] >= BG_AB_HonorScoreTicks[m_HonorMode] )
+ if (m_HonorScoreTics[team] >= m_HonorTics)
{
- (team == BG_TEAM_ALLIANCE) ? RewardHonorToTeam(20, ALLIANCE) : RewardHonorToTeam(20, HORDE);
- m_HonorScoreTics[team] -= BG_AB_HonorScoreTicks[m_HonorMode];
+ RewardHonorToTeam(GetBonusHonorFromKill(1), (team == BG_TEAM_ALLIANCE) ? ALLIANCE : HORDE);
+ m_HonorScoreTics[team] -= m_HonorTics;
}
- if( !m_IsInformedNearVictory && m_TeamScores[team] > 1800 )
+ if (!m_IsInformedNearVictory && m_TeamScores[team] > BG_AB_WARNING_NEAR_VICTORY_SCORE)
{
- if( team == BG_TEAM_ALLIANCE )
- SendMessageToAll(GetTrinityString(LANG_BG_AB_A_NEAR_VICTORY));
+ if (team == BG_TEAM_ALLIANCE)
+ SendMessageToAll(LANG_BG_AB_A_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
else
- SendMessageToAll(GetTrinityString(LANG_BG_AB_H_NEAR_VICTORY));
- PlaySoundToAll(SOUND_NEAR_VICTORY);
+ SendMessageToAll(LANG_BG_AB_H_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
+ PlaySoundToAll(BG_AB_SOUND_NEAR_VICTORY);
m_IsInformedNearVictory = true;
}
- if( m_TeamScores[team] > 2000 )
- m_TeamScores[team] = 2000;
- if( team == BG_TEAM_ALLIANCE )
+ if (m_TeamScores[team] > BG_AB_MAX_TEAM_SCORE)
+ m_TeamScores[team] = BG_AB_MAX_TEAM_SCORE;
+ if (team == BG_TEAM_ALLIANCE)
UpdateWorldState(BG_AB_OP_RESOURCES_ALLY, m_TeamScores[team]);
- if( team == BG_TEAM_HORDE )
+ if (team == BG_TEAM_HORDE)
UpdateWorldState(BG_AB_OP_RESOURCES_HORDE, m_TeamScores[team]);
}
}
// Test win condition
- if( m_TeamScores[BG_TEAM_ALLIANCE] >= 2000 )
+ if (m_TeamScores[BG_TEAM_ALLIANCE] >= BG_AB_MAX_TEAM_SCORE)
EndBattleGround(ALLIANCE);
- if( m_TeamScores[BG_TEAM_HORDE] >= 2000 )
+ if (m_TeamScores[BG_TEAM_HORDE] >= BG_AB_MAX_TEAM_SCORE)
EndBattleGround(HORDE);
}
}
+void BattleGroundAB::StartingEventCloseDoors()
+{
+ // despawn banners, auras and buffs
+ for (int obj = BG_AB_OBJECT_BANNER_NEUTRAL; obj < BG_AB_DYNAMIC_NODES_COUNT * 8; ++obj)
+ SpawnBGObject(obj, RESPAWN_ONE_DAY);
+ for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT * 3; ++i)
+ SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + i, RESPAWN_ONE_DAY);
+
+ // Starting doors
+ DoorClose(BG_AB_OBJECT_GATE_A);
+ DoorClose(BG_AB_OBJECT_GATE_H);
+ SpawnBGObject(BG_AB_OBJECT_GATE_A, RESPAWN_IMMEDIATELY);
+ SpawnBGObject(BG_AB_OBJECT_GATE_H, RESPAWN_IMMEDIATELY);
+
+ // Starting base spirit guides
+ _NodeOccupied(BG_AB_SPIRIT_ALIANCE,ALLIANCE);
+ _NodeOccupied(BG_AB_SPIRIT_HORDE,HORDE);
+}
+
+void BattleGroundAB::StartingEventOpenDoors()
+{
+ // spawn neutral banners
+ for (int banner = BG_AB_OBJECT_BANNER_NEUTRAL, i = 0; i < 5; banner += 8, ++i)
+ SpawnBGObject(banner, RESPAWN_IMMEDIATELY);
+ for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
+ {
+ //randomly select buff to spawn
+ uint8 buff = urand(0, 2);
+ SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + buff + i * 3, RESPAWN_IMMEDIATELY);
+ }
+ DoorOpen(BG_AB_OBJECT_GATE_A);
+ DoorOpen(BG_AB_OBJECT_GATE_H);
+}
+
void BattleGroundAB::AddPlayer(Player *plr)
{
BattleGround::AddPlayer(plr);
@@ -251,19 +218,19 @@ void BattleGroundAB::RemovePlayer(Player * /*plr*/, uint64 /*guid*/)
void BattleGroundAB::HandleAreaTrigger(Player *Source, uint32 Trigger)
{
- if( GetStatus() != STATUS_IN_PROGRESS )
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
switch(Trigger)
{
case 3948: // Arathi Basin Alliance Exit.
- if( Source->GetTeam() != ALLIANCE )
+ if (Source->GetTeam() != ALLIANCE)
Source->GetSession()->SendAreaTriggerMessage("Only The Alliance can use that portal");
else
Source->LeaveBattleground();
break;
case 3949: // Arathi Basin Horde Exit.
- if( Source->GetTeam() != HORDE )
+ if (Source->GetTeam() != HORDE)
Source->GetSession()->SendAreaTriggerMessage("Only The Horde can use that portal");
else
Source->LeaveBattleground();
@@ -288,7 +255,7 @@ void BattleGroundAB::HandleAreaTrigger(Player *Source, uint32 Trigger)
void BattleGroundAB::_CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool delay)
{
// Just put it into the queue
- if( delay )
+ if (delay)
{
m_BannerTimers[node].timer = 2000;
m_BannerTimers[node].type = type;
@@ -301,7 +268,7 @@ void BattleGroundAB::_CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool
SpawnBGObject(obj, RESPAWN_IMMEDIATELY);
// handle aura with banner
- if( !type )
+ if (!type)
return;
obj = node * 8 + ((type == BG_AB_NODE_TYPE_OCCUPIED) ? (5 + teamIndex) : 7);
SpawnBGObject(obj, RESPAWN_IMMEDIATELY);
@@ -313,30 +280,25 @@ void BattleGroundAB::_DelBanner(uint8 node, uint8 type, uint8 teamIndex)
SpawnBGObject(obj, RESPAWN_ONE_DAY);
// handle aura with banner
- if( !type )
+ if (!type)
return;
obj = node * 8 + ((type == BG_AB_NODE_TYPE_OCCUPIED) ? (5 + teamIndex) : 7);
SpawnBGObject(obj, RESPAWN_ONE_DAY);
}
-const char* BattleGroundAB::_GetNodeName(uint8 node)
+int32 BattleGroundAB::_GetNodeNameId(uint8 node)
{
switch (node)
{
- case BG_AB_NODE_STABLES:
- return GetTrinityString(LANG_BG_AB_NODE_STABLES);
- case BG_AB_NODE_BLACKSMITH:
- return GetTrinityString(LANG_BG_AB_NODE_BLACKSMITH);
- case BG_AB_NODE_FARM:
- return GetTrinityString(LANG_BG_AB_NODE_FARM);
- case BG_AB_NODE_LUMBER_MILL:
- return GetTrinityString(LANG_BG_AB_NODE_LUMBER_MILL);
- case BG_AB_NODE_GOLD_MINE:
- return GetTrinityString(LANG_BG_AB_NODE_GOLD_MINE);
+ case BG_AB_NODE_STABLES: return LANG_BG_AB_NODE_STABLES;
+ case BG_AB_NODE_BLACKSMITH: return LANG_BG_AB_NODE_BLACKSMITH;
+ case BG_AB_NODE_FARM: return LANG_BG_AB_NODE_FARM;
+ case BG_AB_NODE_LUMBER_MILL:return LANG_BG_AB_NODE_LUMBER_MILL;
+ case BG_AB_NODE_GOLD_MINE: return LANG_BG_AB_NODE_GOLD_MINE;
default:
ASSERT(0);
}
- return "";
+ return 0;
}
void BattleGroundAB::FillInitialWorldStates(WorldPacket& data)
@@ -355,9 +317,9 @@ void BattleGroundAB::FillInitialWorldStates(WorldPacket& data)
// How many bases each team owns
uint8 ally = 0, horde = 0;
for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node)
- if( m_Nodes[node] == BG_AB_NODE_STATUS_ALLY_OCCUPIED )
+ if (m_Nodes[node] == BG_AB_NODE_STATUS_ALLY_OCCUPIED)
++ally;
- else if( m_Nodes[node] == BG_AB_NODE_STATUS_HORDE_OCCUPIED )
+ else if (m_Nodes[node] == BG_AB_NODE_STATUS_HORDE_OCCUPIED)
++horde;
data << uint32(BG_AB_OP_OCCUPIED_BASES_ALLY) << uint32(ally);
@@ -365,7 +327,7 @@ void BattleGroundAB::FillInitialWorldStates(WorldPacket& data)
// Team scores
data << uint32(BG_AB_OP_RESOURCES_MAX) << uint32(BG_AB_MAX_TEAM_SCORE);
- data << uint32(BG_AB_OP_RESOURCES_WARNING) << uint32(BG_AB_WARNING_SCORE);
+ data << uint32(BG_AB_OP_RESOURCES_WARNING) << uint32(BG_AB_WARNING_NEAR_VICTORY_SCORE);
data << uint32(BG_AB_OP_RESOURCES_ALLY) << uint32(m_TeamScores[BG_TEAM_ALLIANCE]);
data << uint32(BG_AB_OP_RESOURCES_HORDE) << uint32(m_TeamScores[BG_TEAM_HORDE]);
@@ -378,7 +340,7 @@ void BattleGroundAB::_SendNodeUpdate(uint8 node)
// Send node owner state update to refresh map icons on client
const uint8 plusArray[] = {0, 2, 3, 0, 1};
- if( m_prevNodes[node] )
+ if (m_prevNodes[node])
UpdateWorldState(BG_AB_OP_NODESTATES[node] + plusArray[m_prevNodes[node]], 0);
else
UpdateWorldState(BG_AB_OP_NODEICONS[node], 0);
@@ -388,9 +350,9 @@ void BattleGroundAB::_SendNodeUpdate(uint8 node)
// How many bases each team owns
uint8 ally = 0, horde = 0;
for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
- if( m_Nodes[i] == BG_AB_NODE_STATUS_ALLY_OCCUPIED )
+ if (m_Nodes[i] == BG_AB_NODE_STATUS_ALLY_OCCUPIED)
++ally;
- else if( m_Nodes[i] == BG_AB_NODE_STATUS_HORDE_OCCUPIED )
+ else if (m_Nodes[i] == BG_AB_NODE_STATUS_HORDE_OCCUPIED)
++horde;
UpdateWorldState(BG_AB_OP_OCCUPIED_BASES_ALLY, ally);
@@ -399,46 +361,47 @@ void BattleGroundAB::_SendNodeUpdate(uint8 node)
void BattleGroundAB::_NodeOccupied(uint8 node,Team team)
{
- if( !AddSpiritGuide(node, BG_AB_SpiritGuidePos[node][0], BG_AB_SpiritGuidePos[node][1], BG_AB_SpiritGuidePos[node][2], BG_AB_SpiritGuidePos[node][3], team) )
+ if (!AddSpiritGuide(node, BG_AB_SpiritGuidePos[node][0], BG_AB_SpiritGuidePos[node][1], BG_AB_SpiritGuidePos[node][2], BG_AB_SpiritGuidePos[node][3], team))
sLog.outError("Failed to spawn spirit guide! point: %u, team: %u,", node, team);
// SpawnBGCreature(node,RESPAWN_IMMEDIATELY);
uint8 capturedNodes = 0;
for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
{
- if( m_Nodes[node] == GetTeamIndexByTeamId(team) + BG_AB_NODE_TYPE_OCCUPIED && !m_NodeTimers[i])
+ if (m_Nodes[node] == GetTeamIndexByTeamId(team) + BG_AB_NODE_TYPE_OCCUPIED && !m_NodeTimers[i])
++capturedNodes;
}
- if(capturedNodes >= 5)
+ if (capturedNodes >= 5)
CastSpellOnTeam(SPELL_AB_QUEST_REWARD_5_BASES, team);
- if(capturedNodes >= 4)
+ if (capturedNodes >= 4)
CastSpellOnTeam(SPELL_AB_QUEST_REWARD_4_BASES, team);
}
void BattleGroundAB::_NodeDeOccupied(uint8 node)
{
- if( node >= BG_AB_DYNAMIC_NODES_COUNT)
+ if (node >= BG_AB_DYNAMIC_NODES_COUNT)
return;
// Those who are waiting to resurrect at this node are taken to the closest own node's graveyard
std::vector<uint64> ghost_list = m_ReviveQueue[m_BgCreatures[node]];
- if( !ghost_list.empty() )
+ if (!ghost_list.empty())
{
WorldSafeLocsEntry const *ClosestGrave = NULL;
- Player *plr;
- for (std::vector<uint64>::iterator itr = ghost_list.begin(); itr != ghost_list.end(); ++itr)
+ for (std::vector<uint64>::const_iterator itr = ghost_list.begin(); itr != ghost_list.end(); ++itr)
{
- plr = objmgr.GetPlayer(*ghost_list.begin());
- if( !plr )
+ Player* plr = objmgr.GetPlayer(*itr);
+ if (!plr)
continue;
- if( !ClosestGrave )
- ClosestGrave = GetClosestGraveYard(plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), plr->GetTeam());
- plr->TeleportTo(GetMapId(), ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, plr->GetOrientation());
+ if (!ClosestGrave) // cache
+ ClosestGrave = GetClosestGraveYard(plr);
+
+ if (ClosestGrave)
+ plr->TeleportTo(GetMapId(), ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, plr->GetOrientation());
}
}
- if( m_BgCreatures[node] )
+ if (m_BgCreatures[node])
DelCreature(node);
// buff object isn't despawned
@@ -447,7 +410,7 @@ void BattleGroundAB::_NodeDeOccupied(uint8 node)
/* Invoked if a player used a banner as a gameobject */
void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*target_obj*/)
{
- if( GetStatus() != STATUS_IN_PROGRESS )
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
uint8 node = BG_AB_NODE_STABLES;
@@ -458,7 +421,7 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
obj=HashMapHolder<GameObject>::Find(m_BgObjects[node*8+BG_AB_OBJECT_AURA_CONTESTED]);
}
- if( node == BG_AB_DYNAMIC_NODES_COUNT)
+ if (node == BG_AB_DYNAMIC_NODES_COUNT)
{
// this means our player isn't close to any of banners - maybe cheater ??
return;
@@ -466,18 +429,14 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
uint8 teamIndex = GetTeamIndexByTeamId(source->GetTeam());
- // Message to chatlog
- char buf[256];
- uint8 type = (teamIndex == 0) ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE;
-
// Check if player really could use this banner, not cheated
- if( !(m_Nodes[node] == 0 || teamIndex == m_Nodes[node]%2) )
+ if (!(m_Nodes[node] == 0 || teamIndex == m_Nodes[node]%2))
return;
source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
uint32 sound = 0;
// If node is neutral, change to contested
- if( m_Nodes[node] == BG_AB_NODE_TYPE_NEUTRAL )
+ if (m_Nodes[node] == BG_AB_NODE_TYPE_NEUTRAL)
{
UpdatePlayerScore(source, SCORE_BASES_ASSAULTED, 1);
m_prevNodes[node] = m_Nodes[node];
@@ -488,14 +447,20 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
_CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true);
_SendNodeUpdate(node);
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
- sprintf(buf, GetTrinityString(LANG_BG_AB_NODE_CLAIMED), _GetNodeName(node), (teamIndex == 0) ? GetTrinityString(LANG_BG_AB_ALLY) : GetTrinityString(LANG_BG_AB_HORDE));
- sound = SOUND_NODE_CLAIMED;
+
+ // FIXME: team and node names not localized
+ if (teamIndex == 0)
+ SendMessage2ToAll(LANG_BG_AB_NODE_CLAIMED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node), LANG_BG_AB_ALLY);
+ else
+ SendMessage2ToAll(LANG_BG_AB_NODE_CLAIMED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node), LANG_BG_AB_HORDE);
+
+ sound = BG_AB_SOUND_NODE_CLAIMED;
}
// If node is contested
- else if( (m_Nodes[node] == BG_AB_NODE_STATUS_ALLY_CONTESTED) || (m_Nodes[node] == BG_AB_NODE_STATUS_HORDE_CONTESTED) )
+ else if ((m_Nodes[node] == BG_AB_NODE_STATUS_ALLY_CONTESTED) || (m_Nodes[node] == BG_AB_NODE_STATUS_HORDE_CONTESTED))
{
// If last state is NOT occupied, change node to enemy-contested
- if( m_prevNodes[node] < BG_AB_NODE_TYPE_OCCUPIED )
+ if (m_prevNodes[node] < BG_AB_NODE_TYPE_OCCUPIED)
{
UpdatePlayerScore(source, SCORE_BASES_ASSAULTED, 1);
m_prevNodes[node] = m_Nodes[node];
@@ -506,7 +471,12 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
_CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true);
_SendNodeUpdate(node);
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
- sprintf(buf, GetTrinityString(LANG_BG_AB_NODE_ASSAULTED), _GetNodeName(node));
+
+ // FIXME: node names not localized
+ if (teamIndex == 0)
+ SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
+ else
+ SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
}
// If contested, change back to occupied
else
@@ -521,9 +491,14 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
_SendNodeUpdate(node);
m_NodeTimers[node] = 0;
_NodeOccupied(node,(teamIndex == 0) ? ALLIANCE:HORDE);
- sprintf(buf, GetTrinityString(LANG_BG_AB_NODE_DEFENDED), _GetNodeName(node));
+
+ // FIXME: node names not localized
+ if (teamIndex == 0)
+ SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
+ else
+ SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
}
- sound = (teamIndex == 0) ? SOUND_NODE_ASSAULTED_ALLIANCE : SOUND_NODE_ASSAULTED_HORDE;
+ sound = (teamIndex == 0) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE;
}
// If node is occupied, change to enemy-contested
else
@@ -538,18 +513,24 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
_SendNodeUpdate(node);
_NodeDeOccupied(node);
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
- sprintf(buf, GetTrinityString(LANG_BG_AB_NODE_ASSAULTED), _GetNodeName(node));
- sound = (teamIndex == 0) ? SOUND_NODE_ASSAULTED_ALLIANCE : SOUND_NODE_ASSAULTED_HORDE;
+
+ // FIXME: node names not localized
+ if (teamIndex == 0)
+ SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
+ else
+ SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
+
+ sound = (teamIndex == 0) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE;
}
- WorldPacket data;
- ChatHandler::FillMessageData(&data, source->GetSession(), type, LANG_UNIVERSAL, NULL, source->GetGUID(), buf, NULL);
- SendPacketToAll(&data);
+
// If node is occupied again, send "X has taken the Y" msg.
- if( m_Nodes[node] >= BG_AB_NODE_TYPE_OCCUPIED )
+ if (m_Nodes[node] >= BG_AB_NODE_TYPE_OCCUPIED)
{
- sprintf(buf, GetTrinityString(LANG_BG_AB_NODE_TAKEN), (teamIndex == 0) ? GetTrinityString(LANG_BG_AB_ALLY) : GetTrinityString(LANG_BG_AB_HORDE), _GetNodeName(node));
- ChatHandler::FillMessageData(&data, NULL, type, LANG_UNIVERSAL, NULL, 0, buf, NULL);
- SendPacketToAll(&data);
+ // FIXME: team and node names not localized
+ if (teamIndex == 0)
+ SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN,CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL, LANG_BG_AB_ALLY, _GetNodeNameId(node));
+ else
+ SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN,CHAT_MSG_BG_SYSTEM_HORDE, NULL, LANG_BG_AB_HORDE, _GetNodeNameId(node));
}
PlaySoundToAll(sound);
}
@@ -558,7 +539,7 @@ bool BattleGroundAB::SetupBattleGround()
{
for (int i = 0 ; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
{
- if( !AddObject(BG_AB_OBJECT_BANNER_NEUTRAL + 8*i,BG_AB_OBJECTID_NODE_BANNER_0 + i,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY)
+ if (!AddObject(BG_AB_OBJECT_BANNER_NEUTRAL + 8*i,BG_AB_OBJECTID_NODE_BANNER_0 + i,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY)
|| !AddObject(BG_AB_OBJECT_BANNER_CONT_A + 8*i,BG_AB_OBJECTID_BANNER_CONT_A,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY)
|| !AddObject(BG_AB_OBJECT_BANNER_CONT_H + 8*i,BG_AB_OBJECTID_BANNER_CONT_H,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY)
|| !AddObject(BG_AB_OBJECT_BANNER_ALLY + 8*i,BG_AB_OBJECTID_BANNER_A,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY)
@@ -572,7 +553,7 @@ bool BattleGroundAB::SetupBattleGround()
return false;
}
}
- if( !AddObject(BG_AB_OBJECT_GATE_A,BG_AB_OBJECTID_GATE_A,BG_AB_DoorPositions[0][0],BG_AB_DoorPositions[0][1],BG_AB_DoorPositions[0][2],BG_AB_DoorPositions[0][3],BG_AB_DoorPositions[0][4],BG_AB_DoorPositions[0][5],BG_AB_DoorPositions[0][6],BG_AB_DoorPositions[0][7],RESPAWN_IMMEDIATELY)
+ if (!AddObject(BG_AB_OBJECT_GATE_A,BG_AB_OBJECTID_GATE_A,BG_AB_DoorPositions[0][0],BG_AB_DoorPositions[0][1],BG_AB_DoorPositions[0][2],BG_AB_DoorPositions[0][3],BG_AB_DoorPositions[0][4],BG_AB_DoorPositions[0][5],BG_AB_DoorPositions[0][6],BG_AB_DoorPositions[0][7],RESPAWN_IMMEDIATELY)
|| !AddObject(BG_AB_OBJECT_GATE_H,BG_AB_OBJECTID_GATE_H,BG_AB_DoorPositions[1][0],BG_AB_DoorPositions[1][1],BG_AB_DoorPositions[1][2],BG_AB_DoorPositions[1][3],BG_AB_DoorPositions[1][4],BG_AB_DoorPositions[1][5],BG_AB_DoorPositions[1][6],BG_AB_DoorPositions[1][7],RESPAWN_IMMEDIATELY)
)
{
@@ -582,7 +563,7 @@ bool BattleGroundAB::SetupBattleGround()
//buffs
for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
{
- if( !AddObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + 3 * i, Buff_Entries[0], BG_AB_BuffPositions[i][0], BG_AB_BuffPositions[i][1], BG_AB_BuffPositions[i][2], BG_AB_BuffPositions[i][3], 0, 0, sin(BG_AB_BuffPositions[i][3]/2), cos(BG_AB_BuffPositions[i][3]/2), RESPAWN_ONE_DAY)
+ if (!AddObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + 3 * i, Buff_Entries[0], BG_AB_BuffPositions[i][0], BG_AB_BuffPositions[i][1], BG_AB_BuffPositions[i][2], BG_AB_BuffPositions[i][3], 0, 0, sin(BG_AB_BuffPositions[i][3]/2), cos(BG_AB_BuffPositions[i][3]/2), RESPAWN_ONE_DAY)
|| !AddObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + 3 * i + 1, Buff_Entries[1], BG_AB_BuffPositions[i][0], BG_AB_BuffPositions[i][1], BG_AB_BuffPositions[i][2], BG_AB_BuffPositions[i][3], 0, 0, sin(BG_AB_BuffPositions[i][3]/2), cos(BG_AB_BuffPositions[i][3]/2), RESPAWN_ONE_DAY)
|| !AddObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + 3 * i + 2, Buff_Entries[2], BG_AB_BuffPositions[i][0], BG_AB_BuffPositions[i][1], BG_AB_BuffPositions[i][2], BG_AB_BuffPositions[i][3], 0, 0, sin(BG_AB_BuffPositions[i][3]/2), cos(BG_AB_BuffPositions[i][3]/2), RESPAWN_ONE_DAY)
)
@@ -592,8 +573,11 @@ bool BattleGroundAB::SetupBattleGround()
return true;
}
-void BattleGroundAB::ResetBGSubclass()
+void BattleGroundAB::Reset()
{
+ //call parent's class reset
+ BattleGround::Reset();
+
m_TeamScores[BG_TEAM_ALLIANCE] = 0;
m_TeamScores[BG_TEAM_HORDE] = 0;
m_lastTick[BG_TEAM_ALLIANCE] = 0;
@@ -603,6 +587,10 @@ void BattleGroundAB::ResetBGSubclass()
m_ReputationScoreTics[BG_TEAM_ALLIANCE] = 0;
m_ReputationScoreTics[BG_TEAM_HORDE] = 0;
m_IsInformedNearVictory = false;
+ bool isBGWeekend = false; //TODO FIXME - call sBattleGroundMgr.IsBGWeekend(m_TypeID); - you must also implement that call!
+ m_HonorTics = (isBGWeekend) ? BG_AB_ABBGWeekendHonorTicks : BG_AB_NotABBGWeekendHonorTicks;
+ m_ReputationTics = (isBGWeekend) ? BG_AB_ABBGWeekendReputationTicks : BG_AB_NotABBGWeekendReputationTicks;
+
for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
{
m_Nodes[i] = 0;
@@ -612,32 +600,49 @@ void BattleGroundAB::ResetBGSubclass()
}
for (uint8 i = 0; i < BG_AB_ALL_NODES_COUNT; ++i)
- if(m_BgCreatures[i])
+ if (m_BgCreatures[i])
DelCreature(i);
}
-WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(float x, float y, float /*z*/, uint32 team)
+void BattleGroundAB::EndBattleGround(uint32 winner)
{
- uint8 teamIndex = GetTeamIndexByTeamId(team);
+ //win reward
+ if (winner == ALLIANCE)
+ RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
+ if (winner == HORDE)
+ RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
+ //complete map_end rewards (even if no team wins)
+ RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
+ RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
+
+ BattleGround::EndBattleGround(winner);
+}
+
+WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(Player* player)
+{
+ uint8 teamIndex = GetTeamIndexByTeamId(player->GetTeam());
// Is there any occupied node for this team?
std::vector<uint8> nodes;
for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
- if( m_Nodes[i] == teamIndex + 3 )
+ if (m_Nodes[i] == teamIndex + 3)
nodes.push_back(i);
WorldSafeLocsEntry const* good_entry = NULL;
// If so, select the closest node to place ghost on
- if( !nodes.empty() )
+ if (!nodes.empty())
{
+ float plr_x = player->GetPositionX();
+ float plr_y = player->GetPositionY();
+
float mindist = 999999.0f;
for (uint8 i = 0; i < nodes.size(); ++i)
{
WorldSafeLocsEntry const*entry = sWorldSafeLocsStore.LookupEntry( BG_AB_GraveyardIds[nodes[i]] );
- if( !entry )
+ if (!entry)
continue;
- float dist = (entry->x - x)*(entry->x - x)+(entry->y - y)*(entry->y - y);
- if( mindist > dist )
+ float dist = (entry->x - plr_x)*(entry->x - plr_x)+(entry->y - plr_y)*(entry->y - plr_y);
+ if (mindist > dist)
{
mindist = dist;
good_entry = entry;
@@ -646,7 +651,7 @@ WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(float x, float y,
nodes.clear();
}
// If not, place ghost on starting location
- if( !good_entry )
+ if (!good_entry)
good_entry = sWorldSafeLocsStore.LookupEntry( BG_AB_GraveyardIds[teamIndex+5] );
return good_entry;
diff --git a/src/game/BattleGroundAB.h b/src/game/BattleGroundAB.h
index 3fcea59c8e8..1c4a6d3b738 100644
--- a/src/game/BattleGroundAB.h
+++ b/src/game/BattleGroundAB.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -77,17 +77,17 @@ enum BG_AB_NodeObjectId
enum BG_AB_ObjectType
{
// for all 5 node points 8*5=40 objects
- BG_AB_OBJECT_BANNER_NEUTRAL = 0,
- BG_AB_OBJECT_BANNER_CONT_A = 1,
- BG_AB_OBJECT_BANNER_CONT_H = 2,
- BG_AB_OBJECT_BANNER_ALLY = 3,
- BG_AB_OBJECT_BANNER_HORDE = 4,
- BG_AB_OBJECT_AURA_ALLY = 5,
- BG_AB_OBJECT_AURA_HORDE = 6,
- BG_AB_OBJECT_AURA_CONTESTED = 7,
+ BG_AB_OBJECT_BANNER_NEUTRAL = 0,
+ BG_AB_OBJECT_BANNER_CONT_A = 1,
+ BG_AB_OBJECT_BANNER_CONT_H = 2,
+ BG_AB_OBJECT_BANNER_ALLY = 3,
+ BG_AB_OBJECT_BANNER_HORDE = 4,
+ BG_AB_OBJECT_AURA_ALLY = 5,
+ BG_AB_OBJECT_AURA_HORDE = 6,
+ BG_AB_OBJECT_AURA_CONTESTED = 7,
//gates
- BG_AB_OBJECT_GATE_A = 40,
- BG_AB_OBJECT_GATE_H = 41,
+ BG_AB_OBJECT_GATE_A = 40,
+ BG_AB_OBJECT_GATE_H = 41,
//buffs
BG_AB_OBJECT_SPEEDBUFF_STABLES = 42,
BG_AB_OBJECT_REGENBUFF_STABLES = 43,
@@ -130,8 +130,8 @@ enum BG_AB_Timers
enum BG_AB_Score
{
- BG_AB_MAX_TEAM_SCORE = 2000,
- BG_AB_WARNING_SCORE = 1800
+ BG_AB_WARNING_NEAR_VICTORY_SCORE = 1800,
+ BG_AB_MAX_TEAM_SCORE = 2000
};
/* do NOT change the order, else wrong behaviour */
@@ -164,14 +164,19 @@ enum BG_AB_NodeStatus
enum BG_AB_Sounds
{
- SOUND_NODE_CLAIMED = 8192,
- SOUND_NODE_CAPTURED_ALLIANCE = 8173,
- SOUND_NODE_CAPTURED_HORDE = 8213,
- SOUND_NODE_ASSAULTED_ALLIANCE = 8174,
- SOUND_NODE_ASSAULTED_HORDE = 8212,
- SOUND_NEAR_VICTORY = 8456
+ BG_AB_SOUND_NODE_CLAIMED = 8192,
+ BG_AB_SOUND_NODE_CAPTURED_ALLIANCE = 8173,
+ BG_AB_SOUND_NODE_CAPTURED_HORDE = 8213,
+ BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE = 8212,
+ BG_AB_SOUND_NODE_ASSAULTED_HORDE = 8174,
+ BG_AB_SOUND_NEAR_VICTORY = 8456
};
+#define BG_AB_NotABBGWeekendHonorTicks 330
+#define BG_AB_ABBGWeekendHonorTicks 200
+#define BG_AB_NotABBGWeekendReputationTicks 200
+#define BG_AB_ABBGWeekendReputationTicks 150
+
// x, y, z, o
const float BG_AB_NodePositions[BG_AB_DYNAMIC_NODES_COUNT][4] = {
{1166.785f, 1200.132f, -56.70859f, 0.9075713f}, // stables
@@ -238,13 +243,16 @@ class BattleGroundAB : public BattleGround
BattleGroundAB();
~BattleGroundAB();
- void Update(time_t diff);
+ void Update(uint32 diff);
void AddPlayer(Player *plr);
+ virtual void StartingEventCloseDoors();
+ virtual void StartingEventOpenDoors();
void RemovePlayer(Player *plr,uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
virtual bool SetupBattleGround();
- virtual void ResetBGSubclass();
- virtual WorldSafeLocsEntry const* GetClosestGraveYard(float x, float y, float z, uint32 team);
+ virtual void Reset();
+ void EndBattleGround(uint32 winner);
+ virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
/* Scorekeeping */
virtual void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
@@ -265,7 +273,7 @@ class BattleGroundAB : public BattleGround
void _NodeOccupied(uint8 node,Team team);
void _NodeDeOccupied(uint8 node);
- const char* _GetNodeName(uint8 node);
+ int32 _GetNodeNameId(uint8 node);
/* Nodes info:
0: neutral
@@ -273,15 +281,19 @@ class BattleGroundAB : public BattleGround
2: horde contested
3: ally occupied
4: horde occupied */
- uint8 m_Nodes[BG_AB_DYNAMIC_NODES_COUNT];
- uint8 m_prevNodes[BG_AB_DYNAMIC_NODES_COUNT];
- BG_AB_BannerTimer m_BannerTimers[BG_AB_DYNAMIC_NODES_COUNT];
- int32 m_NodeTimers[BG_AB_DYNAMIC_NODES_COUNT];
- uint32 m_TeamScores[2];
- uint32 m_lastTick[2];
- uint32 m_HonorScoreTics[2];
- uint32 m_ReputationScoreTics[2];
- bool m_IsInformedNearVictory;
+ uint8 m_Nodes[BG_AB_DYNAMIC_NODES_COUNT];
+ uint8 m_prevNodes[BG_AB_DYNAMIC_NODES_COUNT];
+ BG_AB_BannerTimer m_BannerTimers[BG_AB_DYNAMIC_NODES_COUNT];
+ uint32 m_NodeTimers[BG_AB_DYNAMIC_NODES_COUNT];
+ uint32 m_TeamScores[BG_TEAMS_COUNT];
+ uint32 m_lastTick[BG_TEAMS_COUNT];
+ uint32 m_HonorScoreTics[BG_TEAMS_COUNT];
+ uint32 m_ReputationScoreTics[BG_TEAMS_COUNT];
+ bool m_IsInformedNearVictory;
+ uint32 m_HonorTics;
+ uint32 m_ReputationTics;
+
+
};
#endif
diff --git a/src/game/BattleGroundAV.cpp b/src/game/BattleGroundAV.cpp
index 6086d0be441..bc0b50d21f0 100644
--- a/src/game/BattleGroundAV.cpp
+++ b/src/game/BattleGroundAV.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,21 +21,23 @@
#include "Player.h"
#include "BattleGround.h"
#include "BattleGroundAV.h"
-#include "Creature.h"
-#include "Chat.h"
-#include "Object.h"
-#include "ObjectMgr.h"
-#include "ObjectAccessor.h"
-#include "MapManager.h"
#include "Language.h"
#include "SpellAuras.h"
#include "Formulas.h"
+#include "WorldPacket.h"
+#include "ObjectMgr.h"
+#include "GameObject.h"
BattleGroundAV::BattleGroundAV()
{
-
m_BgObjects.resize(BG_AV_OBJECT_MAX);
m_BgCreatures.resize(AV_CPLACE_MAX+AV_STATICCPLACE_MAX);
+
+ //TODO FIX ME!
+ m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_EY_START_TWO_MINUTES;
+ m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_EY_START_ONE_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_EY_START_HALF_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_EY_HAS_BEGUN;
}
BattleGroundAV::~BattleGroundAV()
@@ -229,8 +231,6 @@ void BattleGroundAV::UpdateScore(uint16 team, int16 points )
uint8 teamindex = GetTeamIndexByTeamId(team); //0=ally 1=horde
m_Team_Scores[teamindex] += points;
- m_score[teamindex] = m_Team_Scores[teamindex];
-
UpdateWorldState(((teamindex==BG_TEAM_HORDE)?AV_Horde_Score:AV_Alliance_Score), m_Team_Scores[teamindex]);
if( points < 0)
{
@@ -241,7 +241,7 @@ void BattleGroundAV::UpdateScore(uint16 team, int16 points )
}
else if(!m_IsInformedNearVictory[teamindex] && m_Team_Scores[teamindex] < SEND_MSG_NEAR_LOSE)
{
- SendMessageToAll(GetTrinityString((teamindex==BG_TEAM_HORDE)?LANG_BG_AV_H_NEAR_LOSE:LANG_BG_AV_A_NEAR_LOSE));
+ SendMessageToAll(teamindex==BG_TEAM_HORDE?LANG_BG_AV_H_NEAR_LOSE:LANG_BG_AV_A_NEAR_LOSE, teamindex==BG_TEAM_HORDE ? CHAT_MSG_BG_SYSTEM_HORDE : CHAT_MSG_BG_SYSTEM_ALLIANCE);
PlaySoundToAll(AV_SOUND_NEAR_VICTORY);
m_IsInformedNearVictory[teamindex] = true;
}
@@ -296,7 +296,7 @@ Creature* BattleGroundAV::AddAVCreature(uint16 cinfoid, uint16 type )
return creature;
}
-void BattleGroundAV::Update(time_t diff)
+void BattleGroundAV::Update(uint32 diff)
{
BattleGround::Update(diff);
if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
@@ -368,19 +368,19 @@ void BattleGroundAV::Update(time_t diff)
DoorClose(BG_AV_OBJECT_DOOR_A);
DoorClose(BG_AV_OBJECT_DOOR_H);
- SetStartDelayTime(START_DELAY0);
+ SetStartDelayTime(BG_START_DELAY_2M);
}
// After 1 minute, warning is signalled
- else if (GetStartDelayTime() <= START_DELAY1 && !(m_Events & 0x04))
+ else if (GetStartDelayTime() <= BG_START_DELAY_1M && !(m_Events & 0x04))
{
m_Events |= 0x04;
- SendMessageToAll(GetTrinityString(LANG_BG_AV_ONEMINTOSTART));
+ SendMessageToAll(LANG_BG_AV_ONEMINTOSTART, CHAT_MSG_BG_SYSTEM_NEUTRAL);
}
// After 1,5 minute, warning is signalled
- else if (GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x08))
+ else if (GetStartDelayTime() <= BG_START_DELAY_1M + BG_START_DELAY_30S && !(m_Events & 0x08))
{
m_Events |= 0x08;
- SendMessageToAll(GetTrinityString(LANG_BG_AV_HALFMINTOSTART));
+ SendMessageToAll(LANG_BG_AV_HALFMINTOSTART, CHAT_MSG_BG_SYSTEM_NEUTRAL);
}
// After 2 minutes, gates OPEN ! x)
else if (GetStartDelayTime() <= 0 && !(m_Events & 0x10))
@@ -389,7 +389,7 @@ void BattleGroundAV::Update(time_t diff)
UpdateWorldState(AV_SHOW_A_SCORE, 1);
m_Events |= 0x10;
- SendMessageToAll(GetTrinityString(LANG_BG_AV_STARTED));
+ SendMessageToAll(LANG_BG_AV_STARTED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
PlaySoundToAll(SOUND_BG_START);
SetStatus(STATUS_IN_PROGRESS);
@@ -467,6 +467,14 @@ void BattleGroundAV::Update(time_t diff)
}
}
+void BattleGroundAV::StartingEventCloseDoors()
+{
+}
+
+void BattleGroundAV::StartingEventOpenDoors()
+{
+}
+
void BattleGroundAV::AddPlayer(Player *plr)
{
BattleGround::AddPlayer(plr);
@@ -535,7 +543,7 @@ void BattleGroundAV::RemovePlayer(Player* plr,uint64 /*guid*/)
void BattleGroundAV::HandleAreaTrigger(Player *Source, uint32 Trigger)
{
// this is wrong way to implement these things. On official it done by gameobject spell cast.
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
uint32 SpellId = 0;
@@ -568,7 +576,7 @@ void BattleGroundAV::HandleAreaTrigger(Player *Source, uint32 Trigger)
break;
}
- if(SpellId)
+ if (SpellId)
Source->CastSpell(Source, SpellId, true);
}
diff --git a/src/game/BattleGroundAV.h b/src/game/BattleGroundAV.h
index 310635b995f..f9f4f46b0ae 100644
--- a/src/game/BattleGroundAV.h
+++ b/src/game/BattleGroundAV.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -1500,10 +1500,12 @@ class BattleGroundAV : public BattleGround
public:
BattleGroundAV();
~BattleGroundAV();
- void Update(time_t diff);
+ void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
+ virtual void StartingEventCloseDoors();
+ virtual void StartingEventOpenDoors();
void RemovePlayer(Player *plr,uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
diff --git a/src/game/BattleGroundBE.cpp b/src/game/BattleGroundBE.cpp
index a010bb166ac..f61ff697faa 100644
--- a/src/game/BattleGroundBE.cpp
+++ b/src/game/BattleGroundBE.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,14 +22,23 @@
#include "Player.h"
#include "BattleGround.h"
#include "BattleGroundBE.h"
-#include "Creature.h"
#include "ObjectMgr.h"
-#include "MapManager.h"
+#include "WorldPacket.h"
#include "Language.h"
BattleGroundBE::BattleGroundBE()
{
m_BgObjects.resize(BG_BE_OBJECT_MAX);
+
+ m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
+ m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
+ m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
+ m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
+ //we must set messageIds
+ m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
+ m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
+ m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
}
BattleGroundBE::~BattleGroundBE()
@@ -37,77 +46,34 @@ BattleGroundBE::~BattleGroundBE()
}
-void BattleGroundBE::Update(time_t diff)
+void BattleGroundBE::Update(uint32 diff)
{
BattleGround::Update(diff);
- // after bg start we get there
- if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
- {
- ModifyStartDelayTime(diff);
-
- if (!(m_Events & 0x01))
- {
- m_Events |= 0x01;
- // setup here, only when at least one player has ported to the map
- if(!SetupBattleGround())
- {
- EndNow();
- return;
- }
- for(uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_4; i++)
- SpawnBGObject(i, RESPAWN_IMMEDIATELY);
-
- for(uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; i++)
- SpawnBGObject(i, RESPAWN_ONE_DAY);
-
- SetStartDelayTime(START_DELAY1);
- SendMessageToAll(LANG_ARENA_ONE_MINUTE);
- }
- // After 30 seconds, warning is signalled
- else if (GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x04))
- {
- m_Events |= 0x04;
- SendMessageToAll(LANG_ARENA_THIRTY_SECONDS);
- }
- // After 15 seconds, warning is signalled
- else if (GetStartDelayTime() <= START_DELAY3 && !(m_Events & 0x08))
- {
- m_Events |= 0x08;
- SendMessageToAll(LANG_ARENA_FIFTEEN_SECONDS);
- }
- // delay expired (1 minute)
- else if (GetStartDelayTime() <= 0 && !(m_Events & 0x10))
- {
- m_Events |= 0x10;
-
- for(uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_2; i++)
- DoorOpen(i);
-
- for(uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; i++)
- SpawnBGObject(i, 60);
-
- SendMessageToAll(LANG_ARENA_BEGUN);
- SetStatus(STATUS_IN_PROGRESS);
- SetStartDelayTime(0);
-
- for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
- if(Player *plr = objmgr.GetPlayer(itr->first))
- plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
-
- if(!GetPlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
- EndBattleGround(HORDE);
- else if(GetPlayersCountByTeam(ALLIANCE) && !GetPlayersCountByTeam(HORDE))
- EndBattleGround(ALLIANCE);
- }
- }
-
- /*if(GetStatus() == STATUS_IN_PROGRESS)
+ /*if (GetStatus() == STATUS_IN_PROGRESS)
{
// update something
}*/
}
+void BattleGroundBE::StartingEventCloseDoors()
+{
+ for(uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_4; ++i)
+ SpawnBGObject(i, RESPAWN_IMMEDIATELY);
+
+ for(uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; ++i)
+ SpawnBGObject(i, RESPAWN_ONE_DAY);
+}
+
+void BattleGroundBE::StartingEventOpenDoors()
+{
+ for(uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_2; ++i)
+ DoorOpen(i);
+
+ for(uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; ++i)
+ SpawnBGObject(i, 60);
+}
+
void BattleGroundBE::AddPlayer(Player *plr)
{
BattleGround::AddPlayer(plr);
@@ -122,24 +88,21 @@ void BattleGroundBE::AddPlayer(Player *plr)
void BattleGroundBE::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
{
- if(GetStatus() == STATUS_WAIT_LEAVE)
+ if (GetStatus() == STATUS_WAIT_LEAVE)
return;
UpdateWorldState(0x9f1, GetAlivePlayersCountByTeam(ALLIANCE));
UpdateWorldState(0x9f0, GetAlivePlayersCountByTeam(HORDE));
- if(!GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
- EndBattleGround(HORDE);
- else if(GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE))
- EndBattleGround(ALLIANCE);
+ CheckArenaWinConditions();
}
void BattleGroundBE::HandleKillPlayer(Player *player, Player *killer)
{
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
- if(!killer)
+ if (!killer)
{
sLog.outError("Killer player not found");
return;
@@ -150,16 +113,7 @@ void BattleGroundBE::HandleKillPlayer(Player *player, Player *killer)
UpdateWorldState(0x9f1, GetAlivePlayersCountByTeam(ALLIANCE));
UpdateWorldState(0x9f0, GetAlivePlayersCountByTeam(HORDE));
- if(!GetAlivePlayersCountByTeam(ALLIANCE))
- {
- // all opponents killed
- EndBattleGround(HORDE);
- }
- else if(!GetAlivePlayersCountByTeam(HORDE))
- {
- // all opponents killed
- EndBattleGround(ALLIANCE);
- }
+ CheckArenaWinConditions();
}
bool BattleGroundBE::HandlePlayerUnderMap(Player *player)
@@ -171,7 +125,7 @@ bool BattleGroundBE::HandlePlayerUnderMap(Player *player)
void BattleGroundBE::HandleAreaTrigger(Player *Source, uint32 Trigger)
{
// this is wrong way to implement these things. On official it done by gameobject spell cast.
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
//uint32 SpellId = 0;
@@ -190,7 +144,7 @@ void BattleGroundBE::HandleAreaTrigger(Player *Source, uint32 Trigger)
break;
}
- //if(buff_guid)
+ //if (buff_guid)
// HandleTriggerBuff(buff_guid,Source);
}
@@ -201,15 +155,16 @@ void BattleGroundBE::FillInitialWorldStates(WorldPacket &data)
data << uint32(0x9f3) << uint32(1); // 9
}
-void BattleGroundBE::ResetBGSubclass()
+void BattleGroundBE::Reset()
{
-
+ //call parent's class reset
+ BattleGround::Reset();
}
bool BattleGroundBE::SetupBattleGround()
{
// gates
- if( !AddObject(BG_BE_OBJECT_DOOR_1, BG_BE_OBJECT_TYPE_DOOR_1, 6287.277f, 282.1877f, 3.810925f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f, RESPAWN_IMMEDIATELY)
+ if (!AddObject(BG_BE_OBJECT_DOOR_1, BG_BE_OBJECT_TYPE_DOOR_1, 6287.277f, 282.1877f, 3.810925f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f, RESPAWN_IMMEDIATELY)
|| !AddObject(BG_BE_OBJECT_DOOR_2, BG_BE_OBJECT_TYPE_DOOR_2, 6189.546f, 241.7099f, 3.101481f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f, RESPAWN_IMMEDIATELY)
|| !AddObject(BG_BE_OBJECT_DOOR_3, BG_BE_OBJECT_TYPE_DOOR_3, 6299.116f, 296.5494f, 3.308032f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f, RESPAWN_IMMEDIATELY)
|| !AddObject(BG_BE_OBJECT_DOOR_4, BG_BE_OBJECT_TYPE_DOOR_4, 6177.708f, 227.3481f, 3.604374f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f, RESPAWN_IMMEDIATELY)
diff --git a/src/game/BattleGroundBE.h b/src/game/BattleGroundBE.h
index 00f826f8207..e75e332f44f 100644
--- a/src/game/BattleGroundBE.h
+++ b/src/game/BattleGroundBE.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -57,15 +57,17 @@ class BattleGroundBE : public BattleGround
public:
BattleGroundBE();
~BattleGroundBE();
- void Update(time_t diff);
+ void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
+ virtual void StartingEventCloseDoors();
+ virtual void StartingEventOpenDoors();
void RemovePlayer(Player *plr, uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
bool SetupBattleGround();
- void ResetBGSubclass();
+ virtual void Reset();
virtual void FillInitialWorldStates(WorldPacket &d);
void HandleKillPlayer(Player* player, Player *killer);
bool HandlePlayerUnderMap(Player * plr);
diff --git a/src/game/BattleGroundDS.cpp b/src/game/BattleGroundDS.cpp
new file mode 100644
index 00000000000..78360b9b194
--- /dev/null
+++ b/src/game/BattleGroundDS.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2005-2009 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 "Player.h"
+#include "BattleGround.h"
+#include "BattleGroundDS.h"
+#include "Language.h"
+
+BattleGroundDS::BattleGroundDS()
+{
+
+ m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
+ m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
+ m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
+ m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
+ //we must set messageIds
+ m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
+ m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
+ m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
+}
+
+BattleGroundDS::~BattleGroundDS()
+{
+
+}
+
+void BattleGroundDS::Update(uint32 diff)
+{
+ BattleGround::Update(diff);
+}
+
+void BattleGroundDS::StartingEventCloseDoors()
+{
+}
+
+void BattleGroundDS::StartingEventOpenDoors()
+{
+}
+
+void BattleGroundDS::AddPlayer(Player *plr)
+{
+ BattleGround::AddPlayer(plr);
+ //create score and add it to map, default values are set in constructor
+ BattleGroundDSScore* sc = new BattleGroundDSScore;
+
+ m_PlayerScores[plr->GetGUID()] = sc;
+}
+
+void BattleGroundDS::RemovePlayer(Player * /*plr*/, uint64 /*guid*/)
+{
+}
+
+void BattleGroundDS::HandleKillPlayer(Player* player, Player* killer)
+{
+ BattleGround::HandleKillPlayer(player, killer);
+}
+
+void BattleGroundDS::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
+{
+}
+
+bool BattleGroundDS::SetupBattleGround()
+{
+ return true;
+}
diff --git a/src/game/BattleGroundDS.h b/src/game/BattleGroundDS.h
new file mode 100644
index 00000000000..44a6cfbd33a
--- /dev/null
+++ b/src/game/BattleGroundDS.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2005-2009 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 __BATTLEGROUNDDS_H
+#define __BATTLEGROUNDDS_H
+
+class BattleGround;
+
+class BattleGroundDSScore : public BattleGroundScore
+{
+ public:
+ BattleGroundDSScore() {};
+ virtual ~BattleGroundDSScore() {};
+ //TODO fix me
+};
+
+class BattleGroundDS : public BattleGround
+{
+ friend class BattleGroundMgr;
+
+ public:
+ BattleGroundDS();
+ ~BattleGroundDS();
+ void Update(uint32 diff);
+
+ /* inherited from BattlegroundClass */
+ virtual void AddPlayer(Player *plr);
+ virtual void StartingEventCloseDoors();
+ virtual void StartingEventOpenDoors();
+
+ void RemovePlayer(Player *plr, uint64 guid);
+ void HandleAreaTrigger(Player *Source, uint32 Trigger);
+ bool SetupBattleGround();
+ void HandleKillPlayer(Player* player, Player *killer);
+};
+#endif
diff --git a/src/game/BattleGroundEY.cpp b/src/game/BattleGroundEY.cpp
index ecf454d1cfe..7e6063a09d2 100644
--- a/src/game/BattleGroundEY.cpp
+++ b/src/game/BattleGroundEY.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -23,11 +23,10 @@
#include "BattleGround.h"
#include "BattleGroundEY.h"
#include "Creature.h"
-#include "Chat.h"
#include "ObjectMgr.h"
-#include "MapManager.h"
#include "Language.h"
-#include "World.h"
+#include "World.h" //music
+#include "WorldPacket.h"
#include "Util.h"
// these variables aren't used outside of this file, so declare them only here
@@ -45,85 +44,25 @@ BattleGroundEY::BattleGroundEY()
m_Points_Trigger[BLOOD_ELF] = TR_BLOOD_ELF_BUFF;
m_Points_Trigger[DRAENEI_RUINS] = TR_DRAENEI_RUINS_BUFF;
m_Points_Trigger[MAGE_TOWER] = TR_MAGE_TOWER_BUFF;
+
+ m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_EY_START_TWO_MINUTES;
+ m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_EY_START_ONE_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_EY_START_HALF_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_EY_HAS_BEGUN;
}
BattleGroundEY::~BattleGroundEY()
{
}
-void BattleGroundEY::Update(time_t diff)
+void BattleGroundEY::Update(uint32 diff)
{
BattleGround::Update(diff);
- // after bg start we get there (once)
- if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
- {
- ModifyStartDelayTime(diff);
-
- if(!(m_Events & 0x01))
- {
- m_Events |= 0x01;
-
- // setup here, only when at least one player has ported to the map
- if(!SetupBattleGround())
- {
- EndNow();
- return;
- }
-
- SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_IMMEDIATELY);
- SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_IMMEDIATELY);
-
-// SpawnBGCreature(EY_SPIRIT_MAIN_ALLIANCE, RESPAWN_IMMEDIATELY);
-// SpawnBGCreature(EY_SPIRIT_MAIN_HORDE, RESPAWN_IMMEDIATELY);
- for(uint32 i = BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER; i < BG_EY_OBJECT_MAX; ++i)
- SpawnBGObject(i, RESPAWN_ONE_DAY);
-
- SetStartDelayTime(START_DELAY0);
- }
- // After 1 minute, warning is signalled
- else if(GetStartDelayTime() <= START_DELAY1 && !(m_Events & 0x04))
- {
- m_Events |= 0x04;
- SendMessageToAll(GetTrinityString(LANG_BG_EY_ONE_MINUTE));
- }
- // After 1,5 minute, warning is signalled
- else if(GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x08))
- {
- m_Events |= 0x08;
- SendMessageToAll(GetTrinityString(LANG_BG_EY_HALF_MINUTE));
- }
- // After 2 minutes, gates OPEN ! x)
- else if(GetStartDelayTime() < 0 && !(m_Events & 0x10))
- {
- m_Events |= 0x10;
- SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_ONE_DAY);
- SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_ONE_DAY);
-
- for(uint32 i = BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER; i <= BG_EY_OBJECT_FLAG_NETHERSTORM; ++i)
- SpawnBGObject(i, RESPAWN_IMMEDIATELY);
- for(uint32 i = 0; i < EY_POINTS_MAX; ++i)
- {
- //randomly spawn buff
- uint8 buff = urand(0, 2);
- SpawnBGObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + buff + i * 3, RESPAWN_IMMEDIATELY);
- }
-
- SendMessageToAll(GetTrinityString(LANG_BG_EY_BEGIN));
-
- PlaySoundToAll(SOUND_BG_START);
- if(sWorld.getConfig(CONFIG_BG_START_MUSIC))
- PlaySoundToAll(SOUND_BG_START_L70ETC); //MUSIC
- SetStatus(STATUS_IN_PROGRESS);
- for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
- if(Player *plr = objmgr.GetPlayer(itr->first))
- plr->RemoveAurasDueToSpell(SPELL_PREPARATION);
- }
- }
- else if(GetStatus() == STATUS_IN_PROGRESS)
+ if (GetStatus() == STATUS_IN_PROGRESS)
{
m_PointAddingTimer -= diff;
- if(m_PointAddingTimer <= 0)
+ if (m_PointAddingTimer <= 0)
{
m_PointAddingTimer = BG_EY_FPOINTS_TICK_TIME;
if (m_TeamPointsCount[BG_TEAM_ALLIANCE] > 0)
@@ -132,11 +71,11 @@ void BattleGroundEY::Update(time_t diff)
AddPoints(HORDE, BG_EY_TickPoints[m_TeamPointsCount[BG_TEAM_HORDE] - 1]);
}
- if(m_FlagState == BG_EY_FLAG_STATE_WAIT_RESPAWN || m_FlagState == BG_EY_FLAG_STATE_ON_GROUND)
+ if (m_FlagState == BG_EY_FLAG_STATE_WAIT_RESPAWN || m_FlagState == BG_EY_FLAG_STATE_ON_GROUND)
{
m_FlagsTimer -= diff;
- if(m_FlagsTimer < 0)
+ if (m_FlagsTimer < 0)
{
m_FlagsTimer = 0;
if (m_FlagState == BG_EY_FLAG_STATE_WAIT_RESPAWN)
@@ -147,7 +86,7 @@ void BattleGroundEY::Update(time_t diff)
}
m_TowerCapCheckTimer -= diff;
- if(m_TowerCapCheckTimer <= 0)
+ if (m_TowerCapCheckTimer <= 0)
{
//check if player joined point
/*I used this order of calls, because although we will check if one player is in gameobject's distance 2 times
@@ -162,16 +101,39 @@ void BattleGroundEY::Update(time_t diff)
}
}
+void BattleGroundEY::StartingEventCloseDoors()
+{
+ SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_IMMEDIATELY);
+ SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_IMMEDIATELY);
+
+ for(uint32 i = BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER; i < BG_EY_OBJECT_MAX; ++i)
+ SpawnBGObject(i, RESPAWN_ONE_DAY);
+}
+
+void BattleGroundEY::StartingEventOpenDoors()
+{
+ SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_ONE_DAY);
+ SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_ONE_DAY);
+
+ for(uint32 i = BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER; i <= BG_EY_OBJECT_FLAG_NETHERSTORM; ++i)
+ SpawnBGObject(i, RESPAWN_IMMEDIATELY);
+ for(uint32 i = 0; i < EY_POINTS_MAX; ++i)
+ {
+ //randomly spawn buff
+ uint8 buff = urand(0, 2);
+ SpawnBGObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + buff + i * 3, RESPAWN_IMMEDIATELY);
+ }
+}
+
void BattleGroundEY::AddPoints(uint32 Team, uint32 Points)
{
uint8 team_index = GetTeamIndexByTeamId(Team);
m_TeamScores[team_index] += Points;
- m_score[team_index] = m_TeamScores[team_index];
m_HonorScoreTics[team_index] += Points;
- if (m_HonorScoreTics[team_index] >= BG_EY_HonorScoreTicks[m_HonorMode])
+ if (m_HonorScoreTics[team_index] >= m_HonorTics )
{
- RewardHonorToTeam(20, Team);
- m_HonorScoreTics[team_index] -= BG_EY_HonorScoreTicks[m_HonorMode];
+ RewardHonorToTeam(GetBonusHonorFromKill(1), Team);
+ m_HonorScoreTics[team_index] -= m_HonorTics;
}
UpdateTeamScore(Team);
}
@@ -188,13 +150,13 @@ void BattleGroundEY::CheckSomeoneJoinedPoint()
while (j < m_PlayersNearPoint[EY_POINTS_MAX].size())
{
Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[EY_POINTS_MAX][j]);
- if(!plr)
+ if (!plr)
{
sLog.outError("BattleGroundEY: Player " I64FMTD " not found!", m_PlayersNearPoint[EY_POINTS_MAX][j]);
++j;
continue;
}
- if (plr->isAllowUseBattleGroundObject() && plr->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
+ if (plr->CanCaptureTowerPoint() && plr->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
{
//player joined point!
//show progress bar
@@ -222,7 +184,7 @@ void BattleGroundEY::CheckSomeoneLeftPoint()
for(uint8 i = 0; i < EY_POINTS_MAX; ++i)
{
obj = HashMapHolder<GameObject>::Find(m_BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REALVER + i]);
- if(obj)
+ if (obj)
{
uint8 j = 0;
while (j < m_PlayersNearPoint[i].size())
@@ -237,7 +199,7 @@ void BattleGroundEY::CheckSomeoneLeftPoint()
++j;
continue;
}
- if (!plr->isAllowUseBattleGroundObject() || !plr->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
+ if (!plr->CanCaptureTowerPoint() || !plr->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
//move player out of point (add him to players that are out of points
{
m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]);
@@ -305,21 +267,46 @@ void BattleGroundEY::UpdatePointStatuses()
void BattleGroundEY::UpdateTeamScore(uint32 Team)
{
uint32 score = GetTeamScore(Team);
- if(score >= EY_MAX_TEAM_SCORE)
+ //TODO there should be some sound played when one team is near victory!! - and define variables
+ /*if (!m_IsInformedNearVictory && score >= BG_EY_WARNING_NEAR_VICTORY_SCORE)
+ {
+ if (Team == ALLIANCE)
+ SendMessageToAll(LANG_BG_EY_A_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
+ else
+ SendMessageToAll(LANG_BG_EY_H_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
+ PlaySoundToAll(BG_EY_SOUND_NEAR_VICTORY);
+ m_IsInformedNearVictory = true;
+ }*/
+
+ if (score >= BG_EY_MAX_TEAM_SCORE)
{
- score = EY_MAX_TEAM_SCORE;
+ score = BG_EY_MAX_TEAM_SCORE;
EndBattleGround(Team);
}
- if(Team == ALLIANCE)
+ if (Team == ALLIANCE)
UpdateWorldState(EY_ALLIANCE_RESOURCES, score);
else
UpdateWorldState(EY_HORDE_RESOURCES, score);
}
+void BattleGroundEY::EndBattleGround(uint32 winner)
+{
+ //win reward
+ if (winner == ALLIANCE)
+ RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
+ if (winner == HORDE)
+ RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
+ //complete map reward
+ RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
+ RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
+
+ BattleGround::EndBattleGround(winner);
+}
+
void BattleGroundEY::UpdatePointsCount(uint32 Team)
{
- if(Team == ALLIANCE)
+ if (Team == ALLIANCE)
UpdateWorldState(EY_ALLIANCE_BASE, m_TeamPointsCount[BG_TEAM_ALLIANCE]);
else
UpdateWorldState(EY_HORDE_BASE, m_TeamPointsCount[BG_TEAM_HORDE]);
@@ -331,14 +318,14 @@ void BattleGroundEY::UpdatePointsIcons(uint32 Team, uint32 Point)
if (m_PointState[Point] == EY_POINT_UNDER_CONTROL)
{
UpdateWorldState(m_PointsIconStruct[Point].WorldStateControlIndex, 0);
- if(Team == ALLIANCE)
+ if (Team == ALLIANCE)
UpdateWorldState(m_PointsIconStruct[Point].WorldStateAllianceControlledIndex, 1);
else
UpdateWorldState(m_PointsIconStruct[Point].WorldStateHordeControlledIndex, 1);
}
else
{
- if(Team == ALLIANCE)
+ if (Team == ALLIANCE)
UpdateWorldState(m_PointsIconStruct[Point].WorldStateAllianceControlledIndex, 0);
else
UpdateWorldState(m_PointsIconStruct[Point].WorldStateHordeControlledIndex, 0);
@@ -362,16 +349,16 @@ void BattleGroundEY::RemovePlayer(Player *plr, uint64 guid)
// sometimes flag aura not removed :(
for (int j = EY_POINTS_MAX; j >= 0; --j)
{
- for(int i = 0; i < m_PlayersNearPoint[j].size(); ++i)
- if(m_PlayersNearPoint[j][i] == guid)
+ for(size_t i = 0; i < m_PlayersNearPoint[j].size(); ++i)
+ if (m_PlayersNearPoint[j][i] == guid)
m_PlayersNearPoint[j].erase(m_PlayersNearPoint[j].begin() + i);
}
- if(IsFlagPickedup())
+ if (IsFlagPickedup())
{
- if(m_FlagKeeper == guid)
+ if (m_FlagKeeper == guid)
{
- if(plr)
- this->EventPlayerDroppedFlag(plr);
+ if (plr)
+ EventPlayerDroppedFlag(plr);
else
{
SetFlagPicker(0);
@@ -383,7 +370,7 @@ void BattleGroundEY::RemovePlayer(Player *plr, uint64 guid)
void BattleGroundEY::HandleAreaTrigger(Player *Source, uint32 Trigger)
{
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
if(!Source->isAlive()) //hack code, must be removed later
@@ -392,23 +379,23 @@ void BattleGroundEY::HandleAreaTrigger(Player *Source, uint32 Trigger)
switch(Trigger)
{
case TR_BLOOD_ELF_POINT:
- if(m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[BLOOD_ELF] == Source->GetTeam())
- if(m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
+ if (m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[BLOOD_ELF] == Source->GetTeam())
+ if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_BLOOD_ELF);
break;
case TR_FEL_REALVER_POINT:
- if(m_PointState[FEL_REALVER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[FEL_REALVER] == Source->GetTeam())
- if(m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
+ if (m_PointState[FEL_REALVER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[FEL_REALVER] == Source->GetTeam())
+ if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_FEL_REALVER);
break;
case TR_MAGE_TOWER_POINT:
- if(m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[MAGE_TOWER] == Source->GetTeam())
- if(m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
+ if (m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[MAGE_TOWER] == Source->GetTeam())
+ if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_MAGE_TOWER);
break;
case TR_DRAENEI_RUINS_POINT:
- if(m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[DRAENEI_RUINS] == Source->GetTeam())
- if(m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
+ if (m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[DRAENEI_RUINS] == Source->GetTeam())
+ if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_DRAENEI_RUINS);
break;
case 4512:
@@ -432,7 +419,7 @@ void BattleGroundEY::HandleAreaTrigger(Player *Source, uint32 Trigger)
bool BattleGroundEY::SetupBattleGround()
{
// doors
- if( !AddObject(BG_EY_OBJECT_DOOR_A, BG_OBJECT_A_DOOR_EY_ENTRY, 2527.6f, 1596.91f, 1262.13f, -3.12414f, -0.173642f, -0.001515f, 0.98477f, -0.008594f, RESPAWN_IMMEDIATELY)
+ if (!AddObject(BG_EY_OBJECT_DOOR_A, BG_OBJECT_A_DOOR_EY_ENTRY, 2527.6f, 1596.91f, 1262.13f, -3.12414f, -0.173642f, -0.001515f, 0.98477f, -0.008594f, RESPAWN_IMMEDIATELY)
|| !AddObject(BG_EY_OBJECT_DOOR_H, BG_OBJECT_H_DOOR_EY_ENTRY, 1803.21f, 1539.49f, 1261.09f, 3.14159f, 0.173648f, 0, 0.984808f, 0, RESPAWN_IMMEDIATELY)
// banners (alliance)
|| !AddObject(BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2057.46f, 1735.07f, 1187.91f, -0.925024f, 0, 0, 0.446198f, -0.894934f, RESPAWN_ONE_DAY)
@@ -494,12 +481,12 @@ bool BattleGroundEY::SetupBattleGround()
for (int i = 0; i < EY_POINTS_MAX; ++i)
{
AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(m_Points_Trigger[i]);
- if( !at )
+ if (!at)
{
sLog.outError("BattleGroundEY: Unknown trigger: %u", m_Points_Trigger[i]);
continue;
}
- if ( !AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + i * 3, Buff_Entries[0], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY)
+ if (!AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + i * 3, Buff_Entries[0], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY)
|| !AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + i * 3 + 1, Buff_Entries[1], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY)
|| !AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + i * 3 + 2, Buff_Entries[2], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY)
)
@@ -508,14 +495,14 @@ bool BattleGroundEY::SetupBattleGround()
WorldSafeLocsEntry const *sg = NULL;
sg = sWorldSafeLocsStore.LookupEntry(EY_GRAVEYARD_MAIN_ALLIANCE);
- if( !sg || !AddSpiritGuide(EY_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, ALLIANCE) )
+ if (!sg || !AddSpiritGuide(EY_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, ALLIANCE))
{
sLog.outErrorDb("BatteGroundEY: Failed to spawn spirit guide! BattleGround not created!");
return false;
}
sg = sWorldSafeLocsStore.LookupEntry(EY_GRAVEYARD_MAIN_HORDE);
- if( !sg || !AddSpiritGuide(EY_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, HORDE) )
+ if (!sg || !AddSpiritGuide(EY_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, HORDE))
{
sLog.outErrorDb("BatteGroundEY: Failed to spawn spirit guide! BattleGround not created!");
return false;
@@ -524,8 +511,11 @@ bool BattleGroundEY::SetupBattleGround()
return true;
}
-void BattleGroundEY::ResetBGSubclass()
+void BattleGroundEY::Reset()
{
+ //call parent's class reset
+ BattleGround::Reset();
+
m_TeamScores[BG_TEAM_ALLIANCE] = 0;
m_TeamScores[BG_TEAM_HORDE] = 0;
m_TeamPointsCount[BG_TEAM_ALLIANCE] = 0;
@@ -538,6 +528,8 @@ void BattleGroundEY::ResetBGSubclass()
m_DroppedFlagGUID = 0;
m_PointAddingTimer = 0;
m_TowerCapCheckTimer = 0;
+ bool isBGWeekend = false; //TODO FIXME - call sBattleGroundMgr.IsBGWeekend(m_TypeID); - you must also implement that call!
+ m_HonorTics = (isBGWeekend) ? BG_EY_EYWeekendHonorTicks : BG_EY_NotEYWeekendHonorTicks;
for(uint8 i = 0; i < EY_POINTS_MAX; ++i)
{
@@ -560,9 +552,9 @@ void BattleGroundEY::RespawnFlag(bool send_message)
m_FlagState = BG_EY_FLAG_STATE_ON_BASE;
SpawnBGObject(BG_EY_OBJECT_FLAG_NETHERSTORM, RESPAWN_IMMEDIATELY);
- if(send_message)
+ if (send_message)
{
- SendMessageToAll(GetTrinityString(LANG_BG_EY_RESETED_FLAG));
+ SendMessageToAll(LANG_BG_EY_RESETED_FLAG, CHAT_MSG_BG_SYSTEM_NEUTRAL);
PlaySoundToAll(BG_EY_SOUND_FLAG_RESET); // flags respawned sound...
}
@@ -574,7 +566,7 @@ void BattleGroundEY::RespawnFlagAfterDrop()
RespawnFlag(true);
GameObject *obj = HashMapHolder<GameObject>::Find(GetDroppedFlagGUID());
- if(obj)
+ if (obj)
obj->Delete();
else
sLog.outError("BattleGroundEY: Unknown dropped flag guid: %u",GUID_LOPART(GetDroppedFlagGUID()));
@@ -584,7 +576,7 @@ void BattleGroundEY::RespawnFlagAfterDrop()
void BattleGroundEY::HandleKillPlayer(Player *player, Player *killer)
{
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
BattleGround::HandleKillPlayer(player, killer);
@@ -593,11 +585,11 @@ void BattleGroundEY::HandleKillPlayer(Player *player, Player *killer)
void BattleGroundEY::EventPlayerDroppedFlag(Player *Source)
{
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
{
// if not running, do not cast things at the dropper player, neither send unnecessary messages
// just take off the aura
- if(IsFlagPickedup() && GetFlagPickerGUID() == Source->GetGUID())
+ if (IsFlagPickedup() && GetFlagPickerGUID() == Source->GetGUID())
{
SetFlagPicker(0);
Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
@@ -605,59 +597,41 @@ void BattleGroundEY::EventPlayerDroppedFlag(Player *Source)
return;
}
- if(!IsFlagPickedup())
+ if (!IsFlagPickedup())
return;
- if(GetFlagPickerGUID() != Source->GetGUID())
+ if (GetFlagPickerGUID() != Source->GetGUID())
return;
- const char *message = "";
- uint8 type = 0;
-
SetFlagPicker(0);
Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
m_FlagState = BG_EY_FLAG_STATE_ON_GROUND;
m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME;
Source->CastSpell(Source, SPELL_RECENTLY_DROPPED_FLAG, true);
Source->CastSpell(Source, BG_EY_PLAYER_DROPPED_FLAG_SPELL, true);
- if(Source->GetTeam() == ALLIANCE)
- {
- message = GetTrinityString(LANG_BG_EY_DROPPED_FLAG);
- type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
- }
- else
- {
- message = GetTrinityString(LANG_BG_EY_DROPPED_FLAG);
- type = CHAT_MSG_BG_SYSTEM_HORDE;
- }
//this does not work correctly :( (it should remove flag carrier name)
UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
- WorldPacket data;
- ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
- SendPacketToAll(&data);
+ if (Source->GetTeam() == ALLIANCE)
+ SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL);
+ else
+ SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, NULL);
}
void BattleGroundEY::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj)
{
- if(GetStatus() != STATUS_IN_PROGRESS || this->IsFlagPickedup() || !Source->IsWithinDistInMap(target_obj, 10))
+ if (GetStatus() != STATUS_IN_PROGRESS || IsFlagPickedup() || !Source->IsWithinDistInMap(target_obj, 10))
return;
- const char *message;
- uint8 type = 0;
- message = GetTrinityString(LANG_BG_EY_HAS_TAKEN_FLAG);
-
- if(Source->GetTeam() == ALLIANCE)
+ if (Source->GetTeam() == ALLIANCE)
{
UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_ON_PLAYER);
- type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE);
}
else
{
UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_ON_PLAYER);
- type = CHAT_MSG_BG_SYSTEM_HORDE;
PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_HORDE);
}
@@ -671,29 +645,26 @@ void BattleGroundEY::EventPlayerClickedOnFlag(Player *Source, GameObject* target
Source->CastSpell(Source, BG_EY_NETHERSTORM_FLAG_SPELL, true);
Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
- WorldPacket data;
- ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
- SendPacketToAll(&data);
+ if (Source->GetTeam() == ALLIANCE)
+ PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL, Source->GetName());
+ else
+ PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, NULL, Source->GetName());
}
void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point)
{
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
//Natural point
- uint8 message_type = 0;
- const char *message = "";
uint32 Team = m_PointOwnedByTeam[Point];
- if(!Team)
+ if (!Team)
return;
if (Team == ALLIANCE)
{
m_TeamPointsCount[BG_TEAM_ALLIANCE]--;
- message_type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
- message = GetTrinityString(m_LoosingPointTypes[Point].MessageIdAlliance);
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance, RESPAWN_ONE_DAY);
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance + 1, RESPAWN_ONE_DAY);
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance + 2, RESPAWN_ONE_DAY);
@@ -701,8 +672,6 @@ void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point)
else
{
m_TeamPointsCount[BG_TEAM_HORDE]--;
- message_type = CHAT_MSG_BG_SYSTEM_HORDE;
- message = GetTrinityString(m_LoosingPointTypes[Point].MessageIdHorde);
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde, RESPAWN_ONE_DAY);
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde + 1, RESPAWN_ONE_DAY);
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde + 2, RESPAWN_ONE_DAY);
@@ -717,9 +686,10 @@ void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point)
m_PointOwnedByTeam[Point] = EY_POINT_NO_OWNER;
m_PointState[Point] = EY_POINT_NO_OWNER;
- WorldPacket data;
- ChatHandler::FillMessageData(&data, Source->GetSession(), message_type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
- SendPacketToAll(&data);
+ if (Team == ALLIANCE)
+ SendMessageToAll(m_LoosingPointTypes[Point].MessageIdAlliance,CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
+ else
+ SendMessageToAll(m_LoosingPointTypes[Point].MessageIdHorde,CHAT_MSG_BG_SYSTEM_HORDE, Source);
UpdatePointsIcons(Team, Point);
UpdatePointsCount(Team);
@@ -727,11 +697,9 @@ void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point)
void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point)
{
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
- uint8 type = 0;
- const char *message = "";
uint32 Team = Source->GetTeam();
SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType, RESPAWN_ONE_DAY);
@@ -741,8 +709,6 @@ void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point)
if (Team == ALLIANCE)
{
m_TeamPointsCount[BG_TEAM_ALLIANCE]++;
- type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
- message = GetTrinityString(m_CapturingPointTypes[Point].MessageIdAlliance);
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance, RESPAWN_IMMEDIATELY);
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance + 1, RESPAWN_IMMEDIATELY);
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance + 2, RESPAWN_IMMEDIATELY);
@@ -750,8 +716,6 @@ void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point)
else
{
m_TeamPointsCount[BG_TEAM_HORDE]++;
- type = CHAT_MSG_BG_SYSTEM_HORDE;
- message = GetTrinityString(m_CapturingPointTypes[Point].MessageIdHorde);
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde, RESPAWN_IMMEDIATELY);
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 1, RESPAWN_IMMEDIATELY);
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 2, RESPAWN_IMMEDIATELY);
@@ -762,16 +726,17 @@ void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point)
m_PointOwnedByTeam[Point] = Team;
m_PointState[Point] = EY_POINT_UNDER_CONTROL;
- WorldPacket data;
- ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
- SendPacketToAll(&data);
+ if (Team == ALLIANCE)
+ SendMessageToAll(m_CapturingPointTypes[Point].MessageIdAlliance,CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
+ else
+ SendMessageToAll(m_CapturingPointTypes[Point].MessageIdHorde,CHAT_MSG_BG_SYSTEM_HORDE, Source);
- if(m_BgCreatures[Point])
+ if (m_BgCreatures[Point])
DelCreature(Point);
WorldSafeLocsEntry const *sg = NULL;
sg = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[Point].GraveYardId);
- if(!sg || !AddSpiritGuide(Point, sg->x, sg->y, sg->z, 3.124139f, Team))
+ if (!sg || !AddSpiritGuide(Point, sg->x, sg->y, sg->z, 3.124139f, Team))
sLog.outError("BatteGroundEY: Failed to spawn spirit guide! point: %u, team: %u, graveyard_id: %u",
Point, Team, m_CapturingPointTypes[Point].GraveYardId);
@@ -783,43 +748,38 @@ void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point)
void BattleGroundEY::EventPlayerCapturedFlag(Player *Source, uint32 BgObjectType)
{
- if(GetStatus() != STATUS_IN_PROGRESS || this->GetFlagPickerGUID() != Source->GetGUID())
+ if (GetStatus() != STATUS_IN_PROGRESS || GetFlagPickerGUID() != Source->GetGUID())
return;
- uint8 type = 0;
- uint8 team_id = 0;
- const char *message = "";
-
SetFlagPicker(0);
m_FlagState = BG_EY_FLAG_STATE_WAIT_RESPAWN;
Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
- if(Source->GetTeam() == ALLIANCE)
- {
+
+ if (Source->GetTeam() == ALLIANCE)
PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE);
- team_id = BG_TEAM_ALLIANCE;
- message = GetTrinityString(LANG_BG_EY_CAPTURED_FLAG_A);
- type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
- }
else
- {
PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_HORDE);
- team_id = BG_TEAM_HORDE;
- message = GetTrinityString(LANG_BG_EY_CAPTURED_FLAG_H);
- type = CHAT_MSG_BG_SYSTEM_HORDE;
- }
SpawnBGObject(BgObjectType, RESPAWN_IMMEDIATELY);
m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME;
m_FlagCapturedBgObjectType = BgObjectType;
- WorldPacket data;
- ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
- SendPacketToAll(&data);
+ uint8 team_id = 0;
+ if (Source->GetTeam() == ALLIANCE)
+ {
+ team_id = BG_TEAM_ALLIANCE;
+ SendMessageToAll(LANG_BG_EY_CAPTURED_FLAG_A, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
+ }
+ else
+ {
+ team_id = BG_TEAM_HORDE;
+ SendMessageToAll(LANG_BG_EY_CAPTURED_FLAG_H, CHAT_MSG_BG_SYSTEM_HORDE, Source);
+ }
- if(m_TeamPointsCount[team_id] > 0)
+ if (m_TeamPointsCount[team_id] > 0)
AddPoints(Source->GetTeam(), BG_EY_FlagPoints[m_TeamPointsCount[team_id] - 1]);
UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1);
@@ -893,16 +853,16 @@ void BattleGroundEY::FillInitialWorldStates(WorldPacket& data)
data << uint32(0xc0d) << uint32(0x17b);
}
-WorldSafeLocsEntry const *BattleGroundEY::GetClosestGraveYard(float x, float y, float z, uint32 team)
+WorldSafeLocsEntry const *BattleGroundEY::GetClosestGraveYard(Player* player)
{
uint32 g_id = 0;
- if(team == ALLIANCE)
- g_id = EY_GRAVEYARD_MAIN_ALLIANCE;
- else if(team == HORDE)
- g_id = EY_GRAVEYARD_MAIN_HORDE;
- else
- return NULL;
+ switch(player->GetTeam())
+ {
+ case ALLIANCE: g_id = EY_GRAVEYARD_MAIN_ALLIANCE; break;
+ case HORDE: g_id = EY_GRAVEYARD_MAIN_HORDE; break;
+ default: return NULL;
+ }
float distance, nearestDistance;
@@ -911,26 +871,31 @@ WorldSafeLocsEntry const *BattleGroundEY::GetClosestGraveYard(float x, float y,
entry = sWorldSafeLocsStore.LookupEntry(g_id);
nearestEntry = entry;
- if(!entry)
+ if (!entry)
{
sLog.outError("BattleGroundEY: Not found the main team graveyard. Graveyard system isn't working!");
return NULL;
}
- distance = (entry->x - x)*(entry->x - x) + (entry->y - y)*(entry->y - y) + (entry->z - z)*(entry->z - z);
+ float plr_x = player->GetPositionX();
+ float plr_y = player->GetPositionY();
+ float plr_z = player->GetPositionZ();
+
+
+ distance = (entry->x - plr_x)*(entry->x - plr_x) + (entry->y - plr_y)*(entry->y - plr_y) + (entry->z - plr_z)*(entry->z - plr_z);
nearestDistance = distance;
for(uint8 i = 0; i < EY_POINTS_MAX; ++i)
{
- if(m_PointOwnedByTeam[i]==team && m_PointState[i]==EY_POINT_UNDER_CONTROL)
+ if (m_PointOwnedByTeam[i]==player->GetTeam() && m_PointState[i]==EY_POINT_UNDER_CONTROL)
{
entry = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[i].GraveYardId);
- if(!entry)
+ if (!entry)
sLog.outError("BattleGroundEY: Not found graveyard: %u",m_CapturingPointTypes[i].GraveYardId);
else
{
- distance = (entry->x - x)*(entry->x - x) + (entry->y - y)*(entry->y - y) + (entry->z - z)*(entry->z - z);
- if(distance < nearestDistance)
+ distance = (entry->x - plr_x)*(entry->x - plr_x) + (entry->y - plr_y)*(entry->y - plr_y) + (entry->z - plr_z)*(entry->z - plr_z);
+ if (distance < nearestDistance)
{
nearestDistance = distance;
nearestEntry = entry;
diff --git a/src/game/BattleGroundEY.h b/src/game/BattleGroundEY.h
index 30ff2b3e584..a22d6ecc6db 100644
--- a/src/game/BattleGroundEY.h
+++ b/src/game/BattleGroundEY.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -25,9 +25,8 @@
class BattleGround;
-#define EY_MAX_TEAM_SCORE 2000
-#define BG_EY_FLAG_RESPAWN_TIME 10000 //10 seconds
-#define BG_EY_FPOINTS_TICK_TIME 2000 //2 seconds
+#define BG_EY_FLAG_RESPAWN_TIME (10*IN_MILISECONDS) //10 seconds
+#define BG_EY_FPOINTS_TICK_TIME (2*IN_MILISECONDS) //2 seconds
enum BG_EY_WorldStates
{
@@ -73,11 +72,11 @@ enum BG_EY_ProgressBarConsts
enum BG_EY_Sounds
{
//strange ids, but sure about them
- BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE = 8212,
- BG_EY_SOUND_FLAG_CAPTURED_HORDE = 8213,
- BG_EY_SOUND_FLAG_PICKED_UP_HORDE = 8174,
- BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE = 8173,
- BG_EY_SOUND_FLAG_RESET = 8192
+ BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE = 8212,
+ BG_EY_SOUND_FLAG_CAPTURED_HORDE = 8213,
+ BG_EY_SOUND_FLAG_PICKED_UP_HORDE = 8174,
+ BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE = 8173,
+ BG_EY_SOUND_FLAG_RESET = 8192
};
enum BG_EY_Spells
@@ -88,18 +87,18 @@ enum BG_EY_Spells
enum EYBattleGroundObjectEntry
{
- BG_OBJECT_A_DOOR_EY_ENTRY = 184719, //Alliance door
- BG_OBJECT_H_DOOR_EY_ENTRY = 184720, //Horde door
- BG_OBJECT_FLAG1_EY_ENTRY = 184493, //Netherstorm flag (generic)
- BG_OBJECT_FLAG2_EY_ENTRY = 184141, //Netherstorm flag (flagstand)
- BG_OBJECT_FLAG3_EY_ENTRY = 184142, //Netherstorm flag (flagdrop)
- BG_OBJECT_A_BANNER_EY_ENTRY = 184381, //Visual Banner (Alliance)
- BG_OBJECT_H_BANNER_EY_ENTRY = 184380, //Visual Banner (Horde)
- BG_OBJECT_N_BANNER_EY_ENTRY = 184382, //Visual Banner (Neutral)
- BG_OBJECT_BE_TOWER_CAP_EY_ENTRY = 184080, //BE Tower Cap Pt
- BG_OBJECT_FR_TOWER_CAP_EY_ENTRY = 184081, //Fel Reaver Cap Pt
- BG_OBJECT_HU_TOWER_CAP_EY_ENTRY = 184082, //Human Tower Cap Pt
- BG_OBJECT_DR_TOWER_CAP_EY_ENTRY = 184083 //Draenei Tower Cap Pt
+ BG_OBJECT_A_DOOR_EY_ENTRY = 184719, //Alliance door
+ BG_OBJECT_H_DOOR_EY_ENTRY = 184720, //Horde door
+ BG_OBJECT_FLAG1_EY_ENTRY = 184493, //Netherstorm flag (generic)
+ BG_OBJECT_FLAG2_EY_ENTRY = 184141, //Netherstorm flag (flagstand)
+ BG_OBJECT_FLAG3_EY_ENTRY = 184142, //Netherstorm flag (flagdrop)
+ BG_OBJECT_A_BANNER_EY_ENTRY = 184381, //Visual Banner (Alliance)
+ BG_OBJECT_H_BANNER_EY_ENTRY = 184380, //Visual Banner (Horde)
+ BG_OBJECT_N_BANNER_EY_ENTRY = 184382, //Visual Banner (Neutral)
+ BG_OBJECT_BE_TOWER_CAP_EY_ENTRY = 184080, //BE Tower Cap Pt
+ BG_OBJECT_FR_TOWER_CAP_EY_ENTRY = 184081, //Fel Reaver Cap Pt
+ BG_OBJECT_HU_TOWER_CAP_EY_ENTRY = 184082, //Human Tower Cap Pt
+ BG_OBJECT_DR_TOWER_CAP_EY_ENTRY = 184083 //Draenei Tower Cap Pt
};
enum EYBattleGroundPointsTrigger
@@ -131,7 +130,7 @@ enum EYBattleGroundPoints
DRAENEI_RUINS = 2,
MAGE_TOWER = 3,
- EY_PLAYERS_OUT_OF_POINTS = 4,
+ EY_PLAYERS_OUT_OF_POINTS = 4,
EY_POINTS_MAX = 4
};
@@ -212,6 +211,15 @@ enum EYBattleGroundObjectTypes
BG_EY_OBJECT_MAX = 59
};
+#define BG_EY_NotEYWeekendHonorTicks 330
+#define BG_EY_EYWeekendHonorTicks 200
+
+enum BG_EY_Score
+{
+ BG_EY_WARNING_NEAR_VICTORY_SCORE = 1800,
+ BG_EY_MAX_TEAM_SCORE = 2000
+};
+
enum BG_EY_FlagState
{
BG_EY_FLAG_STATE_ON_BASE = 0,
@@ -239,23 +247,32 @@ struct BattleGroundEYPointIconsStruct
struct BattleGroundEYLoosingPointStruct
{
BattleGroundEYLoosingPointStruct(uint32 _SpawnNeutralObjectType, uint32 _DespawnObjectTypeAlliance, uint32 _MessageIdAlliance, uint32 _DespawnObjectTypeHorde, uint32 _MessageIdHorde)
- : SpawnNeutralObjectType(_SpawnNeutralObjectType), DespawnObjectTypeAlliance(_DespawnObjectTypeAlliance), MessageIdAlliance(_MessageIdAlliance), DespawnObjectTypeHorde(_DespawnObjectTypeHorde), MessageIdHorde(_MessageIdHorde) {}
+ : SpawnNeutralObjectType(_SpawnNeutralObjectType),
+ DespawnObjectTypeAlliance(_DespawnObjectTypeAlliance), MessageIdAlliance(_MessageIdAlliance),
+ DespawnObjectTypeHorde(_DespawnObjectTypeHorde), MessageIdHorde(_MessageIdHorde)
+ {}
+
uint32 SpawnNeutralObjectType;
uint32 DespawnObjectTypeAlliance;
+ uint32 MessageIdAlliance;
uint32 DespawnObjectTypeHorde;
uint32 MessageIdHorde;
- uint32 MessageIdAlliance;
};
struct BattleGroundEYCapturingPointStruct
{
BattleGroundEYCapturingPointStruct(uint32 _DespawnNeutralObjectType, uint32 _SpawnObjectTypeAlliance, uint32 _MessageIdAlliance, uint32 _SpawnObjectTypeHorde, uint32 _MessageIdHorde, uint32 _GraveYardId)
- : DespawnNeutralObjectType(_DespawnNeutralObjectType), SpawnObjectTypeAlliance(_SpawnObjectTypeAlliance), MessageIdAlliance(_MessageIdAlliance), SpawnObjectTypeHorde(_SpawnObjectTypeHorde), MessageIdHorde(_MessageIdHorde), GraveYardId(_GraveYardId) {}
+ : DespawnNeutralObjectType(_DespawnNeutralObjectType),
+ SpawnObjectTypeAlliance(_SpawnObjectTypeAlliance), MessageIdAlliance(_MessageIdAlliance),
+ SpawnObjectTypeHorde(_SpawnObjectTypeHorde), MessageIdHorde(_MessageIdHorde),
+ GraveYardId(_GraveYardId)
+ {}
+
uint32 DespawnNeutralObjectType;
uint32 SpawnObjectTypeAlliance;
+ uint32 MessageIdAlliance;
uint32 SpawnObjectTypeHorde;
uint32 MessageIdHorde;
- uint32 MessageIdAlliance;
uint32 GraveYardId;
};
@@ -300,10 +317,12 @@ class BattleGroundEY : public BattleGround
public:
BattleGroundEY();
~BattleGroundEY();
- void Update(time_t diff);
+ void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
+ virtual void StartingEventCloseDoors();
+ virtual void StartingEventOpenDoors();
/* BG Flags */
uint64 GetFlagPickerGUID() const { return m_FlagKeeper; }
@@ -317,10 +336,11 @@ class BattleGroundEY : public BattleGround
void HandleBuffUse(uint64 const& buff_guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
void HandleKillPlayer(Player *player, Player *killer);
- virtual WorldSafeLocsEntry const* GetClosestGraveYard(float x, float y, float z, uint32 team);
+ virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
virtual bool SetupBattleGround();
- virtual void ResetBGSubclass();
+ virtual void Reset();
void UpdateTeamScore(uint32 Team);
+ void EndBattleGround(uint32 winner);
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
virtual void FillInitialWorldStates(WorldPacket& data);
void SetDroppedFlagGUID(uint64 guid) { m_DroppedFlagGUID = guid;}
@@ -370,6 +390,7 @@ class BattleGroundEY : public BattleGround
uint8 m_CurrentPointPlayersCount[2*EY_POINTS_MAX];
int32 m_PointAddingTimer;
+ uint32 m_HonorTics;
};
#endif
diff --git a/src/game/BattleGroundHandler.cpp b/src/game/BattleGroundHandler.cpp
index b1522c939f7..8464dc2e7e4 100644
--- a/src/game/BattleGroundHandler.cpp
+++ b/src/game/BattleGroundHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -25,7 +25,6 @@
#include "Player.h"
#include "ObjectMgr.h"
#include "WorldSession.h"
-#include "MapManager.h"
#include "ObjectAccessor.h"
#include "Object.h"
#include "Chat.h"
@@ -43,8 +42,8 @@ void WorldSession::HandleBattleGroundHelloOpcode( WorldPacket & recv_data )
recv_data >> guid;
sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from: " I64FMT, guid);
- Creature *unit = ObjectAccessor::GetCreature(*_player, guid);
- if(!unit)
+ Creature *unit = GetPlayer()->GetMap()->GetCreature(guid);
+ if (!unit)
return;
if(!unit->isBattleMaster()) // it's not battlemaster
@@ -53,9 +52,9 @@ void WorldSession::HandleBattleGroundHelloOpcode( WorldPacket & recv_data )
// Stop the npc if moving
unit->StopMoving();
- uint32 bgTypeId = objmgr.GetBattleMasterBG(unit->GetEntry());
+ BattleGroundTypeId bgTypeId = sBattleGroundMgr.GetBattleMasterBG(unit->GetEntry());
- if(!_player->GetBGAccessByLevel(bgTypeId))
+ if (!_player->GetBGAccessByLevel(bgTypeId))
{
// temp, must be gossip message...
SendNotification(LANG_YOUR_BG_LEVEL_REQ_ERROR);
@@ -65,7 +64,7 @@ void WorldSession::HandleBattleGroundHelloOpcode( WorldPacket & recv_data )
SendBattlegGroundList(guid, bgTypeId);
}
-void WorldSession::SendBattlegGroundList( uint64 guid, uint32 bgTypeId )
+void WorldSession::SendBattlegGroundList( uint64 guid, BattleGroundTypeId bgTypeId )
{
WorldPacket data;
sBattleGroundMgr.BuildBattleGroundListPacket(&data, guid, _player, bgTypeId);
@@ -77,57 +76,60 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
CHECK_PACKET_SIZE(recv_data, 8+4+4+1);
uint64 guid;
- uint32 bgTypeId;
+ uint32 bgTypeId_;
uint32 instanceId;
uint8 joinAsGroup;
+ bool isPremade = false;
Group * grp;
recv_data >> guid; // battlemaster guid
- recv_data >> bgTypeId; // battleground type id (DBC id)
+ recv_data >> bgTypeId_; // battleground type id (DBC id)
recv_data >> instanceId; // instance id, 0 if First Available selected
recv_data >> joinAsGroup; // join as group
- if(bgTypeId >= MAX_BATTLEGROUND_TYPES)
+ if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
{
- sLog.outError("Battleground: invalid bgtype received. possible cheater? player guid %u",_player->GetGUIDLow());
+ sLog.outError("Battleground: invalid bgtype (%u) received. possible cheater? player guid %u",bgTypeId_,_player->GetGUIDLow());
return;
}
+ BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_);
+
sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from: " I64FMT, guid);
// can do this, since it's battleground, not arena
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId, 0);
+ BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, 0);
// ignore if player is already in BG
- if(_player->InBattleGround())
+ if (_player->InBattleGround())
return;
- Creature *unit = ObjectAccessor::GetCreature(*_player, guid);
- if(!unit)
+ Creature *unit = GetPlayer()->GetMap()->GetCreature(guid);
+ if (!unit)
return;
if(!unit->isBattleMaster()) // it's not battlemaster
return;
// get bg instance or bg template if instance not found
- BattleGround * bg = 0;
- if(instanceId)
- BattleGround *bg = sBattleGroundMgr.GetBattleGround(instanceId);
+ BattleGround *bg = NULL;
+ if (instanceId)
+ bg = sBattleGroundMgr.GetBattleGroundThroughClientInstance(instanceId, bgTypeId);
- if(!bg && !(bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId)))
+ if (!bg && !(bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId)))
{
sLog.outError("Battleground: no available bg / template found");
return;
}
// check queueing conditions
- if(!joinAsGroup)
+ if (!joinAsGroup)
{
// check Deserter debuff
- if( !_player->CanJoinToBattleground() )
+ if (!_player->CanJoinToBattleground())
{
WorldPacket data(SMSG_GROUP_JOINED_BATTLEGROUND, 4);
- data << (uint32) 0xFFFFFFFE;
+ data << uint32(0xFFFFFFFE);
_player->GetSession()->SendPacket(&data);
return;
}
@@ -136,16 +138,17 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
//player is already in this queue
return;
// check if has free queue slots
- if(!_player->HasFreeBattleGroundQueueId())
+ if (!_player->HasFreeBattleGroundQueueId())
return;
}
else
{
grp = _player->GetGroup();
// no group found, error
- if(!grp)
+ if (!grp)
return;
uint32 err = grp->CanJoinBattleGroundQueue(bgTypeId, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0);
+ isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam());
if (err != BG_JOIN_ERR_OK)
{
SendBattleGroundOrArenaJoinError(err);
@@ -155,10 +158,11 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
// if we're here, then the conditions to join a bg are met. We can proceed in joining.
// _player->GetGroup() was already checked, grp is already initialized
- if(joinAsGroup /* && _player->GetGroup()*/)
+ GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, isPremade, 0);
+ uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
+ if (joinAsGroup /* && _player->GetGroup()*/)
{
sLog.outDebug("Battleground: the following players are joining as group:");
- GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, 0);
for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
{
Player *member = itr->getSource();
@@ -171,7 +175,7 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
WorldPacket data;
// send status packet (in queue)
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, member->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0);
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType);
member->GetSession()->SendPacket(&data);
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId);
member->GetSession()->SendPacket(&data);
@@ -179,7 +183,6 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName());
}
sLog.outDebug("Battleground: group end");
- sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel());
}
else
{
@@ -190,14 +193,15 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
WorldPacket data;
// send status packet (in queue)
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0);
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType);
SendPacket(&data);
- GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, 0);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo);
- sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel());
sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
}
+ sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
+ if (!ginfo->IsInvitedToBGInstanceGUID)
+ sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true);
}
void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv_data*/ )
@@ -209,40 +213,62 @@ void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv
if(!bg) // can't be received if player not in battleground
return;
- if(bg->GetTypeID() == BATTLEGROUND_WS)
+ switch( bg->GetTypeID() )
{
- uint32 count1 = 0;
- uint32 count2 = 0;
+ case BATTLEGROUND_WS:
+ {
+ uint32 count1 = 0; //always constant zero?
+ uint32 count2 = 0; //count of next fields
- Player *ap = objmgr.GetPlayer(((BattleGroundWS*)bg)->GetAllianceFlagPickerGUID());
- if(ap) ++count2;
+ Player *ali_plr = objmgr.GetPlayer(((BattleGroundWS*)bg)->GetAllianceFlagPickerGUID());
+ if (ali_plr)
+ ++count2;
- Player *hp = objmgr.GetPlayer(((BattleGroundWS*)bg)->GetHordeFlagPickerGUID());
- if(hp) ++count2;
+ Player *horde_plr = objmgr.GetPlayer(((BattleGroundWS*)bg)->GetHordeFlagPickerGUID());
+ if (horde_plr)
+ ++count2;
- WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, (4+4+16*count1+16*count2));
- data << count1; // alliance flag holders count
- /*for(uint8 i = 0; i < count1; i++)
- {
- data << uint64(0); // guid
- data << (float)0; // x
- data << (float)0; // y
- }*/
- data << count2; // horde flag holders count
- if(ap)
- {
- data << (uint64)ap->GetGUID();
- data << (float)ap->GetPositionX();
- data << (float)ap->GetPositionY();
- }
- if(hp)
- {
- data << (uint64)hp->GetGUID();
- data << (float)hp->GetPositionX();
- data << (float)hp->GetPositionY();
- }
+ WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, (4+4+16*count1+16*count2));
+ data << count1; // alliance flag holders count - obsolete, now always 0
+ /*for(uint8 i = 0; i < count1; ++i)
+ {
+ data << uint64(0); // guid
+ data << (float)0; // x
+ data << (float)0; // y
+ }*/
+ data << count2; // horde flag holders count - obsolete, now count of next fields
+ if (ali_plr)
+ {
+ data << (uint64)ali_plr->GetGUID();
+ data << (float)ali_plr->GetPositionX();
+ data << (float)ali_plr->GetPositionY();
+ }
+ if (horde_plr)
+ {
+ data << (uint64)horde_plr->GetGUID();
+ data << (float)horde_plr->GetPositionX();
+ data << (float)horde_plr->GetPositionY();
+ }
- SendPacket(&data);
+ SendPacket(&data);
+ }
+ break;
+ case BATTLEGROUND_EY:
+ //TODO : fix me!
+ break;
+ case BATTLEGROUND_AB:
+ case BATTLEGROUND_AV:
+ {
+ //for other BG types - send default
+ WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, (4+4));
+ data << uint32(0);
+ data << uint32(0);
+ SendPacket(&data);
+ }
+ break;
+ default:
+ //maybe it is sent also in arena - do nothing
+ break;
}
}
@@ -251,7 +277,7 @@ void WorldSession::HandleBattleGroundPVPlogdataOpcode( WorldPacket & /*recv_data
sLog.outDebug( "WORLD: Recvd MSG_PVP_LOG_DATA Message");
BattleGround *bg = _player->GetBattleGround();
- if(!bg)
+ if (!bg)
return;
WorldPacket data;
@@ -270,19 +296,15 @@ void WorldSession::HandleBattleGroundListOpcode( WorldPacket &recv_data )
uint32 bgTypeId;
recv_data >> bgTypeId; // id from DBC
- if(bgTypeId >= MAX_BATTLEGROUND_TYPES)
+ BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
+ if (!bl)
{
sLog.outError("Battleground: invalid bgtype received.");
return;
}
- BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
-
- if(!bl)
- return;
-
WorldPacket data;
- sBattleGroundMgr.BuildBattleGroundListPacket(&data, _player->GetGUID(), _player, bgTypeId);
+ sBattleGroundMgr.BuildBattleGroundListPacket(&data, _player->GetGUID(), _player, BattleGroundTypeId(bgTypeId));
SendPacket( &data );
}
@@ -295,45 +317,39 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
uint8 type; // arenatype if arena
uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1
uint32 instanceId;
- uint32 bgTypeId; // type id from dbc
+ uint32 bgTypeId_; // type id from dbc
uint16 unk; // 0x1F90 constant?
uint8 action; // enter battle 0x1, leave queue 0x0
- recv_data >> type >> unk2 >> bgTypeId >> unk >> action;
+ recv_data >> type >> unk2 >> bgTypeId_ >> unk >> action;
- if(bgTypeId >= MAX_BATTLEGROUND_TYPES)
+ if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
{
- sLog.outError("Battleground: invalid bgtype received.");
+ sLog.outError("Battleground: invalid bgtype (%u) received.", bgTypeId_);
// update battleground slots for the player to fix his UI and sent data.
// this is a HACK, I don't know why the client starts sending invalid packets in the first place.
// it usually happens with extremely high latency (if debugging / stepping in the code for example)
- if(_player->InBattleGroundQueue())
+ if (_player->InBattleGroundQueue())
{
// update all queues, send invitation info if player is invited, queue info if queued
- for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
+ for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
{
- uint32 queue_id = _player->GetBattleGroundQueueId(i);
- if(!queue_id)
- continue;
- BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = sBattleGroundMgr.m_BattleGroundQueues[queue_id].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].find(_player->GetGUID());
- // if the player is not in queue, contine
- if(itrPlayerStatus == sBattleGroundMgr.m_BattleGroundQueues[queue_id].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].end())
+ BattleGroundQueueTypeId bgQueueTypeId = _player->GetBattleGroundQueueTypeId(i);
+ if (!bgQueueTypeId)
continue;
-
- // no group information, this should never happen
- if(!itrPlayerStatus->second.GroupInfo)
+ BattleGroundTypeId bgTypeId = BattleGroundMgr::BGTemplateId(bgQueueTypeId);
+ BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers;
+ BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID());
+ // if the player is not in queue, continue or no group information - this should never happen
+ if (itrPlayerStatus == qpMap.end() || !itrPlayerStatus->second.GroupInfo)
continue;
BattleGround * bg = NULL;
-
// get possibly needed data from groupinfo
- bgTypeId = itrPlayerStatus->second.GroupInfo->BgTypeId;
uint8 arenatype = itrPlayerStatus->second.GroupInfo->ArenaType;
- uint8 israted = itrPlayerStatus->second.GroupInfo->IsRated;
uint8 status = 0;
-
- if(!itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID)
+ if (!itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID)
{
// not invited to bg, get template
bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
@@ -342,130 +358,124 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
else
{
// get the bg we're invited to
- BattleGround * bg = sBattleGroundMgr.GetBattleGround(itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID);
+ bg = sBattleGroundMgr.GetBattleGround(itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID, bgTypeId);
status = STATUS_WAIT_JOIN;
}
- // if bg not found, then continue
- if(!bg)
- continue;
-
- // don't invite if already in the instance
- if(_player->InBattleGround() && _player->GetBattleGround() && _player->GetBattleGround()->GetInstanceID() == bg->GetInstanceID())
+ // if bg not found, then continue, don't invite if already in the instance
+ if (!bg || (_player->InBattleGround() && _player->GetBattleGround() && _player->GetBattleGround()->GetInstanceID() == bg->GetInstanceID()))
continue;
// re - invite player with proper data
WorldPacket data;
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, itrPlayerStatus->second.GroupInfo->Team?itrPlayerStatus->second.GroupInfo->Team:_player->GetTeam(), i, status, INVITE_ACCEPT_WAIT_TIME, 0, arenatype, israted);
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, status, INVITE_ACCEPT_WAIT_TIME, 0, arenatype);
SendPacket(&data);
}
}
return;
}
- uint32 bgQueueTypeId = 0;
- // get the bg what we were invited to
- BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus;
- bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId,type);
- itrPlayerStatus = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].find(_player->GetGUID());
-
- if(itrPlayerStatus == sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].end())
+ //get GroupQueueInfo from BattleGroundQueue
+ BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_);
+ BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, type);
+ BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers;
+ BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID());
+ if (itrPlayerStatus == qpMap.end())
{
sLog.outError("Battleground: itrplayerstatus not found.");
return;
}
- instanceId = itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID;
- // if action == 1, then instanceId is _required_
- if(!instanceId && action == 1)
+ instanceId = itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID;
+ // if action == 1, then instanceId is required
+ if (!instanceId && action == 1)
{
sLog.outError("Battleground: instance not found.");
return;
}
- BattleGround *bg = sBattleGroundMgr.GetBattleGround(instanceId);
+ BattleGround *bg = sBattleGroundMgr.GetBattleGround(instanceId, bgTypeId);
// bg template might and must be used in case of leaving queue, when instance is not created yet
- if(!bg && action == 0)
+ if (!bg && action == 0)
bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
-
- if(!bg)
+ if (!bg)
{
- sLog.outError("Battleground: bg not found.");
+ sLog.outError("Battleground: bg_template not found for type id %u.", bgTypeId);
return;
}
- bgTypeId = bg->GetTypeID();
-
- if(_player->InBattleGroundQueue())
+ if (_player->InBattleGroundQueue())
{
- uint32 queueSlot = 0;
- uint32 team = 0;
- uint32 arenatype = 0;
- uint32 israted = 0;
- uint32 rating = 0;
- uint32 opponentsRating = 0;
- // get the team info from the queue
- BattleGroundQueue::QueuedPlayersMap::iterator pitr = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].find(_player->GetGUID());
- if(pitr !=sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].end()
- && pitr->second.GroupInfo )
- {
- team = pitr->second.GroupInfo->Team;
- arenatype = pitr->second.GroupInfo->ArenaType;
- israted = pitr->second.GroupInfo->IsRated;
- rating = pitr->second.GroupInfo->ArenaTeamRating;
- opponentsRating = pitr->second.GroupInfo->OpponentsTeamRating;
- }
- else
+ //we must use temporary variables, because GroupQueueInfo pointer can be deleted in BattleGroundQueue::RemovePlayer() function!
+ uint32 team = itrPlayerStatus->second.GroupInfo->Team;
+ uint32 arenaType = itrPlayerStatus->second.GroupInfo->ArenaType;
+ uint32 isRated = itrPlayerStatus->second.GroupInfo->IsRated;
+ uint32 rating = itrPlayerStatus->second.GroupInfo->ArenaTeamRating;
+ uint32 opponentsRating = itrPlayerStatus->second.GroupInfo->OpponentsTeamRating;
+
+ //some checks if player isn't cheating - it is not exactly cheating, but we cannot allow it
+ if (action == 1 && arenaType == 0)
{
- sLog.outError("Battleground: Invalid player queue info!");
- return;
+ //if player is trying to enter battleground (not arena!) and he has deserter debuff, we must just remove him from queue
+ if (!_player->CanJoinToBattleground())
+ {
+ //send bg command result to show nice message
+ WorldPacket data2(SMSG_GROUP_JOINED_BATTLEGROUND, 4);
+ data2 << uint32(0xFFFFFFFE);
+ _player->GetSession()->SendPacket(&data2);
+ action = 0;
+ sLog.outDebug("Battleground: player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName(), _player->GetGUIDLow());
+ }
+ //if player don't match battleground max level, then do not allow him to enter! (this might happen when player leveled up during his waiting in queue
+ if (_player->getLevel() > bg->GetMaxLevel())
+ {
+ sLog.outError("Battleground: Player %s (%u) has level higher than maxlevel of battleground! Do not port him to battleground!", _player->GetName(), _player->GetGUIDLow());
+ action = 0;
+ }
}
+ uint32 queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);
WorldPacket data;
- switch(action)
+ switch( action )
{
- case 1: // port to battleground
- if(!_player->IsInvitedForBattleGroundQueueType(bgQueueTypeId))
- return; // cheating?
+ case 1: // port to battleground
+ if (!_player->IsInvitedForBattleGroundQueueType(bgQueueTypeId))
+ return; // cheating?
// resurrect the player
- if(!_player->isAlive())
+ if (!_player->isAlive())
{
_player->ResurrectPlayer(1.0f);
_player->SpawnCorpseBones();
}
// stop taxi flight at port
- if(_player->isInFlight())
+ if (_player->isInFlight())
{
_player->GetMotionMaster()->MovementExpired();
_player->m_taxi.ClearTaxiDestinations();
}
- _player->RemoveFromGroup();
- queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime());
+
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType());
_player->GetSession()->SendPacket(&data);
// remove battleground queue status from BGmgr
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(_player->GetGUID(), false);
// this is still needed here if battleground "jumping" shouldn't add deserter debuff
- // also this required to prevent stuck at old battleground after SetBattleGroundId set to new
- if( BattleGround *currentBg = _player->GetBattleGround() )
+ // also this is required to prevent stuck at old battleground after SetBattleGroundId set to new
+ if (BattleGround *currentBg = _player->GetBattleGround())
currentBg->RemovePlayerAtLeave(_player->GetGUID(), false, true);
// set the destination instance id
- _player->SetBattleGroundId(bg->GetInstanceID());
+ _player->SetBattleGroundId(bg->GetInstanceID(), bgTypeId);
// set the destination team
_player->SetBGTeam(team);
// bg->HandleBeforeTeleportToBattleGround(_player);
- sBattleGroundMgr.SendToBattleGround(_player, instanceId);
+ sBattleGroundMgr.SendToBattleGround(_player, instanceId, bgTypeId);
// add only in HandleMoveWorldPortAck()
// bg->AddPlayer(_player,team);
- sLog.outDebug("Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.",_player->GetName(),_player->GetGUIDLow(),bg->GetInstanceID(),bg->GetTypeID(),bgQueueTypeId);
+ sLog.outDebug("Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetInstanceID(), bg->GetTypeID(), bgQueueTypeId);
break;
- case 0: // leave queue
- queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);
- /*
- if player leaves rated arena match before match start, it is counted as he played but he lost
- */
- if (israted)
+ case 0: // leave queue
+ // if player leaves rated arena match before match start, it is counted as he played but he lost
+ if (isRated)
{
ArenaTeam * at = objmgr.GetArenaTeamById(team);
if (at)
@@ -475,13 +485,14 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
at->SaveToDB();
}
}
- _player->RemoveBattleGroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_NONE, 0, 0);
+ _player->RemoveBattleGroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(_player->GetGUID(), true);
- // player left queue, we should update it, maybe now his group fits in
- sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId,_player->GetBattleGroundQueueIdFromLevel(),arenatype,israted,rating);
+ // player left queue, we should update it - do not update Arena Queue
+ if (!arenaType)
+ sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId), arenaType, isRated, rating);
SendPacket(&data);
- sLog.outDebug("Battleground: player %s (%u) left queue for bgtype %u, queue type %u.",_player->GetName(),_player->GetGUIDLow(),bg->GetTypeID(),bgQueueTypeId);
+ sLog.outDebug("Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetTypeID(), bgQueueTypeId);
break;
default:
sLog.outError("Battleground port: unknown action %u", action);
@@ -506,9 +517,9 @@ void WorldSession::HandleBattleGroundLeaveOpcode( WorldPacket & /*recv_data*/ )
// return;
// not allow leave battleground in combat
- if(_player->isInCombat())
- if(BattleGround* bg = _player->GetBattleGround())
- if(bg->GetStatus() != STATUS_WAIT_LEAVE)
+ if (_player->isInCombat())
+ if (BattleGround* bg = _player->GetBattleGround())
+ if (bg->GetStatus() != STATUS_WAIT_LEAVE)
return;
_player->LeaveBattleground();
@@ -520,81 +531,56 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
sLog.outDebug( "WORLD: Battleground status" );
WorldPacket data;
-
- // TODO: we must put player back to battleground in case disconnect (< 5 minutes offline time) or teleport player on login(!) from battleground map to entry point
- if(_player->InBattleGround())
+ // we must update all queues here
+ BattleGround *bg = NULL;
+ for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
{
- BattleGround *bg = _player->GetBattleGround();
- if(bg)
+ BattleGroundQueueTypeId bgQueueTypeId = _player->GetBattleGroundQueueTypeId(i);
+ if (!bgQueueTypeId)
+ continue;
+ BattleGroundTypeId bgTypeId = BattleGroundMgr::BGTemplateId(bgQueueTypeId);
+ uint8 arenaType = BattleGroundMgr::BGArenaType(bgQueueTypeId);
+ if (bgTypeId == _player->GetBattleGroundTypeId())
{
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
- uint32 queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);
- if((bg->GetStatus() <= STATUS_IN_PROGRESS))
+ bg = _player->GetBattleGround();
+ //i cannot check any variable from player class because player class doesn't know if player is in 2v2 / 3v3 or 5v5 arena
+ //so i must use bg pointer to get that information
+ if (bg && bg->GetArenaType() == arenaType)
{
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime());
+ // this line is checked, i only don't know if GetStartTime is changing itself after bg end!
+ // send status in BattleGround
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType);
SendPacket(&data);
- }
- for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
- {
- uint32 queue_id = _player->GetBattleGroundQueueId(i); // battlegroundqueueid stores the type id, not the instance id, so this is definitely wrong
- uint8 arenatype = sBattleGroundMgr.BGArenaType(queue_id);
- uint8 isRated = 0;
- if (i == queueSlot || !queue_id) // we need to get the instance ids
- continue;
- BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = sBattleGroundMgr.m_BattleGroundQueues[queue_id].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].find(_player->GetGUID());
- if(itrPlayerStatus == sBattleGroundMgr.m_BattleGroundQueues[queue_id].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].end())
- continue;
- if(itrPlayerStatus->second.GroupInfo)
- {
- arenatype = itrPlayerStatus->second.GroupInfo->ArenaType;
- isRated = itrPlayerStatus->second.GroupInfo->IsRated;
- }
- BattleGround *bg2 = sBattleGroundMgr.GetBattleGroundTemplate(sBattleGroundMgr.BGTemplateId(queue_id)); // try this
- if(bg2)
- {
- //in this call is small bug, this call should be filled by player's waiting time in queue
- //this call nulls all timers for client :
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg2, _player->GetTeam(), i, STATUS_WAIT_QUEUE, 0, 0,arenatype,isRated);
- SendPacket(&data);
- }
+ continue;
}
}
- }
- else
- {
- // we should update all queues? .. i'm not sure if this code is correct
- for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
+ //we are sending update to player about queue - he can be invited there!
+ //get GroupQueueInfo for queue status
+ BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers;
+ BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID());
+ if (itrPlayerStatus == qpMap.end())
+ continue;
+ if (itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID)
{
- uint32 queue_id = _player->GetBattleGroundQueueId(i);
- if(!queue_id)
- continue;
- uint32 bgTypeId = sBattleGroundMgr.BGTemplateId(queue_id);
- uint8 arenatype = sBattleGroundMgr.BGArenaType(queue_id);
- uint8 isRated = 0;
- BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
- BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = sBattleGroundMgr.m_BattleGroundQueues[queue_id].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].find(_player->GetGUID());
- if(itrPlayerStatus == sBattleGroundMgr.m_BattleGroundQueues[queue_id].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].end())
+ bg = sBattleGroundMgr.GetBattleGround(itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID, bgTypeId);
+ if (!bg)
continue;
- if(itrPlayerStatus->second.GroupInfo)
- {
- arenatype = itrPlayerStatus->second.GroupInfo->ArenaType;
- isRated = itrPlayerStatus->second.GroupInfo->IsRated;
- }
- if(bg && queue_id)
- {
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), i, STATUS_WAIT_QUEUE, 0, 0, arenatype, isRated);
- SendPacket(&data);
- }
+ uint32 remainingTime = getMSTimeDiff(getMSTime(), itrPlayerStatus->second.GroupInfo->RemoveInviteTime);
+ // send status invited to BattleGround
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_JOIN, remainingTime, 0, arenaType);
+ SendPacket(&data);
}
- }
-/* else // not sure if it needed...
- {
- for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
+ else
{
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, NULL, _player->GetTeam(),i , STATUS_NONE, 0, 0);
+ bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
+ if (!bg)
+ continue;
+ uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(itrPlayerStatus->second.GroupInfo, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
+ // send status in BattleGround Queue
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(itrPlayerStatus->second.GroupInfo->JoinTime, getMSTime()), arenaType);
SendPacket(&data);
}
- }*/
+ }
}
void WorldSession::HandleAreaSpiritHealerQueryOpcode( WorldPacket & recv_data )
@@ -604,14 +590,14 @@ void WorldSession::HandleAreaSpiritHealerQueryOpcode( WorldPacket & recv_data )
CHECK_PACKET_SIZE(recv_data, 8);
BattleGround *bg = _player->GetBattleGround();
- if(!bg)
+ if (!bg)
return;
uint64 guid;
recv_data >> guid;
- Creature *unit = ObjectAccessor::GetCreature(*_player, guid);
- if(!unit)
+ Creature *unit = GetPlayer()->GetMap()->GetCreature(guid);
+ if (!unit)
return;
if(!unit->isSpiritService()) // it's not spirit service
@@ -627,14 +613,14 @@ void WorldSession::HandleAreaSpiritHealerQueueOpcode( WorldPacket & recv_data )
CHECK_PACKET_SIZE(recv_data, 8);
BattleGround *bg = _player->GetBattleGround();
- if(!bg)
+ if (!bg)
return;
uint64 guid;
recv_data >> guid;
- Creature *unit = ObjectAccessor::GetCreature(*_player, guid);
- if(!unit)
+ Creature *unit = GetPlayer()->GetMap()->GetCreature(guid);
+ if (!unit)
return;
if(!unit->isSpiritService()) // it's not spirit service
@@ -651,19 +637,19 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
recv_data.hexlike();
// ignore if we already in BG or BG queue
- if(_player->InBattleGround())
+ if (_player->InBattleGround())
return;
uint64 guid; // arena Battlemaster guid
- uint8 type; // 2v2, 3v3 or 5v5
+ uint8 arenaslot; // 2v2, 3v3 or 5v5
uint8 asGroup; // asGroup
uint8 isRated; // isRated
Group * grp;
- recv_data >> guid >> type >> asGroup >> isRated;
+ recv_data >> guid >> arenaslot >> asGroup >> isRated;
- Creature *unit = ObjectAccessor::GetCreature(*_player, guid);
- if(!unit)
+ Creature *unit = GetPlayer()->GetMap()->GetCreature(guid);
+ if (!unit)
return;
if(!unit->isBattleMaster()) // it's not battle master
@@ -672,7 +658,7 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
uint8 arenatype = 0;
uint32 arenaRating = 0;
- switch(type)
+ switch(arenaslot)
{
case 0:
arenatype = ARENA_TYPE_2v2;
@@ -684,39 +670,39 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
arenatype = ARENA_TYPE_5v5;
break;
default:
- sLog.outError("Unknown arena type %u at HandleBattleGroundArenaJoin()", type);
+ sLog.outError("Unknown arena slot %u at HandleBattleGroundArenaJoin()", arenaslot);
return;
}
//check existance
BattleGround* bg = NULL;
- if( !(bg = sBattleGroundMgr.GetBattleGroundTemplate(BATTLEGROUND_AA)) )
+ if (!(bg = sBattleGroundMgr.GetBattleGroundTemplate(BATTLEGROUND_AA)))
{
sLog.outError("Battleground: template bg (all arenas) not found");
return;
}
- uint8 bgTypeId = bg->GetTypeID();
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId, arenatype);
+ BattleGroundTypeId bgTypeId = bg->GetTypeID();
+ BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype);
// check queueing conditions
- if(!asGroup)
+ if (!asGroup)
{
// check if already in queue
if (_player->GetBattleGroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES)
//player is already in this queue
return;
// check if has free queue slots
- if(!_player->HasFreeBattleGroundQueueId())
+ if (!_player->HasFreeBattleGroundQueueId())
return;
}
else
{
grp = _player->GetGroup();
// no group found, error
- if(!grp)
+ if (!grp)
return;
- uint32 err = grp->CanJoinBattleGroundQueue(bgTypeId, bgQueueTypeId, arenatype, arenatype, (bool)isRated, type);
+ uint32 err = grp->CanJoinBattleGroundQueue(bgTypeId, bgQueueTypeId, arenatype, arenatype, (bool)isRated, arenaslot);
if (err != BG_JOIN_ERR_OK)
{
SendBattleGroundOrArenaJoinError(err);
@@ -726,12 +712,12 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
uint32 ateamId = 0;
- if(isRated)
+ if (isRated)
{
- ateamId = _player->GetArenaTeamId(type);
+ ateamId = _player->GetArenaTeamId(arenaslot);
// check real arenateam existence only here (if it was moved to group->CanJoin .. () then we would ahve to get it twice)
ArenaTeam * at = objmgr.GetArenaTeamById(ateamId);
- if(!at)
+ if (!at)
{
_player->GetSession()->SendNotInArenaTeamPacket(arenatype);
return;
@@ -746,23 +732,24 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
Player *member = itr->getSource();
// calc avg personal rating
- avg_pers_rating += member->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (type*6) + 5);
+ avg_pers_rating += member->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (arenaslot*6) + 5);
}
- if( arenatype )
+ if (arenatype)
avg_pers_rating /= arenatype;
// if avg personal rating is more than 150 points below the teams rating, the team will be queued against an opponent matching or similar to the average personal rating
- if(avg_pers_rating + 150 < arenaRating)
+ if (avg_pers_rating + 150 < arenaRating)
arenaRating = avg_pers_rating;
}
- if(asGroup)
+ GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, false, arenaRating, ateamId);
+ uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
+ if (asGroup)
{
- GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, arenaRating, ateamId);
sLog.outDebug("Battleground: arena join as group start");
- if(isRated)
- sLog.outDebug("Battleground: arena team id %u, leader %s queued with rating %u for type %u",_player->GetArenaTeamId(type),_player->GetName(),arenaRating,arenatype);
+ if (isRated)
+ sLog.outDebug("Battleground: arena team id %u, leader %s queued with rating %u for type %u",_player->GetArenaTeamId(arenaslot),_player->GetName(),arenaRating,arenatype);
for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
{
Player *member = itr->getSource();
@@ -775,7 +762,7 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
WorldPacket data;
// send status packet (in queue)
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, member->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0, arenatype, isRated);
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype);
member->GetSession()->SendPacket(&data);
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId);
member->GetSession()->SendPacket(&data);
@@ -783,7 +770,8 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
sLog.outDebug("Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName());
}
sLog.outDebug("Battleground: arena join as group end");
- sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(), arenatype, isRated, arenaRating);
+ if (isRated)
+ sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true);
}
else
{
@@ -794,13 +782,12 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
WorldPacket data;
// send status packet (in queue)
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0, arenatype, isRated);
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype);
SendPacket(&data);
- GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, arenaRating);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo);
- sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(), arenatype, isRated, arenaRating);
sLog.outDebug("Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
}
+ sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId), arenatype, isRated, arenaRating);
}
void WorldSession::HandleBattleGroundReportAFK( WorldPacket & recv_data )
@@ -811,7 +798,7 @@ void WorldSession::HandleBattleGroundReportAFK( WorldPacket & recv_data )
recv_data >> playerGuid;
Player *reportedPlayer = objmgr.GetPlayer(playerGuid);
- if(!reportedPlayer)
+ if (!reportedPlayer)
{
sLog.outDebug("WorldSession::HandleBattleGroundReportAFK: player not found");
return;
diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp
index 54d2538068d..f0f801c3060 100644
--- a/src/game/BattleGroundMgr.cpp
+++ b/src/game/BattleGroundMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -19,6 +19,7 @@
*/
#include "Common.h"
+#include "SharedDefines.h"
#include "Player.h"
#include "BattleGroundMgr.h"
#include "BattleGroundAV.h"
@@ -29,16 +30,21 @@
#include "BattleGroundBE.h"
#include "BattleGroundAA.h"
#include "BattleGroundRL.h"
-#include "SharedDefines.h"
-#include "Policies/SingletonImp.h"
+#include "BattleGroundSA.h"
+#include "BattleGroundDS.h"
+#include "BattleGroundRV.h"
#include "MapManager.h"
#include "Map.h"
#include "MapInstanced.h"
#include "ObjectMgr.h"
#include "ProgressBar.h"
-#include "World.h"
#include "Chat.h"
#include "ArenaTeam.h"
+#include "World.h"
+#include "WorldPacket.h"
+#include "ProgressBar.h"
+
+#include "Policies/SingletonImp.h"
INSTANTIATE_SINGLETON_1( BattleGroundMgr );
@@ -48,96 +54,103 @@ INSTANTIATE_SINGLETON_1( BattleGroundMgr );
BattleGroundQueue::BattleGroundQueue()
{
- //queues are empty, we don't have to call clear()
-/* for (int i = 0; i < MAX_BATTLEGROUND_QUEUES; i++)
+ for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
{
- //m_QueuedPlayers[i].Horde = 0;
- //m_QueuedPlayers[i].Alliance = 0;
- //m_QueuedPlayers[i].AverageTime = 0;
- }*/
-}
-
-BattleGroundQueue::~BattleGroundQueue()
-{
- for (int i = 0; i < MAX_BATTLEGROUND_QUEUES; i++)
- {
- m_QueuedPlayers[i].clear();
- for(QueuedGroupsList::iterator itr = m_QueuedGroups[i].begin(); itr!= m_QueuedGroups[i].end(); ++itr)
+ for(uint32 j = 0; j < MAX_BATTLEGROUND_QUEUES; j++)
{
- delete (*itr);
+ m_SumOfWaitTimes[i][j] = 0;
+ m_WaitTimeLastPlayer[i][j] = 0;
+ for(uint32 k = 0; k < COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME; k++)
+ m_WaitTimes[i][j][k] = 0;
}
- m_QueuedGroups[i].clear();
}
}
-// initialize eligible groups from the given source matching the given specifications
-void BattleGroundQueue::EligibleGroups::Init(BattleGroundQueue::QueuedGroupsList *source, uint32 BgTypeId, uint32 side, uint32 MaxPlayers, uint8 ArenaType, bool IsRated, uint32 MinRating, uint32 MaxRating, uint32 DisregardTime, uint32 excludeTeam)
+BattleGroundQueue::~BattleGroundQueue()
{
- // clear from prev initialization
- clear();
- BattleGroundQueue::QueuedGroupsList::iterator itr, next;
- // iterate through the source
- for(itr = source->begin(); itr!= source->end(); itr = next)
+ m_QueuedPlayers.clear();
+ for (int i = 0; i < MAX_BATTLEGROUND_QUEUES; i++)
{
- next = itr;
- ++next;
- if( (*itr)->BgTypeId == BgTypeId && // bg type must match
- (*itr)->ArenaType == ArenaType && // arena type must match
- (*itr)->IsRated == IsRated && // israted must match
- (*itr)->IsInvitedToBGInstanceGUID == 0 && // leave out already invited groups
- (*itr)->Team == side && // match side
- (*itr)->Players.size() <= MaxPlayers && // the group must fit in the bg
- ( !excludeTeam || (*itr)->ArenaTeamId != excludeTeam ) && // if excludeTeam is specified, leave out those arena team ids
- ( !IsRated || (*itr)->Players.size() == MaxPlayers ) && // if rated, then pass only if the player count is exact NEEDS TESTING! (but now this should never happen)
- ( !DisregardTime || (*itr)->JoinTime <= DisregardTime // pass if disregard time is greater than join time
- || (*itr)->ArenaTeamRating == 0 // pass if no rating info
- || ( (*itr)->ArenaTeamRating >= MinRating // pass if matches the rating range
- && (*itr)->ArenaTeamRating <= MaxRating ) ) )
+ for(uint32 j = 0; j < BG_QUEUE_GROUP_TYPES_COUNT; j++)
{
- // the group matches the conditions
- // using push_back for proper selecting when inviting
- push_back((*itr));
+ for(GroupsQueueType::iterator itr = m_QueuedGroups[i][j].begin(); itr!= m_QueuedGroups[i][j].end(); ++itr)
+ delete (*itr);
+ m_QueuedGroups[i][j].clear();
}
}
}
+/*********************************************************/
+/*** BATTLEGROUND QUEUE SELECTION POOLS ***/
+/*********************************************************/
+
// selection pool initialization, used to clean up from prev selection
-void BattleGroundQueue::SelectionPool::Init(EligibleGroups * curr)
+void BattleGroundQueue::SelectionPool::Init()
{
- m_CurrEligGroups = curr;
SelectedGroups.clear();
PlayerCount = 0;
}
// remove group info from selection pool
-void BattleGroundQueue::SelectionPool::RemoveGroup(GroupQueueInfo *ginfo)
+// returns true when we need to try to add new group to selection pool
+// returns false when selection pool is ok or when we kicked smaller group than we need to kick
+// sometimes it can be called on empty selection pool
+bool BattleGroundQueue::SelectionPool::KickGroup(uint32 size)
{
- // find what to remove
- for(std::list<GroupQueueInfo *>::iterator itr = SelectedGroups.begin(); itr != SelectedGroups.end(); ++itr)
+ //find maxgroup or LAST group with size == size and kick it
+ bool found = false;
+ GroupsQueueType::iterator groupToKick = SelectedGroups.begin();
+ for (GroupsQueueType::iterator itr = groupToKick; itr != SelectedGroups.end(); ++itr)
{
- if((*itr)==ginfo)
+ if (abs((int32)((*itr)->Players.size() - size)) <= 1)
{
- SelectedGroups.erase(itr);
- // decrease selected players count
- PlayerCount -= ginfo->Players.size();
- return;
+ groupToKick = itr;
+ found = true;
}
+ else if (!found && (*itr)->Players.size() >= (*groupToKick)->Players.size())
+ groupToKick = itr;
+ }
+ //if pool is empty, do nothing
+ if (GetPlayerCount())
+ {
+ //update player count
+ GroupQueueInfo* ginfo = (*groupToKick);
+ SelectedGroups.erase(groupToKick);
+ PlayerCount -= ginfo->Players.size();
+ //return false if we kicked smaller group or there are enough players in selection pool
+ if (ginfo->Players.size() <= size + 1)
+ return false;
}
+ return true;
}
-// add group to selection
+// add group to selection pool
// used when building selection pools
-void BattleGroundQueue::SelectionPool::AddGroup(GroupQueueInfo * ginfo)
+// returns true if we can invite more players, or when we added group to selection pool
+// returns false when selection pool is full
+bool BattleGroundQueue::SelectionPool::AddGroup(GroupQueueInfo *ginfo, uint32 desiredCount)
{
- SelectedGroups.push_back(ginfo);
- // increase selected players count
- PlayerCount+=ginfo->Players.size();
+ //if group is larger than desired count - don't allow to add it to pool
+ if (!ginfo->IsInvitedToBGInstanceGUID && desiredCount >= PlayerCount + ginfo->Players.size())
+ {
+ SelectedGroups.push_back(ginfo);
+ // increase selected players count
+ PlayerCount += ginfo->Players.size();
+ return true;
+ }
+ if (PlayerCount < desiredCount)
+ return true;
+ return false;
}
+/*********************************************************/
+/*** BATTLEGROUND QUEUES ***/
+/*********************************************************/
+
// add group to bg queue with the given leader and bg specifications
-GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, uint32 BgTypeId, uint8 ArenaType, bool isRated, uint32 arenaRating, uint32 arenateamid)
+GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, BattleGroundTypeId BgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 arenaRating, uint32 arenateamid)
{
- uint32 queue_id = leader->GetBattleGroundQueueIdFromLevel();
+ BGQueueIdBasedOnLevel queue_id = leader->GetBattleGroundQueueIdFromLevel(BgTypeId);
// create new ginfo
// cannot use the method like in addplayer, because that could modify an in-queue group's stats
@@ -147,28 +160,34 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, uint32 BgTypeId, ui
ginfo->ArenaType = ArenaType;
ginfo->ArenaTeamId = arenateamid;
ginfo->IsRated = isRated;
- ginfo->IsInvitedToBGInstanceGUID = 0; // maybe this should be modifiable by function arguments to enable selection of running instances?
+ ginfo->IsInvitedToBGInstanceGUID = 0;
ginfo->JoinTime = getMSTime();
+ ginfo->RemoveInviteTime = 0;
ginfo->Team = leader->GetTeam();
ginfo->ArenaTeamRating = arenaRating;
- ginfo->OpponentsTeamRating = 0; //initialize it to 0
+ ginfo->OpponentsTeamRating = 0;
ginfo->Players.clear();
- m_QueuedGroups[queue_id].push_back(ginfo);
+ //compute index (if group is premade or joined a rated match) to queues
+ uint32 index = 0;
+ if (!isRated && !isPremade)
+ index += BG_TEAMS_COUNT;
+ if (ginfo->Team == HORDE)
+ index++;
+ sLog.outDebug("Adding Group to BattleGroundQueue bgTypeId : %u, queue_id : %u, index : %u", BgTypeId, queue_id, index);
+
+ m_QueuedGroups[queue_id][index].push_back(ginfo);
// return ginfo, because it is needed to add players to this group info
return ginfo;
}
+//add player to playermap
void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo)
{
- uint32 queue_id = plr->GetBattleGroundQueueIdFromLevel();
-
//if player isn't in queue, he is added, if already is, then values are overwritten, no memory leak
- PlayerQueueInfo& info = m_QueuedPlayers[queue_id][plr->GetGUID()];
- info.InviteTime = 0;
- info.LastInviteTime = 0;
+ PlayerQueueInfo& info = m_QueuedPlayers[plr->GetGUID()];
info.LastOnlineTime = getMSTime();
info.GroupInfo = ginfo;
@@ -176,113 +195,228 @@ void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo)
ginfo->Players[plr->GetGUID()] = &info;
}
-void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)
+void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id)
{
- Player *plr = objmgr.GetPlayer(guid);
+ uint32 timeInQueue = getMSTimeDiff(ginfo->JoinTime, getMSTime());
+ uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas!
+ if (!ginfo->ArenaType)
+ {
+ if (ginfo->Team == HORDE)
+ team_index = BG_TEAM_HORDE;
+ }
+ else
+ {
+ if (ginfo->IsRated)
+ team_index = BG_TEAM_HORDE; //for rated arenas use BG_TEAM_HORDE
+ }
- uint32 queue_id = 0;
- QueuedPlayersMap::iterator itr;
- GroupQueueInfo * group;
- QueuedGroupsList::iterator group_itr;
- bool IsSet = false;
- if(plr)
+ //store pointer to arrayindex of player that was added first
+ uint32* lastPlayerAddedPointer = &(m_WaitTimeLastPlayer[team_index][queue_id]);
+ //remove his time from sum
+ m_SumOfWaitTimes[team_index][queue_id] -= m_WaitTimes[team_index][queue_id][(*lastPlayerAddedPointer)];
+ //set average time to new
+ m_WaitTimes[team_index][queue_id][(*lastPlayerAddedPointer)] = timeInQueue;
+ //add new time to sum
+ m_SumOfWaitTimes[team_index][queue_id] += timeInQueue;
+ //set index of last player added to next one
+ (*lastPlayerAddedPointer)++;
+ (*lastPlayerAddedPointer) %= COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME;
+}
+
+uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id)
+{
+ uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas!
+ if (!ginfo->ArenaType)
{
- queue_id = plr->GetBattleGroundQueueIdFromLevel();
+ if (ginfo->Team == HORDE)
+ team_index = BG_TEAM_HORDE;
+ }
+ else
+ {
+ if (ginfo->IsRated)
+ team_index = BG_TEAM_HORDE; //for rated arenas use BG_TEAM_HORDE
+ }
+ //check if there is enought values(we always add values > 0)
+ if (m_WaitTimes[team_index][queue_id][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME - 1] )
+ return (m_SumOfWaitTimes[team_index][queue_id] / COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME);
+ else
+ //if there aren't enough values return 0 - not available
+ return 0;
+}
+
+//remove player from queue and from group info, if group info is empty then remove it too
+void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCount)
+{
+ //Player *plr = objmgr.GetPlayer(guid);
+
+ int32 queue_id = -1; // signed for proper for-loop finish
+ QueuedPlayersMap::iterator itr;
- itr = m_QueuedPlayers[queue_id].find(guid);
- if(itr != m_QueuedPlayers[queue_id].end())
- IsSet = true;
+ //remove player from map, if he's there
+ itr = m_QueuedPlayers.find(guid);
+ if (itr == m_QueuedPlayers.end())
+ {
+ sLog.outError("BattleGroundQueue: couldn't find player to remove GUID: %u", GUID_LOPART(guid));
+ return;
}
- if(!IsSet)
+ GroupQueueInfo* group = itr->second.GroupInfo;
+ GroupsQueueType::iterator group_itr, group_itr_tmp;
+ // mostly people with the highest levels are in battlegrounds, thats why
+ // we count from MAX_BATTLEGROUND_QUEUES - 1 to 0
+ // variable index removes useless searching in other team's queue
+ uint32 index = (group->Team == HORDE) ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE;
+
+ for (int32 queue_id_tmp = MAX_BATTLEGROUND_QUEUES - 1; queue_id_tmp >= 0 && queue_id == -1; --queue_id_tmp)
{
- // either player is offline, or he levelled up to another queue category
- // sLog.outError("Battleground: removing offline player from BG queue - this might not happen, but it should not cause crash");
- for (uint32 i = 0; i < MAX_BATTLEGROUND_QUEUES; i++)
+ //we must check premade and normal team's queue - because when players from premade are joining bg,
+ //they leave groupinfo so we can't use its players size to find out index
+ for (uint32 j = index; j < BG_QUEUE_GROUP_TYPES_COUNT; j += BG_QUEUE_NORMAL_ALLIANCE)
{
- itr = m_QueuedPlayers[i].find(guid);
- if(itr != m_QueuedPlayers[i].end())
+ for(group_itr_tmp = m_QueuedGroups[queue_id_tmp][j].begin(); group_itr_tmp != m_QueuedGroups[queue_id_tmp][j].end(); ++group_itr_tmp)
{
- queue_id = i;
- IsSet = true;
- break;
+ if ((*group_itr_tmp) == group)
+ {
+ queue_id = queue_id_tmp;
+ group_itr = group_itr_tmp;
+ //we must store index to be able to erase iterator
+ index = j;
+ break;
+ }
}
}
}
-
- // couldn't find the player in bg queue, return
- if(!IsSet)
+ //player can't be in queue without group, but just in case
+ if (queue_id == -1)
{
- sLog.outError("Battleground: couldn't find player to remove.");
+ sLog.outError("BattleGroundQueue: ERROR Cannot find groupinfo for player GUID: %u", GUID_LOPART(guid));
return;
}
+ sLog.outDebug("BattleGroundQueue: Removing player GUID %u, from queue_id %u", GUID_LOPART(guid), (uint32)queue_id);
- group = itr->second.GroupInfo;
+ // ALL variables are correctly set
+ // We can ignore leveling up in queue - it should not cause crash
+ // remove player from group
+ // if only one player there, remove group
- for(group_itr=m_QueuedGroups[queue_id].begin(); group_itr != m_QueuedGroups[queue_id].end(); ++group_itr)
+ // remove player queue info from group queue info
+ std::map<uint64, PlayerQueueInfo*>::iterator pitr = group->Players.find(guid);
+ if (pitr != group->Players.end())
+ group->Players.erase(pitr);
+
+ // if invited to bg, and should decrease invited count, then do it
+ if (decreaseInvitedCount && group->IsInvitedToBGInstanceGUID)
{
- if(group == (GroupQueueInfo*)(*group_itr))
- break;
+ BattleGround* bg = sBattleGroundMgr.GetBattleGround(group->IsInvitedToBGInstanceGUID, group->BgTypeId);
+ if (bg)
+ bg->DecreaseInvitedCount(group->Team);
}
- // variables are set (what about leveling up when in queue????)
- // remove player from group
- // if only player there, remove group
+ // remove player queue info
+ m_QueuedPlayers.erase(itr);
- // remove player queue info from group queue info
- std::map<uint64, PlayerQueueInfo*>::iterator pitr = group->Players.find(guid);
+ //if we left BG queue(not porting) OR if arena team left queue for rated match
+ if ((decreaseInvitedCount && !group->ArenaType) || (group->ArenaType && group->IsRated && group->Players.empty()))
+ AnnounceWorld(group, guid, false);
- if(pitr != group->Players.end())
- group->Players.erase(pitr);
+ //if player leaves queue and he is invited to rated arena match, then he have to loose
+ if (group->IsInvitedToBGInstanceGUID && group->IsRated && decreaseInvitedCount)
+ {
+ ArenaTeam * at = objmgr.GetArenaTeamById(group->ArenaTeamId);
+ if (at)
+ {
+ sLog.outDebug("UPDATING memberLost's personal arena rating for %u by opponents rating: %u", GUID_LOPART(guid), group->OpponentsTeamRating);
+ Player *plr = objmgr.GetPlayer(guid);
+ if (plr)
+ at->MemberLost(plr, group->OpponentsTeamRating);
+ else
+ at->OfflineMemberLost(guid, group->OpponentsTeamRating);
+ at->SaveToDB();
+ }
+ }
- // check for iterator correctness
- if (group_itr != m_QueuedGroups[queue_id].end() && itr != m_QueuedPlayers[queue_id].end())
+ // remove group queue info if needed
+ if (group->Players.empty())
{
- // used when player left the queue, NOT used when porting to bg
- if (decreaseInvitedCount)
+ m_QueuedGroups[queue_id][index].erase(group_itr);
+ delete group;
+ }
+ // if group wasn't empty, so it wasn't deleted, and player have left a rated
+ // queue -> everyone from the group should leave too
+ // don't remove recursively if already invited to bg!
+ else if (!group->IsInvitedToBGInstanceGUID && group->IsRated)
+ {
+ // remove next player, this is recursive
+ // first send removal information
+ if (Player *plr2 = objmgr.GetPlayer(group->Players.begin()->first))
{
- // if invited to bg, and should decrease invited count, then do it
- if(group->IsInvitedToBGInstanceGUID)
- {
- BattleGround* bg = sBattleGroundMgr.GetBattleGround(group->IsInvitedToBGInstanceGUID);
- if (bg)
- bg->DecreaseInvitedCount(group->Team);
- if (bg && !bg->GetPlayersSize() && !bg->GetInvitedCount(ALLIANCE) && !bg->GetInvitedCount(HORDE))
- {
- // no more players on battleground, set delete it
- bg->SetDeleteThis();
- }
- }
- // update the join queue, maybe now the player's group fits in a queue!
- // not yet implemented (should store bgTypeId in group queue info?)
+ BattleGround * bg = sBattleGroundMgr.GetBattleGroundTemplate(group->BgTypeId);
+ BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(group->BgTypeId, group->ArenaType);
+ uint32 queueSlot = plr2->GetBattleGroundQueueIndex(bgQueueTypeId);
+ plr2->RemoveBattleGroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to
+ // queue->removeplayer, it causes bugs
+ WorldPacket data;
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0);
+ plr2->GetSession()->SendPacket(&data);
}
- // remove player queue info
- m_QueuedPlayers[queue_id].erase(itr);
- // remove group queue info if needed
- if(group->Players.empty())
+ // then actually delete, this may delete the group as well!
+ RemovePlayer(group->Players.begin()->first, decreaseInvitedCount);
+ }
+}
+
+//Announce world message
+void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue)
+{
+ if(ginfo->ArenaType) //if Arena
+ {
+ if (sWorld.getConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE) && ginfo->IsRated)
{
- m_QueuedGroups[queue_id].erase(group_itr);
- delete group;
+ BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(ginfo->BgTypeId);
+ if (!bg)
+ return;
+
+ char const* bgName = bg->GetName();
+ if (isAddedToQueue)
+ sWorld.SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN, bgName, ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating);
+ else
+ sWorld.SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT, bgName, ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating);
}
- // NEEDS TESTING!
- // group wasn't empty, so it wasn't deleted, and player have left a rated queue -> everyone from the group should leave too
- // don't remove recursively if already invited to bg!
- else if(!group->IsInvitedToBGInstanceGUID && decreaseInvitedCount && group->IsRated)
+ }
+ else //if BG
+ {
+ if (sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE))
{
- // remove next player, this is recursive
- // first send removal information
- if(Player *plr2 = objmgr.GetPlayer(group->Players.begin()->first))
+ Player *plr = objmgr.GetPlayer(playerGUID);
+ BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(ginfo->BgTypeId);
+ if (!bg || !plr)
+ return;
+
+ BGQueueIdBasedOnLevel queue_id = plr->GetBattleGroundQueueIdFromLevel(bg->GetTypeID());
+ char const* bgName = bg->GetName();
+ uint32 MinPlayers = bg->GetMinPlayersPerTeam();
+ uint32 qHorde = 0;
+ uint32 qAlliance = 0;
+ uint32 q_min_level = (queue_id + 1) * 10;
+ GroupsQueueType::const_iterator itr;
+ for(itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr)
+ if (!(*itr)->IsInvitedToBGInstanceGUID)
+ qAlliance += (*itr)->Players.size();
+ for(itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].end(); ++itr)
+ if (!(*itr)->IsInvitedToBGInstanceGUID)
+ qHorde += (*itr)->Players.size();
+
+ // Show queue status to player only (when joining queue)
+ if (sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
+ {
+ ChatHandler(plr).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF,
+ bgName, q_min_level, q_min_level + 10, qAlliance, MinPlayers, qHorde, MinPlayers);
+ }
+ // System message
+ else
{
- BattleGround * bg = sBattleGroundMgr.GetBattleGroundTemplate(group->BgTypeId);
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(group->BgTypeId,group->ArenaType);
- uint32 queueSlot = plr2->GetBattleGroundQueueIndex(bgQueueTypeId);
- plr2->RemoveBattleGroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs
- WorldPacket data;
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, plr2->GetTeam(), queueSlot, STATUS_NONE, 0, 0);
- plr2->GetSession()->SendPacket(&data);
+ sWorld.SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD,
+ bgName, q_min_level, q_min_level + 10, qAlliance, MinPlayers, qHorde, MinPlayers);
}
- // then actually delete, this may delete the group as well!
- RemovePlayer(group->Players.begin()->first,decreaseInvitedCount);
}
}
}
@@ -290,30 +424,48 @@ void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)
bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side)
{
// set side if needed
- if(side)
+ if (side)
ginfo->Team = side;
- if(!ginfo->IsInvitedToBGInstanceGUID)
+ if (!ginfo->IsInvitedToBGInstanceGUID)
{
// not yet invited
// set invitation
ginfo->IsInvitedToBGInstanceGUID = bg->GetInstanceID();
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
+ BattleGroundTypeId bgTypeId = bg->GetTypeID();
+ BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, bg->GetArenaType());
+ BGQueueIdBasedOnLevel queue_id = bg->GetQueueId();
+
+ // set ArenaTeamId for rated matches
+ if (bg->isArena() && bg->isRated())
+ bg->SetArenaTeamIdForTeam(ginfo->Team, ginfo->ArenaTeamId);
+
+ ginfo->RemoveInviteTime = getMSTime() + INVITE_ACCEPT_WAIT_TIME;
+
// loop through the players
for(std::map<uint64,PlayerQueueInfo*>::iterator itr = ginfo->Players.begin(); itr != ginfo->Players.end(); ++itr)
{
- // set status
- itr->second->InviteTime = getMSTime();
- itr->second->LastInviteTime = getMSTime();
-
// get the player
Player* plr = objmgr.GetPlayer(itr->first);
- // if offline, skip him
- if(!plr)
+ // if offline, skip him, this should not happen - player is removed from queue when he logs out
+ if (!plr)
continue;
// invite the player
- sBattleGroundMgr.InvitePlayer(plr, bg->GetInstanceID(),ginfo->Team);
+ PlayerInvitedToBGUpdateAverageWaitTime(ginfo, queue_id);
+ //sBattleGroundMgr.InvitePlayer(plr, bg, ginfo->Team);
+
+ // set invited player counters
+ bg->IncreaseInvitedCount(ginfo->Team);
+
+ plr->SetInviteForBattleGroundQueueType(bgQueueTypeId, ginfo->IsInvitedToBGInstanceGUID);
+
+ // create remind invite events
+ BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(plr->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, ginfo->RemoveInviteTime);
+ plr->m_Events.AddEvent(inviteEvent, plr->m_Events.CalculateTime(INVITATION_REMIND_TIME));
+ // create automatic remove events
+ BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(plr->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, bgQueueTypeId, ginfo->RemoveInviteTime);
+ plr->m_Events.AddEvent(removeEvent, plr->m_Events.CalculateTime(INVITE_ACCEPT_WAIT_TIME));
WorldPacket data;
@@ -322,7 +474,7 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
sLog.outDebug("Battleground: invited plr %s (%u) to BG instance %u queueindex %u bgtype %u, I can't help it if they don't press the enter battle button.",plr->GetName(),plr->GetGUIDLow(),bg->GetInstanceID(),queueSlot,bg->GetTypeID());
// send status packet
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, side?side:plr->GetTeam(), queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0);
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0, ginfo->ArenaType);
plr->GetSession()->SendPacket(&data);
}
return true;
@@ -331,190 +483,292 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
return false;
}
-// used to recursively select groups from eligible groups
-bool BattleGroundQueue::SelectionPool::Build(uint32 MinPlayers, uint32 MaxPlayers, EligibleGroups::iterator startitr)
+/*
+This function is inviting players to already running battlegrounds
+Invitation type is based on config file
+large groups are disadvantageous, because they will be kicked first if invitation type = 1
+*/
+void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel queue_id)
{
- // start from the specified start iterator
- for(EligibleGroups::iterator itr1 = startitr; itr1 != m_CurrEligGroups->end(); ++itr1)
+ int32 hordeFree = bg->GetFreeSlotsForTeam(HORDE);
+ int32 aliFree = bg->GetFreeSlotsForTeam(ALLIANCE);
+
+ //iterator for iterating through bg queue
+ GroupsQueueType::const_iterator Ali_itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].begin();
+ //count of groups in queue - used to stop cycles
+ uint32 aliCount = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].size();
+ //index to queue which group is current
+ uint32 aliIndex = 0;
+ for (; aliIndex < aliCount && m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*Ali_itr), aliFree); aliIndex++)
+ ++Ali_itr;
+ //the same thing for horde
+ GroupsQueueType::const_iterator Horde_itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].begin();
+ uint32 hordeCount = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].size();
+ uint32 hordeIndex = 0;
+ for (; hordeIndex < hordeCount && m_SelectionPools[BG_TEAM_HORDE].AddGroup((*Horde_itr), hordeFree); hordeIndex++)
+ ++Horde_itr;
+
+ //if ofc like BG queue invitation is set in config, then we are happy
+ if (sWorld.getConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) == 0)
+ return;
+
+ /*
+ if we reached this code, then we have to solve NP - complete problem called Subset sum problem
+ So one solution is to check all possible invitation subgroups, or we can use these conditions:
+ 1. Last time when BattleGroundQueue::Update was executed we invited all possible players - so there is only small possibility
+ that we will invite now whole queue, because only 1 change has been made to queues from the last BattleGroundQueue::Update call
+ 2. Other thing we should consider is group order in queue
+ */
+
+ // At first we need to compare free space in bg and our selection pool
+ int32 diffAli = aliFree - int32(m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount());
+ int32 diffHorde = hordeFree - int32(m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount());
+ while( abs(diffAli - diffHorde) > 1 && (m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() > 0 || m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() > 0) )
{
- // if it fits in, select it
- if(GetPlayerCount() + (*itr1)->Players.size() <= MaxPlayers)
+ //each cycle execution we need to kick at least 1 group
+ if (diffAli < diffHorde)
{
- EligibleGroups::iterator next = itr1;
- ++next;
- AddGroup((*itr1));
- if(GetPlayerCount() >= MinPlayers)
+ //kick alliance group, add to pool new group if needed
+ if (m_SelectionPools[BG_TEAM_ALLIANCE].KickGroup(diffHorde - diffAli))
{
- // enough players are selected
- return true;
+ for (; aliIndex < aliCount && m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*Ali_itr), (aliFree >= diffHorde) ? aliFree - diffHorde : 0); aliIndex++)
+ ++Ali_itr;
+ }
+ //if ali selection is already empty, then kick horde group, but if there are less horde than ali in bg - break;
+ if (!m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount())
+ {
+ if (aliFree <= diffHorde + 1)
+ break;
+ m_SelectionPools[BG_TEAM_HORDE].KickGroup(diffHorde - diffAli);
}
- // try building from the rest of the elig. groups
- // if that succeeds, return true
- if(Build(MinPlayers,MaxPlayers,next))
- return true;
- // the rest didn't succeed, so this group cannot be included
- RemoveGroup((*itr1));
}
+ else
+ {
+ //kick horde group, add to pool new group if needed
+ if (m_SelectionPools[BG_TEAM_HORDE].KickGroup(diffAli - diffHorde))
+ {
+ for (; hordeIndex < hordeCount && m_SelectionPools[BG_TEAM_HORDE].AddGroup((*Horde_itr), (hordeFree >= diffAli) ? hordeFree - diffAli : 0); hordeIndex++)
+ ++Horde_itr;
+ }
+ if (!m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount())
+ {
+ if (hordeFree <= diffAli + 1)
+ break;
+ m_SelectionPools[BG_TEAM_ALLIANCE].KickGroup(diffAli - diffHorde);
+ }
+ }
+ //count diffs after small update
+ diffAli = aliFree - int32(m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount());
+ diffHorde = hordeFree - int32(m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount());
}
- // build didn't succeed
- return false;
}
-// this function is responsible for the selection of queued groups when trying to create new battlegrounds
-bool BattleGroundQueue::BuildSelectionPool(uint32 bgTypeId, uint32 queue_id, uint32 MinPlayers, uint32 MaxPlayers, SelectionPoolBuildMode mode, uint8 ArenaType, bool isRated, uint32 MinRating, uint32 MaxRating, uint32 DisregardTime, uint32 excludeTeam)
+// this method checks if premade versus premade battleground is possible
+// then after 30 mins (default) in queue it moves premade group to normal queue
+// it tries to invite as much players as it can - to MaxPlayersPerTeam, because premade groups have more than MinPlayersPerTeam players
+bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam)
{
- uint32 side;
- switch(mode)
- {
- case NORMAL_ALLIANCE:
- case ONESIDE_ALLIANCE_TEAM1:
- case ONESIDE_ALLIANCE_TEAM2:
- side = ALLIANCE;
- break;
- case NORMAL_HORDE:
- case ONESIDE_HORDE_TEAM1:
- case ONESIDE_HORDE_TEAM2:
- side = HORDE;
- break;
- default:
- //unknown mode, return false
- sLog.outDebug("Battleground: unknown selection pool build mode, returning...");
- return false;
- break;
- }
-
- // initiate the groups eligible to create the bg
- m_EligibleGroups.Init(&(m_QueuedGroups[queue_id]), bgTypeId, side, MaxPlayers, ArenaType, isRated, MinRating, MaxRating, DisregardTime, excludeTeam);
- // init the selected groups (clear)
- // and set m_CurrEligGroups pointer
- // we set it this way to only have one EligibleGroups object to save some memory
- m_SelectionPools[mode].Init(&m_EligibleGroups);
- // build succeeded
- if(m_SelectionPools[mode].Build(MinPlayers,MaxPlayers,m_EligibleGroups.begin()))
- {
- // the selection pool is set, return
- sLog.outDebug("Battleground-debug: pool build succeeded, return true");
- sLog.outDebug("Battleground-debug: Player size for mode %u is %u", mode, m_SelectionPools[mode].GetPlayerCount());
- for(std::list<GroupQueueInfo* >::iterator itr = m_SelectionPools[mode].SelectedGroups.begin(); itr != m_SelectionPools[mode].SelectedGroups.end(); ++itr)
+ //check match
+ if (!m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].empty() && !m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].empty())
+ {
+ //start premade match
+ //if groups aren't invited
+ GroupsQueueType::const_iterator ali_group, horde_group;
+ for( ali_group = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].begin(); ali_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].end(); ++ali_group)
+ if (!(*ali_group)->IsInvitedToBGInstanceGUID)
+ break;
+ for( horde_group = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].begin(); horde_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].end(); ++horde_group)
+ if (!(*horde_group)->IsInvitedToBGInstanceGUID)
+ break;
+
+ if (ali_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].end() && horde_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].end())
{
- sLog.outDebug("Battleground-debug: queued group in selection with %u players",(*itr)->Players.size());
- for(std::map<uint64, PlayerQueueInfo * >::iterator itr2 = (*itr)->Players.begin(); itr2 != (*itr)->Players.end(); ++itr2)
- sLog.outDebug("Battleground-debug: player in above group GUID %u", (uint32)(itr2->first));
+ m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*ali_group), MaxPlayersPerTeam);
+ m_SelectionPools[BG_TEAM_HORDE].AddGroup((*horde_group), MaxPlayersPerTeam);
+ //add groups/players from normal queue to size of bigger group
+ uint32 maxPlayers = std::max(m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount(), m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount());
+ GroupsQueueType::const_iterator itr;
+ for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
+ {
+ for(itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++itr)
+ {
+ //if itr can join BG and player count is less that maxPlayers, then add group to selectionpool
+ if (!(*itr)->IsInvitedToBGInstanceGUID && !m_SelectionPools[i].AddGroup((*itr), maxPlayers))
+ break;
+ }
+ }
+ //premade selection pools are set
+ return true;
+ }
+ }
+ // now check if we can move group from Premade queue to normal queue (timer has expired) or group size lowered!!
+ // this could be 2 cycles but i'm checking only first team in queue - it can cause problem -
+ // if first is invited to BG and seconds timer expired, but we can ignore it, because players have only 80 seconds to click to enter bg
+ // and when they click or after 80 seconds the queue info is removed from queue
+ uint32 time_before = getMSTime() - sWorld.getConfig(CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH);
+ for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
+ {
+ if (!m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE + i].empty())
+ {
+ GroupsQueueType::iterator itr = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE + i].begin();
+ if (!(*itr)->IsInvitedToBGInstanceGUID && ((*itr)->JoinTime < time_before || (*itr)->Players.size() < MinPlayersPerTeam))
+ {
+ //we must insert group to normal queue and erase pointer from premade queue
+ m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].push_front((*itr));
+ m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE + i].erase(itr);
+ }
}
- return true;
}
- // failed to build a selection pool matching the given values
+ //selection pools are not set
return false;
}
-// used to remove the Enter Battle window if the battle has already, but someone still has it
-// (this can happen in arenas mainly, since the preparation is shorter than the timer for the bgqueueremove event
-void BattleGroundQueue::BGEndedRemoveInvites(BattleGround *bg)
+// this method tries to create battleground or arena with MinPlayersPerTeam against MinPlayersPerTeam
+bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BGQueueIdBasedOnLevel queue_id, uint32 minPlayers, uint32 maxPlayers)
{
- uint32 queue_id = bg->GetQueueType();
- uint32 bgInstanceId = bg->GetInstanceID();
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
- QueuedGroupsList::iterator itr, next;
- for(itr = m_QueuedGroups[queue_id].begin(); itr != m_QueuedGroups[queue_id].end(); itr = next)
- {
- // must do this way, because the groupinfo will be deleted when all playerinfos are removed
- GroupQueueInfo * ginfo = (*itr);
- next = itr;
- ++next;
- // if group was invited to this bg instance, then remove all references
- if(ginfo->IsInvitedToBGInstanceGUID == bgInstanceId)
+ GroupsQueueType::const_iterator itr_team[BG_TEAMS_COUNT];
+ for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
+ {
+ itr_team[i] = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin();
+ for(; itr_team[i] != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++(itr_team[i]))
{
- // after removing this much playerinfos, the ginfo will be deleted, so we'll use a for loop
- uint32 to_remove = ginfo->Players.size();
- uint32 team = ginfo->Team;
- for(int i = 0; i < to_remove; ++i)
+ if (!(*(itr_team[i]))->IsInvitedToBGInstanceGUID)
{
- // always remove the first one in the group
- std::map<uint64, PlayerQueueInfo * >::iterator itr2 = ginfo->Players.begin();
- if(itr2 == ginfo->Players.end())
- {
- sLog.outError("Empty Players in ginfo, this should never happen!");
- return;
- }
+ m_SelectionPools[i].AddGroup(*(itr_team[i]), maxPlayers);
+ if (m_SelectionPools[i].GetPlayerCount() >= minPlayers)
+ break;
+ }
+ }
+ }
+ //try to invite same number of players - this cycle may cause longer wait time even if there are enough players in queue, but we want ballanced bg
+ uint32 j = BG_TEAM_ALLIANCE;
+ if (m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() < m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount())
+ j = BG_TEAM_HORDE;
+ if( sWorld.getConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) != 0
+ && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() >= minPlayers && m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() >= minPlayers )
+ {
+ //we will try to invite more groups to team with less players indexed by j
+ ++(itr_team[j]); //this will not cause a crash, because for cycle above reached break;
+ for(; itr_team[j] != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + j].end(); ++(itr_team[j]))
+ {
+ if (!(*(itr_team[j]))->IsInvitedToBGInstanceGUID)
+ if (!m_SelectionPools[j].AddGroup(*(itr_team[j]), m_SelectionPools[(j + 1) % BG_TEAMS_COUNT].GetPlayerCount()))
+ break;
+ }
+ // do not allow to start bg with more than 2 players more on 1 faction
+ if (abs((int32)(m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() - m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount())) > 2)
+ return false;
+ }
+ //allow 1v0 if debug bg
+ if (sBattleGroundMgr.isTesting() && bg_template->isBattleGround() && (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount()))
+ return true;
+ //return true if there are enough players in selection pools - enable to work .debug bg command correctly
+ return m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() >= minPlayers && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() >= minPlayers;
+}
- // get the player
- Player * plr = objmgr.GetPlayer(itr2->first);
- if(!plr)
- {
- sLog.outError("Player offline when trying to remove from GroupQueueInfo, this should never happen.");
- continue;
- }
+// this method will check if we can invite players to same faction skirmish match
+bool BattleGroundQueue::CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_id, uint32 minPlayersPerTeam)
+{
+ if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() < minPlayersPerTeam && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() < minPlayersPerTeam)
+ return false;
+ uint32 teamIndex = BG_TEAM_ALLIANCE;
+ uint32 otherTeam = BG_TEAM_HORDE;
+ uint32 otherTeamId = HORDE;
+ if (m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() == minPlayersPerTeam )
+ {
+ teamIndex = BG_TEAM_HORDE;
+ otherTeam = BG_TEAM_ALLIANCE;
+ otherTeamId = ALLIANCE;
+ }
+ //clear other team's selection
+ m_SelectionPools[otherTeam].Init();
+ //store last ginfo pointer
+ GroupQueueInfo* ginfo = m_SelectionPools[teamIndex].SelectedGroups.back();
+ //set itr_team to group that was added to selection pool latest
+ GroupsQueueType::iterator itr_team = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].begin();
+ for(; itr_team != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr_team)
+ if (ginfo == *itr_team)
+ break;
+ if (itr_team == m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end())
+ return false;
+ GroupsQueueType::iterator itr_team2 = itr_team;
+ ++itr_team2;
+ //invite players to other selection pool
+ for(; itr_team2 != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr_team2)
+ {
+ //if selection pool is full then break;
+ if (!(*itr_team2)->IsInvitedToBGInstanceGUID && !m_SelectionPools[otherTeam].AddGroup(*itr_team2, minPlayersPerTeam))
+ break;
+ }
+ if (m_SelectionPools[otherTeam].GetPlayerCount() != minPlayersPerTeam)
+ return false;
- // get the queueslot
- uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId);
- if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue
- {
- plr->RemoveBattleGroundQueueId(bgQueueTypeId);
- // remove player from queue, this might delete the ginfo as well! don't use that pointer after this!
- RemovePlayer(itr2->first, true);
- // this is probably unneeded, since this player was already invited -> does not fit when initing eligible groups
- // but updating the queue can't hurt
- Update(bgQueueTypeId, bg->GetQueueType());
- // send info to client
- WorldPacket data;
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, team, queueSlot, STATUS_NONE, 0, 0);
- plr->GetSession()->SendPacket(&data);
- }
+ //here we have correct 2 selections and we need to change one teams team and move selection pool teams to other team's queue
+ for(GroupsQueueType::iterator itr = m_SelectionPools[otherTeam].SelectedGroups.begin(); itr != m_SelectionPools[otherTeam].SelectedGroups.end(); ++itr)
+ {
+ //set correct team
+ (*itr)->Team = otherTeamId;
+ //add team to other queue
+ m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + otherTeam].push_front(*itr);
+ //remove team from old queue
+ GroupsQueueType::iterator itr2 = itr_team;
+ ++itr2;
+ for(; itr2 != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr2)
+ {
+ if (*itr2 == *itr)
+ {
+ m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].erase(itr2);
+ break;
}
}
}
+ return true;
}
/*
this method is called when group is inserted, or player / group is removed from BG Queue - there is only one player's status changed, so we don't use while(true) cycles to invite whole queue
it must be called after fully adding the members of a group to ensure group joining
-should be called after removeplayer functions in some cases
+should be called from BattleGround::RemovePlayer function in some cases
*/
-void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype, bool isRated, uint32 arenaRating)
+void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated, uint32 arenaRating)
{
- if (queue_id >= MAX_BATTLEGROUND_QUEUES)
- {
- //this is error, that caused crashes (not in , but now it shouldn't)
- sLog.outError("BattleGroundQueue::Update() called for non existing queue type - this can cause crash, pls report problem, if this is the last line of error log before crash");
- return;
- }
-
- //if no players in queue ... do nothing
- if (m_QueuedGroups[queue_id].empty())
+ //if no players in queue - do nothing
+ if( m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].empty() &&
+ m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].empty() &&
+ m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].empty() &&
+ m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].empty() )
return;
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId, arenatype);
-
- //battleground with free slot for player should be always the last in this queue
+ //battleground with free slot for player should be always in the beggining of the queue
+ // maybe it would be better to create bgfreeslotqueue for each queue_id_based_on_level
BGFreeSlotQueueType::iterator itr, next;
for (itr = sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].end(); itr = next)
{
next = itr;
++next;
- // battleground is running, so if:
- // DO NOT allow queue manager to invite new player to running arena
- if ((*itr)->isBattleGround() && (*itr)->GetTypeID() == bgTypeId && (*itr)->GetQueueType() == queue_id && (*itr)->GetStatus() > STATUS_WAIT_QUEUE && (*itr)->GetStatus() < STATUS_WAIT_LEAVE)
+ // DO NOT allow queue manager to invite new player to arena
+ if( (*itr)->isBattleGround() && (*itr)->GetTypeID() == bgTypeId && (*itr)->GetQueueId() == queue_id &&
+ (*itr)->GetStatus() > STATUS_WAIT_QUEUE && (*itr)->GetStatus() < STATUS_WAIT_LEAVE )
{
- //we must check both teams
BattleGround* bg = *itr; //we have to store battleground pointer here, because when battleground is full, it is removed from free queue (not yet implemented!!)
// and iterator is invalid
- for(QueuedGroupsList::iterator itr = m_QueuedGroups[queue_id].begin(); itr != m_QueuedGroups[queue_id].end(); ++itr)
- {
- // did the group join for this bg type?
- if((*itr)->BgTypeId != bgTypeId)
- continue;
- // if so, check if fits in
- if(bg->GetFreeSlotsForTeam((*itr)->Team) >= (*itr)->Players.size())
- {
- // if group fits in, invite it
- InviteGroupToBG((*itr),bg,(*itr)->Team);
- }
- }
+ // clear selection pools
+ m_SelectionPools[BG_TEAM_ALLIANCE].Init();
+ m_SelectionPools[BG_TEAM_HORDE].Init();
+
+ // call a function that does the job for us
+ FillPlayersToBG(bg, queue_id);
+
+ // now everything is set, invite players
+ for(GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.end(); ++citr)
+ InviteGroupToBG((*citr), bg, (*citr)->Team);
+ for(GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_HORDE].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_HORDE].SelectedGroups.end(); ++citr)
+ InviteGroupToBG((*citr), bg, (*citr)->Team);
if (!bg->HasFreeSlots())
{
- //remove BG from BGFreeSlotQueue
+ // remove BG from BGFreeSlotQueue
bg->RemoveFromBGFreeSlotQueue();
}
}
@@ -523,25 +777,29 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype
// finished iterating through the bgs with free slots, maybe we need to create a new bg
BattleGround * bg_template = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
- if(!bg_template)
+ if (!bg_template)
{
sLog.outError("Battleground: Update: bg template not found for %u", bgTypeId);
return;
}
-
// get the min. players per team, properly for larger arenas as well. (must have full teams for arena matches!)
uint32 MinPlayersPerTeam = bg_template->GetMinPlayersPerTeam();
uint32 MaxPlayersPerTeam = bg_template->GetMaxPlayersPerTeam();
- if(bg_template->isArena())
+ if (sBattleGroundMgr.isTesting())
+ MinPlayersPerTeam = 1;
+ if (bg_template->isArena())
{
- if(sBattleGroundMgr.isArenaTesting())
+ if (sBattleGroundMgr.isArenaTesting())
{
MaxPlayersPerTeam = 1;
MinPlayersPerTeam = 1;
}
else
{
- switch(arenatype)
+ //this switch can be much shorter
+ MaxPlayersPerTeam = arenaType;
+ MinPlayersPerTeam = arenaType;
+ /*switch(arenaType)
{
case ARENA_TYPE_2v2:
MaxPlayersPerTeam = 2;
@@ -555,293 +813,192 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype
MaxPlayersPerTeam = 5;
MinPlayersPerTeam = 5;
break;
- }
+ }*/
}
}
- // found out the minimum and maximum ratings the newly added team should battle against
- // arenaRating is the rating of the latest joined team
- uint32 arenaMinRating = (arenaRating <= sBattleGroundMgr.GetMaxRatingDifference()) ? 0 : arenaRating - sBattleGroundMgr.GetMaxRatingDifference();
- // if no rating is specified, set maxrating to 0
- uint32 arenaMaxRating = (arenaRating == 0)? 0 : arenaRating + sBattleGroundMgr.GetMaxRatingDifference();
- uint32 discardTime = 0;
- // if max rating difference is set and the time past since server startup is greater than the rating discard time
- // (after what time the ratings aren't taken into account when making teams) then
- // the discard time is current_time - time_to_discard, teams that joined after that, will have their ratings taken into account
- // else leave the discard time on 0, this way all ratings will be discarded
- if(sBattleGroundMgr.GetMaxRatingDifference() && getMSTime() >= sBattleGroundMgr.GetRatingDiscardTimer())
- discardTime = getMSTime() - sBattleGroundMgr.GetRatingDiscardTimer();
-
- // try to build the selection pools
- bool bAllyOK = BuildSelectionPool(bgTypeId, queue_id, MinPlayersPerTeam, MaxPlayersPerTeam, NORMAL_ALLIANCE, arenatype, isRated, arenaMinRating, arenaMaxRating, discardTime);
- if(bAllyOK)
- sLog.outDebug("Battleground: ally pool successfully built");
- else
- sLog.outDebug("Battleground: ally pool wasn't created");
- bool bHordeOK = BuildSelectionPool(bgTypeId, queue_id, MinPlayersPerTeam, MaxPlayersPerTeam, NORMAL_HORDE, arenatype, isRated, arenaMinRating, arenaMaxRating, discardTime);
- if(bHordeOK)
- sLog.outDebug("Battleground: horde pool successfully built");
- else
- sLog.outDebug("Battleground: horde pool wasn't created");
+ m_SelectionPools[BG_TEAM_ALLIANCE].Init();
+ m_SelectionPools[BG_TEAM_HORDE].Init();
- // if selection pools are ready, create the new bg
- if (bAllyOK && bHordeOK)
+ if (bg_template->isBattleGround())
{
- BattleGround * bg2 = 0;
- // special handling for arenas
- if(bg_template->isArena())
+ //check if there is premade against premade match
+ if (CheckPremadeMatch(queue_id, MinPlayersPerTeam, MaxPlayersPerTeam))
{
- // Find a random arena, that can be created
- uint8 arenas[] = {BATTLEGROUND_NA, BATTLEGROUND_BE, BATTLEGROUND_RL};
- uint32 arena_num = urand(0,2);
- if( !(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[arena_num%3])) &&
- !(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[(arena_num+1)%3])) &&
- !(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[(arena_num+2)%3])) )
+ //create new battleground
+ BattleGround * bg2 = NULL;
+ if (!(bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, queue_id, 0, false)))
{
- sLog.outError("Battleground: couldn't create any arena instance!");
+ sLog.outError("BattleGroundQueue::Update - Cannot create battleground: %u", bgTypeId);
return;
}
-
- // set the MaxPlayersPerTeam values based on arenatype
- // setting the min player values isn't needed, since we won't be using that value later on.
- if(sBattleGroundMgr.isArenaTesting())
- {
- bg2->SetMaxPlayersPerTeam(1);
- bg2->SetMaxPlayers(2);
- }
- else
- {
- switch(arenatype)
- {
- case ARENA_TYPE_2v2:
- bg2->SetMaxPlayersPerTeam(2);
- bg2->SetMaxPlayers(4);
- break;
- case ARENA_TYPE_3v3:
- bg2->SetMaxPlayersPerTeam(3);
- bg2->SetMaxPlayers(6);
- break;
- case ARENA_TYPE_5v5:
- bg2->SetMaxPlayersPerTeam(5);
- bg2->SetMaxPlayers(10);
- break;
- default:
- break;
- }
- }
- }
- else
- {
- // create new battleground
- bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId);
- }
-
- if(!bg2)
- {
- sLog.outError("Battleground: couldn't create bg %u",bgTypeId);
- return;
- }
-
- // start the joining of the bg
- bg2->SetStatus(STATUS_WAIT_JOIN);
- bg2->SetQueueType(queue_id);
- // initialize arena / rating info
- bg2->SetArenaType(arenatype);
- // set rating
- bg2->SetRated(isRated);
-
- std::list<GroupQueueInfo* >::iterator itr;
-
- // Send amount of invites based on the difference between the sizes of the two faction's queues
- uint32 QUEUED_HORDE = m_SelectionPools[NORMAL_HORDE].SelectedGroups.size();
- uint32 QUEUED_ALLIANCE = m_SelectionPools[NORMAL_ALLIANCE].SelectedGroups.size();
- uint16 maxbginvites = 0;
-
- if(QUEUED_ALLIANCE <= QUEUED_HORDE)
- maxbginvites = QUEUED_ALLIANCE;
- else
- maxbginvites = QUEUED_HORDE;
-
- // invite groups from horde selection pool
- uint16 invitecounter = 0;
- for(itr = m_SelectionPools[NORMAL_HORDE].SelectedGroups.begin(); itr != m_SelectionPools[NORMAL_HORDE].SelectedGroups.end(); ++itr)
- {
- if (invitecounter >= maxbginvites)
- return;
- InviteGroupToBG((*itr),bg2,HORDE);
- ++invitecounter;
- }
-
- // invite groups from ally selection pool
- invitecounter = 0;
- for(itr = m_SelectionPools[NORMAL_ALLIANCE].SelectedGroups.begin(); itr != m_SelectionPools[NORMAL_ALLIANCE].SelectedGroups.end(); ++itr)
- {
- if (invitecounter >= maxbginvites)
- return;
- InviteGroupToBG((*itr),bg2,ALLIANCE);
- ++invitecounter;
- }
-
- if (isRated)
- {
- std::list<GroupQueueInfo* >::iterator itr_alliance = m_SelectionPools[NORMAL_ALLIANCE].SelectedGroups.begin();
- std::list<GroupQueueInfo* >::iterator itr_horde = m_SelectionPools[NORMAL_HORDE].SelectedGroups.begin();
- (*itr_alliance)->OpponentsTeamRating = (*itr_horde)->ArenaTeamRating;
- sLog.outDebug("setting opposite team rating for team %u to %u", (*itr_alliance)->ArenaTeamId, (*itr_alliance)->OpponentsTeamRating);
- (*itr_horde)->OpponentsTeamRating = (*itr_alliance)->ArenaTeamRating;
- sLog.outDebug("setting opposite team rating for team %u to %u", (*itr_horde)->ArenaTeamId, (*itr_horde)->OpponentsTeamRating);
+ //invite those selection pools
+ for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
+ for(GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.end(); ++citr)
+ InviteGroupToBG((*citr), bg2, (*citr)->Team);
+ //start bg
+ bg2->StartBattleGround();
+ //clear structures
+ m_SelectionPools[BG_TEAM_ALLIANCE].Init();
+ m_SelectionPools[BG_TEAM_HORDE].Init();
}
-
- // start the battleground
- bg2->StartBattleGround();
}
- // there weren't enough players for a "normal" match
- // if arena, enable horde versus horde or alliance versus alliance teams here
-
- else if(bg_template->isArena())
+ // now check if there are in queues enough players to start new game of (normal battleground, or non-rated arena)
+ if (!isRated)
{
- bool bOneSideHordeTeam1 = false, bOneSideHordeTeam2 = false;
- bool bOneSideAllyTeam1 = false, bOneSideAllyTeam2 = false;
- bOneSideHordeTeam1 = BuildSelectionPool(bgTypeId, queue_id,MaxPlayersPerTeam,MaxPlayersPerTeam,ONESIDE_HORDE_TEAM1,arenatype, isRated, arenaMinRating, arenaMaxRating, discardTime);
- if(bOneSideHordeTeam1)
- {
- // one team has been selected, find out if other can be selected too
- std::list<GroupQueueInfo* >::iterator itr;
- // temporarily change the team side to enable building the next pool excluding the already selected groups
- for(itr = m_SelectionPools[ONESIDE_HORDE_TEAM1].SelectedGroups.begin(); itr != m_SelectionPools[ONESIDE_HORDE_TEAM1].SelectedGroups.end(); ++itr)
- (*itr)->Team=ALLIANCE;
-
- bOneSideHordeTeam2 = BuildSelectionPool(bgTypeId, queue_id,MaxPlayersPerTeam,MaxPlayersPerTeam,ONESIDE_HORDE_TEAM2,arenatype, isRated, arenaMinRating, arenaMaxRating, discardTime, (*(m_SelectionPools[ONESIDE_HORDE_TEAM1].SelectedGroups.begin()))->ArenaTeamId);
-
- // change back the team to horde
- for(itr = m_SelectionPools[ONESIDE_HORDE_TEAM1].SelectedGroups.begin(); itr != m_SelectionPools[ONESIDE_HORDE_TEAM1].SelectedGroups.end(); ++itr)
- (*itr)->Team=HORDE;
-
- if(!bOneSideHordeTeam2)
- bOneSideHordeTeam1 = false;
- }
- if(!bOneSideHordeTeam1)
+ // if there are enough players in pools, start new battleground or non rated arena
+ if (CheckNormalMatch(bg_template, queue_id, MinPlayersPerTeam, MaxPlayersPerTeam)
+ || (bg_template->isArena() && CheckSkirmishForSameFaction(queue_id, MinPlayersPerTeam)) )
{
- // check for one sided ally
- bOneSideAllyTeam1 = BuildSelectionPool(bgTypeId, queue_id,MaxPlayersPerTeam,MaxPlayersPerTeam,ONESIDE_ALLIANCE_TEAM1,arenatype, isRated, arenaMinRating, arenaMaxRating, discardTime);
- if(bOneSideAllyTeam1)
+ // we successfully created a pool
+ BattleGround * bg2 = NULL;
+ if (!(bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, queue_id, arenaType, false)))
{
- // one team has been selected, find out if other can be selected too
- std::list<GroupQueueInfo* >::iterator itr;
- // temporarily change the team side to enable building the next pool excluding the already selected groups
- for(itr = m_SelectionPools[ONESIDE_ALLIANCE_TEAM1].SelectedGroups.begin(); itr != m_SelectionPools[ONESIDE_ALLIANCE_TEAM1].SelectedGroups.end(); ++itr)
- (*itr)->Team=HORDE;
-
- bOneSideAllyTeam2 = BuildSelectionPool(bgTypeId, queue_id,MaxPlayersPerTeam,MaxPlayersPerTeam,ONESIDE_ALLIANCE_TEAM2,arenatype, isRated, arenaMinRating, arenaMaxRating, discardTime,(*(m_SelectionPools[ONESIDE_ALLIANCE_TEAM1].SelectedGroups.begin()))->ArenaTeamId);
-
- // change back the team to ally
- for(itr = m_SelectionPools[ONESIDE_ALLIANCE_TEAM1].SelectedGroups.begin(); itr != m_SelectionPools[ONESIDE_ALLIANCE_TEAM1].SelectedGroups.end(); ++itr)
- (*itr)->Team=ALLIANCE;
+ sLog.outError("BattleGroundQueue::Update - Cannot create battleground: %u", bgTypeId);
+ return;
}
- if(!bOneSideAllyTeam2)
- bOneSideAllyTeam1 = false;
+ // invite those selection pools
+ for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
+ for(GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.end(); ++citr)
+ InviteGroupToBG((*citr), bg2, (*citr)->Team);
+ // start bg
+ bg2->StartBattleGround();
}
- // 1-sided BuildSelectionPool() will work, because the MinPlayersPerTeam == MaxPlayersPerTeam in every arena!!!!
- if( (bOneSideHordeTeam1 && bOneSideHordeTeam2) ||
- (bOneSideAllyTeam1 && bOneSideAllyTeam2) )
+ }
+ else if (bg_template->isArena())
+ {
+ // found out the minimum and maximum ratings the newly added team should battle against
+ // arenaRating is the rating of the latest joined team, or 0
+ // 0 is on (automatic update call) and we must set it to team's with longest wait time
+ if (!arenaRating )
{
- // which side has enough players?
- uint32 side = 0;
- SelectionPoolBuildMode mode1, mode2;
- // find out what pools are we using
- if(bOneSideAllyTeam1 && bOneSideAllyTeam2)
+ GroupQueueInfo* front1 = NULL;
+ GroupQueueInfo* front2 = NULL;
+ if (!m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].empty())
{
- side = ALLIANCE;
- mode1 = ONESIDE_ALLIANCE_TEAM1;
- mode2 = ONESIDE_ALLIANCE_TEAM2;
+ front1 = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].front();
+ arenaRating = front1->ArenaTeamRating;
}
- else
+ if (!m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].empty())
{
- side = HORDE;
- mode1 = ONESIDE_HORDE_TEAM1;
- mode2 = ONESIDE_HORDE_TEAM2;
+ front2 = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].front();
+ arenaRating = front2->ArenaTeamRating;
}
-
- // create random arena
- uint8 arenas[] = {BATTLEGROUND_NA, BATTLEGROUND_BE, BATTLEGROUND_RL};
- uint32 arena_num = urand(0,2);
- BattleGround* bg2 = NULL;
- if( !(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[arena_num%3])) &&
- !(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[(arena_num+1)%3])) &&
- !(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[(arena_num+2)%3])) )
+ if (front1 && front2)
{
- sLog.outError("Could not create arena.");
- return;
+ if (front1->JoinTime < front2->JoinTime)
+ arenaRating = front1->ArenaTeamRating;
}
+ else if (!front1 && !front2)
+ return; //queues are empty
+ }
+
+ //set rating range
+ uint32 arenaMinRating = (arenaRating <= sBattleGroundMgr.GetMaxRatingDifference()) ? 0 : arenaRating - sBattleGroundMgr.GetMaxRatingDifference();
+ uint32 arenaMaxRating = arenaRating + sBattleGroundMgr.GetMaxRatingDifference();
+ // if max rating difference is set and the time past since server startup is greater than the rating discard time
+ // (after what time the ratings aren't taken into account when making teams) then
+ // the discard time is current_time - time_to_discard, teams that joined after that, will have their ratings taken into account
+ // else leave the discard time on 0, this way all ratings will be discarded
+ uint32 discardTime = getMSTime() - sBattleGroundMgr.GetRatingDiscardTimer();
+
+ // we need to find 2 teams which will play next game
+
+ GroupsQueueType::iterator itr_team[BG_TEAMS_COUNT];
- sLog.outDebug("Battleground: One-faction arena created.");
- // init stats
- if(sBattleGroundMgr.isArenaTesting())
+ //optimalization : --- we dont need to use selection_pools - each update we select max 2 groups
+
+ for(uint32 i = BG_QUEUE_PREMADE_ALLIANCE; i < BG_QUEUE_NORMAL_ALLIANCE; i++)
+ {
+ // take the group that joined first
+ itr_team[i] = m_QueuedGroups[queue_id][i].begin();
+ for(; itr_team[i] != m_QueuedGroups[queue_id][i].end(); ++(itr_team[i]))
{
- bg2->SetMaxPlayersPerTeam(1);
- bg2->SetMaxPlayers(2);
+ // if group match conditions, then add it to pool
+ if( !(*itr_team[i])->IsInvitedToBGInstanceGUID
+ && (((*itr_team[i])->ArenaTeamRating >= arenaMinRating && (*itr_team[i])->ArenaTeamRating <= arenaMaxRating)
+ || (*itr_team[i])->JoinTime < discardTime) )
+ {
+ m_SelectionPools[i].AddGroup((*itr_team[i]), MaxPlayersPerTeam);
+ // break for cycle to be able to start selecting another group from same faction queue
+ break;
+ }
}
- else
+ }
+ // now we are done if we have 2 groups - ali vs horde!
+ // if we don't have, we must try to continue search in same queue
+ // tmp variables are correctly set
+ // this code isn't much userfriendly - but it is supposed to continue search for mathing group in HORDE queue
+ if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() == 0 && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount())
+ {
+ itr_team[BG_TEAM_ALLIANCE] = itr_team[BG_TEAM_HORDE];
+ ++itr_team[BG_TEAM_ALLIANCE];
+ for(; itr_team[BG_TEAM_ALLIANCE] != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].end(); ++(itr_team[BG_TEAM_ALLIANCE]))
{
- switch(arenatype)
+ if( !(*itr_team[BG_TEAM_ALLIANCE])->IsInvitedToBGInstanceGUID
+ && (((*itr_team[BG_TEAM_ALLIANCE])->ArenaTeamRating >= arenaMinRating && (*itr_team[BG_TEAM_ALLIANCE])->ArenaTeamRating <= arenaMaxRating)
+ || (*itr_team[BG_TEAM_ALLIANCE])->JoinTime < discardTime) )
{
- case ARENA_TYPE_2v2:
- bg2->SetMaxPlayersPerTeam(2);
- bg2->SetMaxPlayers(4);
- break;
- case ARENA_TYPE_3v3:
- bg2->SetMaxPlayersPerTeam(3);
- bg2->SetMaxPlayers(6);
- break;
- case ARENA_TYPE_5v5:
- bg2->SetMaxPlayersPerTeam(5);
- bg2->SetMaxPlayers(10);
+ m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*itr_team[BG_TEAM_ALLIANCE]), MaxPlayersPerTeam);
break;
- default:
+ }
+ }
+ }
+ // this code isn't much userfriendly - but it is supposed to continue search for mathing group in ALLIANCE queue
+ if (m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() == 0 && m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount())
+ {
+ itr_team[BG_TEAM_HORDE] = itr_team[BG_TEAM_ALLIANCE];
+ ++itr_team[BG_TEAM_HORDE];
+ for(; itr_team[BG_TEAM_HORDE] != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].end(); ++(itr_team[BG_TEAM_HORDE]))
+ {
+ if( !(*itr_team[BG_TEAM_HORDE])->IsInvitedToBGInstanceGUID
+ && (((*itr_team[BG_TEAM_HORDE])->ArenaTeamRating >= arenaMinRating && (*itr_team[BG_TEAM_HORDE])->ArenaTeamRating <= arenaMaxRating)
+ || (*itr_team[BG_TEAM_HORDE])->JoinTime < discardTime) )
+ {
+ m_SelectionPools[BG_TEAM_HORDE].AddGroup((*itr_team[BG_TEAM_HORDE]), MaxPlayersPerTeam);
break;
}
}
+ }
- bg2->SetRated(isRated);
-
- // assigned team of the other group
- uint32 other_side;
- if(side == ALLIANCE)
- other_side = HORDE;
- else
- other_side = ALLIANCE;
-
- // start the joining of the bg
- bg2->SetStatus(STATUS_WAIT_JOIN);
- bg2->SetQueueType(queue_id);
- // initialize arena / rating info
- bg2->SetArenaType(arenatype);
-
- std::list<GroupQueueInfo* >::iterator itr;
-
- // invite players from the first group as horde players (actually green team)
- for(itr = m_SelectionPools[mode1].SelectedGroups.begin(); itr != m_SelectionPools[mode1].SelectedGroups.end(); ++itr)
+ //if we have 2 teams, then start new arena and invite players!
+ if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount())
+ {
+ BattleGround* arena = NULL;
+ if (!(arena = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, queue_id, arenaType, true)))
{
- InviteGroupToBG((*itr),bg2,HORDE);
+ sLog.outError("BattlegroundQueue::Update couldn't create arena instance for rated arena match!");
+ return;
}
- // invite players from the second group as ally players (actually gold team)
- for(itr = m_SelectionPools[mode2].SelectedGroups.begin(); itr != m_SelectionPools[mode2].SelectedGroups.end(); ++itr)
+ (*(itr_team[BG_TEAM_ALLIANCE]))->OpponentsTeamRating = (*(itr_team[BG_TEAM_HORDE]))->ArenaTeamRating;
+ sLog.outDebug("setting oposite teamrating for team %u to %u", (*(itr_team[BG_TEAM_ALLIANCE]))->ArenaTeamId, (*(itr_team[BG_TEAM_ALLIANCE]))->OpponentsTeamRating);
+ (*(itr_team[BG_TEAM_HORDE]))->OpponentsTeamRating = (*(itr_team[BG_TEAM_ALLIANCE]))->ArenaTeamRating;
+ sLog.outDebug("setting oposite teamrating for team %u to %u", (*(itr_team[BG_TEAM_HORDE]))->ArenaTeamId, (*(itr_team[BG_TEAM_HORDE]))->OpponentsTeamRating);
+ // now we must move team if we changed its faction to another faction queue, because then we will spam log by errors in Queue::RemovePlayer
+ if ((*(itr_team[BG_TEAM_ALLIANCE]))->Team != ALLIANCE)
{
- InviteGroupToBG((*itr),bg2,ALLIANCE);
+ // add to alliance queue
+ m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].push_front(*(itr_team[BG_TEAM_ALLIANCE]));
+ // erase from horde queue
+ m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].erase(itr_team[BG_TEAM_ALLIANCE]);
+ itr_team[BG_TEAM_ALLIANCE] = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].begin();
}
-
- if (isRated)
+ if ((*(itr_team[BG_TEAM_HORDE]))->Team != HORDE)
{
- std::list<GroupQueueInfo* >::iterator itr_alliance = m_SelectionPools[mode1].SelectedGroups.begin();
- std::list<GroupQueueInfo* >::iterator itr_horde = m_SelectionPools[mode2].SelectedGroups.begin();
- (*itr_alliance)->OpponentsTeamRating = (*itr_horde)->ArenaTeamRating;
- (*itr_horde)->OpponentsTeamRating = (*itr_alliance)->ArenaTeamRating;
+ m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].push_front(*(itr_team[BG_TEAM_HORDE]));
+ m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].erase(itr_team[BG_TEAM_HORDE]);
+ itr_team[BG_TEAM_HORDE] = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].begin();
}
- bg2->StartBattleGround();
+ InviteGroupToBG(*(itr_team[BG_TEAM_ALLIANCE]), arena, ALLIANCE);
+ InviteGroupToBG(*(itr_team[BG_TEAM_HORDE]), arena, HORDE);
+
+ sLog.outDebug("Starting rated arena match!");
+
+ arena->StartBattleGround();
}
}
}
@@ -853,36 +1010,29 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype
bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
{
Player* plr = objmgr.GetPlayer( m_PlayerGuid );
-
// player logged off (we should do nothing, he is correctly removed from queue in another procedure)
if (!plr)
return true;
- // Player can be in another BG queue and must be removed in normal way in any case
- // // player is already in battleground ... do nothing (battleground queue status is deleted when player is teleported to BG)
- // if (plr->GetBattleGroundId() > 0)
- // return true;
-
- BattleGround* bg = sBattleGroundMgr.GetBattleGround(m_BgInstanceGUID);
+ BattleGround* bg = sBattleGroundMgr.GetBattleGround(m_BgInstanceGUID, m_BgTypeId);
+ //if battleground ended and its instance deleted - do nothing
if (!bg)
return true;
- uint32 queueSlot = plr->GetBattleGroundQueueIndex(bg->GetTypeID());
- if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue
+ BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
+ uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId);
+ if( queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES ) // player is in queue or in battleground
{
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
- uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId);
- if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue
+ // check if player is invited to this bg
+ BattleGroundQueue::QueuedPlayersMap const& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers;
+ BattleGroundQueue::QueuedPlayersMap::const_iterator qItr = qpMap.find(m_PlayerGuid);
+ if( qItr != qpMap.end() && qItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID
+ && qItr->second.GroupInfo->RemoveInviteTime == m_RemoveTime )
{
- // check if player is invited to this bg ... this check must be here, because when player leaves queue and joins another, it would cause a problems
- BattleGroundQueue::QueuedPlayersMap const& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[plr->GetBattleGroundQueueIdFromLevel()];
- BattleGroundQueue::QueuedPlayersMap::const_iterator qItr = qpMap.find(m_PlayerGuid);
- if (qItr != qpMap.end() && qItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID)
- {
- WorldPacket data;
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, qItr->second.GroupInfo->Team, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME/2, 0);
- plr->GetSession()->SendPacket(&data);
- }
+ WorldPacket data;
+ //we must send remaining time in queue
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, 0, qItr->second.GroupInfo->ArenaType);
+ plr->GetSession()->SendPacket(&data);
}
}
return true; //event will be deleted
@@ -890,10 +1040,18 @@ bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
void BGQueueInviteEvent::Abort(uint64 /*e_time*/)
{
- //this should not be called
- sLog.outError("Battleground invite event ABORTED!");
+ //do nothing
}
+/*
+ this event has many possibilities when it is executed:
+ 1. player is in battleground ( he clicked enter on invitation window )
+ 2. player left battleground queue and he isn't there any more
+ 3. player left battleground queue and he joined it again and IsInvitedToBGInstanceGUID = 0
+ 4. player left queue and he joined again and he has been invited to same battleground again -> we should not remove him from queue yet
+ 5. player is invited to bg and he didn't choose what to do and timer expired - only in this condition we should call queue::RemovePlayer
+ we must remove player in the 5. case even if battleground object doesn't exist!
+*/
bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
{
Player* plr = objmgr.GetPlayer( m_PlayerGuid );
@@ -901,40 +1059,33 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
// player logged off (we should do nothing, he is correctly removed from queue in another procedure)
return true;
- BattleGround* bg = sBattleGroundMgr.GetBattleGround(m_BgInstanceGUID);
- if (!bg)
- return true;
-
- sLog.outDebug("Battleground: removing player %u from bg queue for instance %u because of not pressing enter battle in time.",plr->GetGUIDLow(),m_BgInstanceGUID);
+ BattleGround* bg = sBattleGroundMgr.GetBattleGround(m_BgInstanceGUID, m_BgTypeId);
+ //battleground can be deleted already when we are removing queue info
+ //bg pointer can be NULL! so use it carefully!
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
- uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId);
- if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue
+ uint32 queueSlot = plr->GetBattleGroundQueueIndex(m_BgQueueTypeId);
+ if( queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES ) // player is in queue, or in Battleground
{
- // check if player is invited to this bg ... this check must be here, because when player leaves queue and joins another, it would cause a problems
- BattleGroundQueue::QueuedPlayersMap::iterator qMapItr = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[plr->GetBattleGroundQueueIdFromLevel()].find(m_PlayerGuid);
- if (qMapItr != sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[plr->GetBattleGroundQueueIdFromLevel()].end() && qMapItr->second.GroupInfo && qMapItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID)
+ // check if player is in queue for this BG and if we are removing his invite event
+ BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[m_BgQueueTypeId].m_QueuedPlayers;
+ BattleGroundQueue::QueuedPlayersMap::iterator qMapItr = qpMap.find(m_PlayerGuid);
+ if( qMapItr != qpMap.end() && qMapItr->second.GroupInfo
+ && qMapItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID
+ && qMapItr->second.GroupInfo->RemoveInviteTime == m_RemoveTime )
{
- if (qMapItr->second.GroupInfo->IsRated)
- {
- ArenaTeam * at = objmgr.GetArenaTeamById(qMapItr->second.GroupInfo->ArenaTeamId);
- if (at)
- {
- sLog.outDebug("UPDATING memberLost's personal arena rating for %u by opponents rating: %u", GUID_LOPART(plr->GetGUID()), qMapItr->second.GroupInfo->OpponentsTeamRating);
- at->MemberLost(plr, qMapItr->second.GroupInfo->OpponentsTeamRating);
- at->SaveToDB();
- }
- }
- plr->RemoveBattleGroundQueueId(bgQueueTypeId);
- sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(m_PlayerGuid, true);
- sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgQueueTypeId, bg->GetQueueType());
+ sLog.outDebug("Battleground: removing player %u from bg queue for instance %u because of not pressing enter battle in time.",plr->GetGUIDLow(),m_BgInstanceGUID);
+
+ plr->RemoveBattleGroundQueueId(m_BgQueueTypeId);
+ sBattleGroundMgr.m_BattleGroundQueues[m_BgQueueTypeId].RemovePlayer(m_PlayerGuid, true);
+ //update queues if battleground isn't ended
+ if (bg)
+ sBattleGroundMgr.m_BattleGroundQueues[m_BgQueueTypeId].Update(m_BgTypeId, bg->GetQueueId());
+
WorldPacket data;
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, m_PlayersTeam, queueSlot, STATUS_NONE, 0, 0);
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0);
plr->GetSession()->SendPacket(&data);
}
}
- else
- sLog.outDebug("Battleground: Player was already removed from queue");
//event will be deleted
return true;
@@ -942,76 +1093,98 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
void BGQueueRemoveEvent::Abort(uint64 /*e_time*/)
{
- //this should not be called
- sLog.outError("Battleground remove event ABORTED!");
+ //do nothing
}
/*********************************************************/
/*** BATTLEGROUND MANAGER ***/
/*********************************************************/
-BattleGroundMgr::BattleGroundMgr()
+BattleGroundMgr::BattleGroundMgr() : m_AutoDistributionTimeChecker(0), m_ArenaTesting(false)
{
- m_BattleGrounds.clear();
- m_AutoDistributePoints = (bool)sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS);
- m_MaxRatingDifference = sWorld.getConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE);
- m_RatingDiscardTimer = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);
- m_PrematureFinishTimer = sWorld.getConfig(CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER);
- m_NextRatingDiscardUpdate = m_RatingDiscardTimer;
- m_AutoDistributionTimeChecker = 0;
- m_ArenaTesting = false;
+ for(uint32 i = BATTLEGROUND_TYPE_NONE; i < MAX_BATTLEGROUND_TYPE_ID; i++)
+ m_BattleGrounds[i].clear();
+ m_NextRatingDiscardUpdate = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);
+ m_Testing=false;
}
BattleGroundMgr::~BattleGroundMgr()
{
- BattleGroundSet::iterator itr, next;
- for(itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); itr = next)
+ DeleteAllBattleGrounds();
+}
+
+void BattleGroundMgr::DeleteAllBattleGrounds()
+{
+ for(uint32 i = BATTLEGROUND_TYPE_NONE; i < MAX_BATTLEGROUND_TYPE_ID; i++)
{
- next = itr;
- ++next;
- BattleGround * bg = itr->second;
- m_BattleGrounds.erase(itr);
- delete bg;
+ for(BattleGroundSet::iterator itr = m_BattleGrounds[i].begin(); itr != m_BattleGrounds[i].end();)
+ {
+ BattleGround * bg = itr->second;
+ m_BattleGrounds[i].erase(itr++);
+ if (!m_ClientBattleGroundIds[i][bg->GetQueueId()].empty())
+ m_ClientBattleGroundIds[i][bg->GetQueueId()].erase(bg->GetClientInstanceID());
+ delete bg;
+ }
+ }
+
+ // destroy template battlegrounds that listed only in queues (other already terminated)
+ for(uint32 bgTypeId = 0; bgTypeId < MAX_BATTLEGROUND_TYPE_ID; ++bgTypeId)
+ {
+ // ~BattleGround call unregistring BG from queue
+ while(!BGFreeSlotQueue[bgTypeId].empty())
+ delete BGFreeSlotQueue[bgTypeId].front();
}
- m_BattleGrounds.clear();
}
// used to update running battlegrounds, and delete finished ones
-void BattleGroundMgr::Update(time_t diff)
+void BattleGroundMgr::Update(uint32 diff)
{
BattleGroundSet::iterator itr, next;
- for(itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); itr = next)
+ for(uint32 i = BATTLEGROUND_TYPE_NONE; i < MAX_BATTLEGROUND_TYPE_ID; i++)
{
- next = itr;
- ++next;
- itr->second->Update(diff);
- // use the SetDeleteThis variable
- // direct deletion caused crashes
- if(itr->second->m_SetDeleteThis)
+ itr = m_BattleGrounds[i].begin();
+ // skip updating battleground template
+ if (itr != m_BattleGrounds[i].end())
+ ++itr;
+ for(; itr != m_BattleGrounds[i].end(); itr = next)
{
- BattleGround * bg = itr->second;
- m_BattleGrounds.erase(itr);
- delete bg;
+ next = itr;
+ ++next;
+ itr->second->Update(diff);
+ // use the SetDeleteThis variable
+ // direct deletion caused crashes
+ if (itr->second->m_SetDeleteThis)
+ {
+ BattleGround * bg = itr->second;
+ m_BattleGrounds[i].erase(itr);
+ if (!m_ClientBattleGroundIds[i][bg->GetQueueId()].empty())
+ m_ClientBattleGroundIds[i][bg->GetQueueId()].erase(bg->GetClientInstanceID());
+ delete bg;
+ }
}
}
// if rating difference counts, maybe force-update queues
- if(m_MaxRatingDifference)
+ if (sWorld.getConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE) && sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER))
{
// it's time to force update
- if(m_NextRatingDiscardUpdate < diff)
+ if (m_NextRatingDiscardUpdate < diff)
{
// forced update for level 70 rated arenas
- m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA,6,ARENA_TYPE_2v2,true,0);
- m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA,6,ARENA_TYPE_3v3,true,0);
- m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA,6,ARENA_TYPE_5v5,true,0);
- m_NextRatingDiscardUpdate = m_RatingDiscardTimer;
+ sLog.outDebug("BattleGroundMgr: UPDATING ARENA QUEUES");
+ m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_79, ARENA_TYPE_2v2, true, 0);
+ m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_80, ARENA_TYPE_2v2, true, 0);
+ m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_79, ARENA_TYPE_3v3, true, 0);
+ m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_80, ARENA_TYPE_3v3, true, 0);
+ m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_79, ARENA_TYPE_5v5, true, 0);
+ m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_80, ARENA_TYPE_5v5, true, 0);
+ m_NextRatingDiscardUpdate = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);
}
else
m_NextRatingDiscardUpdate -= diff;
}
- if(m_AutoDistributePoints)
+ if (sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS))
{
- if(m_AutoDistributionTimeChecker < diff)
+ if (m_AutoDistributionTimeChecker < diff)
{
if(time(NULL) > m_NextAutoDistributionTime)
{
@@ -1026,10 +1199,11 @@ void BattleGroundMgr::Update(time_t diff)
}
}
-void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint32 team, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint32 arenatype, uint8 israted)
+void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype)
{
// we can be in 3 queues in same time...
- if(StatusID == 0)
+
+ if (StatusID == 0 || !bg)
{
data->Initialize(SMSG_BATTLEFIELD_STATUS, 4*3);
*data << uint32(QueueSlot); // queue id (0...2)
@@ -1040,10 +1214,11 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro
data->Initialize(SMSG_BATTLEFIELD_STATUS, (4+1+1+4+2+4+1+4+4+4));
*data << uint32(QueueSlot); // queue id (0...2) - player can be in 3 queues in time
// uint64 in client
- *data << uint64( uint64(arenatype ? arenatype : bg->GetArenaType()) | (uint64(0x0D) << 8) | (uint64(bg->GetTypeID()) << 16) | (uint64(0x1F90) << 48) );
- *data << uint32(0); // unknown
+ *data << uint64( uint64(arenatype) | (uint64(0x0D) << 8) | (uint64(bg->GetTypeID()) << 16) | (uint64(0x1F90) << 48) );
+ *data << uint32(bg->GetClientInstanceID());
// alliance/horde for BG and skirmish/rated for Arenas
- *data << uint8(bg->isArena() ? ( israted ? israted : bg->isRated() ) : bg->GetTeamIndexByTeamId(team));
+ // following displays the minimap-icon 0 = faction icon 1 = arenaicon
+ *data << uint8(bg->isRated());
/* *data << uint8(arenatype ? arenatype : bg->GetArenaType()); // team type (0=BG, 2=2x2, 3=3x3, 5=5x5), for arenas // NOT PROPER VALUE IF ARENA ISN'T RUNNING YET!!!!
switch(bg->GetTypeID()) // value depends on bg id
{
@@ -1071,12 +1246,21 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro
case BATTLEGROUND_RL:
*data << uint8(8);
break;
+ case BATTLEGROUND_SA:
+ *data << uint8(9);
+ break;
+ case BATTLEGROUND_DS:
+ *data << uint8(10);
+ break;
+ case BATTLEGROUND_RV:
+ *data << uint8(11);
+ break;
default: // unknown
*data << uint8(0);
break;
}
- if(bg->isArena() && (StatusID == STATUS_WAIT_QUEUE))
+ if (bg->isArena() && (StatusID == STATUS_WAIT_QUEUE))
*data << uint32(BATTLEGROUND_AA); // all arenas I don't think so.
else
*data << uint32(bg->GetTypeID()); // BG id from DBC
@@ -1084,17 +1268,14 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro
*data << uint16(0x1F90); // unk value 8080
*data << uint32(bg->GetInstanceID()); // instance id
- if(bg->isBattleGround())
- *data << uint8(bg->GetTeamIndexByTeamId(team)); // team
- else
- *data << uint8(israted?israted:bg->isRated()); // is rated battle
+ *data << uint8(bg->isArena()); // minimap-icon 0=faction 1=arena
*/
*data << uint32(StatusID); // status
switch(StatusID)
{
case STATUS_WAIT_QUEUE: // status_in_queue
*data << uint32(Time1); // average wait time, milliseconds
- *data << uint32(Time2); // time in queue, updated every minute?
+ *data << uint32(Time2); // time in queue, updated every minute!, milliseconds
break;
case STATUS_WAIT_JOIN: // status_invite
*data << uint32(bg->GetMapId()); // map id
@@ -1102,7 +1283,7 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro
break;
case STATUS_IN_PROGRESS: // status_in_progress
*data << uint32(bg->GetMapId()); // map id
- *data << uint32(Time1); // 0 at bg start, 120000 after bg end, time to bg auto leave, milliseconds
+ *data << uint32(Time1); // time to bg auto leave, 0 at bg start, 120000 after bg end, milliseconds
*data << uint32(Time2); // time from bg start, milliseconds
*data << uint8(0x1); // unk sometimes 0x0!
break;
@@ -1115,16 +1296,16 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro
void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
{
uint8 type = (bg->isArena() ? 1 : 0);
- // last check on 2.4.1
+ // last check on 3.0.3
data->Initialize(MSG_PVP_LOG_DATA, (1+1+4+40*bg->GetPlayerScoresSize()));
- *data << uint8(type); // seems to be type (battleground=0/arena=1)
+ *data << uint8(type); // type (battleground=0/arena=1)
if(type) // arena
{
// it seems this must be according to BG_WINNER_A/H and _NOT_ BG_TEAM_A/H
for(int i = 1; i >= 0; --i)
{
- *data << uint32(3000-bg->m_ArenaTeamRatingChanges[i]); // rating change: showed value - 3000
+ *data << uint32(bg->m_ArenaTeamRatingChanges[i]);
*data << uint32(3999); // huge thanks for TOM_RUS for this!
sLog.outDebug("rating change: %d", bg->m_ArenaTeamRatingChanges[i]);
}
@@ -1132,16 +1313,16 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
{
uint32 at_id = bg->m_ArenaTeamIds[i];
ArenaTeam * at = objmgr.GetArenaTeamById(at_id);
- if(at)
+ if (at)
*data << at->GetName();
- else//*/
+ else
*data << (uint8)0;
}
}
- if(bg->GetWinner() == 2)
+ if (bg->GetStatus() != STATUS_WAIT_LEAVE)
{
- *data << uint8(0); // bg in progress
+ *data << uint8(0); // bg not ended
}
else
{
@@ -1155,10 +1336,7 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
{
*data << (uint64)itr->first;
*data << (int32)itr->second->KillingBlows;
- Player *plr = objmgr.GetPlayer(itr->first);
- uint32 team = bg->GetPlayerTeam(itr->first);
- if(!team && plr) team = plr->GetTeam();
- if(type == 0)
+ if (type == 0)
{
*data << (int32)itr->second->HonorableKills;
*data << (int32)itr->second->Deaths;
@@ -1166,18 +1344,12 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
}
else
{
- // that part probably wrong
- if(plr)
- {
- if(team == HORDE)
- *data << uint8(0);
- else if(team == ALLIANCE)
- {
- *data << uint8(1);
- }
- else
- *data << uint8(0);
- }
+ Player *plr = objmgr.GetPlayer(itr->first);
+ uint32 team = bg->GetPlayerTeam(itr->first);
+ if (!team && plr)
+ team = plr->GetTeam();
+ if (( bg->GetWinner()==0 && team == ALLIANCE ) || ( bg->GetWinner()==1 && team==HORDE ))
+ *data << uint8(1);
else
*data << uint8(0);
}
@@ -1204,13 +1376,16 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
*data << (uint32)((BattleGroundABScore*)itr->second)->BasesDefended; // bases defended
break;
case BATTLEGROUND_EY:
- *data << (uint32)0x00000001; // count of next fields
+ *data << (uint32)0x00000001; // count of next fields
*data << (uint32)((BattleGroundEYScore*)itr->second)->FlagCaptures; // flag captures
break;
case BATTLEGROUND_NA:
case BATTLEGROUND_BE:
case BATTLEGROUND_AA:
case BATTLEGROUND_RL:
+ case BATTLEGROUND_SA: // wotlk
+ case BATTLEGROUND_DS: // wotlk
+ case BATTLEGROUND_RV: // wotlk
*data << (int32)0; // 0
break;
default:
@@ -1221,7 +1396,7 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
}
}
-void BattleGroundMgr::BuildGroupJoinedBattlegroundPacket(WorldPacket *data, uint32 bgTypeId)
+void BattleGroundMgr::BuildGroupJoinedBattlegroundPacket(WorldPacket *data, BattleGroundTypeId bgTypeId)
{
/*bgTypeId is:
0 - Your group has joined a battleground queue, but you are not eligible
@@ -1249,10 +1424,10 @@ void BattleGroundMgr::BuildPlaySoundPacket(WorldPacket *data, uint32 soundid)
*data << uint32(soundid);
}
-void BattleGroundMgr::BuildPlayerLeftBattleGroundPacket(WorldPacket *data, Player *plr)
+void BattleGroundMgr::BuildPlayerLeftBattleGroundPacket(WorldPacket *data, const uint64& guid)
{
data->Initialize(SMSG_BATTLEGROUND_PLAYER_LEFT, 8);
- *data << uint64(plr->GetGUID());
+ *data << uint64(guid);
}
void BattleGroundMgr::BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Player *plr)
@@ -1261,62 +1436,97 @@ void BattleGroundMgr::BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Pla
*data << uint64(plr->GetGUID());
}
-void BattleGroundMgr::InvitePlayer(Player* plr, uint32 bgInstanceGUID, uint32 team)
+BattleGround * BattleGroundMgr::GetBattleGroundThroughClientInstance(uint32 instanceId, BattleGroundTypeId bgTypeId)
{
- // set invited player counters:
- BattleGround* bg = GetBattleGround(bgInstanceGUID);
- if(!bg)
- return;
- bg->IncreaseInvitedCount(team);
+ //cause at HandleBattleGroundJoinOpcode the clients sends the instanceid he gets from
+ //SMSG_BATTLEFIELD_LIST we need to find the battleground with this clientinstance-id
+ BattleGround* bg = GetBattleGroundTemplate(bgTypeId);
+ if (!bg)
+ return NULL;
- plr->SetInviteForBattleGroundQueueType(BGQueueTypeId(bg->GetTypeID(),bg->GetArenaType()), bgInstanceGUID);
+ if (bg->isArena())
+ return GetBattleGround(instanceId, bgTypeId);
- // set the arena teams for rated matches
- if(bg->isArena() && bg->isRated())
+ for(BattleGroundSet::iterator itr = m_BattleGrounds[bgTypeId].begin(); itr != m_BattleGrounds[bgTypeId].end(); ++itr)
+ {
+ if (itr->second->GetClientInstanceID() == instanceId)
+ return itr->second;
+ }
+ return NULL;
+}
+
+BattleGround * BattleGroundMgr::GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId)
+{
+ //search if needed
+ BattleGroundSet::iterator itr;
+ if (bgTypeId == BATTLEGROUND_TYPE_NONE)
{
- switch(bg->GetArenaType())
+ for(uint32 i = BATTLEGROUND_AV; i < MAX_BATTLEGROUND_TYPE_ID; i++)
{
- case ARENA_TYPE_2v2:
- bg->SetArenaTeamIdForTeam(team, plr->GetArenaTeamId(0));
- break;
- case ARENA_TYPE_3v3:
- bg->SetArenaTeamIdForTeam(team, plr->GetArenaTeamId(1));
- break;
- case ARENA_TYPE_5v5:
- bg->SetArenaTeamIdForTeam(team, plr->GetArenaTeamId(2));
- break;
- default:
- break;
+ itr = m_BattleGrounds[i].find(InstanceID);
+ if (itr != m_BattleGrounds[i].end())
+ return itr->second;
}
+ return NULL;
}
+ itr = m_BattleGrounds[bgTypeId].find(InstanceID);
+ return ( (itr != m_BattleGrounds[bgTypeId].end()) ? itr->second : NULL );
+}
- // create invite events:
- //add events to player's counters ---- this is not good way - there should be something like global event processor, where we should add those events
- BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(plr->GetGUID(), bgInstanceGUID);
- plr->m_Events.AddEvent(inviteEvent, plr->m_Events.CalculateTime(INVITE_ACCEPT_WAIT_TIME/2));
- BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(plr->GetGUID(), bgInstanceGUID, team);
- plr->m_Events.AddEvent(removeEvent, plr->m_Events.CalculateTime(INVITE_ACCEPT_WAIT_TIME));
+BattleGround * BattleGroundMgr::GetBattleGroundTemplate(BattleGroundTypeId bgTypeId)
+{
+ //map is sorted and we can be sure that lowest instance id has only BG template
+ return m_BattleGrounds[bgTypeId].empty() ? NULL : m_BattleGrounds[bgTypeId].begin()->second;
}
-BattleGround * BattleGroundMgr::GetBattleGroundTemplate(uint32 bgTypeId)
+uint32 BattleGroundMgr::CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id)
{
- return BGFreeSlotQueue[bgTypeId].empty() ? NULL : BGFreeSlotQueue[bgTypeId].back();
+ if (IsArenaType(bgTypeId))
+ return 0; //arenas don't have client-instanceids
+
+ // we create here an instanceid, which is just for
+ // displaying this to the client and without any other use..
+ // the client-instanceIds are unique for each battleground-type
+ // the instance-id just needs to be as low as possible, beginning with 1
+ // the following works, because std::set is default ordered with "<"
+ // the optimalization would be to use as bitmask std::vector<uint32> - but that would only make code unreadable
+ uint32 lastId = 0;
+ for(std::set<uint32>::iterator itr = m_ClientBattleGroundIds[bgTypeId][queue_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][queue_id].end();)
+ {
+ if( (++lastId) != *itr) //if there is a gap between the ids, we will break..
+ break;
+ lastId = *itr;
+ }
+ m_ClientBattleGroundIds[bgTypeId][queue_id].insert(lastId + 1);
+ return lastId + 1;
}
// create a new battleground that will really be used to play
-BattleGround * BattleGroundMgr::CreateNewBattleGround(uint32 bgTypeId)
+BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated)
{
- BattleGround *bg = NULL;
-
// get the template BG
BattleGround *bg_template = GetBattleGroundTemplate(bgTypeId);
-
- if(!bg_template)
+ if (!bg_template)
{
sLog.outError("BattleGround: CreateNewBattleGround - bg template not found for %u", bgTypeId);
- return 0;
+ return NULL;
}
+ //for arenas there is random map used
+ if (bg_template->isArena())
+ {
+ BattleGroundTypeId arenas[] = {BATTLEGROUND_NA, BATTLEGROUND_BE, BATTLEGROUND_RL};
+ uint32 arena_num = urand(0,2);
+ bgTypeId = arenas[arena_num];
+ bg_template = GetBattleGroundTemplate(bgTypeId);
+ if (!bg_template)
+ {
+ sLog.outError("BattleGround: CreateNewBattleGround - bg template not found for %u", bgTypeId);
+ return NULL;
+ }
+ }
+
+ BattleGround *bg = NULL;
// create a copy of the BG template
switch(bgTypeId)
{
@@ -1344,42 +1554,47 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(uint32 bgTypeId)
case BATTLEGROUND_RL:
bg = new BattleGroundRL(*(BattleGroundRL*)bg_template);
break;
+ case BATTLEGROUND_SA:
+ bg = new BattleGroundSA(*(BattleGroundSA*)bg_template);
+ break;
+ case BATTLEGROUND_DS:
+ bg = new BattleGroundDS(*(BattleGroundDS*)bg_template);
+ break;
+ case BATTLEGROUND_RV:
+ bg = new BattleGroundRV(*(BattleGroundRV*)bg_template);
+ break;
default:
- //bg = new BattleGround;
+ //error, but it is handled few lines above
return 0;
- break; // placeholder for non implemented BG
}
// generate a new instance id
bg->SetInstanceID(MapManager::Instance().GenerateInstanceId()); // set instance id
+ bg->SetClientInstanceID(CreateClientVisibleInstanceId(bgTypeId, queue_id));
// reset the new bg (set status to status_wait_queue from status_none)
bg->Reset();
- /* will be setup in BG::Update() when the first player is ported in
- if(!(bg->SetupBattleGround()))
- {
- sLog.outError("BattleGround: CreateNewBattleGround: SetupBattleGround failed for bg %u", bgTypeId);
- delete bg;
- return 0;
- }
- */
+ // start the joining of the bg
+ bg->SetStatus(STATUS_WAIT_JOIN);
+ bg->SetQueueId(queue_id);
+ bg->SetArenaType(arenaType);
+ bg->SetRated(isRated);
// add BG to free slot queue
bg->AddToBGFreeSlotQueue();
// add bg to update list
- AddBattleGround(bg->GetInstanceID(), bg);
+ AddBattleGround(bg->GetInstanceID(), bg->GetTypeID(), bg);
return bg;
}
// used to create the BG templates
-uint32 BattleGroundMgr::CreateBattleGround(uint32 bgTypeId, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO)
+uint32 BattleGroundMgr::CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsArena, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO)
{
// Create the BG
BattleGround *bg = NULL;
-
switch(bgTypeId)
{
case BATTLEGROUND_AV: bg = new BattleGroundAV; break;
@@ -1390,35 +1605,27 @@ uint32 BattleGroundMgr::CreateBattleGround(uint32 bgTypeId, uint32 MinPlayersPer
case BATTLEGROUND_AA: bg = new BattleGroundAA; break;
case BATTLEGROUND_EY: bg = new BattleGroundEY; break;
case BATTLEGROUND_RL: bg = new BattleGroundRL; break;
+ case BATTLEGROUND_SA: bg = new BattleGroundSA; break;
+ case BATTLEGROUND_DS: bg = new BattleGroundDS; break;
+ case BATTLEGROUND_RV: bg = new BattleGroundRV; break;
default:bg = new BattleGround; break; // placeholder for non implemented BG
}
bg->SetMapId(MapID);
-
- bg->Reset();
-
- BattlemasterListEntry const *bl = sBattlemasterListStore.LookupEntry(bgTypeId);
- //in previous method is checked if exists entry in sBattlemasterListStore, so no check needed
- if (bl)
- {
- bg->SetArenaorBGType(bl->type == TYPE_ARENA);
- }
-
bg->SetTypeID(bgTypeId);
- bg->SetInstanceID(0); // template bg, instance id is 0
+ bg->SetInstanceID(0);
+ bg->SetArenaorBGType(IsArena);
bg->SetMinPlayersPerTeam(MinPlayersPerTeam);
bg->SetMaxPlayersPerTeam(MaxPlayersPerTeam);
- bg->SetMinPlayers(MinPlayersPerTeam*2);
- bg->SetMaxPlayers(MaxPlayersPerTeam*2);
+ bg->SetMinPlayers(MinPlayersPerTeam * 2);
+ bg->SetMaxPlayers(MaxPlayersPerTeam * 2);
bg->SetName(BattleGroundName);
bg->SetTeamStartLoc(ALLIANCE, Team1StartLocX, Team1StartLocY, Team1StartLocZ, Team1StartLocO);
bg->SetTeamStartLoc(HORDE, Team2StartLocX, Team2StartLocY, Team2StartLocZ, Team2StartLocO);
bg->SetLevelRange(LevelMin, LevelMax);
- //add BattleGround instance to FreeSlotQueue (.back() will return the template!)
- bg->AddToBGFreeSlotQueue();
-
- // do NOT add to update list, since this is a template battleground!
+ // add bg to update list
+ AddBattleGround(bg->GetInstanceID(), bg->GetTypeID(), bg);
// return some not-null value, bgTypeId is good enough for me
return bgTypeId;
@@ -1431,13 +1638,14 @@ void BattleGroundMgr::CreateInitialBattleGrounds()
uint32 MaxPlayersPerTeam, MinPlayersPerTeam, MinLvl, MaxLvl, start1, start2;
BattlemasterListEntry const *bl;
WorldSafeLocsEntry const *start;
+ bool IsArena;
uint32 count = 0;
// 0 1 2 3 4 5 6 7 8
QueryResult *result = WorldDatabase.Query("SELECT id, MinPlayersPerTeam,MaxPlayersPerTeam,MinLvl,MaxLvl,AllianceStartLoc,AllianceStartO,HordeStartLoc,HordeStartO FROM battleground_template");
- if(!result)
+ if (!result)
{
barGoLink bar(1);
@@ -1455,44 +1663,46 @@ void BattleGroundMgr::CreateInitialBattleGrounds()
Field *fields = result->Fetch();
bar.step();
- uint32 bgTypeID = fields[0].GetUInt32();
+ uint32 bgTypeID_ = fields[0].GetUInt32();
- // can be overwrited by values from DB
- bl = sBattlemasterListStore.LookupEntry(bgTypeID);
- if(!bl)
+ // can be overwrite by values from DB
+ bl = sBattlemasterListStore.LookupEntry(bgTypeID_);
+ if (!bl)
{
- sLog.outError("Battleground ID %u not found in BattlemasterList.dbc. Battleground not created.",bgTypeID);
+ sLog.outError("Battleground ID %u not found in BattlemasterList.dbc. Battleground not created.", bgTypeID_);
continue;
}
- MaxPlayersPerTeam = bl->maxplayersperteam;
- MinPlayersPerTeam = bl->maxplayersperteam/2;
- MinLvl = bl->minlvl;
- MaxLvl = bl->maxlvl;
-
- if(fields[1].GetUInt32())
- MinPlayersPerTeam = fields[1].GetUInt32();
-
- if(fields[2].GetUInt32())
- MaxPlayersPerTeam = fields[2].GetUInt32();
-
- if(fields[3].GetUInt32())
- MinLvl = fields[3].GetUInt32();
+ BattleGroundTypeId bgTypeID = BattleGroundTypeId(bgTypeID_);
- if(fields[4].GetUInt32())
- MaxLvl = fields[4].GetUInt32();
+ IsArena = (bl->type == TYPE_ARENA);
+ MinPlayersPerTeam = fields[1].GetUInt32();
+ MaxPlayersPerTeam = fields[2].GetUInt32();
+ MinLvl = fields[3].GetUInt32();
+ MaxLvl = fields[4].GetUInt32();
+ //check values from DB
+ if (MaxPlayersPerTeam == 0 || MinPlayersPerTeam == 0 || MinPlayersPerTeam > MaxPlayersPerTeam)
+ {
+ MaxPlayersPerTeam = bl->maxplayersperteam;
+ MinPlayersPerTeam = bl->maxplayersperteam / 2;
+ }
+ if (MinLvl == 0 || MaxLvl == 0 || MinLvl > MaxLvl)
+ {
+ MinLvl = bl->minlvl;
+ MaxLvl = bl->maxlvl;
+ }
start1 = fields[5].GetUInt32();
start = sWorldSafeLocsStore.LookupEntry(start1);
- if(start)
+ if (start)
{
AStartLoc[0] = start->x;
AStartLoc[1] = start->y;
AStartLoc[2] = start->z;
AStartLoc[3] = fields[6].GetFloat();
}
- else if(bgTypeID == BATTLEGROUND_AA)
+ else if (bgTypeID == BATTLEGROUND_AA)
{
AStartLoc[0] = 0;
AStartLoc[1] = 0;
@@ -1501,21 +1711,21 @@ void BattleGroundMgr::CreateInitialBattleGrounds()
}
else
{
- sLog.outErrorDb("Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `AllianceStartLoc`. BG not created.",bgTypeID,start1);
+ sLog.outErrorDb("Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `AllianceStartLoc`. BG not created.", bgTypeID, start1);
continue;
}
start2 = fields[7].GetUInt32();
start = sWorldSafeLocsStore.LookupEntry(start2);
- if(start)
+ if (start)
{
HStartLoc[0] = start->x;
HStartLoc[1] = start->y;
HStartLoc[2] = start->z;
HStartLoc[3] = fields[8].GetFloat();
}
- else if(bgTypeID == BATTLEGROUND_AA)
+ else if (bgTypeID == BATTLEGROUND_AA)
{
HStartLoc[0] = 0;
HStartLoc[1] = 0;
@@ -1524,12 +1734,12 @@ void BattleGroundMgr::CreateInitialBattleGrounds()
}
else
{
- sLog.outErrorDb("Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `HordeStartLoc`. BG not created.",bgTypeID,start2);
+ sLog.outErrorDb("Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `HordeStartLoc`. BG not created.", bgTypeID, start2);
continue;
}
//sLog.outDetail("Creating battleground %s, %u-%u", bl->name[sWorld.GetDBClang()], MinLvl, MaxLvl);
- if(!CreateBattleGround(bgTypeID, MinPlayersPerTeam, MaxPlayersPerTeam, MinLvl, MaxLvl, bl->name[sWorld.GetDefaultDbcLocale()], bl->mapid[0], AStartLoc[0], AStartLoc[1], AStartLoc[2], AStartLoc[3], HStartLoc[0], HStartLoc[1], HStartLoc[2], HStartLoc[3]))
+ if (!CreateBattleGround(bgTypeID, IsArena, MinPlayersPerTeam, MaxPlayersPerTeam, MinLvl, MaxLvl, bl->name[sWorld.GetDefaultDbcLocale()], bl->mapid[0], AStartLoc[0], AStartLoc[1], AStartLoc[2], AStartLoc[3], HStartLoc[0], HStartLoc[1], HStartLoc[2], HStartLoc[3]))
continue;
++count;
@@ -1543,11 +1753,11 @@ void BattleGroundMgr::CreateInitialBattleGrounds()
void BattleGroundMgr::InitAutomaticArenaPointDistribution()
{
- if(m_AutoDistributePoints)
+ if (sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS))
{
sLog.outDebug("Initializing Automatic Arena Point Distribution");
QueryResult * result = CharacterDatabase.Query("SELECT NextArenaPointDistributionTime FROM saved_variables");
- if(!result)
+ if (!result)
{
sLog.outDebug("Battleground: Next arena point distribution time not found in SavedVariables, reseting it now.");
m_NextAutoDistributionTime = time(NULL) + BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY * sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS);
@@ -1555,7 +1765,7 @@ void BattleGroundMgr::InitAutomaticArenaPointDistribution()
}
else
{
- m_NextAutoDistributionTime = (*result)[0].GetUInt64();
+ m_NextAutoDistributionTime = time_t((*result)[0].GetUInt64());
delete result;
}
sLog.outDebug("Automatic Arena Point Distribution initialized.");
@@ -1565,9 +1775,9 @@ void BattleGroundMgr::InitAutomaticArenaPointDistribution()
void BattleGroundMgr::DistributeArenaPoints()
{
// used to distribute arena points based on last week's stats
- sWorld.SendGlobalText("Flushing Arena points based on team ratings, this may take a few minutes. Please stand by...", NULL);
+ sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_START);
- sWorld.SendGlobalText("Distributing arena points to players...", NULL);
+ sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_ONLINE_START);
//temporary structure for storing maximum points to add values for all players
std::map<uint32, uint32> PlayerPoints;
@@ -1575,7 +1785,7 @@ void BattleGroundMgr::DistributeArenaPoints()
//at first update all points for all team members
for(ObjectMgr::ArenaTeamMap::iterator team_itr = objmgr.GetArenaTeamMapBegin(); team_itr != objmgr.GetArenaTeamMapEnd(); ++team_itr)
{
- if(ArenaTeam * at = team_itr->second)
+ if (ArenaTeam * at = team_itr->second)
{
at->UpdateArenaPointsHelper(PlayerPoints);
}
@@ -1585,7 +1795,7 @@ void BattleGroundMgr::DistributeArenaPoints()
for (std::map<uint32, uint32>::iterator plr_itr = PlayerPoints.begin(); plr_itr != PlayerPoints.end(); ++plr_itr)
{
//update to database
- CharacterDatabase.PExecute("UPDATE characters SET arena_pending_points = '%u' WHERE `guid` = '%u'", plr_itr->second, plr_itr->first);
+ CharacterDatabase.PExecute("UPDATE characters SET arena_pending_points = '%u' WHERE guid = '%u'", plr_itr->second, plr_itr->first);
//add points if player is online
Player* pl = objmgr.GetPlayer(plr_itr->first);
if (pl)
@@ -1594,12 +1804,12 @@ void BattleGroundMgr::DistributeArenaPoints()
PlayerPoints.clear();
- sWorld.SendGlobalText("Finished setting arena points for online players.", NULL);
+ sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_ONLINE_END);
- sWorld.SendGlobalText("Modifying played count, arena points etc. for loaded arena teams, sending updated stats to online players...", NULL);
+ sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_TEAM_START);
for(ObjectMgr::ArenaTeamMap::iterator titr = objmgr.GetArenaTeamMapBegin(); titr != objmgr.GetArenaTeamMapEnd(); ++titr)
{
- if(ArenaTeam * at = titr->second)
+ if (ArenaTeam * at = titr->second)
{
at->FinishWeek(); // set played this week etc values to 0 in memory, too
at->SaveToDB(); // save changes
@@ -1607,17 +1817,18 @@ void BattleGroundMgr::DistributeArenaPoints()
}
}
- sWorld.SendGlobalText("Modification done.", NULL);
+ sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_TEAM_END);
- sWorld.SendGlobalText("Done flushing Arena points.", NULL);
+ sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_END);
}
-void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, uint64 guid, Player* plr, uint32 bgTypeId)
+void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint64& guid, Player* plr, BattleGroundTypeId bgTypeId)
{
- uint32 PlayerLevel = 10;
+ if (!plr)
+ return;
- if(plr)
- PlayerLevel = plr->getLevel();
+ uint32 PlayerLevel = 10;
+ PlayerLevel = plr->getLevel();
data->Initialize(SMSG_BATTLEFIELD_LIST);
*data << uint64(guid); // battlemaster guid
@@ -1635,27 +1846,25 @@ void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, uint64 guid
uint32 count = 0;
*data << uint32(0x00); // number of bg instances
- for(std::map<uint32, BattleGround*>::iterator itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); ++itr)
+ uint32 queue_id = plr->GetBattleGroundQueueIdFromLevel(bgTypeId);
+ for(std::set<uint32>::iterator itr = m_ClientBattleGroundIds[bgTypeId][queue_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][queue_id].end();++itr)
{
- if(itr->second->GetTypeID() == bgTypeId && (PlayerLevel >= itr->second->GetMinLevel()) && (PlayerLevel <= itr->second->GetMaxLevel()))
- {
- *data << uint32(itr->second->GetInstanceID());
- ++count;
- }
+ *data << uint32(*itr);
+ ++count;
}
data->put<uint32>( count_pos , count);
}
}
-void BattleGroundMgr::SendToBattleGround(Player *pl, uint32 instanceId)
+void BattleGroundMgr::SendToBattleGround(Player *pl, uint32 instanceId, BattleGroundTypeId bgTypeId)
{
- BattleGround *bg = GetBattleGround(instanceId);
- if(bg)
+ BattleGround *bg = GetBattleGround(instanceId, bgTypeId);
+ if (bg)
{
uint32 mapid = bg->GetMapId();
float x, y, z, O;
uint32 team = pl->GetBGTeam();
- if(team==0)
+ if (team==0)
team = pl->GetTeam();
bg->GetTeamStartLoc(team, x, y, z, O);
@@ -1668,24 +1877,17 @@ void BattleGroundMgr::SendToBattleGround(Player *pl, uint32 instanceId)
}
}
-void BattleGroundMgr::SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, uint64 guid)
+void BattleGroundMgr::SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, const uint64& guid)
{
WorldPacket data(SMSG_AREA_SPIRIT_HEALER_TIME, 12);
uint32 time_ = 30000 - bg->GetLastResurrectTime(); // resurrect every 30 seconds
- if(time_ == uint32(-1))
+ if (time_ == uint32(-1))
time_ = 0;
data << guid << time_;
pl->GetSession()->SendPacket(&data);
}
-void BattleGroundMgr::RemoveBattleGround(uint32 instanceID)
-{
- BattleGroundSet::iterator itr = m_BattleGrounds.find(instanceID);
- if(itr!=m_BattleGrounds.end())
- m_BattleGrounds.erase(itr);
-}
-
-bool BattleGroundMgr::IsArenaType(uint32 bgTypeId) const
+bool BattleGroundMgr::IsArenaType(BattleGroundTypeId bgTypeId)
{
return ( bgTypeId == BATTLEGROUND_AA ||
bgTypeId == BATTLEGROUND_BE ||
@@ -1693,96 +1895,169 @@ bool BattleGroundMgr::IsArenaType(uint32 bgTypeId) const
bgTypeId == BATTLEGROUND_RL );
}
-bool BattleGroundMgr::IsBattleGroundType(uint32 bgTypeId) const
-{
- return !IsArenaType(bgTypeId);
-}
-
-uint32 BattleGroundMgr::BGQueueTypeId(uint32 bgTypeId, uint8 arenaType) const
+BattleGroundQueueTypeId BattleGroundMgr::BGQueueTypeId(BattleGroundTypeId bgTypeId, uint8 arenaType)
{
switch(bgTypeId)
{
- case BATTLEGROUND_WS:
- return BATTLEGROUND_QUEUE_WS;
- case BATTLEGROUND_AB:
- return BATTLEGROUND_QUEUE_AB;
- case BATTLEGROUND_AV:
- return BATTLEGROUND_QUEUE_AV;
- case BATTLEGROUND_EY:
- return BATTLEGROUND_QUEUE_EY;
- case BATTLEGROUND_AA:
- case BATTLEGROUND_NA:
- case BATTLEGROUND_RL:
- case BATTLEGROUND_BE:
- switch(arenaType)
- {
- case ARENA_TYPE_2v2:
- return BATTLEGROUND_QUEUE_2v2;
- case ARENA_TYPE_3v3:
- return BATTLEGROUND_QUEUE_3v3;
- case ARENA_TYPE_5v5:
- return BATTLEGROUND_QUEUE_5v5;
+ case BATTLEGROUND_WS:
+ return BATTLEGROUND_QUEUE_WS;
+ case BATTLEGROUND_AB:
+ return BATTLEGROUND_QUEUE_AB;
+ case BATTLEGROUND_AV:
+ return BATTLEGROUND_QUEUE_AV;
+ case BATTLEGROUND_EY:
+ return BATTLEGROUND_QUEUE_EY;
+ case BATTLEGROUND_SA:
+ return BATTLEGROUND_QUEUE_SA;
+ case BATTLEGROUND_AA:
+ case BATTLEGROUND_NA:
+ case BATTLEGROUND_RL:
+ case BATTLEGROUND_BE:
+ case BATTLEGROUND_DS:
+ case BATTLEGROUND_RV:
+ switch(arenaType)
+ {
+ case ARENA_TYPE_2v2:
+ return BATTLEGROUND_QUEUE_2v2;
+ case ARENA_TYPE_3v3:
+ return BATTLEGROUND_QUEUE_3v3;
+ case ARENA_TYPE_5v5:
+ return BATTLEGROUND_QUEUE_5v5;
+ default:
+ return BATTLEGROUND_QUEUE_NONE;
+ }
default:
- return 0;
- }
- default:
- return 0;
+ return BATTLEGROUND_QUEUE_NONE;
}
}
-uint32 BattleGroundMgr::BGTemplateId(uint32 bgQueueTypeId) const
+BattleGroundTypeId BattleGroundMgr::BGTemplateId(BattleGroundQueueTypeId bgQueueTypeId)
{
switch(bgQueueTypeId)
{
- case BATTLEGROUND_QUEUE_WS:
- return BATTLEGROUND_WS;
- case BATTLEGROUND_QUEUE_AB:
- return BATTLEGROUND_AB;
- case BATTLEGROUND_QUEUE_AV:
- return BATTLEGROUND_AV;
- case BATTLEGROUND_QUEUE_EY:
- return BATTLEGROUND_EY;
- case BATTLEGROUND_QUEUE_2v2:
- case BATTLEGROUND_QUEUE_3v3:
- case BATTLEGROUND_QUEUE_5v5:
- return BATTLEGROUND_AA;
- default:
- return 0;
+ case BATTLEGROUND_QUEUE_WS:
+ return BATTLEGROUND_WS;
+ case BATTLEGROUND_QUEUE_AB:
+ return BATTLEGROUND_AB;
+ case BATTLEGROUND_QUEUE_AV:
+ return BATTLEGROUND_AV;
+ case BATTLEGROUND_QUEUE_EY:
+ return BATTLEGROUND_EY;
+ case BATTLEGROUND_QUEUE_SA:
+ return BATTLEGROUND_SA;
+ case BATTLEGROUND_QUEUE_2v2:
+ case BATTLEGROUND_QUEUE_3v3:
+ case BATTLEGROUND_QUEUE_5v5:
+ return BATTLEGROUND_AA;
+ default:
+ return BattleGroundTypeId(0); // used for unknown template (it existed and do nothing)
}
}
-uint8 BattleGroundMgr::BGArenaType(uint32 bgQueueTypeId) const
+uint8 BattleGroundMgr::BGArenaType(BattleGroundQueueTypeId bgQueueTypeId)
{
switch(bgQueueTypeId)
{
- case BATTLEGROUND_QUEUE_2v2:
- return ARENA_TYPE_2v2;
- case BATTLEGROUND_QUEUE_3v3:
- return ARENA_TYPE_3v3;
- case BATTLEGROUND_QUEUE_5v5:
- return ARENA_TYPE_5v5;
- default:
- return 0;
+ case BATTLEGROUND_QUEUE_2v2:
+ return ARENA_TYPE_2v2;
+ case BATTLEGROUND_QUEUE_3v3:
+ return ARENA_TYPE_3v3;
+ case BATTLEGROUND_QUEUE_5v5:
+ return ARENA_TYPE_5v5;
+ default:
+ return 0;
}
}
+void BattleGroundMgr::ToggleTesting()
+{
+ m_Testing = !m_Testing;
+ if (m_Testing)
+ sWorld.SendWorldText(LANG_DEBUG_BG_ON);
+ else
+ sWorld.SendWorldText(LANG_DEBUG_BG_OFF);
+}
+
void BattleGroundMgr::ToggleArenaTesting()
{
m_ArenaTesting = !m_ArenaTesting;
- if(m_ArenaTesting)
- sWorld.SendGlobalText("Arenas are set to 1v1 for debugging. So, don't join as group.", NULL);
+ if (m_ArenaTesting)
+ sWorld.SendWorldText(LANG_DEBUG_ARENA_ON);
else
- sWorld.SendGlobalText("Arenas are set to normal playercount.", NULL);
+ sWorld.SendWorldText(LANG_DEBUG_ARENA_OFF);
}
void BattleGroundMgr::SetHolidayWeekends(uint32 mask)
{
- for(uint32 bgtype = 1; bgtype <= 8; ++bgtype)
+ for(uint32 bgtype = 1; bgtype < MAX_BATTLEGROUND_TYPE_ID; ++bgtype)
{
- if(BattleGround * bg = GetBattleGroundTemplate(bgtype))
+ if(BattleGround * bg = GetBattleGroundTemplate(BattleGroundTypeId(bgtype)))
{
bg->SetHoliday(mask & (1 << bgtype));
}
}
}
+uint32 BattleGroundMgr::GetMaxRatingDifference() const
+{
+ // this is for stupid people who can't use brain and set max rating difference to 0
+ uint32 diff = sWorld.getConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE);
+ if (diff == 0)
+ diff = 5000;
+ return diff;
+}
+
+uint32 BattleGroundMgr::GetRatingDiscardTimer() const
+{
+ return sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);
+}
+
+uint32 BattleGroundMgr::GetPrematureFinishTime() const
+{
+ return sWorld.getConfig(CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER);
+}
+
+void BattleGroundMgr::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();
+ if (!sBattlemasterListStore.LookupEntry(bgTypeId))
+ {
+ sLog.outErrorDb("Table `battlemaster_entry` contain entry %u for not existed battleground type %u, ignored.",entry,bgTypeId);
+ continue;
+ }
+
+ mBattleMastersMap[entry] = BattleGroundTypeId(bgTypeId);
+
+ } while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u battlemaster entries", count );
+}
diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h
index 5edcc1457d3..d9cc9deae13 100644
--- a/src/game/BattleGroundMgr.h
+++ b/src/game/BattleGroundMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,30 +21,23 @@
#ifndef __BATTLEGROUNDMGR_H
#define __BATTLEGROUNDMGR_H
-#include "BattleGround.h"
+#include "Common.h"
#include "Policies/Singleton.h"
+#include "BattleGround.h"
-class BattleGround;
-
-//TODO it is not possible to have this structure, because we should have BattlegroundSet for each queue
-//so i propose to change this type to array 1..MAX_BATTLEGROUND_TYPES of sets or maps..
typedef std::map<uint32, BattleGround*> BattleGroundSet;
-//typedef std::map<uint32, BattleGroundQueue*> BattleGroundQueueSet;
-typedef std::deque<BattleGround*> BGFreeSlotQueueType;
-#define MAX_BATTLEGROUND_QUEUES 7 // for level ranges 10-19, 20-29, 30-39, 40-49, 50-59, 60-69, 70+
+//this container can't be deque, because deque doesn't like removing the last element - if you remove it, it invalidates next iterator and crash appears
+typedef std::list<BattleGround*> BGFreeSlotQueueType;
-#define MAX_BATTLEGROUND_TYPES 9 // each BG type will be in array
+typedef UNORDERED_MAP<uint32, BattleGroundTypeId> BattleMastersMap;
-#define MAX_BATTLEGROUND_QUEUE_TYPES 8
-
-#define BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY 86400 // seconds in a day
+#define BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY 86400 // seconds in a day
+#define COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME 10
struct GroupQueueInfo; // type predefinition
struct PlayerQueueInfo // stores information for players in queue
{
- uint32 InviteTime; // first invite time
- uint32 LastInviteTime; // last invite time
uint32 LastOnlineTime; // for tracking and removing offline players from queue after 5 minutes
GroupQueueInfo * GroupInfo; // pointer to the associated groupqueueinfo
};
@@ -53,16 +46,26 @@ struct GroupQueueInfo // stores informatio
{
std::map<uint64, PlayerQueueInfo*> Players; // player queue info map
uint32 Team; // Player team (ALLIANCE/HORDE)
- uint32 BgTypeId; // battleground type id
+ BattleGroundTypeId BgTypeId; // battleground type id
bool IsRated; // rated
uint8 ArenaType; // 2v2, 3v3, 5v5 or 0 when BG
uint32 ArenaTeamId; // team id if rated match
uint32 JoinTime; // time when group was added
+ uint32 RemoveInviteTime; // time when we will remove invite for players in group
uint32 IsInvitedToBGInstanceGUID; // was invited to certain BG
uint32 ArenaTeamRating; // if rated match, inited to the rating of the team
uint32 OpponentsTeamRating; // for rated arena matches
};
+enum BattleGroundQueueGroupTypes
+{
+ BG_QUEUE_PREMADE_ALLIANCE = 0,
+ BG_QUEUE_PREMADE_HORDE = 1,
+ BG_QUEUE_NORMAL_ALLIANCE = 2,
+ BG_QUEUE_NORMAL_HORDE = 3
+};
+#define BG_QUEUE_GROUP_TYPES_COUNT 4
+
class BattleGround;
class BattleGroundQueue
{
@@ -70,64 +73,61 @@ class BattleGroundQueue
BattleGroundQueue();
~BattleGroundQueue();
- void Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype = 0, bool isRated = false, uint32 minRating = 0);
+ void Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0);
- GroupQueueInfo * AddGroup(Player * leader, uint32 BgTypeId, uint8 ArenaType, bool isRated, uint32 ArenaRating, uint32 ArenaTeamId = 0);
+ void FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel queue_id);
+ bool CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam);
+ bool CheckNormalMatch(BattleGround* bg_template, BGQueueIdBasedOnLevel queue_id, uint32 minPlayers, uint32 maxPlayers);
+ bool CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_id, uint32 minPlayersPerTeam);
+ GroupQueueInfo * AddGroup(Player * leader, BattleGroundTypeId bgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 ArenaRating, uint32 ArenaTeamId = 0);
void AddPlayer(Player *plr, GroupQueueInfo *ginfo);
- void RemovePlayer(uint64 guid, bool decreaseInvitedCount);
+ void RemovePlayer(const uint64& guid, bool decreaseInvitedCount);
+ void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id);
+ uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id);
+
void DecreaseGroupLength(uint32 queueId, uint32 AsGroup);
- void BGEndedRemoveInvites(BattleGround * bg);
+ void AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue);
typedef std::map<uint64, PlayerQueueInfo> QueuedPlayersMap;
- QueuedPlayersMap m_QueuedPlayers[MAX_BATTLEGROUND_QUEUES];
-
- typedef std::list<GroupQueueInfo*> QueuedGroupsList;
- QueuedGroupsList m_QueuedGroups[MAX_BATTLEGROUND_QUEUES];
-
- // class to hold pointers to the groups eligible for a specific selection pool building mode
- class EligibleGroups : public std::list<GroupQueueInfo *>
- {
- public:
- void Init(QueuedGroupsList * source, uint32 BgTypeId, uint32 side, uint32 MaxPlayers, uint8 ArenaType = 0, bool IsRated = false, uint32 MinRating = 0, uint32 MaxRating = 0, uint32 DisregardTime = 0, uint32 excludeTeam = 0);
- };
-
- EligibleGroups m_EligibleGroups;
+ QueuedPlayersMap m_QueuedPlayers;
+
+ //we need constant add to begin and constant remove / add from the end, therefore deque suits our problem well
+ typedef std::list<GroupQueueInfo*> GroupsQueueType;
+
+ /*
+ This two dimensional array is used to store All queued groups
+ First dimension specifies the bgTypeId
+ Second dimension specifies the player's group types -
+ BG_QUEUE_PREMADE_ALLIANCE is used for premade alliance groups and alliance rated arena teams
+ BG_QUEUE_PREMADE_HORDE is used for premade horde groups and horde rated arena teams
+ BG_QUEUE_NORMAL_ALLIANCE is used for normal (or small) alliance groups or non-rated arena matches
+ BG_QUEUE_NORMAL_HORDE is used for normal (or small) horde groups or non-rated arena matches
+ */
+ GroupsQueueType m_QueuedGroups[MAX_BATTLEGROUND_QUEUES][BG_QUEUE_GROUP_TYPES_COUNT];
// class to select and invite groups to bg
class SelectionPool
{
public:
- void Init(EligibleGroups * curr);
- void AddGroup(GroupQueueInfo * group);
- void RemoveGroup(GroupQueueInfo * group);
+ void Init();
+ bool AddGroup(GroupQueueInfo *ginfo, uint32 desiredCount);
+ bool KickGroup(uint32 size);
uint32 GetPlayerCount() const {return PlayerCount;}
- bool Build(uint32 MinPlayers, uint32 MaxPlayers, EligibleGroups::iterator startitr);
public:
- std::list<GroupQueueInfo *> SelectedGroups;
+ GroupsQueueType SelectedGroups;
private:
uint32 PlayerCount;
- EligibleGroups * m_CurrEligGroups;
- };
-
- enum SelectionPoolBuildMode
- {
- NORMAL_ALLIANCE,
- NORMAL_HORDE,
- ONESIDE_ALLIANCE_TEAM1,
- ONESIDE_ALLIANCE_TEAM2,
- ONESIDE_HORDE_TEAM1,
- ONESIDE_HORDE_TEAM2,
-
- NUM_SELECTION_POOL_TYPES
};
- SelectionPool m_SelectionPools[NUM_SELECTION_POOL_TYPES];
-
- bool BuildSelectionPool(uint32 bgTypeId, uint32 queue_id, uint32 MinPlayers, uint32 MaxPlayers, SelectionPoolBuildMode mode, uint8 ArenaType = 0, bool isRated = false, uint32 MinRating = 0, uint32 MaxRating = 0, uint32 DisregardTime = 0, uint32 excludeTeam = 0);
+ //one selection pool for horde, other one for alliance
+ SelectionPool m_SelectionPools[BG_TEAMS_COUNT];
private:
bool InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side);
+ uint32 m_WaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME];
+ uint32 m_WaitTimeLastPlayer[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES];
+ uint32 m_SumOfWaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES];
};
/*
@@ -137,7 +137,10 @@ class BattleGroundQueue
class BGQueueInviteEvent : public BasicEvent
{
public:
- BGQueueInviteEvent(uint64 pl_guid, uint32 BgInstanceGUID) : m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID) {};
+ BGQueueInviteEvent(const uint64& pl_guid, uint32 BgInstanceGUID, BattleGroundTypeId BgTypeId, uint32 removeTime) :
+ m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID), m_BgTypeId(BgTypeId), m_RemoveTime(removeTime)
+ {
+ };
virtual ~BGQueueInviteEvent() {};
virtual bool Execute(uint64 e_time, uint32 p_time);
@@ -145,23 +148,32 @@ class BGQueueInviteEvent : public BasicEvent
private:
uint64 m_PlayerGuid;
uint32 m_BgInstanceGUID;
+ uint32 m_RemoveTime;
+ BattleGroundTypeId m_BgTypeId;
};
/*
- This class is used to remove player from BG queue after 2 minutes from first invitation
+ This class is used to remove player from BG queue after 1 minute 20 seconds from first invitation
+ We must store removeInvite time in case player left queue and joined and is invited again
+ We must store bgQueueTypeId, because battleground can be deleted already, when player entered it
*/
class BGQueueRemoveEvent : public BasicEvent
{
public:
- BGQueueRemoveEvent(uint64 pl_guid, uint32 bgInstanceGUID, uint32 playersTeam) : m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_PlayersTeam(playersTeam) {};
- virtual ~BGQueueRemoveEvent() {};
+ BGQueueRemoveEvent(const uint64& pl_guid, uint32 bgInstanceGUID, BattleGroundTypeId BgTypeId, BattleGroundQueueTypeId bgQueueTypeId, uint32 removeTime)
+ : m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_RemoveTime(removeTime), m_BgTypeId(BgTypeId), m_BgQueueTypeId(bgQueueTypeId)
+ {}
+
+ virtual ~BGQueueRemoveEvent() {}
virtual bool Execute(uint64 e_time, uint32 p_time);
virtual void Abort(uint64 e_time);
private:
uint64 m_PlayerGuid;
uint32 m_BgInstanceGUID;
- uint32 m_PlayersTeam;
+ uint32 m_RemoveTime;
+ BattleGroundTypeId m_BgTypeId;
+ BattleGroundQueueTypeId m_BgQueueTypeId;
};
class BattleGroundMgr
@@ -170,83 +182,81 @@ class BattleGroundMgr
/* Construction */
BattleGroundMgr();
~BattleGroundMgr();
- void Update(time_t diff);
+ void Update(uint32 diff);
/* Packet Building */
void BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Player *plr);
- void BuildPlayerLeftBattleGroundPacket(WorldPacket *data, Player *plr);
- void BuildBattleGroundListPacket(WorldPacket *data, uint64 guid, Player *plr, uint32 bgTypeId);
- void BuildGroupJoinedBattlegroundPacket(WorldPacket *data, uint32 bgTypeId);
+ void BuildPlayerLeftBattleGroundPacket(WorldPacket *data, const uint64& guid);
+ void BuildBattleGroundListPacket(WorldPacket *data, const uint64& guid, Player *plr, BattleGroundTypeId bgTypeId);
+ void BuildGroupJoinedBattlegroundPacket(WorldPacket *data, BattleGroundTypeId bgTypeId);
void BuildUpdateWorldStatePacket(WorldPacket *data, uint32 field, uint32 value);
void BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg);
- void BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint32 team, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint32 arenatype = 0, uint8 israted = 0);
+ void BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype);
void BuildPlaySoundPacket(WorldPacket *data, uint32 soundid);
-
- /* Player invitation */
- // called from Queue update, or from Addplayer to queue
- void InvitePlayer(Player* plr, uint32 bgInstanceGUID, uint32 team);
+ void SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, const uint64& guid);
/* Battlegrounds */
- BattleGroundSet::iterator GetBattleGroundsBegin() { return m_BattleGrounds.begin(); };
- BattleGroundSet::iterator GetBattleGroundsEnd() { return m_BattleGrounds.end(); };
+ BattleGround* GetBattleGroundThroughClientInstance(uint32 instanceId, BattleGroundTypeId bgTypeId);
+ BattleGround* GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId); //there must be uint32 because MAX_BATTLEGROUND_TYPE_ID means unknown
- BattleGround* GetBattleGround(uint32 ID)
- {
- BattleGroundSet::iterator i = m_BattleGrounds.find(ID);
- if(i != m_BattleGrounds.end())
- return i->second;
- else
- return NULL;
- };
-
- BattleGround * GetBattleGroundTemplate(uint32 bgTypeId);
- BattleGround * CreateNewBattleGround(uint32 bgTypeId);
+ BattleGround* GetBattleGroundTemplate(BattleGroundTypeId bgTypeId);
+ BattleGround* CreateNewBattleGround(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated);
- uint32 CreateBattleGround(uint32 bgTypeId, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO);
+ uint32 CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsArena, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO);
- inline void AddBattleGround(uint32 ID, BattleGround* BG) { m_BattleGrounds[ID] = BG; };
- void RemoveBattleGround(uint32 instanceID);
+ void AddBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId, BattleGround* BG) { m_BattleGrounds[bgTypeId][InstanceID] = BG; };
+ void RemoveBattleGround(uint32 instanceID, BattleGroundTypeId bgTypeId) { m_BattleGrounds[bgTypeId].erase(instanceID); }
+ uint32 CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id);
void CreateInitialBattleGrounds();
+ void DeleteAllBattleGrounds();
- void SendToBattleGround(Player *pl, uint32 bgTypeId);
+ void SendToBattleGround(Player *pl, uint32 InstanceID, BattleGroundTypeId bgTypeId);
/* Battleground queues */
//these queues are instantiated when creating BattlegroundMrg
BattleGroundQueue m_BattleGroundQueues[MAX_BATTLEGROUND_QUEUE_TYPES]; // public, because we need to access them in BG handler code
- BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPES];
+ BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPE_ID];
- void SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, uint64 guid);
-
- bool IsArenaType(uint32 bgTypeId) const;
- bool IsBattleGroundType(uint32 bgTypeId) const;
- uint32 BGQueueTypeId(uint32 bgTypeId, uint8 arenaType) const;
- uint32 BGTemplateId(uint32 bgQueueTypeId) const;
- uint8 BGArenaType(uint32 bgQueueTypeId) const;
-
- uint32 GetMaxRatingDifference() const {return m_MaxRatingDifference;}
- uint32 GetRatingDiscardTimer() const {return m_RatingDiscardTimer;}
+ uint32 GetMaxRatingDifference() const;
+ uint32 GetRatingDiscardTimer() const;
+ uint32 GetPrematureFinishTime() const;
void InitAutomaticArenaPointDistribution();
void DistributeArenaPoints();
- uint32 GetPrematureFinishTime() const {return m_PrematureFinishTimer;}
void ToggleArenaTesting();
- const bool isArenaTesting() const { return m_ArenaTesting; }
+ void ToggleTesting();
void SetHolidayWeekends(uint32 mask);
+ void LoadBattleMastersEntry();
+ BattleGroundTypeId GetBattleMasterBG(uint32 entry) const
+ {
+ BattleMastersMap::const_iterator itr = mBattleMastersMap.find(entry);
+ if (itr != mBattleMastersMap.end())
+ return itr->second;
+ return BATTLEGROUND_WS;
+ }
+
+ bool isArenaTesting() const { return m_ArenaTesting; }
+ bool isTesting() const { return m_Testing; }
+
+ static bool IsArenaType(BattleGroundTypeId bgTypeId);
+ static bool IsBattleGroundType(BattleGroundTypeId bgTypeId) { return !BattleGroundMgr::IsArenaType(bgTypeId); }
+ static BattleGroundQueueTypeId BGQueueTypeId(BattleGroundTypeId bgTypeId, uint8 arenaType);
+ static BattleGroundTypeId BGTemplateId(BattleGroundQueueTypeId bgQueueTypeId);
+ static uint8 BGArenaType(BattleGroundQueueTypeId bgQueueTypeId);
private:
+ BattleMastersMap mBattleMastersMap;
/* Battlegrounds */
- BattleGroundSet m_BattleGrounds;
- uint32 m_MaxRatingDifference;
- uint32 m_RatingDiscardTimer;
+ BattleGroundSet m_BattleGrounds[MAX_BATTLEGROUND_TYPE_ID];
+ std::set<uint32> m_ClientBattleGroundIds[MAX_BATTLEGROUND_TYPE_ID][MAX_BATTLEGROUND_QUEUES]; //the instanceids just visible for the client
uint32 m_NextRatingDiscardUpdate;
- bool m_AutoDistributePoints;
- uint64 m_NextAutoDistributionTime;
+ time_t m_NextAutoDistributionTime;
uint32 m_AutoDistributionTimeChecker;
- uint32 m_PrematureFinishTimer;
bool m_ArenaTesting;
+ bool m_Testing;
};
#define sBattleGroundMgr Trinity::Singleton<BattleGroundMgr>::Instance()
diff --git a/src/game/BattleGroundNA.cpp b/src/game/BattleGroundNA.cpp
index 5debaa3c6a5..f46746829e7 100644
--- a/src/game/BattleGroundNA.cpp
+++ b/src/game/BattleGroundNA.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,14 +22,23 @@
#include "Player.h"
#include "BattleGround.h"
#include "BattleGroundNA.h"
-#include "Creature.h"
#include "ObjectMgr.h"
-#include "MapManager.h"
+#include "WorldPacket.h"
#include "Language.h"
BattleGroundNA::BattleGroundNA()
{
m_BgObjects.resize(BG_NA_OBJECT_MAX);
+
+ m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
+ m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
+ m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
+ m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
+ //we must set messageIds
+ m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
+ m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
+ m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
}
BattleGroundNA::~BattleGroundNA()
@@ -37,74 +46,31 @@ BattleGroundNA::~BattleGroundNA()
}
-void BattleGroundNA::Update(time_t diff)
+void BattleGroundNA::Update(uint32 diff)
{
BattleGround::Update(diff);
- // after bg start we get there
- if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
- {
- ModifyStartDelayTime(diff);
-
- if (!(m_Events & 0x01))
- {
- m_Events |= 0x01;
- // setup here, only when at least one player has ported to the map
- if(!SetupBattleGround())
- {
- EndNow();
- return;
- }
- for(uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_4; i++)
- SpawnBGObject(i, RESPAWN_IMMEDIATELY);
-
- SetStartDelayTime(START_DELAY1);
- SendMessageToAll(LANG_ARENA_ONE_MINUTE);
- }
- // After 30 seconds, warning is signalled
- else if (GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x04))
- {
- m_Events |= 0x04;
- SendMessageToAll(LANG_ARENA_THIRTY_SECONDS);
- }
- // After 15 seconds, warning is signalled
- else if (GetStartDelayTime() <= START_DELAY3 && !(m_Events & 0x08))
- {
- m_Events |= 0x08;
- SendMessageToAll(LANG_ARENA_FIFTEEN_SECONDS);
- }
- // delay expired (1 minute)
- else if (GetStartDelayTime() <= 0 && !(m_Events & 0x10))
- {
- m_Events |= 0x10;
-
- for(uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_2; i++)
- DoorOpen(i);
-
- for(uint32 i = BG_NA_OBJECT_BUFF_1; i <= BG_NA_OBJECT_BUFF_2; i++)
- SpawnBGObject(i, 60);
-
- SendMessageToAll(LANG_ARENA_BEGUN);
- SetStatus(STATUS_IN_PROGRESS);
- SetStartDelayTime(0);
-
- for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
- if(Player *plr = objmgr.GetPlayer(itr->first))
- plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
-
- if(!GetPlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
- EndBattleGround(HORDE);
- else if(GetPlayersCountByTeam(ALLIANCE) && !GetPlayersCountByTeam(HORDE))
- EndBattleGround(ALLIANCE);
- }
- }
-
- /*if(GetStatus() == STATUS_IN_PROGRESS)
+ /*if (GetStatus() == STATUS_IN_PROGRESS)
{
// update something
}*/
}
+void BattleGroundNA::StartingEventCloseDoors()
+{
+ for(uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_4; ++i)
+ SpawnBGObject(i, RESPAWN_IMMEDIATELY);
+}
+
+void BattleGroundNA::StartingEventOpenDoors()
+{
+ for(uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_2; ++i)
+ DoorOpen(i);
+
+ for(uint32 i = BG_NA_OBJECT_BUFF_1; i <= BG_NA_OBJECT_BUFF_2; ++i)
+ SpawnBGObject(i, 60);
+}
+
void BattleGroundNA::AddPlayer(Player *plr)
{
BattleGround::AddPlayer(plr);
@@ -119,24 +85,21 @@ void BattleGroundNA::AddPlayer(Player *plr)
void BattleGroundNA::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
{
- if(GetStatus() == STATUS_WAIT_LEAVE)
+ if (GetStatus() == STATUS_WAIT_LEAVE)
return;
UpdateWorldState(0xa0f, GetAlivePlayersCountByTeam(ALLIANCE));
UpdateWorldState(0xa10, GetAlivePlayersCountByTeam(HORDE));
- if(!GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
- EndBattleGround(HORDE);
- else if(GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE))
- EndBattleGround(ALLIANCE);
+ CheckArenaWinConditions();
}
void BattleGroundNA::HandleKillPlayer(Player *player, Player *killer)
{
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
- if(!killer)
+ if (!killer)
{
sLog.outError("BattleGroundNA: Killer player not found");
return;
@@ -147,16 +110,7 @@ void BattleGroundNA::HandleKillPlayer(Player *player, Player *killer)
UpdateWorldState(0xa0f, GetAlivePlayersCountByTeam(ALLIANCE));
UpdateWorldState(0xa10, GetAlivePlayersCountByTeam(HORDE));
- if(!GetAlivePlayersCountByTeam(ALLIANCE))
- {
- // all opponents killed
- EndBattleGround(HORDE);
- }
- else if(!GetAlivePlayersCountByTeam(HORDE))
- {
- // all opponents killed
- EndBattleGround(ALLIANCE);
- }
+ CheckArenaWinConditions();
}
bool BattleGroundNA::HandlePlayerUnderMap(Player *player)
@@ -167,7 +121,7 @@ bool BattleGroundNA::HandlePlayerUnderMap(Player *player)
void BattleGroundNA::HandleAreaTrigger(Player *Source, uint32 Trigger)
{
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
//uint32 SpellId = 0;
@@ -183,7 +137,7 @@ void BattleGroundNA::HandleAreaTrigger(Player *Source, uint32 Trigger)
break;
}
- //if(buff_guid)
+ //if (buff_guid)
// HandleTriggerBuff(buff_guid,Source);
}
@@ -194,15 +148,16 @@ void BattleGroundNA::FillInitialWorldStates(WorldPacket &data)
data << uint32(0xa11) << uint32(1); // 9
}
-void BattleGroundNA::ResetBGSubclass()
+void BattleGroundNA::Reset()
{
-
+ //call parent's class reset
+ BattleGround::Reset();
}
bool BattleGroundNA::SetupBattleGround()
{
// gates
- if( !AddObject(BG_NA_OBJECT_DOOR_1, BG_NA_OBJECT_TYPE_DOOR_1, 4031.854, 2966.833, 12.6462, -2.648788, 0, 0, 0.9697962, -0.2439165, RESPAWN_IMMEDIATELY)
+ if (!AddObject(BG_NA_OBJECT_DOOR_1, BG_NA_OBJECT_TYPE_DOOR_1, 4031.854, 2966.833, 12.6462, -2.648788, 0, 0, 0.9697962, -0.2439165, RESPAWN_IMMEDIATELY)
|| !AddObject(BG_NA_OBJECT_DOOR_2, BG_NA_OBJECT_TYPE_DOOR_2, 4081.179, 2874.97, 12.39171, 0.4928045, 0, 0, 0.2439165, 0.9697962, RESPAWN_IMMEDIATELY)
|| !AddObject(BG_NA_OBJECT_DOOR_3, BG_NA_OBJECT_TYPE_DOOR_3, 4023.709, 2981.777, 10.70117, -2.648788, 0, 0, 0.9697962, -0.2439165, RESPAWN_IMMEDIATELY)
|| !AddObject(BG_NA_OBJECT_DOOR_4, BG_NA_OBJECT_TYPE_DOOR_4, 4090.064, 2858.438, 10.23631, 0.4928045, 0, 0, 0.2439165, 0.9697962, RESPAWN_IMMEDIATELY)
diff --git a/src/game/BattleGroundNA.h b/src/game/BattleGroundNA.h
index ae419b9fc44..56e2cf373c4 100644
--- a/src/game/BattleGroundNA.h
+++ b/src/game/BattleGroundNA.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -58,15 +58,17 @@ class BattleGroundNA : public BattleGround
public:
BattleGroundNA();
~BattleGroundNA();
- void Update(time_t diff);
+ void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
+ virtual void StartingEventCloseDoors();
+ virtual void StartingEventOpenDoors();
void RemovePlayer(Player *plr, uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
bool SetupBattleGround();
- virtual void ResetBGSubclass();
+ virtual void Reset();
virtual void FillInitialWorldStates(WorldPacket &d);
void HandleKillPlayer(Player* player, Player *killer);
bool HandlePlayerUnderMap(Player * plr);
diff --git a/src/game/BattleGroundRL.cpp b/src/game/BattleGroundRL.cpp
index 6d68403fe4c..f8f8bd9fef5 100644
--- a/src/game/BattleGroundRL.cpp
+++ b/src/game/BattleGroundRL.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,14 +22,23 @@
#include "Player.h"
#include "BattleGround.h"
#include "BattleGroundRL.h"
-#include "Creature.h"
#include "ObjectMgr.h"
-#include "MapManager.h"
#include "Language.h"
+#include "WorldPacket.h"
BattleGroundRL::BattleGroundRL()
{
m_BgObjects.resize(BG_RL_OBJECT_MAX);
+
+ m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
+ m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
+ m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
+ m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
+ //we must set messageIds
+ m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
+ m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
+ m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
}
BattleGroundRL::~BattleGroundRL()
@@ -37,75 +46,31 @@ BattleGroundRL::~BattleGroundRL()
}
-void BattleGroundRL::Update(time_t diff)
+void BattleGroundRL::Update(uint32 diff)
{
BattleGround::Update(diff);
- if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
- {
- ModifyStartDelayTime(diff);
-
- if (!(m_Events & 0x01))
- {
- m_Events |= 0x01;
-
- // setup here, only when at least one player has ported to the map
- if(!SetupBattleGround())
- {
- EndNow();
- return;
- }
-
- for(uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; i++)
- SpawnBGObject(i, RESPAWN_IMMEDIATELY);
-
- SetStartDelayTime(START_DELAY1);
- SendMessageToAll(LANG_ARENA_ONE_MINUTE);
- }
- // After 30 seconds, warning is signalled
- else if (GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x04))
- {
- m_Events |= 0x04;
- SendMessageToAll(LANG_ARENA_THIRTY_SECONDS);
- }
- // After 15 seconds, warning is signalled
- else if (GetStartDelayTime() <= START_DELAY3 && !(m_Events & 0x08))
- {
- m_Events |= 0x08;
- SendMessageToAll(LANG_ARENA_FIFTEEN_SECONDS);
- }
- // delay expired (1 minute)
- else if (GetStartDelayTime() <= 0 && !(m_Events & 0x10))
- {
- m_Events |= 0x10;
-
- for(uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; i++)
- DoorOpen(i);
-
- for(uint32 i = BG_RL_OBJECT_BUFF_1; i <= BG_RL_OBJECT_BUFF_2; i++)
- SpawnBGObject(i, 60);
-
- SendMessageToAll(LANG_ARENA_BEGUN);
- SetStatus(STATUS_IN_PROGRESS);
- SetStartDelayTime(0);
-
- for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
- if(Player *plr = objmgr.GetPlayer(itr->first))
- plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
-
- if(!GetPlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
- EndBattleGround(HORDE);
- else if(GetPlayersCountByTeam(ALLIANCE) && !GetPlayersCountByTeam(HORDE))
- EndBattleGround(ALLIANCE);
- }
- }
-
- /*if(GetStatus() == STATUS_IN_PROGRESS)
+ /*if (GetStatus() == STATUS_IN_PROGRESS)
{
// update something
}*/
}
+void BattleGroundRL::StartingEventCloseDoors()
+{
+ for(uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; ++i)
+ SpawnBGObject(i, RESPAWN_IMMEDIATELY);
+}
+
+void BattleGroundRL::StartingEventOpenDoors()
+{
+ for(uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; ++i)
+ DoorOpen(i);
+
+ for(uint32 i = BG_RL_OBJECT_BUFF_1; i <= BG_RL_OBJECT_BUFF_2; ++i)
+ SpawnBGObject(i, 60);
+}
+
void BattleGroundRL::AddPlayer(Player *plr)
{
BattleGround::AddPlayer(plr);
@@ -120,24 +85,21 @@ void BattleGroundRL::AddPlayer(Player *plr)
void BattleGroundRL::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
{
- if(GetStatus() == STATUS_WAIT_LEAVE)
+ if (GetStatus() == STATUS_WAIT_LEAVE)
return;
UpdateWorldState(0xbb8, GetAlivePlayersCountByTeam(ALLIANCE));
UpdateWorldState(0xbb9, GetAlivePlayersCountByTeam(HORDE));
- if(!GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
- EndBattleGround(HORDE);
- else if(GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE))
- EndBattleGround(ALLIANCE);
+ CheckArenaWinConditions();
}
void BattleGroundRL::HandleKillPlayer(Player *player, Player *killer)
{
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
- if(!killer)
+ if (!killer)
{
sLog.outError("Killer player not found");
return;
@@ -148,16 +110,7 @@ void BattleGroundRL::HandleKillPlayer(Player *player, Player *killer)
UpdateWorldState(0xbb8, GetAlivePlayersCountByTeam(ALLIANCE));
UpdateWorldState(0xbb9, GetAlivePlayersCountByTeam(HORDE));
- if(!GetAlivePlayersCountByTeam(ALLIANCE))
- {
- // all opponents killed
- EndBattleGround(HORDE);
- }
- else if(!GetAlivePlayersCountByTeam(HORDE))
- {
- // all opponents killed
- EndBattleGround(ALLIANCE);
- }
+ CheckArenaWinConditions();
}
bool BattleGroundRL::HandlePlayerUnderMap(Player *player)
@@ -169,7 +122,7 @@ bool BattleGroundRL::HandlePlayerUnderMap(Player *player)
void BattleGroundRL::HandleAreaTrigger(Player *Source, uint32 Trigger)
{
// this is wrong way to implement these things. On official it done by gameobject spell cast.
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
//uint32 SpellId = 0;
@@ -185,7 +138,7 @@ void BattleGroundRL::HandleAreaTrigger(Player *Source, uint32 Trigger)
break;
}
- //if(buff_guid)
+ //if (buff_guid)
// HandleTriggerBuff(buff_guid,Source);
}
@@ -196,15 +149,16 @@ void BattleGroundRL::FillInitialWorldStates(WorldPacket &data)
data << uint32(0xbba) << uint32(1); // 9
}
-void BattleGroundRL::ResetBGSubclass()
+void BattleGroundRL::Reset()
{
-
+ //call parent's reset
+ BattleGround::Reset();
}
bool BattleGroundRL::SetupBattleGround()
{
// gates
- if( !AddObject(BG_RL_OBJECT_DOOR_1, BG_RL_OBJECT_TYPE_DOOR_1, 1293.561, 1601.938, 31.60557, -1.457349, 0, 0, -0.6658813, 0.7460576, RESPAWN_IMMEDIATELY)
+ if (!AddObject(BG_RL_OBJECT_DOOR_1, BG_RL_OBJECT_TYPE_DOOR_1, 1293.561, 1601.938, 31.60557, -1.457349, 0, 0, -0.6658813, 0.7460576, RESPAWN_IMMEDIATELY)
|| !AddObject(BG_RL_OBJECT_DOOR_2, BG_RL_OBJECT_TYPE_DOOR_2, 1278.648, 1730.557, 31.60557, 1.684245, 0, 0, 0.7460582, 0.6658807, RESPAWN_IMMEDIATELY)
// buffs
|| !AddObject(BG_RL_OBJECT_BUFF_1, BG_RL_OBJECT_TYPE_BUFF_1, 1328.719971, 1632.719971, 36.730400, -1.448624, 0, 0, 0.6626201, -0.7489557, 120)
diff --git a/src/game/BattleGroundRL.h b/src/game/BattleGroundRL.h
index 599cb53dc63..772c9dd0879 100644
--- a/src/game/BattleGroundRL.h
+++ b/src/game/BattleGroundRL.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -54,16 +54,18 @@ class BattleGroundRL : public BattleGround
public:
BattleGroundRL();
~BattleGroundRL();
- void Update(time_t diff);
+ void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
+ virtual void Reset();
+ virtual void FillInitialWorldStates(WorldPacket &d);
+ virtual void StartingEventCloseDoors();
+ virtual void StartingEventOpenDoors();
void RemovePlayer(Player *plr, uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
bool SetupBattleGround();
- virtual void ResetBGSubclass();
- virtual void FillInitialWorldStates(WorldPacket &d);
void HandleKillPlayer(Player* player, Player *killer);
bool HandlePlayerUnderMap(Player * plr);
};
diff --git a/src/game/BattleGroundRV.cpp b/src/game/BattleGroundRV.cpp
new file mode 100644
index 00000000000..8c252c35c97
--- /dev/null
+++ b/src/game/BattleGroundRV.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2005-2009 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 "Player.h"
+#include "BattleGround.h"
+#include "BattleGroundRV.h"
+#include "Language.h"
+
+BattleGroundRV::BattleGroundRV()
+{
+
+ m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
+ m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
+ m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
+ m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
+ //we must set messageIds
+ m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
+ m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
+ m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
+}
+
+BattleGroundRV::~BattleGroundRV()
+{
+
+}
+
+void BattleGroundRV::Update(uint32 diff)
+{
+ BattleGround::Update(diff);
+}
+
+void BattleGroundRV::StartingEventCloseDoors()
+{
+}
+
+void BattleGroundRV::StartingEventOpenDoors()
+{
+}
+
+void BattleGroundRV::AddPlayer(Player *plr)
+{
+ BattleGround::AddPlayer(plr);
+ //create score and add it to map, default values are set in constructor
+ BattleGroundRVScore* sc = new BattleGroundRVScore;
+
+ m_PlayerScores[plr->GetGUID()] = sc;
+}
+
+void BattleGroundRV::RemovePlayer(Player * /*plr*/, uint64 /*guid*/)
+{
+}
+
+void BattleGroundRV::HandleKillPlayer(Player* player, Player* killer)
+{
+ BattleGround::HandleKillPlayer(player, killer);
+}
+
+void BattleGroundRV::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
+{
+}
+
+bool BattleGroundRV::SetupBattleGround()
+{
+ return true;
+}
diff --git a/src/game/BattleGroundRV.h b/src/game/BattleGroundRV.h
new file mode 100644
index 00000000000..e3e94baf101
--- /dev/null
+++ b/src/game/BattleGroundRV.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2005-2009 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 __BATTLEGROUNDRV_H
+#define __BATTLEGROUNDRV_H
+
+class BattleGround;
+
+class BattleGroundRVScore : public BattleGroundScore
+{
+ public:
+ BattleGroundRVScore() {};
+ virtual ~BattleGroundRVScore() {};
+ //TODO fix me
+};
+
+class BattleGroundRV : public BattleGround
+{
+ friend class BattleGroundMgr;
+
+ public:
+ BattleGroundRV();
+ ~BattleGroundRV();
+ void Update(uint32 diff);
+
+ /* inherited from BattlegroundClass */
+ virtual void AddPlayer(Player *plr);
+ virtual void StartingEventCloseDoors();
+ virtual void StartingEventOpenDoors();
+
+ void RemovePlayer(Player *plr, uint64 guid);
+ void HandleAreaTrigger(Player *Source, uint32 Trigger);
+ bool SetupBattleGround();
+ void HandleKillPlayer(Player* player, Player *killer);
+};
+#endif
diff --git a/src/game/BattleGroundSA.cpp b/src/game/BattleGroundSA.cpp
new file mode 100644
index 00000000000..c52635a04c7
--- /dev/null
+++ b/src/game/BattleGroundSA.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2005-2009 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 "Player.h"
+#include "BattleGround.h"
+#include "BattleGroundSA.h"
+#include "Language.h"
+
+BattleGroundSA::BattleGroundSA()
+{
+ //TODO FIX ME!
+ m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_WS_START_TWO_MINUTES;
+ m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN;
+}
+
+BattleGroundSA::~BattleGroundSA()
+{
+
+}
+
+void BattleGroundSA::Update(uint32 diff)
+{
+ BattleGround::Update(diff);
+}
+
+void BattleGroundSA::StartingEventCloseDoors()
+{
+}
+
+void BattleGroundSA::StartingEventOpenDoors()
+{
+}
+
+void BattleGroundSA::AddPlayer(Player *plr)
+{
+ BattleGround::AddPlayer(plr);
+ //create score and add it to map, default values are set in constructor
+ BattleGroundSAScore* sc = new BattleGroundSAScore;
+
+ m_PlayerScores[plr->GetGUID()] = sc;
+}
+
+void BattleGroundSA::RemovePlayer(Player* /*plr*/,uint64 /*guid*/)
+{
+
+}
+
+void BattleGroundSA::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
+{
+ // this is wrong way to implement these things. On official it done by gameobject spell cast.
+ if (GetStatus() != STATUS_IN_PROGRESS)
+ return;
+}
+
+void BattleGroundSA::UpdatePlayerScore(Player* Source, uint32 type, uint32 value)
+{
+
+ std::map<uint64, BattleGroundScore*>::iterator itr = m_PlayerScores.find(Source->GetGUID());
+
+ if(itr == m_PlayerScores.end()) // player not found...
+ return;
+
+ BattleGround::UpdatePlayerScore(Source,type,value);
+}
diff --git a/src/game/BattleGroundSA.h b/src/game/BattleGroundSA.h
new file mode 100644
index 00000000000..3ba23d02656
--- /dev/null
+++ b/src/game/BattleGroundSA.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2005-2009 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 __BATTLEGROUNDSA_H
+#define __BATTLEGROUNDSA_H
+
+class BattleGround;
+
+class BattleGroundSAScore : public BattleGroundScore
+{
+ public:
+ BattleGroundSAScore() {};
+ virtual ~BattleGroundSAScore() {};
+};
+
+class BattleGroundSA : public BattleGround
+{
+ friend class BattleGroundMgr;
+
+ public:
+ BattleGroundSA();
+ ~BattleGroundSA();
+ void Update(uint32 diff);
+
+ /* inherited from BattlegroundClass */
+ virtual void AddPlayer(Player *plr);
+ virtual void StartingEventCloseDoors();
+ virtual void StartingEventOpenDoors();
+
+ void RemovePlayer(Player *plr,uint64 guid);
+ void HandleAreaTrigger(Player *Source, uint32 Trigger);
+ //bool SetupBattleGround();
+
+ /* Scorekeeping */
+ void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
+
+ private:
+};
+#endif
diff --git a/src/game/BattleGroundWS.cpp b/src/game/BattleGroundWS.cpp
index 3a8c5668a7a..76ecde6527b 100644
--- a/src/game/BattleGroundWS.cpp
+++ b/src/game/BattleGroundWS.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -24,8 +24,8 @@
#include "BattleGroundWS.h"
#include "Creature.h"
#include "GameObject.h"
-#include "Chat.h"
-#include "MapManager.h"
+#include "ObjectMgr.h"
+#include "WorldPacket.h"
#include "Language.h"
#include "World.h"
@@ -52,123 +52,58 @@ BattleGroundWS::BattleGroundWS()
{
m_BgObjects.resize(BG_WS_OBJECT_MAX);
m_BgCreatures.resize(BG_CREATURES_MAX_WS);
+
+ m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_WS_START_TWO_MINUTES;
+ m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN;
}
BattleGroundWS::~BattleGroundWS()
{
}
-void BattleGroundWS::Update(time_t diff)
+void BattleGroundWS::Update(uint32 diff)
{
BattleGround::Update(diff);
- // after bg start we get there (once)
- if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
- {
- ModifyStartDelayTime(diff);
-
- if(!(m_Events & 0x01))
- {
- m_Events |= 0x01;
-
- // setup here, only when at least one player has ported to the map
- if(!SetupBattleGround())
- {
- EndNow();
- return;
- }
-
-// for(uint32 i = WS_SPIRIT_MAIN_ALLIANCE; i <= WS_SPIRIT_MAIN_HORDE; i++)
-// SpawnBGCreature(i, RESPAWN_IMMEDIATELY);
-
- for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_H_4; i++)
- {
- SpawnBGObject(i, RESPAWN_IMMEDIATELY);
- DoorClose(i);
- }
- for(uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; i++)
- SpawnBGObject(i, RESPAWN_ONE_DAY);
-
- SetStartDelayTime(START_DELAY0);
- }
- // After 1 minute, warning is signalled
- else if(GetStartDelayTime() <= START_DELAY1 && !(m_Events & 0x04))
- {
- m_Events |= 0x04;
- SendMessageToAll(GetTrinityString(LANG_BG_WS_ONE_MINUTE));
- }
- // After 1,5 minute, warning is signalled
- else if(GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x08))
- {
- m_Events |= 0x08;
- SendMessageToAll(GetTrinityString(LANG_BG_WS_HALF_MINUTE));
- }
- // After 2 minutes, gates OPEN ! x)
- else if(GetStartDelayTime() < 0 && !(m_Events & 0x10))
- {
- m_Events |= 0x10;
- for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_A_4; i++)
- DoorOpen(i);
- for(uint32 i = BG_WS_OBJECT_DOOR_H_1; i <= BG_WS_OBJECT_DOOR_H_2; i++)
- DoorOpen(i);
-
- SpawnBGObject(BG_WS_OBJECT_DOOR_A_5, RESPAWN_ONE_DAY);
- SpawnBGObject(BG_WS_OBJECT_DOOR_A_6, RESPAWN_ONE_DAY);
- SpawnBGObject(BG_WS_OBJECT_DOOR_H_3, RESPAWN_ONE_DAY);
- SpawnBGObject(BG_WS_OBJECT_DOOR_H_4, RESPAWN_ONE_DAY);
-
- for(uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; i++)
- SpawnBGObject(i, RESPAWN_IMMEDIATELY);
-
- SendMessageToAll(GetTrinityString(LANG_BG_WS_BEGIN));
-
- PlaySoundToAll(SOUND_BG_START);
- if(sWorld.getConfig(CONFIG_BG_START_MUSIC))
- PlaySoundToAll(SOUND_BG_START_L70ETC); //MUSIC - Custom config
- SetStatus(STATUS_IN_PROGRESS);
-
- for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
- if(Player* plr = objmgr.GetPlayer(itr->first))
- plr->RemoveAurasDueToSpell(SPELL_PREPARATION);
- }
- }
- else if(GetStatus() == STATUS_IN_PROGRESS)
+ if (GetStatus() == STATUS_IN_PROGRESS)
{
- if(m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
+ if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
{
m_FlagsTimer[BG_TEAM_ALLIANCE] -= diff;
- if(m_FlagsTimer[BG_TEAM_ALLIANCE] < 0)
+ if (m_FlagsTimer[BG_TEAM_ALLIANCE] < 0)
{
m_FlagsTimer[BG_TEAM_ALLIANCE] = 0;
RespawnFlag(ALLIANCE, true);
}
}
- if(m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
+ if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
{
m_FlagsDropTimer[BG_TEAM_ALLIANCE] -= diff;
- if(m_FlagsDropTimer[BG_TEAM_ALLIANCE] < 0)
+ if (m_FlagsDropTimer[BG_TEAM_ALLIANCE] < 0)
{
m_FlagsDropTimer[BG_TEAM_ALLIANCE] = 0;
RespawnFlagAfterDrop(ALLIANCE);
}
}
- if(m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
+ if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
{
m_FlagsTimer[BG_TEAM_HORDE] -= diff;
- if(m_FlagsTimer[BG_TEAM_HORDE] < 0)
+ if (m_FlagsTimer[BG_TEAM_HORDE] < 0)
{
m_FlagsTimer[BG_TEAM_HORDE] = 0;
RespawnFlag(HORDE, true);
}
}
- if(m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
+ if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
{
m_FlagsDropTimer[BG_TEAM_HORDE] -= diff;
- if(m_FlagsDropTimer[BG_TEAM_HORDE] < 0)
+ if (m_FlagsDropTimer[BG_TEAM_HORDE] < 0)
{
m_FlagsDropTimer[BG_TEAM_HORDE] = 0;
RespawnFlagAfterDrop(HORDE);
@@ -177,6 +112,33 @@ void BattleGroundWS::Update(time_t diff)
}
}
+void BattleGroundWS::StartingEventCloseDoors()
+{
+ for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_H_4; ++i)
+ {
+ DoorClose(i);
+ SpawnBGObject(i, RESPAWN_IMMEDIATELY);
+ }
+ for(uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; ++i)
+ SpawnBGObject(i, RESPAWN_ONE_DAY);
+}
+
+void BattleGroundWS::StartingEventOpenDoors()
+{
+ for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_A_4; ++i)
+ DoorOpen(i);
+ for(uint32 i = BG_WS_OBJECT_DOOR_H_1; i <= BG_WS_OBJECT_DOOR_H_2; ++i)
+ DoorOpen(i);
+
+ SpawnBGObject(BG_WS_OBJECT_DOOR_A_5, RESPAWN_ONE_DAY);
+ SpawnBGObject(BG_WS_OBJECT_DOOR_A_6, RESPAWN_ONE_DAY);
+ SpawnBGObject(BG_WS_OBJECT_DOOR_H_3, RESPAWN_ONE_DAY);
+ SpawnBGObject(BG_WS_OBJECT_DOOR_H_4, RESPAWN_ONE_DAY);
+
+ for(uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; ++i)
+ SpawnBGObject(i, RESPAWN_IMMEDIATELY);
+}
+
void BattleGroundWS::AddPlayer(Player *plr)
{
BattleGround::AddPlayer(plr);
@@ -188,7 +150,7 @@ void BattleGroundWS::AddPlayer(Player *plr)
void BattleGroundWS::RespawnFlag(uint32 Team, bool captured)
{
- if(Team == ALLIANCE)
+ if (Team == ALLIANCE)
{
sLog.outDebug("Respawn Alliance flag");
m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_BASE;
@@ -199,37 +161,37 @@ void BattleGroundWS::RespawnFlag(uint32 Team, bool captured)
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
}
- if(captured)
+ if (captured)
{
//when map_update will be allowed for battlegrounds this code will be useless
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
- SendMessageToAll(GetTrinityString(LANG_BG_WS_F_PLACED));
+ SendMessageToAll(LANG_BG_WS_F_PLACED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED); // flag respawned sound...
}
}
void BattleGroundWS::RespawnFlagAfterDrop(uint32 team)
{
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
RespawnFlag(team,false);
- if(team == ALLIANCE)
+ if (team == ALLIANCE)
{
SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
- SendMessageToAll(GetTrinityString(LANG_BG_WS_ALLIANCE_FLAG_RESPAWNED));
+ SendMessageToAll(LANG_BG_WS_ALLIANCE_FLAG_RESPAWNED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
}
else
{
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
- SendMessageToAll(GetTrinityString(LANG_BG_WS_HORDE_FLAG_RESPAWNED));
+ SendMessageToAll(LANG_BG_WS_HORDE_FLAG_RESPAWNED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
}
PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED);
GameObject *obj = HashMapHolder<GameObject>::Find(GetDroppedFlagGUID(team));
- if(obj)
+ if (obj)
obj->Delete();
else
sLog.outError("unknown droped flag bg, guid: %u",GUID_LOPART(GetDroppedFlagGUID(team)));
@@ -239,17 +201,13 @@ void BattleGroundWS::RespawnFlagAfterDrop(uint32 team)
void BattleGroundWS::EventPlayerCapturedFlag(Player *Source)
{
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
- uint8 type = 0;
uint32 winner = 0;
- const char *message = "";
-
- //TODO FIX reputation and honor gains for low level players!
Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
- if(Source->GetTeam() == ALLIANCE)
+ if (Source->GetTeam() == ALLIANCE)
{
if (!this->IsHordeFlagPickedup())
return;
@@ -258,13 +216,10 @@ void BattleGroundWS::EventPlayerCapturedFlag(Player *Source)
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_WAIT_RESPAWN;
// Drop Horde Flag from Player
Source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
- message = GetTrinityString(LANG_BG_WS_CAPTURED_HF);
- type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
- if(GetTeamScore(ALLIANCE) < BG_WS_MAX_TEAM_SCORE)
+ if (GetTeamScore(ALLIANCE) < BG_WS_MAX_TEAM_SCORE)
AddPoint(ALLIANCE, 1);
PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE);
- RewardReputationToTeam(890, BG_WSG_Reputation[m_HonorMode][BG_WSG_FLAG_CAP], ALLIANCE); // +35 reputation
- RewardHonorToTeam(BG_WSG_Honor[m_HonorMode][BG_WSG_FLAG_CAP], ALLIANCE); // +40 bonushonor
+ RewardReputationToTeam(890, m_ReputationCapture, ALLIANCE);
}
else
{
@@ -275,34 +230,34 @@ void BattleGroundWS::EventPlayerCapturedFlag(Player *Source)
m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_WAIT_RESPAWN;
// Drop Alliance Flag from Player
Source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
- message = GetTrinityString(LANG_BG_WS_CAPTURED_AF);
- type = CHAT_MSG_BG_SYSTEM_HORDE;
- if(GetTeamScore(HORDE) < BG_WS_MAX_TEAM_SCORE)
+ if (GetTeamScore(HORDE) < BG_WS_MAX_TEAM_SCORE)
AddPoint(HORDE, 1);
PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE);
- RewardReputationToTeam(889, BG_WSG_Reputation[m_HonorMode][BG_WSG_FLAG_CAP], HORDE); // +35 reputation
- RewardHonorToTeam(BG_WSG_Honor[m_HonorMode][BG_WSG_FLAG_CAP], HORDE); // +40 bonushonor
+ RewardReputationToTeam(889, m_ReputationCapture, HORDE);
}
+ //for flag capture is reward 2 honorable kills
+ RewardHonorToTeam(GetBonusHonorFromKill(2), Source->GetTeam());
SpawnBGObject(BG_WS_OBJECT_H_FLAG, BG_WS_FLAG_RESPAWN_TIME);
SpawnBGObject(BG_WS_OBJECT_A_FLAG, BG_WS_FLAG_RESPAWN_TIME);
- WorldPacket data;
- ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
- SendPacketToAll(&data);
+ if (Source->GetTeam() == ALLIANCE)
+ SendMessageToAll(LANG_BG_WS_CAPTURED_HF, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
+ else
+ SendMessageToAll(LANG_BG_WS_CAPTURED_AF, CHAT_MSG_BG_SYSTEM_HORDE, Source);
UpdateFlagState(Source->GetTeam(), 1); // flag state none
UpdateTeamScore(Source->GetTeam());
// only flag capture should be updated
- UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1); // +1 flag captures...
+ UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1); // +1 flag captures
- if(GetTeamScore(ALLIANCE) == BG_WS_MAX_TEAM_SCORE)
+ if (GetTeamScore(ALLIANCE) == BG_WS_MAX_TEAM_SCORE)
winner = ALLIANCE;
- if(GetTeamScore(HORDE) == BG_WS_MAX_TEAM_SCORE)
+ if (GetTeamScore(HORDE) == BG_WS_MAX_TEAM_SCORE)
winner = HORDE;
- if(winner)
+ if (winner)
{
UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 0);
UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 0);
@@ -320,15 +275,15 @@ void BattleGroundWS::EventPlayerCapturedFlag(Player *Source)
void BattleGroundWS::EventPlayerDroppedFlag(Player *Source)
{
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
{
// if not running, do not cast things at the dropper player (prevent spawning the "dropped" flag), neither send unnecessary messages
// just take off the aura
- if(Source->GetTeam() == ALLIANCE)
+ if (Source->GetTeam() == ALLIANCE)
{
- if(!this->IsHordeFlagPickedup())
+ if (!this->IsHordeFlagPickedup())
return;
- if(GetHordeFlagPickerGUID() == Source->GetGUID())
+ if (GetHordeFlagPickerGUID() == Source->GetGUID())
{
SetHordeFlagPicker(0);
Source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
@@ -336,9 +291,9 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player *Source)
}
else
{
- if(!this->IsAllianceFlagPickedup())
+ if (!this->IsAllianceFlagPickedup())
return;
- if(GetAllianceFlagPickerGUID() == Source->GetGUID())
+ if (GetAllianceFlagPickerGUID() == Source->GetGUID())
{
SetAllianceFlagPicker(0);
Source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
@@ -347,36 +302,30 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player *Source)
return;
}
- const char *message = "";
- uint8 type = 0;
bool set = false;
- if(Source->GetTeam() == ALLIANCE)
+ if (Source->GetTeam() == ALLIANCE)
{
- if(!this->IsHordeFlagPickedup())
+ if (!IsHordeFlagPickedup())
return;
- if(GetHordeFlagPickerGUID() == Source->GetGUID())
+ if (GetHordeFlagPickerGUID() == Source->GetGUID())
{
SetHordeFlagPicker(0);
Source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_GROUND;
- message = GetTrinityString(LANG_BG_WS_DROPPED_HF);
- type = CHAT_MSG_BG_SYSTEM_HORDE;
Source->CastSpell(Source, BG_WS_SPELL_WARSONG_FLAG_DROPPED, true);
set = true;
}
}
else
{
- if(!this->IsAllianceFlagPickedup())
+ if (!IsAllianceFlagPickedup())
return;
- if(GetAllianceFlagPickerGUID() == Source->GetGUID())
+ if (GetAllianceFlagPickerGUID() == Source->GetGUID())
{
SetAllianceFlagPicker(0);
Source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_GROUND;
- message = GetTrinityString(LANG_BG_WS_DROPPED_AF);
- type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
Source->CastSpell(Source, BG_WS_SPELL_SILVERWING_FLAG_DROPPED, true);
set = true;
}
@@ -387,14 +336,16 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player *Source)
Source->CastSpell(Source, SPELL_RECENTLY_DROPPED_FLAG, true);
UpdateFlagState(Source->GetTeam(), 1);
- WorldPacket data;
- ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
- SendPacketToAll(&data);
-
- if(Source->GetTeam() == ALLIANCE)
+ if (Source->GetTeam() == ALLIANCE)
+ {
+ SendMessageToAll(LANG_BG_WS_DROPPED_HF, CHAT_MSG_BG_SYSTEM_HORDE, Source);
UpdateWorldState(BG_WS_FLAG_UNK_HORDE, uint32(-1));
+ }
else
+ {
+ SendMessageToAll(LANG_BG_WS_DROPPED_AF, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, uint32(-1));
+ }
m_FlagsDropTimer[GetTeamIndexByTeamId(Source->GetTeam()) ? 0 : 1] = BG_WS_FLAG_DROP_TIME;
}
@@ -402,17 +353,17 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player *Source)
void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj)
{
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
- const char *message;
- uint8 type = 0;
+ int32 message_id = 0;
+ ChatMsg type;
//alliance flag picked up from base
if(Source->GetTeam() == HORDE && this->GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_BASE
&& this->m_BgObjects[BG_WS_OBJECT_A_FLAG] == target_obj->GetGUID())
{
- message = GetTrinityString(LANG_BG_WS_PICKEDUP_AF);
+ message_id = LANG_BG_WS_PICKEDUP_AF;
type = CHAT_MSG_BG_SYSTEM_HORDE;
PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_ONE_DAY);
@@ -428,7 +379,7 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
if (Source->GetTeam() == ALLIANCE && this->GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_BASE
&& this->m_BgObjects[BG_WS_OBJECT_H_FLAG] == target_obj->GetGUID())
{
- message = GetTrinityString(LANG_BG_WS_PICKEDUP_HF);
+ message_id = LANG_BG_WS_PICKEDUP_HF;
type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_ONE_DAY);
@@ -441,11 +392,11 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
}
//Alliance flag on ground(not in base) (returned or picked up again from ground!)
- if(this->GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10) && target_obj->GetGOInfo()->id == BG_OBJECT_A_FLAG_GROUND_WS_ENTRY)
+ if (GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10))
{
- if(Source->GetTeam() == ALLIANCE)
+ if (Source->GetTeam() == ALLIANCE)
{
- message = GetTrinityString(LANG_BG_WS_RETURNED_AF);
+ message_id = LANG_BG_WS_RETURNED_AF;
type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
UpdateFlagState(HORDE, BG_WS_FLAG_STATE_WAIT_RESPAWN);
RespawnFlag(ALLIANCE, false);
@@ -455,7 +406,7 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
}
else
{
- message = GetTrinityString(LANG_BG_WS_PICKEDUP_AF);
+ message_id = LANG_BG_WS_PICKEDUP_AF;
type = CHAT_MSG_BG_SYSTEM_HORDE;
PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_ONE_DAY);
@@ -470,11 +421,11 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
}
//Horde flag on ground(not in base) (returned or picked up again)
- if(this->GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10) && target_obj->GetGOInfo()->id == BG_OBJECT_H_FLAG_GROUND_WS_ENTRY)
+ if (GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10))
{
- if(Source->GetTeam() == HORDE)
+ if (Source->GetTeam() == HORDE)
{
- message = GetTrinityString(LANG_BG_WS_RETURNED_HF);
+ message_id = LANG_BG_WS_RETURNED_HF;
type = CHAT_MSG_BG_SYSTEM_HORDE;
UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_WAIT_RESPAWN);
RespawnFlag(HORDE, false);
@@ -484,7 +435,7 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
}
else
{
- message = GetTrinityString(LANG_BG_WS_PICKEDUP_HF);
+ message_id = LANG_BG_WS_PICKEDUP_HF;
type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_ONE_DAY);
@@ -498,21 +449,19 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
//target_obj->Delete();
}
- if (!type)
+ if (!message_id)
return;
- WorldPacket data;
- ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
- SendPacketToAll(&data);
+ SendMessageToAll(message_id, type, Source);
Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
}
void BattleGroundWS::RemovePlayer(Player *plr, uint64 guid)
{
// sometimes flag aura not removed :(
- if(IsAllianceFlagPickedup() && m_FlagKeepers[BG_TEAM_ALLIANCE] == guid)
+ if (IsAllianceFlagPickedup() && m_FlagKeepers[BG_TEAM_ALLIANCE] == guid)
{
- if(!plr)
+ if (!plr)
{
sLog.outError("BattleGroundWS: Removing offline player who has the FLAG!!");
this->SetAllianceFlagPicker(0);
@@ -521,9 +470,9 @@ void BattleGroundWS::RemovePlayer(Player *plr, uint64 guid)
else
this->EventPlayerDroppedFlag(plr);
}
- if(IsHordeFlagPickedup() && m_FlagKeepers[BG_TEAM_HORDE] == guid)
+ if (IsHordeFlagPickedup() && m_FlagKeepers[BG_TEAM_HORDE] == guid)
{
- if(!plr)
+ if (!plr)
{
sLog.outError("BattleGroundWS: Removing offline player who has the FLAG!!");
this->SetHordeFlagPicker(0);
@@ -536,7 +485,7 @@ void BattleGroundWS::RemovePlayer(Player *plr, uint64 guid)
void BattleGroundWS::UpdateFlagState(uint32 team, uint32 value)
{
- if(team == ALLIANCE)
+ if (team == ALLIANCE)
UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, value);
else
UpdateWorldState(BG_WS_FLAG_STATE_HORDE, value);
@@ -544,7 +493,7 @@ void BattleGroundWS::UpdateFlagState(uint32 team, uint32 value)
void BattleGroundWS::UpdateTeamScore(uint32 team)
{
- if(team == ALLIANCE)
+ if (team == ALLIANCE)
UpdateWorldState(BG_WS_FLAG_CAPTURES_ALLIANCE, GetTeamScore(team));
else
UpdateWorldState(BG_WS_FLAG_CAPTURES_HORDE, GetTeamScore(team));
@@ -553,7 +502,7 @@ void BattleGroundWS::UpdateTeamScore(uint32 team)
void BattleGroundWS::HandleAreaTrigger(Player *Source, uint32 Trigger)
{
// this is wrong way to implement these things. On official it done by gameobject spell cast.
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
//uint32 SpellId = 0;
@@ -579,13 +528,13 @@ void BattleGroundWS::HandleAreaTrigger(Player *Source, uint32 Trigger)
//buff_guid = m_BgObjects[BG_WS_OBJECT_BERSERKBUFF_2];
break;
case 3646: // Alliance Flag spawn
- if(m_FlagState[BG_TEAM_HORDE] && !m_FlagState[BG_TEAM_ALLIANCE])
- if(GetHordeFlagPickerGUID() == Source->GetGUID())
+ if (m_FlagState[BG_TEAM_HORDE] && !m_FlagState[BG_TEAM_ALLIANCE])
+ if (GetHordeFlagPickerGUID() == Source->GetGUID())
EventPlayerCapturedFlag(Source);
break;
case 3647: // Horde Flag spawn
- if(m_FlagState[BG_TEAM_ALLIANCE] && !m_FlagState[BG_TEAM_HORDE])
- if(GetAllianceFlagPickerGUID() == Source->GetGUID())
+ if (m_FlagState[BG_TEAM_ALLIANCE] && !m_FlagState[BG_TEAM_HORDE])
+ if (GetAllianceFlagPickerGUID() == Source->GetGUID())
EventPlayerCapturedFlag(Source);
break;
case 3649: // unk1
@@ -599,14 +548,14 @@ void BattleGroundWS::HandleAreaTrigger(Player *Source, uint32 Trigger)
break;
}
- //if(buff_guid)
+ //if (buff_guid)
// HandleTriggerBuff(buff_guid,Source);
}
bool BattleGroundWS::SetupBattleGround()
{
// flags
- if( !AddObject(BG_WS_OBJECT_A_FLAG, BG_OBJECT_A_FLAG_WS_ENTRY, 1540.423f, 1481.325f, 351.8284f, 3.089233f, 0, 0, 0.9996573f, 0.02617699f, BG_WS_FLAG_RESPAWN_TIME/1000)
+ if (!AddObject(BG_WS_OBJECT_A_FLAG, BG_OBJECT_A_FLAG_WS_ENTRY, 1540.423f, 1481.325f, 351.8284f, 3.089233f, 0, 0, 0.9996573f, 0.02617699f, BG_WS_FLAG_RESPAWN_TIME/1000)
|| !AddObject(BG_WS_OBJECT_H_FLAG, BG_OBJECT_H_FLAG_WS_ENTRY, 916.0226f, 1434.405f, 345.413f, 0.01745329f, 0, 0, 0.008726535f, 0.9999619f, BG_WS_FLAG_RESPAWN_TIME/1000)
// buffs
|| !AddObject(BG_WS_OBJECT_SPEEDBUFF_1, BG_OBJECTID_SPEEDBUFF_ENTRY, 1449.93f, 1470.71f, 342.6346f, -1.64061f, 0, 0, 0.7313537f, -0.6819983f, BUFF_RESPAWN_TIME)
@@ -634,14 +583,14 @@ bool BattleGroundWS::SetupBattleGround()
}
WorldSafeLocsEntry const *sg = sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_ALLIANCE);
- if(!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, ALLIANCE))
+ if (!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, ALLIANCE))
{
sLog.outErrorDb("BatteGroundWS: Failed to spawn Alliance spirit guide! BattleGround not created!");
return false;
}
sg = sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_HORDE);
- if(!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, HORDE))
+ if (!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, HORDE))
{
sLog.outErrorDb("BatteGroundWS: Failed to spawn Horde spirit guide! BattleGround not created!");
return false;
@@ -652,8 +601,11 @@ bool BattleGroundWS::SetupBattleGround()
return true;
}
-void BattleGroundWS::ResetBGSubclass()
+void BattleGroundWS::Reset()
{
+ //call parent's class reset
+ BattleGround::Reset();
+
m_FlagKeepers[BG_TEAM_ALLIANCE] = 0;
m_FlagKeepers[BG_TEAM_HORDE] = 0;
m_DroppedFlagGUID[BG_TEAM_ALLIANCE] = 0;
@@ -662,19 +614,36 @@ void BattleGroundWS::ResetBGSubclass()
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
m_TeamScores[BG_TEAM_ALLIANCE] = 0;
m_TeamScores[BG_TEAM_HORDE] = 0;
+ bool isBGWeekend = false; //TODO FIXME - call sBattleGroundMgr.IsBGWeekend(m_TypeID); - you must also implement that call!
+ m_ReputationCapture = (isBGWeekend) ? 45 : 35;
+ m_HonorWinKills = (isBGWeekend) ? 3 : 1;
+ m_HonorEndKills = (isBGWeekend) ? 4 : 2;
/* Spirit nodes is static at this BG and then not required deleting at BG reset.
- if(m_BgCreatures[WS_SPIRIT_MAIN_ALLIANCE])
+ if (m_BgCreatures[WS_SPIRIT_MAIN_ALLIANCE])
DelCreature(WS_SPIRIT_MAIN_ALLIANCE);
-
- if(m_BgCreatures[WS_SPIRIT_MAIN_HORDE])
+ if (m_BgCreatures[WS_SPIRIT_MAIN_HORDE])
DelCreature(WS_SPIRIT_MAIN_HORDE);
*/
}
+void BattleGroundWS::EndBattleGround(uint32 winner)
+{
+ //win reward
+ if (winner == ALLIANCE)
+ RewardHonorToTeam(GetBonusHonorFromKill(m_HonorWinKills), ALLIANCE);
+ if (winner == HORDE)
+ RewardHonorToTeam(GetBonusHonorFromKill(m_HonorWinKills), HORDE);
+ //complete map_end rewards (even if no team wins)
+ RewardHonorToTeam(GetBonusHonorFromKill(m_HonorEndKills), ALLIANCE);
+ RewardHonorToTeam(GetBonusHonorFromKill(m_HonorEndKills), HORDE);
+
+ BattleGround::EndBattleGround(winner);
+}
+
void BattleGroundWS::HandleKillPlayer(Player *player, Player *killer)
{
- if(GetStatus() != STATUS_IN_PROGRESS)
+ if (GetStatus() != STATUS_IN_PROGRESS)
return;
EventPlayerDroppedFlag(player);
@@ -704,19 +673,42 @@ void BattleGroundWS::UpdatePlayerScore(Player *Source, uint32 type, uint32 value
}
}
+WorldSafeLocsEntry const* BattleGroundWS::GetClosestGraveYard(Player* player)
+{
+ //if status in progress, it returns main graveyards with spiritguides
+ //else it will return the graveyard in the flagroom - this is especially good
+ //if a player dies in preparation phase - then the player can't cheat
+ //and teleport to the graveyard outside the flagroom
+ //and start running around, while the doors are still closed
+ if (player->GetTeam() == ALLIANCE)
+ {
+ if (GetStatus() == STATUS_IN_PROGRESS)
+ return sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_ALLIANCE);
+ else
+ return sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_FLAGROOM_ALLIANCE);
+ }
+ else
+ {
+ if (GetStatus() == STATUS_IN_PROGRESS)
+ return sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_HORDE);
+ else
+ return sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_FLAGROOM_HORDE);
+ }
+}
+
void BattleGroundWS::FillInitialWorldStates(WorldPacket& data)
{
data << uint32(BG_WS_FLAG_CAPTURES_ALLIANCE) << uint32(GetTeamScore(ALLIANCE));
data << uint32(BG_WS_FLAG_CAPTURES_HORDE) << uint32(GetTeamScore(HORDE));
- if(m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
+ if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(-1);
else if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_PLAYER)
data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(1);
else
data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(0);
- if(m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
+ if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(-1);
else if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_PLAYER)
data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(1);
diff --git a/src/game/BattleGroundWS.h b/src/game/BattleGroundWS.h
index 4e57826cd30..906bccfe6ab 100644
--- a/src/game/BattleGroundWS.h
+++ b/src/game/BattleGroundWS.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -29,7 +29,7 @@ enum BG_WS_TimerOrScore
BG_WS_FLAG_RESPAWN_TIME = 23000,
BG_WS_FLAG_DROP_TIME = 10000,
BG_WS_SPELL_FORCE_TIME = 600000,
- BG_WS_SPELL_BRUTAL_TIME = 900000
+ BG_WS_SPELL_BRUTAL_TIME = 900000
};
enum BG_WS_Sound
@@ -116,8 +116,10 @@ enum BG_WS_FlagState
enum BG_WS_Graveyards
{
- WS_GRAVEYARD_MAIN_ALLIANCE = 771,
- WS_GRAVEYARD_MAIN_HORDE = 772
+ WS_GRAVEYARD_FLAGROOM_ALLIANCE = 769,
+ WS_GRAVEYARD_FLAGROOM_HORDE = 770,
+ WS_GRAVEYARD_MAIN_ALLIANCE = 771,
+ WS_GRAVEYARD_MAIN_HORDE = 772
};
enum BG_WS_CreatureTypes
@@ -145,10 +147,12 @@ class BattleGroundWS : public BattleGround
/* Construction */
BattleGroundWS();
~BattleGroundWS();
- void Update(time_t diff);
+ void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
+ virtual void StartingEventCloseDoors();
+ virtual void StartingEventOpenDoors();
/* BG Flags */
uint64 GetAllianceFlagPickerGUID() const { return m_FlagKeepers[BG_TEAM_ALLIANCE]; }
@@ -174,7 +178,9 @@ class BattleGroundWS : public BattleGround
void HandleAreaTrigger(Player *Source, uint32 Trigger);
void HandleKillPlayer(Player *player, Player *killer);
bool SetupBattleGround();
- virtual void ResetBGSubclass();
+ virtual void Reset();
+ void EndBattleGround(uint32 winner);
+ virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
void UpdateFlagState(uint32 team, uint32 value);
void UpdateTeamScore(uint32 team);
@@ -185,9 +191,9 @@ class BattleGroundWS : public BattleGround
/* Scorekeeping */
uint32 GetTeamScore(uint32 TeamID) const { return m_TeamScores[GetTeamIndexByTeamId(TeamID)]; }
- void AddPoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] += Points; m_score[GetTeamIndexByTeamId(TeamID)] = m_TeamScores[GetTeamIndexByTeamId(TeamID)];}
- void SetTeamPoint(uint32 TeamID, uint32 Points = 0) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] = Points; m_score[GetTeamIndexByTeamId(TeamID)] = m_TeamScores[GetTeamIndexByTeamId(TeamID)];}
- void RemovePoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] -= Points; m_score[GetTeamIndexByTeamId(TeamID)] = m_TeamScores[GetTeamIndexByTeamId(TeamID)]; }
+ void AddPoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] += Points; }
+ void SetTeamPoint(uint32 TeamID, uint32 Points = 0) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] = Points; }
+ void RemovePoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] -= Points; }
private:
uint64 m_FlagKeepers[2]; // 0 - alliance, 1 - horde
@@ -197,8 +203,9 @@ class BattleGroundWS : public BattleGround
int32 m_FlagsTimer[2];
int32 m_FlagsDropTimer[2];
- int32 m_FlagSpellForceTimer;
- int32 m_FlagSpellBrutalTimer;
+ uint32 m_ReputationCapture;
+ uint32 m_HonorWinKills;
+ uint32 m_HonorEndKills;
};
#endif
diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt
index 621ce3def3e..081d9669696 100644
--- a/src/game/CMakeLists.txt
+++ b/src/game/CMakeLists.txt
@@ -4,6 +4,8 @@
SET(game_STAT_SRCS
AccountMgr.cpp
AccountMgr.h
+ AchievementMgr.h
+ AchievementMgr.cpp
AddonHandler.cpp
AddonHandler.h
AggressorAI.cpp
@@ -12,9 +14,9 @@ SET(game_STAT_SRCS
ArenaTeam.cpp
ArenaTeam.h
ArenaTeamHandler.cpp
+ AuctionHouseHandler.cpp
AuctionHouseBot.cpp
AuctionHouseBot.h
- AuctionHouseHandler.cpp
AuctionHouseMgr.cpp
AuctionHouseMgr.h
Bag.cpp
@@ -24,22 +26,31 @@ SET(game_STAT_SRCS
BattleGroundAB.cpp
BattleGroundAV.cpp
BattleGroundBE.cpp
+ BattleGroundDS.cpp
BattleGroundEY.cpp
BattleGroundNA.cpp
BattleGroundRL.cpp
+ BattleGroundRV.cpp
+ BattleGroundSA.cpp
BattleGroundWS.cpp
BattleGround.h
BattleGroundAA.h
BattleGroundAB.h
BattleGroundAV.h
BattleGroundBE.h
+ BattleGroundDS.h
BattleGroundEY.h
BattleGroundNA.h
BattleGroundRL.h
+ BattleGroundRV.h
+ BattleGroundSA.h
BattleGroundWS.h
BattleGroundHandler.cpp
BattleGroundMgr.cpp
BattleGroundMgr.h
+ Calendar.cpp
+ Calendar.h
+ CalendarHandler.cpp
Cell.h
CellImpl.h
Channel.cpp
@@ -62,10 +73,17 @@ SET(game_STAT_SRCS
CreatureAIRegistry.h
CreatureAISelector.cpp
CreatureAISelector.h
+ CreatureEventAI.cpp
+ CreatureEventAIMgr.cpp
Creature.cpp
Creature.h
CreatureGroups.cpp
CreatureGroups.h
+ DBCEnums.h
+ DBCStores.cpp
+ DBCStores.h
+ DBCStructure.h
+ DBCfmt.h
Debugcmds.cpp
DestinationHolder.cpp
DestinationHolder.h
@@ -76,8 +94,8 @@ SET(game_STAT_SRCS
FleeingMovementGenerator.cpp
FleeingMovementGenerator.h
Formulas.h
- GameEvent.cpp
- GameEvent.h
+ GameEventMgr.cpp
+ GameEventMgr.h
GameObject.cpp
GameObject.h
GlobalEvents.cpp
@@ -131,6 +149,8 @@ SET(game_STAT_SRCS
MapInstanced.h
MapManager.cpp
MapManager.h
+ MapReference.h
+ MapRefManager.h
MiscHandler.cpp
MotionMaster.cpp
MotionMaster.h
@@ -151,6 +171,8 @@ SET(game_STAT_SRCS
Object.h
ObjectMgr.cpp
ObjectMgr.h
+ ObjectPosSelector.cpp
+ ObjectPosSelector.h
Opcodes.cpp
Opcodes.h
OutdoorPvP.cpp
@@ -184,6 +206,8 @@ SET(game_STAT_SRCS
PlayerDump.h
PointMovementGenerator.cpp
PointMovementGenerator.h
+ PoolHandler.cpp
+ PoolHandler.h
PossessedAI.cpp
PossessedAI.h
QueryHandler.cpp
@@ -194,6 +218,8 @@ SET(game_STAT_SRCS
RandomMovementGenerator.h
ReactorAI.cpp
ReactorAI.h
+ ReputationMgr.cpp
+ ReputationMgr.h
ScriptCalls.cpp
ScriptCalls.h
SharedDefines.h
@@ -221,7 +247,7 @@ SET(game_STAT_SRCS
TemporarySummon.h
TicketHandler.cpp
TicketMgr.cpp
- TicketMgr.h
+ TicketMgr.h
Tools.cpp
Tools.h
TotemAI.cpp
@@ -241,6 +267,8 @@ SET(game_STAT_SRCS
UpdateData.h
UpdateFields.h
UpdateMask.h
+ Vehicle.cpp
+ Vehicle.h
VoiceChatHandler.cpp
WaypointManager.cpp
WaypointManager.h
diff --git a/src/game/Calendar.cpp b/src/game/Calendar.cpp
new file mode 100644
index 00000000000..0c1efb20f87
--- /dev/null
+++ b/src/game/Calendar.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2005-2009 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
+ */
diff --git a/src/game/Calendar.h b/src/game/Calendar.h
new file mode 100644
index 00000000000..7a86afa7db7
--- /dev/null
+++ b/src/game/Calendar.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2005-2009 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 MANGOS_CALENDAR_H
+#define MANGOS_CALENDAR_H
+
+class Calendar
+{
+
+};
+#endif
diff --git a/src/game/CalendarHandler.cpp b/src/game/CalendarHandler.cpp
new file mode 100644
index 00000000000..3cd186c15d3
--- /dev/null
+++ b/src/game/CalendarHandler.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2005-2009 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 "Common.h"
+#include "Log.h"
+#include "Player.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
+#include "Opcodes.h"
+#include "InstanceSaveMgr.h"
+
+void WorldSession::HandleCalendarGetCalendar(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_GET_CALENDAR");
+ recv_data.hexlike();
+
+ time_t cur_time = time(NULL);
+
+ WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR,4+4*0+4+4*0+4+4);
+
+ // TODO: calendar invite event output
+ data << (uint32) 0; //invite node count
+ // TODO: calendar event output
+ data << (uint32) 0; //event count
+
+ data << (uint32) 0; //wtf??
+ data << (uint32) secsToTimeBitFields(cur_time); // current time
+
+ uint32 counter = 0;
+ size_t p_counter = data.wpos();
+ data << uint32(counter); // instance save count
+
+ for(int i = 0; i < TOTAL_DIFFICULTIES; ++i)
+ {
+ for (Player::BoundInstancesMap::const_iterator itr = _player->m_boundInstances[i].begin(); itr != _player->m_boundInstances[i].end(); ++itr)
+ {
+ if(itr->second.perm)
+ {
+ InstanceSave *save = itr->second.save;
+ data << uint32(save->GetMapId());
+ data << uint32(save->GetDifficulty());
+ data << uint32(save->GetResetTime() - cur_time);
+ data << uint64(save->GetInstanceId()); // instance save id as unique instance copy id
+ ++counter;
+ }
+ }
+ }
+ data.put<uint32>(p_counter,counter);
+
+ data << (uint32) 1135753200; //wtf?? (28.12.2005 12:00)
+ data << (uint32) 0; // unk counter 4
+ data << (uint32) 0; // unk counter 5
+ //sLog.outDebug("Sending calendar");
+ //data.hexlike();
+ SendPacket(&data);
+}
+
+void WorldSession::HandleCalendarGetEvent(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_GET_EVENT");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarGuildFilter(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_GUILD_FILTER");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarArenaTeam(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_ARENA_TEAM");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarAddEvent(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_ADD_EVENT");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarUpdateEvent(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_UPDATE_EVENT");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarRemoveEvent(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_REMOVE_EVENT");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarCopyEvent(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_COPY_EVENT");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarEventInvite(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_INVITE");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarEventRsvp(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_RSVP");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarEventRemoveInvite(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_REMOVE_INVITE");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarEventStatus(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_STATUS");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarEventModeratorStatus(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_MODERATOR_STATUS");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarComplain(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_COMPLAIN");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarGetNumPending(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_GET_NUM_PENDING");
+ recv_data.hexlike();
+
+ WorldPacket data(SMSG_CALENDAR_SEND_NUM_PENDING, 4);
+ data << uint32(0); // 0 - no pending invites, 1 - some pending invites
+ SendPacket(&data);
+}
diff --git a/src/game/Cell.h b/src/game/Cell.h
index 160e037bcfb..7e66d5d9f73 100644
--- a/src/game/Cell.h
+++ b/src/game/Cell.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -93,13 +93,13 @@ struct TRINITY_DLL_DECL Cell
y = data.Part.grid_y*MAX_NUMBER_OF_CELLS + data.Part.cell_y;
}
- inline bool DiffCell(const Cell &cell) const
+ bool DiffCell(const Cell &cell) const
{
return( data.Part.cell_x != cell.data.Part.cell_x ||
data.Part.cell_y != cell.data.Part.cell_y );
}
- inline bool DiffGrid(const Cell &cell) const
+ bool DiffGrid(const Cell &cell) const
{
return( data.Part.grid_x != cell.data.Part.grid_x ||
data.Part.grid_y != cell.data.Part.grid_y );
diff --git a/src/game/CellImpl.h b/src/game/CellImpl.h
index 463b051f7ac..e74e0013a19 100644
--- a/src/game/CellImpl.h
+++ b/src/game/CellImpl.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/Channel.cpp b/src/game/Channel.cpp
index bf787d7d25d..588eb15f0cc 100644
--- a/src/game/Channel.cpp
+++ b/src/game/Channel.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -24,7 +24,7 @@
#include "SocialMgr.h"
Channel::Channel(const std::string& name, uint32 channel_id)
-: m_name(name), m_announce(true), m_moderate(false), m_channelId(channel_id), m_ownerGUID(0), m_password(""), m_flags(0)
+: m_announce(true), m_moderate(false), m_name(name), m_flags(0), m_channelId(channel_id), m_ownerGUID(0)
{
// set special flags if built-in channel
ChatChannelsEntry const* ch = GetChannelEntryFor(channel_id);
@@ -171,7 +171,7 @@ void Channel::Leave(uint64 p, bool send)
void Channel::KickOrBan(uint64 good, const char *badname, bool ban)
{
- uint32 sec = 0;
+ AccountTypes sec = SEC_PLAYER;
Player *gplr = objmgr.GetPlayer(good);
if(gplr)
sec = gplr->GetSession()->GetSecurity();
@@ -300,10 +300,11 @@ void Channel::Password(uint64 p, const char *pass)
void Channel::SetMode(uint64 p, const char *p2n, bool mod, bool set)
{
- uint32 sec = 0;
Player *plr = objmgr.GetPlayer(p);
- if(plr)
- sec = plr->GetSession()->GetSecurity();
+ if (!plr)
+ return;
+
+ uint32 sec = plr->GetSession()->GetSecurity();
if(!IsOn(p))
{
@@ -368,10 +369,11 @@ void Channel::SetMode(uint64 p, const char *p2n, bool mod, bool set)
void Channel::SetOwner(uint64 p, const char *newname)
{
- uint32 sec = 0;
Player *plr = objmgr.GetPlayer(p);
- if(plr)
- sec = plr->GetSession()->GetSecurity();
+ if (!plr)
+ return;
+
+ uint32 sec = plr->GetSession()->GetSecurity();
if(!IsOn(p))
{
@@ -449,13 +451,13 @@ void Channel::List(Player* player)
bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST) || player->GetSession()->GetSecurity() > SEC_PLAYER;
uint32 count = 0;
- for(PlayerList::iterator i = players.begin(); i != players.end(); ++i)
+ for(PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
{
Player *plr = objmgr.GetPlayer(i->first);
// PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all
- if( plr && ( plr->GetSession()->GetSecurity() == SEC_PLAYER || gmInWhoList && plr->IsVisibleGloballyFor(player) ) )
+ if (plr && ( plr->GetSession()->GetSecurity() == SEC_PLAYER || (gmInWhoList && plr->IsVisibleGloballyFor(player))))
{
data << uint64(i->first);
data << uint8(i->second.flags); // flags seems to be changed...
@@ -662,7 +664,7 @@ void Channel::SetOwner(uint64 guid, bool exclaim)
void Channel::SendToAll(WorldPacket *data, uint64 p)
{
- for(PlayerList::iterator i = players.begin(); i != players.end(); ++i)
+ for(PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
{
Player *plr = objmgr.GetPlayer(i->first);
if(plr)
@@ -675,7 +677,7 @@ void Channel::SendToAll(WorldPacket *data, uint64 p)
void Channel::SendToAllButOne(WorldPacket *data, uint64 who)
{
- for(PlayerList::iterator i = players.begin(); i != players.end(); ++i)
+ for(PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
{
if(i->first != who)
{
@@ -693,12 +695,12 @@ void Channel::SendToOne(WorldPacket *data, uint64 who)
plr->GetSession()->SendPacket(data);
}
-void Channel::Voice(uint64 guid1, uint64 guid2)
+void Channel::Voice(uint64 /*guid1*/, uint64 /*guid2*/)
{
}
-void Channel::DeVoice(uint64 guid1, uint64 guid2)
+void Channel::DeVoice(uint64 /*guid1*/, uint64 /*guid2*/)
{
}
diff --git a/src/game/Channel.h b/src/game/Channel.h
index 82b62df12c4..924046e4739 100644
--- a/src/game/Channel.h
+++ b/src/game/Channel.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -23,7 +23,6 @@
#include "Common.h"
#include "WorldPacket.h"
-#include "WorldSession.h"
#include "Opcodes.h"
#include "Player.h"
@@ -31,95 +30,95 @@
#include <map>
#include <string>
-class Channel
+enum ChatNotify
{
- enum ChatNotify
- {
- CHAT_JOINED_NOTICE = 0x00, //+ "%s joined channel.";
- CHAT_LEFT_NOTICE = 0x01, //+ "%s left channel.";
- //CHAT_SUSPENDED_NOTICE = 0x01, // "%s left channel.";
- CHAT_YOU_JOINED_NOTICE = 0x02, //+ "Joined Channel: [%s]"; -- You joined
- //CHAT_YOU_CHANGED_NOTICE = 0x02, // "Changed Channel: [%s]";
- CHAT_YOU_LEFT_NOTICE = 0x03, //+ "Left Channel: [%s]"; -- You left
- CHAT_WRONG_PASSWORD_NOTICE = 0x04, //+ "Wrong password for %s.";
- CHAT_NOT_MEMBER_NOTICE = 0x05, //+ "Not on channel %s.";
- CHAT_NOT_MODERATOR_NOTICE = 0x06, //+ "Not a moderator of %s.";
- CHAT_PASSWORD_CHANGED_NOTICE = 0x07, //+ "[%s] Password changed by %s.";
- CHAT_OWNER_CHANGED_NOTICE = 0x08, //+ "[%s] Owner changed to %s.";
- CHAT_PLAYER_NOT_FOUND_NOTICE = 0x09, //+ "[%s] Player %s was not found.";
- CHAT_NOT_OWNER_NOTICE = 0x0A, //+ "[%s] You are not the channel owner.";
- CHAT_CHANNEL_OWNER_NOTICE = 0x0B, //+ "[%s] Channel owner is %s.";
- CHAT_MODE_CHANGE_NOTICE = 0x0C, //?
- CHAT_ANNOUNCEMENTS_ON_NOTICE = 0x0D, //+ "[%s] Channel announcements enabled by %s.";
- CHAT_ANNOUNCEMENTS_OFF_NOTICE = 0x0E, //+ "[%s] Channel announcements disabled by %s.";
- CHAT_MODERATION_ON_NOTICE = 0x0F, //+ "[%s] Channel moderation enabled by %s.";
- CHAT_MODERATION_OFF_NOTICE = 0x10, //+ "[%s] Channel moderation disabled by %s.";
- CHAT_MUTED_NOTICE = 0x11, //+ "[%s] You do not have permission to speak.";
- CHAT_PLAYER_KICKED_NOTICE = 0x12, //? "[%s] Player %s kicked by %s.";
- CHAT_BANNED_NOTICE = 0x13, //+ "[%s] You are banned from that channel.";
- CHAT_PLAYER_BANNED_NOTICE = 0x14, //? "[%s] Player %s banned by %s.";
- CHAT_PLAYER_UNBANNED_NOTICE = 0x15, //? "[%s] Player %s unbanned by %s.";
- CHAT_PLAYER_NOT_BANNED_NOTICE = 0x16, //+ "[%s] Player %s is not banned.";
- CHAT_PLAYER_ALREADY_MEMBER_NOTICE = 0x17, //+ "[%s] Player %s is already on the channel.";
- CHAT_INVITE_NOTICE = 0x18, //+ "%2$s has invited you to join the channel '%1$s'.";
- CHAT_INVITE_WRONG_FACTION_NOTICE = 0x19, //+ "Target is in the wrong alliance for %s.";
- CHAT_WRONG_FACTION_NOTICE = 0x1A, //+ "Wrong alliance for %s.";
- CHAT_INVALID_NAME_NOTICE = 0x1B, //+ "Invalid channel name";
- CHAT_NOT_MODERATED_NOTICE = 0x1C, //+ "%s is not moderated";
- CHAT_PLAYER_INVITED_NOTICE = 0x1D, //+ "[%s] You invited %s to join the channel";
- CHAT_PLAYER_INVITE_BANNED_NOTICE = 0x1E, //+ "[%s] %s has been banned.";
- CHAT_THROTTLED_NOTICE = 0x1F, //+ "[%s] The number of messages that can be sent to this channel is limited, please wait to send another message.";
- CHAT_NOT_IN_AREA_NOTICE = 0x20, //+ "[%s] You are not in the correct area for this channel."; -- The user is trying to send a chat to a zone specific channel, and they're not physically in that zone.
- CHAT_NOT_IN_LFG_NOTICE = 0x21, //+ "[%s] You must be queued in looking for group before joining this channel."; -- The user must be in the looking for group system to join LFG chat channels.
- CHAT_VOICE_ON_NOTICE = 0x22, //+ "[%s] Channel voice enabled by %s.";
- CHAT_VOICE_OFF_NOTICE = 0x23, //+ "[%s] Channel voice disabled by %s.";
- };
+ CHAT_JOINED_NOTICE = 0x00, //+ "%s joined channel.";
+ CHAT_LEFT_NOTICE = 0x01, //+ "%s left channel.";
+ //CHAT_SUSPENDED_NOTICE = 0x01, // "%s left channel.";
+ CHAT_YOU_JOINED_NOTICE = 0x02, //+ "Joined Channel: [%s]"; -- You joined
+ //CHAT_YOU_CHANGED_NOTICE = 0x02, // "Changed Channel: [%s]";
+ CHAT_YOU_LEFT_NOTICE = 0x03, //+ "Left Channel: [%s]"; -- You left
+ CHAT_WRONG_PASSWORD_NOTICE = 0x04, //+ "Wrong password for %s.";
+ CHAT_NOT_MEMBER_NOTICE = 0x05, //+ "Not on channel %s.";
+ CHAT_NOT_MODERATOR_NOTICE = 0x06, //+ "Not a moderator of %s.";
+ CHAT_PASSWORD_CHANGED_NOTICE = 0x07, //+ "[%s] Password changed by %s.";
+ CHAT_OWNER_CHANGED_NOTICE = 0x08, //+ "[%s] Owner changed to %s.";
+ CHAT_PLAYER_NOT_FOUND_NOTICE = 0x09, //+ "[%s] Player %s was not found.";
+ CHAT_NOT_OWNER_NOTICE = 0x0A, //+ "[%s] You are not the channel owner.";
+ CHAT_CHANNEL_OWNER_NOTICE = 0x0B, //+ "[%s] Channel owner is %s.";
+ CHAT_MODE_CHANGE_NOTICE = 0x0C, //?
+ CHAT_ANNOUNCEMENTS_ON_NOTICE = 0x0D, //+ "[%s] Channel announcements enabled by %s.";
+ CHAT_ANNOUNCEMENTS_OFF_NOTICE = 0x0E, //+ "[%s] Channel announcements disabled by %s.";
+ CHAT_MODERATION_ON_NOTICE = 0x0F, //+ "[%s] Channel moderation enabled by %s.";
+ CHAT_MODERATION_OFF_NOTICE = 0x10, //+ "[%s] Channel moderation disabled by %s.";
+ CHAT_MUTED_NOTICE = 0x11, //+ "[%s] You do not have permission to speak.";
+ CHAT_PLAYER_KICKED_NOTICE = 0x12, //? "[%s] Player %s kicked by %s.";
+ CHAT_BANNED_NOTICE = 0x13, //+ "[%s] You are banned from that channel.";
+ CHAT_PLAYER_BANNED_NOTICE = 0x14, //? "[%s] Player %s banned by %s.";
+ CHAT_PLAYER_UNBANNED_NOTICE = 0x15, //? "[%s] Player %s unbanned by %s.";
+ CHAT_PLAYER_NOT_BANNED_NOTICE = 0x16, //+ "[%s] Player %s is not banned.";
+ CHAT_PLAYER_ALREADY_MEMBER_NOTICE = 0x17, //+ "[%s] Player %s is already on the channel.";
+ CHAT_INVITE_NOTICE = 0x18, //+ "%2$s has invited you to join the channel '%1$s'.";
+ CHAT_INVITE_WRONG_FACTION_NOTICE = 0x19, //+ "Target is in the wrong alliance for %s.";
+ CHAT_WRONG_FACTION_NOTICE = 0x1A, //+ "Wrong alliance for %s.";
+ CHAT_INVALID_NAME_NOTICE = 0x1B, //+ "Invalid channel name";
+ CHAT_NOT_MODERATED_NOTICE = 0x1C, //+ "%s is not moderated";
+ CHAT_PLAYER_INVITED_NOTICE = 0x1D, //+ "[%s] You invited %s to join the channel";
+ CHAT_PLAYER_INVITE_BANNED_NOTICE = 0x1E, //+ "[%s] %s has been banned.";
+ CHAT_THROTTLED_NOTICE = 0x1F, //+ "[%s] The number of messages that can be sent to this channel is limited, please wait to send another message.";
+ CHAT_NOT_IN_AREA_NOTICE = 0x20, //+ "[%s] You are not in the correct area for this channel."; -- The user is trying to send a chat to a zone specific channel, and they're not physically in that zone.
+ CHAT_NOT_IN_LFG_NOTICE = 0x21, //+ "[%s] You must be queued in looking for group before joining this channel."; -- The user must be in the looking for group system to join LFG chat channels.
+ CHAT_VOICE_ON_NOTICE = 0x22, //+ "[%s] Channel voice enabled by %s.";
+ CHAT_VOICE_OFF_NOTICE = 0x23, //+ "[%s] Channel voice disabled by %s.";
+};
- enum ChannelFlags
- {
- CHANNEL_FLAG_NONE = 0x00,
- CHANNEL_FLAG_CUSTOM = 0x01,
- // 0x02
- CHANNEL_FLAG_TRADE = 0x04,
- CHANNEL_FLAG_NOT_LFG = 0x08,
- CHANNEL_FLAG_GENERAL = 0x10,
- CHANNEL_FLAG_CITY = 0x20,
- CHANNEL_FLAG_LFG = 0x40,
- CHANNEL_FLAG_VOICE = 0x80
- // General 0x18 = 0x10 | 0x08
- // Trade 0x3C = 0x20 | 0x10 | 0x08 | 0x04
- // LocalDefence 0x18 = 0x10 | 0x08
- // GuildRecruitment 0x38 = 0x20 | 0x10 | 0x08
- // LookingForGroup 0x50 = 0x40 | 0x10
- };
+enum ChannelFlags
+{
+ CHANNEL_FLAG_NONE = 0x00,
+ CHANNEL_FLAG_CUSTOM = 0x01,
+ // 0x02
+ CHANNEL_FLAG_TRADE = 0x04,
+ CHANNEL_FLAG_NOT_LFG = 0x08,
+ CHANNEL_FLAG_GENERAL = 0x10,
+ CHANNEL_FLAG_CITY = 0x20,
+ CHANNEL_FLAG_LFG = 0x40,
+ CHANNEL_FLAG_VOICE = 0x80
+ // General 0x18 = 0x10 | 0x08
+ // Trade 0x3C = 0x20 | 0x10 | 0x08 | 0x04
+ // LocalDefence 0x18 = 0x10 | 0x08
+ // GuildRecruitment 0x38 = 0x20 | 0x10 | 0x08
+ // LookingForGroup 0x50 = 0x40 | 0x10
+};
- enum ChannelDBCFlags
- {
- CHANNEL_DBC_FLAG_NONE = 0x00000,
- CHANNEL_DBC_FLAG_INITIAL = 0x00001, // General, Trade, LocalDefense, LFG
- CHANNEL_DBC_FLAG_ZONE_DEP = 0x00002, // General, Trade, LocalDefense, GuildRecruitment
- CHANNEL_DBC_FLAG_GLOBAL = 0x00004, // WorldDefense
- CHANNEL_DBC_FLAG_TRADE = 0x00008, // Trade
- CHANNEL_DBC_FLAG_CITY_ONLY = 0x00010, // Trade, GuildRecruitment
- CHANNEL_DBC_FLAG_CITY_ONLY2 = 0x00020, // Trade, GuildRecruitment
- CHANNEL_DBC_FLAG_DEFENSE = 0x10000, // LocalDefense, WorldDefense
- CHANNEL_DBC_FLAG_GUILD_REQ = 0x20000, // GuildRecruitment
- CHANNEL_DBC_FLAG_LFG = 0x40000 // LookingForGroup
- };
+enum ChannelDBCFlags
+{
+ CHANNEL_DBC_FLAG_NONE = 0x00000,
+ CHANNEL_DBC_FLAG_INITIAL = 0x00001, // General, Trade, LocalDefense, LFG
+ CHANNEL_DBC_FLAG_ZONE_DEP = 0x00002, // General, Trade, LocalDefense, GuildRecruitment
+ CHANNEL_DBC_FLAG_GLOBAL = 0x00004, // WorldDefense
+ CHANNEL_DBC_FLAG_TRADE = 0x00008, // Trade
+ CHANNEL_DBC_FLAG_CITY_ONLY = 0x00010, // Trade, GuildRecruitment
+ CHANNEL_DBC_FLAG_CITY_ONLY2 = 0x00020, // Trade, GuildRecruitment
+ CHANNEL_DBC_FLAG_DEFENSE = 0x10000, // LocalDefense, WorldDefense
+ CHANNEL_DBC_FLAG_GUILD_REQ = 0x20000, // GuildRecruitment
+ CHANNEL_DBC_FLAG_LFG = 0x40000 // LookingForGroup
+};
- enum ChannelMemberFlags
- {
- MEMBER_FLAG_NONE = 0x00,
- MEMBER_FLAG_OWNER = 0x01,
- MEMBER_FLAG_MODERATOR = 0x02,
- MEMBER_FLAG_VOICED = 0x04,
- MEMBER_FLAG_MUTED = 0x08,
- MEMBER_FLAG_CUSTOM = 0x10,
- MEMBER_FLAG_MIC_MUTED = 0x20,
- // 0x40
- // 0x80
- };
+enum ChannelMemberFlags
+{
+ MEMBER_FLAG_NONE = 0x00,
+ MEMBER_FLAG_OWNER = 0x01,
+ MEMBER_FLAG_MODERATOR = 0x02,
+ MEMBER_FLAG_VOICED = 0x04,
+ MEMBER_FLAG_MUTED = 0x08,
+ MEMBER_FLAG_CUSTOM = 0x10,
+ MEMBER_FLAG_MIC_MUTED = 0x20,
+ // 0x40
+ // 0x80
+};
+class Channel
+{
struct PlayerInfo
{
uint64 player;
@@ -204,11 +203,8 @@ class Channel
void SendToAllButOne(WorldPacket *data, uint64 who);
void SendToOne(WorldPacket *data, uint64 who);
- bool IsOn(uint64 who) const { return players.count(who) != 0; }
-
- bool IsBanned(const uint64 guid) const {return banned.count(guid) != 0; }
-
- bool IsFirst() const { return !(players.size() > 1); }
+ bool IsOn(uint64 who) const { return players.find(who) != players.end(); }
+ bool IsBanned(uint64 guid) const { return banned.find(guid) != banned.end(); }
uint8 GetPlayerFlags(uint64 p) const
{
diff --git a/src/game/ChannelHandler.cpp b/src/game/ChannelHandler.cpp
index 71e7ea365c2..9b06693c589 100644
--- a/src/game/ChannelHandler.cpp
+++ b/src/game/ChannelHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/ChannelMgr.h b/src/game/ChannelMgr.h
index 453ee144d86..73e69c371ab 100644
--- a/src/game/ChannelMgr.h
+++ b/src/game/ChannelMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -34,13 +34,13 @@ class ChannelMgr
ChannelMgr() {}
~ChannelMgr()
{
- for(ChannelMap::iterator itr = channels.begin();itr!=channels.end(); ++itr)
+ for(ChannelMap::const_iterator itr = channels.begin();itr!=channels.end(); ++itr)
delete itr->second;
channels.clear();
}
Channel *GetJoinChannel(const std::string& name, uint32 channel_id)
{
- if(channels.count(name) == 0)
+ if (channels.find(name) == channels.end())
{
Channel *nchan = new Channel(name,channel_id);
channels[name] = nchan;
diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
index 4aef21df530..ca6a96c3b08 100644
--- a/src/game/CharacterHandler.cpp
+++ b/src/game/CharacterHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -31,7 +31,6 @@
#include "Guild.h"
#include "UpdateMask.h"
#include "Auth/md5.h"
-#include "MapManager.h"
#include "ObjectAccessor.h"
#include "Group.h"
#include "Database/DatabaseImpl.h"
@@ -64,11 +63,11 @@ bool LoginQueryHolder::Initialize()
// NOTE: all fields in `characters` must be read to prevent lost character data at next save in case wrong DB structure.
// !!! NOTE: including unused `zone`,`online`
- res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty, arena_pending_points FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid));
+ res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty, arena_pending_points,bgid,bgteam,bgmap,bgx,bgy,bgz,bgo FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT leaderGuid FROM group_member WHERE memberGuid ='%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", GUID_LOPART(m_guid));
- res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid));
- res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS, "SELECT spell,slot,active,disabled FROM character_spell WHERE guid = '%u'", GUID_LOPART(m_guid));
+ res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,effect_mask,stackcount,amount0, amount1, amount2 ,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid));
+ res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS, "SELECT spell,active,disabled FROM character_spell WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS, "SELECT quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4 FROM character_queststatus WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS,"SELECT quest,time FROM character_queststatus_daily WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADTUTORIALS, "SELECT tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7 FROM character_tutorial WHERE account = '%u' AND realmid = '%u'", GetAccountId(), realmID);
@@ -85,6 +84,8 @@ bool LoginQueryHolder::Initialize()
// in other case still be dummy query
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGUILD, "SELECT guildid,rank FROM guild_member WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADARENAINFO, "SELECT arenateamid, played_week, played_season, personal_rating FROM arena_team_member WHERE guid='%u'", GUID_LOPART(m_guid));
+ res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS, "SELECT achievement, date FROM character_achievement WHERE guid = '%u'", GUID_LOPART(m_guid));
+ res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS,"SELECT criteria, counter, date FROM character_achievement_progress WHERE guid = '%u'", GUID_LOPART(m_guid));
return res;
}
@@ -164,7 +165,7 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ )
"SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, "
// 9 10 11 12 13
"characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid "
- "FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='0' "
+ "FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='%u' "
"LEFT JOIN guild_member ON characters.guid = guild_member.guid "
"WHERE characters.account = '%u' ORDER BY characters.guid"
:
@@ -173,11 +174,11 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ )
"SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, "
// 9 10 11 12 13 14
"characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid, genitive "
- "FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='0' "
+ "FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='%u' "
"LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid "
"LEFT JOIN guild_member ON characters.guid = guild_member.guid "
"WHERE characters.account = '%u' ORDER BY characters.guid",
- GetAccountId());
+ PET_SAVE_AS_CURRENT,GetAccountId());
}
void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
@@ -234,17 +235,16 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
if (raceEntry->addon > Expansion())
{
data << (uint8)CHAR_CREATE_EXPANSION;
- sLog.outError("Not Expansion 1 account:[%d] but tried to Create character with expansion 1 race (%u)",GetAccountId(),race_);
+ sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u race (%u)",Expansion(),GetAccountId(),raceEntry->addon,race_);
SendPacket( &data );
return;
}
// prevent character creating Expansion class without Expansion account
- // TODO: use possible addon field in ChrClassesEntry in next dbc version
- if (Expansion() < 2 && class_ == CLASS_DEATH_KNIGHT)
+ if (classEntry->addon > Expansion())
{
- data << (uint8)CHAR_CREATE_EXPANSION;
- sLog.outError("Not Expansion 2 account:[%d] but tried to Create character with expansion 2 class (%u)",GetAccountId(),class_);
+ data << (uint8)CHAR_CREATE_EXPANSION_CLASS;
+ sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u class (%u)",Expansion(),GetAccountId(),classEntry->addon,class_);
SendPacket( &data );
return;
}
@@ -311,29 +311,77 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
}
}
+ // speedup check for heroic class disabled case
+ uint32 heroic_free_slots = sWorld.getConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
+ if(heroic_free_slots==0 && GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT)
+ {
+ data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT;
+ SendPacket( &data );
+ return;
+ }
+
+ // speedup check for heroic class disabled case
+ uint32 req_level_for_heroic = sWorld.getConfig(CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING);
+ if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ {
+ data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT;
+ SendPacket( &data );
+ return;
+ }
+
bool AllowTwoSideAccounts = !sWorld.IsPvPRealm() || sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || GetSecurity() > SEC_PLAYER;
uint32 skipCinematics = sWorld.getConfig(CONFIG_SKIP_CINEMATICS);
bool have_same_race = false;
- if(!AllowTwoSideAccounts || skipCinematics == 1)
+
+ // if 0 then allowed creating without any characters
+ bool have_req_level_for_heroic = (req_level_for_heroic==0);
+
+ if(!AllowTwoSideAccounts || skipCinematics == 1 || class_ == CLASS_DEATH_KNIGHT)
{
- QueryResult *result2 = CharacterDatabase.PQuery("SELECT DISTINCT race FROM characters WHERE account = '%u' %s", GetAccountId(),skipCinematics == 1 ? "" : "LIMIT 1");
+ QueryResult *result2 = CharacterDatabase.PQuery("SELECT guid,race,class FROM characters WHERE account = '%u' %s",
+ GetAccountId(), (skipCinematics == 1 || class_ == CLASS_DEATH_KNIGHT) ? "" : "LIMIT 1");
if(result2)
{
uint32 team_= Player::TeamForRace(race_);
Field* field = result2->Fetch();
- uint8 race = field[0].GetUInt32();
+ uint8 acc_race = field[1].GetUInt32();
+
+ if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT)
+ {
+ uint8 acc_class = field[2].GetUInt32();
+ if(acc_class == CLASS_DEATH_KNIGHT)
+ {
+ if(heroic_free_slots > 0)
+ --heroic_free_slots;
+
+ if(heroic_free_slots==0)
+ {
+ data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT;
+ SendPacket( &data );
+ return;
+ }
+ }
+
+ if(!have_req_level_for_heroic)
+ {
+ uint32 acc_guid = field[0].GetUInt32();
+ uint32 acc_level = Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,acc_guid);
+ if(acc_level >= req_level_for_heroic)
+ have_req_level_for_heroic = true;
+ }
+ }
// need to check team only for first character
// TODO: what to if account already has characters of both races?
if (!AllowTwoSideAccounts)
{
- uint32 team=0;
- if(race > 0)
- team = Player::TeamForRace(race);
+ uint32 acc_team=0;
+ if(acc_race > 0)
+ acc_team = Player::TeamForRace(acc_race);
- if(team != team_)
+ if(acc_team != team_)
{
data << (uint8)CHAR_CREATE_PVP_TEAMS_VIOLATION;
SendPacket( &data );
@@ -342,20 +390,55 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
}
}
- if (skipCinematics == 1)
+ // search same race for cinematic or same class if need
+ // TODO: check if cinematic already shown? (already logged in?; cinematic field)
+ while ((skipCinematics == 1 && !have_same_race) || class_ == CLASS_DEATH_KNIGHT)
{
- // TODO: check if cinematic already shown? (already logged in?; cinematic field)
- while (race_ != race && result2->NextRow())
+ if(!result2->NextRow())
+ break;
+
+ field = result2->Fetch();
+ acc_race = field[1].GetUInt32();
+
+ if(!have_same_race)
+ have_same_race = race_ == acc_race;
+
+ if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT)
{
- field = result2->Fetch();
- race = field[0].GetUInt32();
+ uint8 acc_class = field[2].GetUInt32();
+ if(acc_class == CLASS_DEATH_KNIGHT)
+ {
+ if(heroic_free_slots > 0)
+ --heroic_free_slots;
+
+ if(heroic_free_slots==0)
+ {
+ data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT;
+ SendPacket( &data );
+ return;
+ }
+ }
+
+ if(!have_req_level_for_heroic)
+ {
+ uint32 acc_guid = field[0].GetUInt32();
+ uint32 acc_level = Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,acc_guid);
+ if(acc_level >= req_level_for_heroic)
+ have_req_level_for_heroic = true;
+ }
}
- have_same_race = race_ == race;
}
delete result2;
}
}
+ if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && !have_req_level_for_heroic)
+ {
+ data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT;
+ SendPacket( &data );
+ return;
+ }
+
// extract other data required for player creating
uint8 gender, skin, face, hairStyle, hairColor, facialHair, outfitId;
recv_data >> gender >> skin >> face;
@@ -373,7 +456,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
return;
}
- if(have_same_race && skipCinematics == 1 || skipCinematics == 2)
+ if ((have_same_race && skipCinematics == 1) || skipCinematics == 2)
pNewChar->setCinematic(1); // not show intro
// Player created, save it now
@@ -439,7 +522,7 @@ void WorldSession::HandleCharDeleteOpcode( WorldPacket & recv_data )
return;
std::string IP_str = GetRemoteAddress();
- sLog.outDetail("Account: %d (IP: %s) Delete Character:[%s] (guid:%u)",GetAccountId(),IP_str.c_str(),name.c_str(),GUID_LOPART(guid));
+ sLog.outDetail("Account: %d (IP: %s) Delete Character:[%s] (guid: %u)",GetAccountId(),IP_str.c_str(),name.c_str(),GUID_LOPART(guid));
sLog.outChar("Account: %d (IP: %s) Delete Character:[%s] (guid: %u)",GetAccountId(),IP_str.c_str(),name.c_str(),GUID_LOPART(guid));
if(sLog.IsOutCharDump()) // optimize GetPlayerDump call
@@ -514,9 +597,11 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
data << pCurrChar->GetOrientation();
SendPacket(&data);
- data.Initialize( SMSG_ACCOUNT_DATA_TIMES, 128 );
- for(int i = 0; i < 32; i++)
- data << uint32(0);
+ data.Initialize( SMSG_ACCOUNT_DATA_TIMES, 4+1+8*4 ); // changed in WotLK
+ data << uint32(time(NULL)); // unix time of something
+ data << uint8(1);
+ for(int i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
+ data << uint32(GetAccountData(i)->Time); // also unix time
SendPacket(&data);
data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0
@@ -562,6 +647,11 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
DEBUG_LOG( "WORLD: Sent server info" );
}
+ data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4+4);
+ data << uint32(0);
+ data << uint32(0);
+ SendPacket(&data);
+
//QueryResult *result = CharacterDatabase.PQuery("SELECT guildid,rank FROM guild_member WHERE guid = '%u'",pCurrChar->GetGUIDLow());
QueryResult *resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD);
@@ -619,12 +709,12 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
{
pCurrChar->setCinematic(1);
- ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace());
- if(rEntry)
+ if(ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(pCurrChar->getClass()))
{
- data.Initialize( SMSG_TRIGGER_CINEMATIC,4 );
- data << uint32(rEntry->startmovie);
- SendPacket( &data );
+ if (cEntry->CinematicSequence)
+ pCurrChar->SendCinematicStart(cEntry->CinematicSequence);
+ else if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace()))
+ pCurrChar->SendCinematicStart(rEntry->CinematicSequence);
// send new char string if not empty
if (!sWorld.GetNewCharString().empty())
@@ -672,28 +762,11 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)
pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
- //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+41, 8326);
- //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+42, 20584);
- //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAFLAGS+6, 238);
- //pCurrChar->SetUInt32Value(UNIT_FIELD_AURALEVELS+11, 514);
- //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+11, 65535);
- //pCurrChar->SetUInt32Value(UNIT_FIELD_DISPLAYID, 1825);
- //if (pCurrChar->getRace() == RACE_NIGHTELF)
- //{
- // pCurrChar->SetSpeed(MOVE_RUN, 1.5f*1.2f, true);
- // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f*1.2f, true);
- //}
- //else
- //{
- // pCurrChar->SetSpeed(MOVE_RUN, 1.5f, true);
- // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f, true);
- //}
pCurrChar->SetMovement(MOVE_WATER_WALK);
}
if(uint32 sourceNode = pCurrChar->m_taxi.GetTaxiSource())
{
-
sLog.outDebug( "WORLD: Restart character %u taxi flight", pCurrChar->GetGUIDLow() );
uint32 MountId = objmgr.GetTaxiMount(sourceNode, pCurrChar->GetTeam());
@@ -741,13 +814,12 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
SendDoFlight( MountId, path, startNode );
}
- // Load pet if any and player is alive and not in taxi flight
- if(pCurrChar->isAlive() && pCurrChar->m_taxi.GetTaxiSource()==0)
- pCurrChar->LoadPet();
+ // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned)
+ pCurrChar->LoadPet();
// Set FFA PvP for non GM in non-rest mode
if(sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_RESTING) )
- pCurrChar->SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ pCurrChar->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
if(pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP))
pCurrChar->SetContestedPvP();
@@ -795,15 +867,7 @@ void WorldSession::HandleSetFactionAtWar( WorldPacket & recv_data )
recv_data >> repListID;
recv_data >> flag;
- FactionStateList::iterator itr = GetPlayer()->m_factions.find(repListID);
- if (itr == GetPlayer()->m_factions.end())
- return;
-
- // always invisible or hidden faction can't change war state
- if(itr->second.Flags & (FACTION_FLAG_INVISIBLE_FORCED|FACTION_FLAG_HIDDEN) )
- return;
-
- GetPlayer()->SetFactionAtWar(&itr->second,flag);
+ GetPlayer()->GetReputationMgr().SetAtWar(repListID,flag);
}
//I think this function is never used :/ I dunno, but i guess this opcode not exists
@@ -811,7 +875,7 @@ void WorldSession::HandleSetFactionCheat( WorldPacket & /*recv_data*/ )
{
//CHECK_PACKET_SIZE(recv_data,4+4);
- //sLog.outDebug("WORLD SESSION: HandleSetFactionCheat");
+ sLog.outError("WORLD SESSION: HandleSetFactionCheat, not expected call, please report.");
/*
uint32 FactionID;
uint32 Standing;
@@ -831,7 +895,7 @@ void WorldSession::HandleSetFactionCheat( WorldPacket & /*recv_data*/ )
}
}
*/
- GetPlayer()->UpdateReputation();
+ GetPlayer()->GetReputationMgr().SendStates();
}
void WorldSession::HandleMeetingStoneInfo( WorldPacket & /*recv_data*/ )
@@ -867,14 +931,14 @@ void WorldSession::HandleTutorialFlag( WorldPacket & recv_data )
void WorldSession::HandleTutorialClear( WorldPacket & /*recv_data*/ )
{
- for ( uint32 iI = 0; iI < 8; iI++)
- GetPlayer()->SetTutorialInt( iI, 0xFFFFFFFF );
+ for (int i = 0; i < 8; ++i)
+ GetPlayer()->SetTutorialInt( i, 0xFFFFFFFF );
}
void WorldSession::HandleTutorialReset( WorldPacket & /*recv_data*/ )
{
- for ( uint32 iI = 0; iI < 8; iI++)
- GetPlayer()->SetTutorialInt( iI, 0x00000000 );
+ for (int i = 0; i < 8; ++i)
+ GetPlayer()->SetTutorialInt( i, 0x00000000 );
}
void WorldSession::HandleSetWatchedFactionIndexOpcode(WorldPacket & recv_data)
@@ -896,11 +960,7 @@ void WorldSession::HandleSetWatchedFactionInactiveOpcode(WorldPacket & recv_data
uint8 inactive;
recv_data >> replistid >> inactive;
- FactionStateList::iterator itr = _player->m_factions.find(replistid);
- if (itr == _player->m_factions.end())
- return;
-
- _player->SetFactionInactive(&itr->second, inactive);
+ _player->GetReputationMgr().SetInactive(replistid, inactive);
}
void WorldSession::HandleToggleHelmOpcode( WorldPacket & /*recv_data*/ )
@@ -917,11 +977,11 @@ void WorldSession::HandleToggleCloakOpcode( WorldPacket & /*recv_data*/ )
void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)
{
+ CHECK_PACKET_SIZE(recv_data, 8+1);
+
uint64 guid;
std::string newname;
- CHECK_PACKET_SIZE(recv_data, 8+1);
-
recv_data >> guid;
recv_data >> newname;
@@ -929,15 +989,15 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)
if(!normalizePlayerName(newname))
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
- data << (uint8)CHAR_NAME_NO_NAME;
+ data << uint8(CHAR_NAME_NO_NAME);
SendPacket( &data );
return;
}
- if(!ObjectMgr::IsValidName(newname,true))
+ if(!ObjectMgr::IsValidName(newname, true))
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
- data << (uint8)CHAR_NAME_INVALID_CHARACTER;
+ data << uint8(CHAR_NAME_INVALID_CHARACTER);
SendPacket( &data );
return;
}
@@ -946,7 +1006,7 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)
if(GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(newname))
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
- data << (uint8)CHAR_NAME_RESERVED;
+ data << uint8(CHAR_NAME_RESERVED);
SendPacket( &data );
return;
}
@@ -975,7 +1035,7 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uin
if (!result)
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
- data << (uint8)CHAR_CREATE_ERROR;
+ data << uint8(CHAR_CREATE_ERROR);
session->SendPacket( &data );
return;
}
@@ -989,11 +1049,11 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uin
CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME), guidLow);
CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", guidLow);
- sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s",session->GetAccountId(), session->GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str());
+ sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", session->GetAccountId(), session->GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str());
- WorldPacket data(SMSG_CHAR_RENAME,1+8+(newname.size()+1));
- data << (uint8)RESPONSE_SUCCESS;
- data << guid;
+ WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newname.size()+1));
+ data << uint8(RESPONSE_SUCCESS);
+ data << uint64(guid);
data << newname;
session->SendPacket(&data);
}
@@ -1088,3 +1148,170 @@ void WorldSession::HandleDeclinedPlayerNameOpcode(WorldPacket& recv_data)
SendPacket(&data);
}
+void WorldSession::HandleAlterAppearance( WorldPacket & recv_data )
+{
+ sLog.outDebug("CMSG_ALTER_APPEARANCE");
+
+ CHECK_PACKET_SIZE(recv_data, 4+4+4);
+
+ uint32 Hair, Color, FacialHair;
+ recv_data >> Hair >> Color >> FacialHair;
+
+ BarberShopStyleEntry const* bs_hair = sBarberShopStyleStore.LookupEntry(Hair);
+
+ if(!bs_hair || bs_hair->type != 0 || bs_hair->race != _player->getRace() || bs_hair->gender != _player->getGender())
+ return;
+
+ BarberShopStyleEntry const* bs_facialHair = sBarberShopStyleStore.LookupEntry(FacialHair);
+
+ if(!bs_facialHair || bs_facialHair->type != 2 || bs_facialHair->race != _player->getRace() || bs_facialHair->gender != _player->getGender())
+ return;
+
+ uint32 Cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id);
+
+ // 0 - ok
+ // 1,3 - not enough money
+ // 2 - you have to seat on barber chair
+ if(_player->GetMoney() < Cost)
+ {
+ WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4);
+ data << uint32(1); // no money
+ SendPacket(&data);
+ return;
+ }
+ else
+ {
+ WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4);
+ data << uint32(0); // ok
+ SendPacket(&data);
+ }
+
+ _player->ModifyMoney(-int32(Cost)); // it isn't free
+ _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER, Cost);
+
+ _player->SetByteValue(PLAYER_BYTES, 2, uint8(bs_hair->hair_id));
+ _player->SetByteValue(PLAYER_BYTES, 3, uint8(Color));
+ _player->SetByteValue(PLAYER_BYTES_2, 0, uint8(bs_facialHair->hair_id));
+
+ _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, 1);
+
+ _player->SetStandState(0); // stand up
+}
+
+void WorldSession::HandleRemoveGlyph( WorldPacket & recv_data )
+{
+ CHECK_PACKET_SIZE(recv_data, 4);
+
+ uint32 slot;
+ recv_data >> slot;
+
+ if(slot >= MAX_GLYPH_SLOT_INDEX)
+ {
+ sLog.outDebug("Client sent wrong glyph slot number in opcode CMSG_REMOVE_GLYPH %u", slot);
+ return;
+ }
+
+ if(uint32 glyph = _player->GetGlyph(slot))
+ {
+ if(GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph))
+ {
+ _player->RemoveAurasDueToSpell(gp->SpellId);
+ _player->SetGlyph(slot, 0);
+ }
+ }
+}
+
+void WorldSession::HandleCharCustomize(WorldPacket& recv_data)
+{
+ CHECK_PACKET_SIZE(recv_data, 8+1);
+
+ uint64 guid;
+ std::string newname;
+
+ recv_data >> guid;
+ recv_data >> newname;
+
+ CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1+1+1+1+1);
+
+ uint8 gender, skin, face, hairStyle, hairColor, facialHair;
+ recv_data >> gender >> skin >> hairColor >> hairStyle >> facialHair >> face;
+
+ QueryResult *result = CharacterDatabase.PQuery("SELECT at_login FROM characters WHERE guid ='%u'", GUID_LOPART(guid));
+ if (!result)
+ {
+ WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
+ data << uint8(CHAR_CREATE_ERROR);
+ SendPacket( &data );
+ return;
+ }
+
+ Field *fields = result->Fetch();
+ uint32 at_loginFlags = fields[0].GetUInt32();
+ delete result;
+
+ if (!(at_loginFlags & AT_LOGIN_CUSTOMIZE))
+ {
+ WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
+ data << uint8(CHAR_CREATE_ERROR);
+ SendPacket( &data );
+ return;
+ }
+
+ // prevent character rename to invalid name
+ if(!normalizePlayerName(newname))
+ {
+ WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
+ data << uint8(CHAR_NAME_NO_NAME);
+ SendPacket( &data );
+ return;
+ }
+
+ if(!ObjectMgr::IsValidName(newname,true))
+ {
+ WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
+ data << uint8(CHAR_NAME_INVALID_CHARACTER);
+ SendPacket( &data );
+ return;
+ }
+
+ // check name limitations
+ if(GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(newname))
+ {
+ WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
+ data << uint8(CHAR_NAME_RESERVED);
+ SendPacket( &data );
+ return;
+ }
+
+ // character with this name already exist
+ if(uint64 newguid = objmgr.GetPlayerGUIDByName(newname))
+ {
+ if(newguid != guid)
+ {
+ WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
+ data << uint8(CHAR_CREATE_NAME_IN_USE);
+ SendPacket( &data );
+ return;
+ }
+ }
+
+ CharacterDatabase.escape_string(newname);
+ Player::Customize(guid, gender, skin, face, hairStyle, hairColor, facialHair);
+ CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_CUSTOMIZE), GUID_LOPART(guid));
+ CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", GUID_LOPART(guid));
+
+ std::string IP_str = GetRemoteAddress();
+ sLog.outChar("Account: %d (IP: %s), Character guid: %u Customized to: %s", GetAccountId(), IP_str.c_str(), GUID_LOPART(guid), newname.c_str());
+
+ WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1+8+(newname.size()+1)+6);
+ data << uint8(RESPONSE_SUCCESS);
+ data << uint64(guid);
+ data << newname;
+ data << uint8(gender);
+ data << uint8(skin);
+ data << uint8(face);
+ data << uint8(hairStyle);
+ data << uint8(hairColor);
+ data << uint8(facialHair);
+ SendPacket(&data);
+}
diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
index 15206f10c29..c2293fb8848 100644
--- a/src/game/Chat.cpp
+++ b/src/game/Chat.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -30,11 +30,28 @@
#include "Player.h"
#include "UpdateMask.h"
#include "Chat.h"
-#include "MapManager.h"
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
+#include "AccountMgr.h"
#include "TicketMgr.h"
+// Supported shift-links (client generated and server side)
+// |color|Harea:area_id|h[name]|h|r
+// |color|Hcreature:creature_guid|h[name]|h|r
+// |color|Hcreature_entry:creature_id|h[name]|h|r
+// |color|Hgameevent:id|h[name]|h|r
+// |color|Hgameobject:go_guid|h[name]|h|r
+// |color|Hgameobject_entry:go_id|h[name]|h|r
+// |color|Hitem:item_id:perm_ench_id:0:0|h[name]|h|r
+// |color|Hitemset:itemset_id|h[name]|h|r
+// |color|Hplayer:name|h[name]|h|r - client, in some messages, at click copy only name instead link
+// |color|Hquest:quest_id|h[name]|h|r
+// |color|Hskill:skill_id|h[name]|h|r
+// |color|Hspell:spell_id|h[name]|h|r - client, spellbook spell icon shift-click
+// |color|Htalent:talent_id,rank|h[name]|h|r - client, talent icon shift-click
+// |color|Htele:id|h[name]|h|r
+// |color|Htrade:spell_id,cur_value,max_value,unk3int,unk3str|h[name]|h|r - client, spellbook profession icon shift-click
+
bool ChatHandler::load_command_table = true;
ChatCommand * ChatHandler::getCommandTable()
@@ -52,168 +69,189 @@ ChatCommand * ChatHandler::getCommandTable()
{ "create", SEC_CONSOLE, true, &ChatHandler::HandleAccountCreateCommand, "", NULL },
{ "delete", SEC_CONSOLE, true, &ChatHandler::HandleAccountDeleteCommand, "", NULL },
{ "onlinelist", SEC_CONSOLE, true, &ChatHandler::HandleAccountOnlineListCommand, "", NULL },
+ { "lock", SEC_PLAYER, false, &ChatHandler::HandleAccountLockCommand, "", NULL },
{ "set", SEC_ADMINISTRATOR, true, NULL, "", accountSetCommandTable },
+ { "password", SEC_PLAYER, false, &ChatHandler::HandleAccountPasswordCommand, "", NULL },
{ "", SEC_PLAYER, false, &ChatHandler::HandleAccountCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand serverSetCommandTable[] =
+ static ChatCommand banCommandTable[] =
{
- { "loglevel", SEC_CONSOLE, true, &ChatHandler::HandleServerSetLogLevelCommand, "", NULL },
- { "difftime", SEC_CONSOLE, true, &ChatHandler::HandleServerSetDiffTimeCommand, "", NULL },
- { "motd", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerSetMotdCommand, "", NULL },
+ { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanAccountCommand, "", NULL },
+ { "character", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanCharacterCommand, "", NULL },
+ { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanIPCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand serverIdleRestartCommandTable[] =
+ static ChatCommand baninfoCommandTable[] =
{
- { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
- { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerIdleRestartCommand, "", NULL },
+ { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanInfoAccountCommand, "", NULL },
+ { "character", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanInfoCharacterCommand, "", NULL },
+ { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanInfoIPCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand serverIdleShutdownCommandTable[] =
+ static ChatCommand banlistCommandTable[] =
{
- { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
- { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerIdleShutDownCommand, "", NULL },
+ { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanListAccountCommand, "", NULL },
+ { "character", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanListCharacterCommand, "", NULL },
+ { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanListIPCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand serverRestartCommandTable[] =
+ static ChatCommand castCommandTable[] =
{
- { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
- { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerRestartCommand, "", NULL },
+ { "back", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastBackCommand, "", NULL },
+ { "dist", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastDistCommand, "", NULL },
+ { "self", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastSelfCommand, "", NULL },
+ { "target", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastTargetCommand, "", NULL },
+ { "", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand serverShutdownCommandTable[] =
+ static ChatCommand characterCommandTable[] =
{
- { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
- { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCommand, "", NULL },
+ { "customize", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterCustomizeCommand, "", NULL },
+ { "delete", SEC_CONSOLE, true, &ChatHandler::HandleCharacterDeleteCommand, "", NULL },
+ { "level", SEC_ADMINISTRATOR, true, &ChatHandler::HandleCharacterLevelCommand, "", NULL },
+ { "rename", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterRenameCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand serverCommandTable[] =
+ static ChatCommand debugPlayCommandTable[] =
{
- { "corpses", SEC_GAMEMASTER, true, &ChatHandler::HandleServerCorpsesCommand, "", NULL },
- { "exit", SEC_CONSOLE, true, &ChatHandler::HandleServerExitCommand, "", 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, NULL, "", serverRestartCommandTable },
- { "shutdown", SEC_ADMINISTRATOR, true, NULL, "", serverShutdownCommandTable },
- { "set", SEC_ADMINISTRATOR, true, NULL, "", serverSetCommandTable },
- { NULL, 0, false, NULL, "", NULL }
+ { "cinematic", SEC_MODERATOR, false, &ChatHandler::HandleDebugPlayCinematicCommand, "", NULL },
+ { "movie", SEC_MODERATOR, false, &ChatHandler::HandleDebugPlayMovieCommand, "", NULL },
+ { "sound", SEC_MODERATOR, false, &ChatHandler::HandleDebugPlaySoundCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand modifyCommandTable[] =
+ static ChatCommand debugSendCommandTable[] =
{
- { "hp", SEC_MODERATOR, false, &ChatHandler::HandleModifyHPCommand, "", NULL },
- { "mana", SEC_MODERATOR, false, &ChatHandler::HandleModifyManaCommand, "", NULL },
- { "rage", SEC_MODERATOR, false, &ChatHandler::HandleModifyRageCommand, "", NULL },
- { "energy", SEC_MODERATOR, false, &ChatHandler::HandleModifyEnergyCommand, "", NULL },
- { "money", SEC_MODERATOR, false, &ChatHandler::HandleModifyMoneyCommand, "", NULL },
- { "speed", SEC_MODERATOR, false, &ChatHandler::HandleModifySpeedCommand, "", NULL },
- { "swim", SEC_MODERATOR, false, &ChatHandler::HandleModifySwimCommand, "", NULL },
- { "scale", SEC_MODERATOR, false, &ChatHandler::HandleModifyScaleCommand, "", NULL },
- { "bit", SEC_MODERATOR, false, &ChatHandler::HandleModifyBitCommand, "", NULL },
- { "bwalk", SEC_MODERATOR, false, &ChatHandler::HandleModifyBWalkCommand, "", NULL },
- { "fly", SEC_MODERATOR, false, &ChatHandler::HandleModifyFlyCommand, "", NULL },
- { "aspeed", SEC_MODERATOR, false, &ChatHandler::HandleModifyASpeedCommand, "", NULL },
- { "faction", SEC_MODERATOR, false, &ChatHandler::HandleModifyFactionCommand, "", NULL },
- { "spell", SEC_MODERATOR, false, &ChatHandler::HandleModifySpellCommand, "", NULL },
- { "tp", SEC_MODERATOR, false, &ChatHandler::HandleModifyTalentCommand, "", NULL },
- { "titles", SEC_MODERATOR, false, &ChatHandler::HandleModifyKnownTitlesCommand, "", NULL },
- { "mount", SEC_MODERATOR, false, &ChatHandler::HandleModifyMountCommand, "", NULL },
- { "honor", SEC_MODERATOR, false, &ChatHandler::HandleModifyHonorCommand, "", NULL },
- { "rep", SEC_MODERATOR, false, &ChatHandler::HandleModifyRepCommand, "", NULL },
- { "arena", SEC_MODERATOR, false, &ChatHandler::HandleModifyArenaCommand, "", NULL },
- { "drunk", SEC_MODERATOR, false, &ChatHandler::HandleDrunkCommand, "", NULL },
- { "standstate", SEC_GAMEMASTER, false, &ChatHandler::HandleStandStateCommand, "", NULL },
- { "morph", SEC_GAMEMASTER, false, &ChatHandler::HandleMorphCommand, "", NULL },
- { "gender", SEC_ADMINISTRATOR, false, &ChatHandler::HandleModifyGenderCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "buyerror", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendBuyErrorCommand, "", NULL },
+ { "channelnotify", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendChannelNotifyCommand, "", NULL },
+ { "chatmmessage", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendChatMsgCommand, "", NULL },
+ { "equiperror", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendEquipErrorCommand, "", NULL },
+ { "largepacket", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendLargePacketCommand, "", NULL },
+ { "opcode", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendOpcodeCommand, "", NULL },
+ { "poi", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendPoiCommand, "", NULL },
+ { "qpartymsg", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendQuestPartyMsgCommand, "", NULL },
+ { "qinvalidmsg", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendQuestInvalidMsgCommand, "", NULL },
+ { "sellerror", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendSellErrorCommand, "", NULL },
+ { "setphaseshift", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendSetPhaseShiftCommand, "", NULL },
+ { "spellfail", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendSpellFailCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand wpCommandTable[] =
+ static ChatCommand debugCommandTable[] =
{
- { "show", SEC_GAMEMASTER, false, &ChatHandler::HandleWpShowCommand, "", NULL },
- { "addwp", SEC_GAMEMASTER, false, &ChatHandler::HandleWpAddCommand, "", NULL },
- { "load", SEC_GAMEMASTER, false, &ChatHandler::HandleWpLoadPathCommand, "", NULL },
- { "modify", SEC_GAMEMASTER, false, &ChatHandler::HandleWpModifyCommand, "", NULL },
- { "event", SEC_GAMEMASTER, false, &ChatHandler::HandleWpEventCommand, "", NULL },
- { "unload", SEC_GAMEMASTER, false, &ChatHandler::HandleWpUnLoadPathCommand, "", NULL },
+ { "setbit", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSet32Bit, "", NULL },
+ { "threat", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugThreatList, "", NULL },
+ { "hostil", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugHostilRefList, "", NULL },
+ { "anim", SEC_GAMEMASTER, false, &ChatHandler::HandleDebugAnimCommand, "", NULL },
+ { "arena", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugArenaCommand, "", NULL },
+ { "bg", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugBattlegroundCommand, "", NULL },
+ { "getitemstate", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugGetItemState, "", NULL },
+ { "lootrecipient", SEC_GAMEMASTER, false, &ChatHandler::HandleDebugGetLootRecipient, "", NULL },
+ { "getvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugGetValue, "", NULL },
+ { "Mod32Value", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugMod32Value, "", NULL },
+ { "play", SEC_MODERATOR, false, NULL, "", debugPlayCommandTable },
+ { "send", SEC_ADMINISTRATOR, false, NULL, "", debugSendCommandTable },
+ { "setitemflag", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetItemFlagCommand, "", NULL },
+ { "setvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetValue, "", NULL },
+ { "spawnvehicle", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSpawnVehicle, "", NULL },
+ { "setvid", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetVehicleId, "", NULL },
+ { "entervehicle", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugEnterVehicle, "", NULL },
+ { "uws", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugUpdateWorldStateCommand, "", NULL },
+ { "update", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugUpdate, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+ static ChatCommand eventCommandTable[] =
+ {
+ { "activelist", SEC_GAMEMASTER, true, &ChatHandler::HandleEventActiveListCommand, "", NULL },
+ { "start", SEC_GAMEMASTER, true, &ChatHandler::HandleEventStartCommand, "", NULL },
+ { "stop", SEC_GAMEMASTER, true, &ChatHandler::HandleEventStopCommand, "", NULL },
+ { "", SEC_GAMEMASTER, true, &ChatHandler::HandleEventInfoCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
-
- static ChatCommand banCommandTable[] =
+ static ChatCommand gmCommandTable[] =
{
- { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanAccountCommand, "", NULL },
- { "character", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanCharacterCommand, "", NULL },
- { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanIPCommand, "", NULL },
+ { "chat", SEC_MODERATOR, false, &ChatHandler::HandleGMChatCommand, "", NULL },
+ { "fly", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGMFlyCommand, "", NULL },
+ { "ingame", SEC_PLAYER, true, &ChatHandler::HandleGMListIngameCommand, "", NULL },
+ { "list", SEC_ADMINISTRATOR, true, &ChatHandler::HandleGMListFullCommand, "", NULL },
+ { "visible", SEC_MODERATOR, false, &ChatHandler::HandleGMVisibleCommand, "", NULL },
+ { "", SEC_MODERATOR, false, &ChatHandler::HandleGMCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand baninfoCommandTable[] =
+ static ChatCommand goCommandTable[] =
{
- { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanInfoAccountCommand, "", NULL },
- { "character", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanInfoCharacterCommand, "", NULL },
- { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanInfoIPCommand, "", NULL },
+ { "creature", SEC_MODERATOR, false, &ChatHandler::HandleGoCreatureCommand, "", NULL },
+ { "graveyard", SEC_MODERATOR, false, &ChatHandler::HandleGoGraveyardCommand, "", NULL },
+ { "grid", SEC_MODERATOR, false, &ChatHandler::HandleGoGridCommand, "", NULL },
+ { "object", SEC_MODERATOR, false, &ChatHandler::HandleGoObjectCommand, "", NULL },
+ { "trigger", SEC_MODERATOR, false, &ChatHandler::HandleGoTriggerCommand, "", NULL },
+ { "zonexy", SEC_MODERATOR, false, &ChatHandler::HandleGoZoneXYCommand, "", NULL },
+ { "xy", SEC_MODERATOR, false, &ChatHandler::HandleGoXYCommand, "", NULL },
+ { "xyz", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL },
+ { "", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL },
+
+ { "ticket", SEC_MODERATOR, false, &ChatHandler::HandleGoTicketCommand, "", NULL },
+
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand banlistCommandTable[] =
+ static ChatCommand gobjectCommandTable[] =
{
- { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanListAccountCommand, "", NULL },
- { "character", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanListCharacterCommand, "", NULL },
- { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanListIPCommand, "", NULL },
+ { "activate", SEC_GAMEMASTER, false, &ChatHandler::HandleActivateObjectCommand, "", NULL },
+ { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectAddCommand, "", NULL },
+ { "delete", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectDeleteCommand, "", NULL },
+ { "move", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectMoveCommand, "", NULL },
+ { "near", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectNearCommand, "", NULL },
+ { "state", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectStateCommand, "", NULL },
+ { "setphase", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectPhaseCommand, "", NULL },
+ { "target", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectTargetCommand, "", NULL },
+ { "tempadd", SEC_GAMEMASTER, false, &ChatHandler::HandleTempGameObjectCommand, "", NULL },
+ { "turn", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectTurnCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand unbanCommandTable[] =
+ static ChatCommand groupCommandTable[] =
{
- { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleUnBanAccountCommand, "", NULL },
- { "character", SEC_ADMINISTRATOR, true, &ChatHandler::HandleUnBanCharacterCommand, "", NULL },
- { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleUnBanIPCommand, "", NULL },
+ { "leader", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGroupLeaderCommand, "", NULL },
+ { "disband", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGroupDisbandCommand, "", NULL },
+ { "remove", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGroupRemoveCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand guildCommandTable[] =
+ {
+ { "create", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildCreateCommand, "", NULL },
+ { "delete", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildDeleteCommand, "", NULL },
+ { "invite", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildInviteCommand, "", NULL },
+ { "uninvite", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildUninviteCommand, "", NULL },
+ { "rank", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildRankCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand debugCommandTable[] =
+ static ChatCommand honorCommandTable[] =
{
- { "inarc", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugInArcCommand, "", NULL },
- { "spellfail", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSpellFailCommand, "", NULL },
- { "setpoi", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSetPoiCommand, "", NULL },
- { "qpartymsg", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendQuestPartyMsgCommand, "", NULL },
- { "qinvalidmsg", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendQuestInvalidMsgCommand, "", NULL },
- { "equiperr", SEC_ADMINISTRATOR, false, &ChatHandler::HandleEquipErrorCommand, "", NULL },
- { "sellerr", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSellErrorCommand, "", NULL },
- { "buyerr", SEC_ADMINISTRATOR, false, &ChatHandler::HandleBuyErrorCommand, "", NULL },
- { "sendopcode", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendOpcodeCommand, "", NULL },
- { "uws", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUpdateWorldStateCommand, "", NULL },
- { "ps", SEC_ADMINISTRATOR, false, &ChatHandler::HandlePlaySound2Command, "", NULL },
- { "scn", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendChannelNotifyCommand, "", NULL },
- { "scm", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendChatMsgCommand, "", NULL },
- { "getitemstate", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGetItemState, "", NULL },
- { "playsound", SEC_MODERATOR, false, &ChatHandler::HandlePlaySoundCommand, "", NULL },
- { "update", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUpdate, "", NULL },
- { "setvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSetValue, "", NULL },
- { "getvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGetValue, "", NULL },
- { "Mod32Value", SEC_ADMINISTRATOR, false, &ChatHandler::HandleMod32Value, "", NULL },
- { "anim", SEC_GAMEMASTER, false, &ChatHandler::HandleAnimCommand, "", NULL },
- { "lootrecipient", SEC_GAMEMASTER, false, &ChatHandler::HandleGetLootRecipient, "", NULL },
- { "arena", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugArenaCommand, "", NULL },
+ { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleHonorAddCommand, "", NULL },
+ { "addkill", SEC_GAMEMASTER, false, &ChatHandler::HandleHonorAddKillCommand, "", NULL },
+ { "update", SEC_GAMEMASTER, false, &ChatHandler::HandleHonorUpdateCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand eventCommandTable[] =
+ static ChatCommand instanceCommandTable[] =
{
- { "activelist", SEC_GAMEMASTER, true, &ChatHandler::HandleEventActiveListCommand, "", NULL },
- { "start", SEC_GAMEMASTER, true, &ChatHandler::HandleEventStartCommand, "", NULL },
- { "stop", SEC_GAMEMASTER, true, &ChatHandler::HandleEventStopCommand, "", NULL },
- { "", SEC_GAMEMASTER, true, &ChatHandler::HandleEventInfoCommand, "", NULL },
+ { "listbinds", SEC_ADMINISTRATOR, false, &ChatHandler::HandleInstanceListBindsCommand, "", NULL },
+ { "unbind", SEC_ADMINISTRATOR, false, &ChatHandler::HandleInstanceUnbindCommand, "", NULL },
+ { "stats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleInstanceStatsCommand, "", NULL },
+ { "savedata", SEC_ADMINISTRATOR, false, &ChatHandler::HandleInstanceSaveDataCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
@@ -225,6 +263,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "all_default", SEC_MODERATOR, false, &ChatHandler::HandleLearnAllDefaultCommand, "", NULL },
{ "all_lang", SEC_MODERATOR, false, &ChatHandler::HandleLearnAllLangCommand, "", NULL },
{ "all_myclass", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllMyClassCommand, "", NULL },
+ { "all_mypettalents",SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllMyPetTalentsCommand,"", NULL },
{ "all_myspells", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllMySpellsCommand, "", NULL },
{ "all_mytalents", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllMyTalentsCommand, "", NULL },
{ "all_recipes", SEC_GAMEMASTER, false, &ChatHandler::HandleLearnAllRecipesCommand, "", NULL },
@@ -232,9 +271,140 @@ ChatCommand * ChatHandler::getCommandTable()
{ NULL, 0, false, NULL, "", NULL }
};
+ static ChatCommand listCommandTable[] =
+ {
+ { "creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleListCreatureCommand, "", NULL },
+ { "item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleListItemCommand, "", NULL },
+ { "object", SEC_ADMINISTRATOR, true, &ChatHandler::HandleListObjectCommand, "", NULL },
+ { "auras", SEC_ADMINISTRATOR, false, &ChatHandler::HandleListAurasCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand lookupPlayerCommandTable[] =
+ {
+ { "ip", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerIpCommand, "", NULL },
+ { "account", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerAccountCommand, "", NULL },
+ { "email", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerEmailCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand lookupCommandTable[] =
+ {
+ { "area", SEC_MODERATOR, true, &ChatHandler::HandleLookupAreaCommand, "", NULL },
+ { "creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupCreatureCommand, "", NULL },
+ { "event", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupEventCommand, "", NULL },
+ { "faction", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupFactionCommand, "", NULL },
+ { "item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupItemCommand, "", NULL },
+ { "itemset", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupItemSetCommand, "", NULL },
+ { "object", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupObjectCommand, "", NULL },
+ { "quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupQuestCommand, "", NULL },
+ { "player", SEC_GAMEMASTER, true, NULL, "", lookupPlayerCommandTable },
+ { "skill", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupSkillCommand, "", NULL },
+ { "spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupSpellCommand, "", NULL },
+ { "tele", SEC_MODERATOR, true, &ChatHandler::HandleLookupTeleCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand modifyCommandTable[] =
+ {
+ { "hp", SEC_MODERATOR, false, &ChatHandler::HandleModifyHPCommand, "", NULL },
+ { "mana", SEC_MODERATOR, false, &ChatHandler::HandleModifyManaCommand, "", NULL },
+ { "rage", SEC_MODERATOR, false, &ChatHandler::HandleModifyRageCommand, "", NULL },
+ { "runicpower", SEC_MODERATOR, false, &ChatHandler::HandleModifyRunicPowerCommand, "", NULL },
+ { "energy", SEC_MODERATOR, false, &ChatHandler::HandleModifyEnergyCommand, "", NULL },
+ { "money", SEC_MODERATOR, false, &ChatHandler::HandleModifyMoneyCommand, "", NULL },
+ { "speed", SEC_MODERATOR, false, &ChatHandler::HandleModifySpeedCommand, "", NULL },
+ { "swim", SEC_MODERATOR, false, &ChatHandler::HandleModifySwimCommand, "", NULL },
+ { "scale", SEC_MODERATOR, false, &ChatHandler::HandleModifyScaleCommand, "", NULL },
+ { "bit", SEC_MODERATOR, false, &ChatHandler::HandleModifyBitCommand, "", NULL },
+ { "bwalk", SEC_MODERATOR, false, &ChatHandler::HandleModifyBWalkCommand, "", NULL },
+ { "fly", SEC_MODERATOR, false, &ChatHandler::HandleModifyFlyCommand, "", NULL },
+ { "aspeed", SEC_MODERATOR, false, &ChatHandler::HandleModifyASpeedCommand, "", NULL },
+ { "faction", SEC_MODERATOR, false, &ChatHandler::HandleModifyFactionCommand, "", NULL },
+ { "spell", SEC_MODERATOR, false, &ChatHandler::HandleModifySpellCommand, "", NULL },
+ { "tp", SEC_MODERATOR, false, &ChatHandler::HandleModifyTalentCommand, "", NULL },
+ { "titles", SEC_MODERATOR, false, &ChatHandler::HandleModifyKnownTitlesCommand, "", NULL },
+ { "mount", SEC_MODERATOR, false, &ChatHandler::HandleModifyMountCommand, "", NULL },
+ { "honor", SEC_MODERATOR, false, &ChatHandler::HandleModifyHonorCommand, "", NULL },
+ { "rep", SEC_GAMEMASTER, false, &ChatHandler::HandleModifyRepCommand, "", NULL },
+ { "arena", SEC_MODERATOR, false, &ChatHandler::HandleModifyArenaCommand, "", NULL },
+ { "drunk", SEC_MODERATOR, false, &ChatHandler::HandleModifyDrunkCommand, "", NULL },
+ { "standstate", SEC_GAMEMASTER, false, &ChatHandler::HandleModifyStandStateCommand, "", NULL },
+ { "morph", SEC_GAMEMASTER, false, &ChatHandler::HandleModifyMorphCommand, "", NULL },
+ { "phase", SEC_ADMINISTRATOR, false, &ChatHandler::HandleModifyPhaseCommand, "", NULL },
+ { "gender", SEC_GAMEMASTER, false, &ChatHandler::HandleModifyGenderCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand npcCommandTable[] =
+ {
+ { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddCommand, "", NULL },
+ { "additem", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddVendorItemCommand, "", NULL },
+ { "addmove", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddMoveCommand, "", NULL },
+ { "allowmove", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcAllowMovementCommand, "", NULL },
+ { "changeentry", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcChangeEntryCommand, "", NULL },
+ { "changelevel", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcChangeLevelCommand, "", NULL },
+ { "delete", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcDeleteCommand, "", NULL },
+ { "delitem", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcDelVendorItemCommand, "", NULL },
+ { "factionid", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFactionIdCommand, "", NULL },
+ { "flag", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFlagCommand, "", NULL },
+ { "follow", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFollowCommand, "", NULL },
+ { "info", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcInfoCommand, "", NULL },
+ { "move", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcMoveCommand, "", NULL },
+ { "playemote", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcPlayEmoteCommand, "", NULL },
+ { "setmodel", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetModelCommand, "", NULL },
+ { "setmovetype", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetMoveTypeCommand, "", NULL },
+ { "setphase", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetPhaseCommand, "", NULL },
+ { "spawndist", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSpawnDistCommand, "", NULL },
+ { "spawntime", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSpawnTimeCommand, "", NULL },
+ { "say", SEC_MODERATOR, false, &ChatHandler::HandleNpcSayCommand, "", NULL },
+ { "textemote", SEC_MODERATOR, false, &ChatHandler::HandleNpcTextEmoteCommand, "", NULL },
+ { "unfollow", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcUnFollowCommand, "", NULL },
+ { "whisper", SEC_MODERATOR, false, &ChatHandler::HandleNpcWhisperCommand, "", NULL },
+ { "yell", SEC_MODERATOR, false, &ChatHandler::HandleNpcYellCommand, "", NULL },
+ { "tempadd", SEC_GAMEMASTER, false, &ChatHandler::HandleTempAddSpwCommand, "", NULL },
+ { "tame", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcTameCommand, "", NULL },
+ { "setdeathstate", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetDeathStateCommand, "", NULL },
+ { "addformation", SEC_MODERATOR, false, &ChatHandler::HandleNpcAddFormationCommand, "", NULL },
+
+ //{ TODO: fix or remove this commands
+ { "addweapon", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcAddWeaponCommand, "", NULL },
+ { "name", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcNameCommand, "", NULL },
+ { "subname", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSubNameCommand, "", NULL },
+ //}
+
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand petCommandTable[] =
+ {
+ { "create", SEC_GAMEMASTER, false, &ChatHandler::HandleCreatePetCommand, "", NULL },
+ { "learn", SEC_GAMEMASTER, false, &ChatHandler::HandlePetLearnCommand, "", NULL },
+ { "unlearn", SEC_GAMEMASTER, false, &ChatHandler::HandlePetUnlearnCommand, "", NULL },
+ { "tp", SEC_GAMEMASTER, false, &ChatHandler::HandlePetTpCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand pdumpCommandTable[] =
+ {
+ { "load", SEC_ADMINISTRATOR, true, &ChatHandler::HandlePDumpLoadCommand, "", NULL },
+ { "write", SEC_ADMINISTRATOR, true, &ChatHandler::HandlePDumpWriteCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand questCommandTable[] =
+ {
+ { "add", SEC_ADMINISTRATOR, false, &ChatHandler::HandleQuestAdd, "", NULL },
+ { "complete", SEC_ADMINISTRATOR, false, &ChatHandler::HandleQuestComplete, "", NULL },
+ { "remove", SEC_ADMINISTRATOR, false, &ChatHandler::HandleQuestRemove, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
static ChatCommand reloadCommandTable[] =
{
{ "all", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllCommand, "", NULL },
+ { "all_achievement",SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllAchievementCommand,"", NULL },
+ { "all_area", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllAreaCommand, "", NULL },
{ "all_loot", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllLootCommand, "", NULL },
{ "all_npc", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllNpcCommand, "", NULL },
{ "all_quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllQuestCommand, "", NULL },
@@ -245,6 +415,8 @@ ChatCommand * ChatHandler::getCommandTable()
{ "config", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadConfigCommand, "", NULL },
+ { "achievement_criteria_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAchievementCriteriaDataCommand, "", NULL },
+ { "achievement_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAchievementRewardCommand, "", NULL },
{ "areatrigger_tavern", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAreaTriggerTavernCommand, "", NULL },
{ "areatrigger_teleport", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAreaTriggerTeleportCommand, "", NULL },
{ "access_requirement", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAccessRequirementCommand, "", NULL },
@@ -266,13 +438,23 @@ ChatCommand * ChatHandler::getCommandTable()
{ "gameobject_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameObjectScriptsCommand, "", NULL },
{ "item_enchantment_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemEnchantementsCommand, "", NULL },
{ "item_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL },
- { "trinity_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadTrinityStringCommand, "", NULL },
+ { "locales_achievement_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesAchievementRewardCommand,"", NULL },
+ { "locales_creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesCreatureCommand, "", NULL },
+ { "locales_gameobject", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesGameobjectCommand, "", NULL },
+ { "locales_item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesItemCommand, "", NULL },
+ { "locales_npc_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesNpcTextCommand, "", NULL },
+ { "locales_page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPageTextCommand, "", NULL },
+ { "locales_points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPointsOfInterestCommand, "", NULL },
+ { "locales_quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesQuestCommand, "", NULL },
+// { "auctions", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAuctionsCommand, "", NULL },
+ { "milling_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMillingCommand, "", NULL },
{ "npc_gossip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL },
{ "npc_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcOptionCommand, "", NULL },
{ "npc_trainer", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcTrainerCommand, "", NULL },
{ "npc_vendor", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcVendorCommand, "", NULL },
{ "page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPageTextsCommand, "", NULL },
{ "pickpocketing_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesPickpocketingCommand,"",NULL},
+ { "points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPointsOfInterestCommand, "",NULL},
{ "prospecting_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesProspectingCommand,"", NULL },
{ "quest_mail_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesQuestMailCommand, "", NULL },
{ "quest_end_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestEndScriptsCommand, "", NULL },
@@ -286,93 +468,30 @@ ChatCommand * ChatHandler::getCommandTable()
{ "skinning_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSkinningCommand, "", NULL },
{ "spell_affect", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellAffectCommand, "", NULL },
{ "spell_required", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellRequiredCommand, "", NULL },
+ { "spell_area", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellAreaCommand, "", NULL },
{ "spell_elixir", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellElixirCommand, "", NULL },
{ "spell_learn_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellLearnSpellCommand, "", NULL },
+ { "spell_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSpellCommand, "", NULL },
{ "spell_linked_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellLinkedSpellCommand, "", NULL },
{ "spell_pet_auras", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellPetAurasCommand, "", NULL },
{ "spell_proc_event", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellProcEventCommand, "", NULL },
+ { "spell_bonus_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellBonusesCommand, "", NULL },
{ "spell_script_target", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptTargetCommand, "", NULL },
{ "spell_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptsCommand, "", NULL },
{ "spell_target_position", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL },
{ "spell_threats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellThreatsCommand, "", NULL },
{ "spell_disabled", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellDisabledCommand, "", NULL },
- { "locales_creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesCreatureCommand, "", NULL },
- { "locales_gameobject", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesGameobjectCommand, "", NULL },
- { "locales_item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesItemCommand, "", NULL },
- { "locales_npc_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesNpcTextCommand, "", NULL },
- { "locales_page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPageTextCommand, "", NULL },
- { "locales_quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesQuestCommand, "", NULL },
+ { "trinity_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadTrinityStringCommand, "", NULL },
{ "auctions", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAuctionsCommand, "", NULL },
{ "waypoint_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadWpScriptsCommand, "", NULL },
{ "gm_tickets", SEC_ADMINISTRATOR, true, &ChatHandler::HandleGMTicketReloadCommand, "", NULL },
- { "", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand honorCommandTable[] =
- {
- { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleAddHonorCommand, "", NULL },
- { "addkill", SEC_GAMEMASTER, false, &ChatHandler::HandleHonorAddKillCommand, "", NULL },
- { "update", SEC_GAMEMASTER, false, &ChatHandler::HandleUpdateHonorFieldsCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
- static ChatCommand guildCommandTable[] =
- {
- { "create", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildCreateCommand, "", NULL },
- { "delete", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildDeleteCommand, "", NULL },
- { "invite", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildInviteCommand, "", NULL },
- { "uninvite", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildUninviteCommand, "", NULL },
- { "rank", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildRankCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
- static ChatCommand petCommandTable[] =
- {
- { "create", SEC_GAMEMASTER, false, &ChatHandler::HandleCreatePetCommand, "", NULL },
- { "learn", SEC_GAMEMASTER, false, &ChatHandler::HandlePetLearnCommand, "", NULL },
- { "unlearn", SEC_GAMEMASTER, false, &ChatHandler::HandlePetUnlearnCommand, "", NULL },
- { "tp", SEC_GAMEMASTER, false, &ChatHandler::HandlePetTpCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
-
- static ChatCommand groupCommandTable[] =
- {
- { "leader", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGroupLeaderCommand, "", NULL },
- { "disband", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGroupDisbandCommand, "", NULL },
- { "remove", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGroupRemoveCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
- static ChatCommand lookupPlayerCommandTable[] =
- {
- { "ip", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerIpCommand, "", NULL },
- { "account", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerAccountCommand, "", NULL },
- { "email", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerEmailCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
- static ChatCommand lookupCommandTable[] =
- {
- { "area", SEC_MODERATOR, true, &ChatHandler::HandleLookupAreaCommand, "", NULL },
- { "creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupCreatureCommand, "", NULL },
- { "event", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupEventCommand, "", NULL },
- { "faction", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupFactionCommand, "", NULL },
- { "item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupItemCommand, "", NULL },
- { "itemset", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupItemSetCommand, "", NULL },
- { "object", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupObjectCommand, "", NULL },
- { "quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupQuestCommand, "", NULL },
- { "player", SEC_GAMEMASTER, true, NULL, "", lookupPlayerCommandTable },
- { "skill", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupSkillCommand, "", NULL },
- { "spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupSpellCommand, "", NULL },
- { "tele", SEC_MODERATOR, true, &ChatHandler::HandleLookupTeleCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
static ChatCommand resetCommandTable[] =
{
+ { "achievements", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetAchievementsCommand, "", NULL },
{ "honor", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetHonorCommand, "", NULL },
{ "level", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetLevelCommand, "", NULL },
{ "spells", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetSpellsCommand, "", NULL },
@@ -382,132 +501,95 @@ ChatCommand * ChatHandler::getCommandTable()
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand castCommandTable[] =
+ static ChatCommand sendCommandTable[] =
{
- { "back", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastBackCommand, "", NULL },
- { "dist", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastDistCommand, "", NULL },
- { "self", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastSelfCommand, "", NULL },
- { "target", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastTargetCommand, "", NULL },
- { "", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastCommand, "", NULL },
+ { "items", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendItemsCommand, "", NULL },
+ { "mail", SEC_MODERATOR, true, &ChatHandler::HandleSendMailCommand, "", NULL },
+ { "message", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMessageCommand, "", NULL },
+ { "money", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMoneyCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand pdumpCommandTable[] =
+ static ChatCommand serverIdleRestartCommandTable[] =
{
- { "load", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLoadPDumpCommand, "", NULL },
- { "write", SEC_ADMINISTRATOR, true, &ChatHandler::HandleWritePDumpCommand, "", NULL },
+ { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
+ { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerIdleRestartCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand listCommandTable[] =
+ static ChatCommand serverIdleShutdownCommandTable[] =
{
- { "creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleListCreatureCommand, "", NULL },
- { "item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleListItemCommand, "", NULL },
- { "object", SEC_ADMINISTRATOR, true, &ChatHandler::HandleListObjectCommand, "", NULL },
- { "auras", SEC_ADMINISTRATOR, false, &ChatHandler::HandleListAurasCommand, "", NULL },
+ { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
+ { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerIdleShutDownCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand teleCommandTable[] =
+ static ChatCommand serverRestartCommandTable[] =
{
- { "add", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAddTeleCommand, "", NULL },
- { "del", SEC_ADMINISTRATOR, true, &ChatHandler::HandleDelTeleCommand, "", NULL },
- { "name", SEC_MODERATOR, true, &ChatHandler::HandleNameTeleCommand, "", NULL },
- { "group", SEC_MODERATOR, false, &ChatHandler::HandleGroupTeleCommand, "", NULL },
- { "", SEC_MODERATOR, false, &ChatHandler::HandleTeleCommand, "", NULL },
+ { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
+ { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerRestartCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand npcCommandTable[] =
+ static ChatCommand serverShutdownCommandTable[] =
{
- { "say", SEC_MODERATOR, false, &ChatHandler::HandleNpcSayCommand, "", NULL },
- { "textemote", SEC_MODERATOR, false, &ChatHandler::HandleNpcTextEmoteCommand, "", NULL },
- { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddCommand, "", NULL },
- { "delete", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcDeleteCommand, "", NULL },
- { "spawndist", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSpawnDistCommand, "", NULL },
- { "spawntime", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSpawnTimeCommand, "", NULL },
- { "factionid", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFactionIdCommand, "", NULL },
- { "addmove", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddMoveCommand, "", NULL },
- { "setmovetype", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetMoveTypeCommand, "", NULL },
- { "move", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcMoveCommand, "", NULL },
- { "changelevel", SEC_GAMEMASTER, false, &ChatHandler::HandleChangeLevelCommand, "", NULL },
- { "setmodel", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetModelCommand, "", NULL },
- { "additem", SEC_GAMEMASTER, false, &ChatHandler::HandleAddVendorItemCommand, "", NULL },
- { "delitem", SEC_GAMEMASTER, false, &ChatHandler::HandleDelVendorItemCommand, "", NULL },
- { "flag", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFlagCommand, "", NULL },
- { "changeentry", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcChangeEntryCommand, "", NULL },
- { "info", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcInfoCommand, "", NULL },
- { "playemote", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcPlayEmoteCommand, "", NULL },
- { "follow", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFollowCommand, "", NULL },
- { "unfollow", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcUnFollowCommand, "", NULL },
- { "whisper", SEC_MODERATOR, false, &ChatHandler::HandleNpcWhisperCommand, "", NULL },
- { "yell", SEC_MODERATOR, false, &ChatHandler::HandleNpcYellCommand, "", NULL },
- { "addtemp", SEC_GAMEMASTER, false, &ChatHandler::HandleTempAddSpwCommand, "", NULL },
- { "addformation", SEC_MODERATOR, false, &ChatHandler::HandleNpcAddFormationCommand, "", NULL },
+ { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
+ { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCommand, "", NULL },
{ "setlink", SEC_MODERATOR, false, &ChatHandler::HandleNpcSetLinkCommand, "", NULL },
-
- //{ TODO: fix or remove this commands
- { "name", SEC_GAMEMASTER, false, &ChatHandler::HandleNameCommand, "", NULL },
- { "subname", SEC_GAMEMASTER, false, &ChatHandler::HandleSubNameCommand, "", NULL },
- { "addweapon", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAddWeaponCommand, "", NULL },
- //}
-
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand goCommandTable[] =
+ static ChatCommand serverSetCommandTable[] =
{
- { "grid", SEC_MODERATOR, false, &ChatHandler::HandleGoGridCommand, "", NULL },
- { "creature", SEC_GAMEMASTER, false, &ChatHandler::HandleGoCreatureCommand, "", NULL },
- { "object", SEC_GAMEMASTER, false, &ChatHandler::HandleGoObjectCommand, "", NULL },
- { "ticket", SEC_MODERATOR, false, &ChatHandler::HandleGoTicketCommand, "", NULL },
- { "trigger", SEC_GAMEMASTER, false, &ChatHandler::HandleGoTriggerCommand, "", NULL },
- { "graveyard", SEC_GAMEMASTER, false, &ChatHandler::HandleGoGraveyardCommand, "", NULL },
- { "zonexy", SEC_MODERATOR, false, &ChatHandler::HandleGoZoneXYCommand, "", NULL },
- { "xy", SEC_MODERATOR, false, &ChatHandler::HandleGoXYCommand, "", NULL },
- { "xyz", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL },
- { "", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL },
+ { "difftime", SEC_CONSOLE, true, &ChatHandler::HandleServerSetDiffTimeCommand, "", NULL },
+ { "loglevel", SEC_CONSOLE, true, &ChatHandler::HandleServerSetLogLevelCommand, "", NULL },
+ { "logfilelevel", SEC_CONSOLE, true, &ChatHandler::HandleServerSetLogFileLevelCommand, "", NULL },
+ { "motd", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerSetMotdCommand, "", NULL },
+ { "closed", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerSetClosedCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand gobjectCommandTable[] =
+ static ChatCommand serverCommandTable[] =
{
- { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectCommand, "", NULL },
- { "delete", SEC_GAMEMASTER, false, &ChatHandler::HandleDelObjectCommand, "", NULL },
- { "target", SEC_GAMEMASTER, false, &ChatHandler::HandleTargetObjectCommand, "", NULL },
- { "turn", SEC_GAMEMASTER, false, &ChatHandler::HandleTurnObjectCommand, "", NULL },
- { "move", SEC_GAMEMASTER, false, &ChatHandler::HandleMoveObjectCommand, "", NULL },
- { "near", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNearObjectCommand, "", NULL },
- { "activate", SEC_GAMEMASTER, false, &ChatHandler::HandleActivateObjectCommand, "", NULL },
- { "addtemp", SEC_GAMEMASTER, false, &ChatHandler::HandleTempGameObjectCommand, "", NULL },
+ { "corpses", SEC_GAMEMASTER, true, &ChatHandler::HandleServerCorpsesCommand, "", NULL },
+ { "exit", SEC_CONSOLE, true, &ChatHandler::HandleServerExitCommand, "", 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 },
+ { "plimit", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerPLimitCommand, "", NULL },
+ { "restart", SEC_ADMINISTRATOR, true, NULL, "", serverRestartCommandTable },
+ { "shutdown", SEC_ADMINISTRATOR, true, NULL, "", serverShutdownCommandTable },
+ { "set", SEC_ADMINISTRATOR, true, NULL, "", serverSetCommandTable },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand questCommandTable[] =
+ static ChatCommand teleCommandTable[] =
{
- { "add", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAddQuest, "", NULL },
- { "complete", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCompleteQuest, "", NULL },
- { "remove", SEC_ADMINISTRATOR, false, &ChatHandler::HandleRemoveQuest, "", NULL },
+ { "add", SEC_ADMINISTRATOR, false, &ChatHandler::HandleTeleAddCommand, "", NULL },
+ { "del", SEC_ADMINISTRATOR, true, &ChatHandler::HandleTeleDelCommand, "", NULL },
+ { "name", SEC_MODERATOR, true, &ChatHandler::HandleTeleNameCommand, "", NULL },
+ { "group", SEC_MODERATOR, false, &ChatHandler::HandleTeleGroupCommand, "", NULL },
+ { "", SEC_MODERATOR, false, &ChatHandler::HandleTeleCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand gmCommandTable[] =
+ static ChatCommand unbanCommandTable[] =
{
- { "chat", SEC_MODERATOR, false, &ChatHandler::HandleGMChatCommand, "", NULL },
- { "ingame", SEC_PLAYER, true, &ChatHandler::HandleGMListIngameCommand, "", NULL },
- { "list", SEC_ADMINISTRATOR, true, &ChatHandler::HandleGMListFullCommand, "", NULL },
- { "visible", SEC_MODERATOR, false, &ChatHandler::HandleVisibleCommand, "", NULL },
- { "fly", SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlyModeCommand, "", NULL },
- { "", SEC_MODERATOR, false, &ChatHandler::HandleGMmodeCommand, "", NULL },
+ { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleUnBanAccountCommand, "", NULL },
+ { "character", SEC_ADMINISTRATOR, true, &ChatHandler::HandleUnBanCharacterCommand, "", NULL },
+ { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleUnBanIPCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand instanceCommandTable[] =
+ static ChatCommand wpCommandTable[] =
{
- { "listbinds", SEC_MODERATOR, false, &ChatHandler::HandleInstanceListBindsCommand, "", NULL },
- { "unbind", SEC_MODERATOR, false, &ChatHandler::HandleInstanceUnbindCommand, "", NULL },
- { "stats", SEC_MODERATOR, true, &ChatHandler::HandleInstanceStatsCommand, "", NULL },
- { "savedata", SEC_MODERATOR, false, &ChatHandler::HandleInstanceSaveDataCommand, "", NULL },
+ { "show", SEC_GAMEMASTER, false, &ChatHandler::HandleWpShowCommand, "", NULL },
+ { "addwp", SEC_GAMEMASTER, false, &ChatHandler::HandleWpAddCommand, "", NULL },
+ { "load", SEC_GAMEMASTER, false, &ChatHandler::HandleWpLoadPathCommand, "", NULL },
+ { "modify", SEC_GAMEMASTER, false, &ChatHandler::HandleWpModifyCommand, "", NULL },
+ { "event", SEC_GAMEMASTER, false, &ChatHandler::HandleWpEventCommand, "", NULL },
+ { "unload", SEC_GAMEMASTER, false, &ChatHandler::HandleWpUnLoadPathCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
@@ -528,34 +610,34 @@ ChatCommand * ChatHandler::getCommandTable()
static ChatCommand commandTable[] =
{
- { "account", SEC_PLAYER, true, NULL, "", accountCommandTable },
- { "gm", SEC_MODERATOR, true, NULL, "", gmCommandTable },
- { "ticket", SEC_MODERATOR, false, NULL, "", ticketCommandTable },
- { "npc", SEC_MODERATOR, false, NULL, "", npcCommandTable },
- { "go", SEC_MODERATOR, false, NULL, "", goCommandTable },
- { "learn", SEC_MODERATOR, false, NULL, "", learnCommandTable },
- { "modify", SEC_MODERATOR, false, NULL, "", modifyCommandTable },
- { "debug", SEC_MODERATOR, false, NULL, "", debugCommandTable },
- { "tele", SEC_MODERATOR, true, NULL, "", teleCommandTable },
- { "event", SEC_GAMEMASTER, false, NULL, "", eventCommandTable },
- { "gobject", SEC_GAMEMASTER, false, NULL, "", gobjectCommandTable },
- { "honor", SEC_GAMEMASTER, false, NULL, "", honorCommandTable },
-
- //wp commands
- { "path", SEC_GAMEMASTER, false, NULL, "", wpCommandTable },
- { "loadpath", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadAllPaths, "", NULL },
-
- { "quest", SEC_ADMINISTRATOR, false, NULL, "", questCommandTable },
- { "reload", SEC_ADMINISTRATOR, true, NULL, "", reloadCommandTable },
- { "list", SEC_ADMINISTRATOR, true, NULL, "", listCommandTable },
- { "lookup", SEC_ADMINISTRATOR, true, NULL, "", lookupCommandTable },
- { "pdump", SEC_ADMINISTRATOR, true, NULL, "", pdumpCommandTable },
- { "guild", SEC_ADMINISTRATOR, true, NULL, "", guildCommandTable },
- { "cast", SEC_ADMINISTRATOR, false, NULL, "", castCommandTable },
- { "reset", SEC_ADMINISTRATOR, false, NULL, "", resetCommandTable },
+ { "account", SEC_PLAYER, true, NULL, "", accountCommandTable },
+ { "gm", SEC_MODERATOR, true, NULL, "", gmCommandTable },
+ { "npc", SEC_MODERATOR, false, NULL, "", npcCommandTable },
+ { "go", SEC_MODERATOR, false, NULL, "", goCommandTable },
+ { "learn", SEC_MODERATOR, false, NULL, "", learnCommandTable },
+ { "modify", SEC_MODERATOR, false, NULL, "", modifyCommandTable },
+ { "debug", SEC_MODERATOR, false, NULL, "", debugCommandTable },
+ { "tele", SEC_MODERATOR, true, NULL, "", teleCommandTable },
+ { "character", SEC_GAMEMASTER, false, NULL, "", characterCommandTable},
+ { "event", SEC_GAMEMASTER, false, NULL, "", eventCommandTable },
+ { "gobject", SEC_GAMEMASTER, false, NULL, "", gobjectCommandTable },
+ { "honor", SEC_GAMEMASTER, false, NULL, "", honorCommandTable },
+ { "wp", SEC_GAMEMASTER, false, NULL, "", wpCommandTable },
+ { "quest", SEC_ADMINISTRATOR, false, NULL, "", questCommandTable },
+ { "reload", SEC_ADMINISTRATOR, true, NULL, "", reloadCommandTable },
+ { "list", SEC_ADMINISTRATOR, true, NULL, "", listCommandTable },
+ { "lookup", SEC_ADMINISTRATOR, true, NULL, "", lookupCommandTable },
+ { "pdump", SEC_ADMINISTRATOR, true, NULL, "", pdumpCommandTable },
+ { "guild", SEC_ADMINISTRATOR, true, NULL, "", guildCommandTable },
+ { "cast", SEC_ADMINISTRATOR, false, NULL, "", castCommandTable },
+ { "reset", SEC_ADMINISTRATOR, false, NULL, "", resetCommandTable },
{ "instance", SEC_ADMINISTRATOR, true, NULL, "", instanceCommandTable },
- { "server", SEC_ADMINISTRATOR, true, NULL, "", serverCommandTable },
+ { "server", SEC_ADMINISTRATOR, true, NULL, "", serverCommandTable },
+
{ "pet", SEC_GAMEMASTER, false, NULL, "", petCommandTable },
+ { "loadpath", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadAllPaths, "", NULL },
+ { "ahbotoptions", SEC_GAMEMASTER, false, &ChatHandler::HandleAHBotOptionsCommand, "", NULL },
+ { "ticket", SEC_MODERATOR, false, NULL, "", ticketCommandTable },
{ "aura", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAuraCommand, "", NULL },
{ "unaura", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnAuraCommand, "", NULL },
@@ -571,7 +653,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "commands", SEC_PLAYER, true, &ChatHandler::HandleCommandsCommand, "", NULL },
{ "demorph", SEC_GAMEMASTER, false, &ChatHandler::HandleDeMorphCommand, "", NULL },
{ "die", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDieCommand, "", NULL },
- { "revive", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReviveCommand, "", NULL },
+ { "revive", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReviveCommand, "", NULL },
{ "dismount", SEC_PLAYER, false, &ChatHandler::HandleDismountCommand, "", NULL },
{ "gps", SEC_MODERATOR, false, &ChatHandler::HandleGPSCommand, "", NULL },
{ "guid", SEC_GAMEMASTER, false, &ChatHandler::HandleGUIDCommand, "", NULL },
@@ -584,14 +666,12 @@ ChatCommand * ChatHandler::getCommandTable()
{ "save", SEC_PLAYER, false, &ChatHandler::HandleSaveCommand, "", NULL },
{ "saveall", SEC_MODERATOR, true, &ChatHandler::HandleSaveAllCommand, "", NULL },
{ "kick", SEC_GAMEMASTER, true, &ChatHandler::HandleKickPlayerCommand, "", NULL },
- { "ban", SEC_ADMINISTRATOR, true, NULL, "", banCommandTable },
- { "unban", SEC_ADMINISTRATOR, true, NULL, "", unbanCommandTable },
- { "baninfo", SEC_ADMINISTRATOR, false, NULL, "", baninfoCommandTable },
- { "banlist", SEC_ADMINISTRATOR, true, NULL, "", banlistCommandTable },
- { "plimit", SEC_ADMINISTRATOR, true, &ChatHandler::HandlePLimitCommand, "", NULL },
+ { "ban", SEC_ADMINISTRATOR, true, NULL, "", banCommandTable },
+ { "unban", SEC_ADMINISTRATOR, true, NULL, "", unbanCommandTable },
+ { "baninfo", SEC_ADMINISTRATOR, false, NULL, "", baninfoCommandTable },
+ { "banlist", SEC_ADMINISTRATOR, true, NULL, "", banlistCommandTable },
{ "start", SEC_PLAYER, false, &ChatHandler::HandleStartCommand, "", NULL },
{ "taxicheat", SEC_MODERATOR, false, &ChatHandler::HandleTaxiCheatCommand, "", NULL },
- { "allowmove", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAllowMovementCommand, "", NULL },
{ "linkgrave", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLinkGraveCommand, "", NULL },
{ "neargrave", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNearGraveCommand, "", NULL },
{ "explorecheat", SEC_ADMINISTRATOR, false, &ChatHandler::HandleExploreCheatCommand, "", NULL },
@@ -608,34 +688,27 @@ ChatCommand * ChatHandler::getCommandTable()
{ "setskill", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSetSkillCommand, "", NULL },
{ "whispers", SEC_MODERATOR, false, &ChatHandler::HandleWhispersCommand, "", NULL },
{ "pinfo", SEC_GAMEMASTER, true, &ChatHandler::HandlePInfoCommand, "", NULL },
- { "password", SEC_PLAYER, false, &ChatHandler::HandlePasswordCommand, "", NULL },
- { "lockaccount", SEC_PLAYER, false, &ChatHandler::HandleLockAccountCommand, "", NULL },
{ "respawn", SEC_ADMINISTRATOR, false, &ChatHandler::HandleRespawnCommand, "", NULL },
- { "senditems", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendItemsCommand, "", NULL },
- { "sendmail", SEC_MODERATOR, true, &ChatHandler::HandleSendMailCommand, "", NULL },
- { "sendmoney", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMoneyCommand, "", NULL },
- { "rename", SEC_GAMEMASTER, true, &ChatHandler::HandleRenameCommand, "", NULL },
+ { "send", SEC_MODERATOR, true, NULL, "", sendCommandTable },
{ "loadscripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLoadScriptsCommand, "", NULL },
- { "mute", SEC_GAMEMASTER, true, &ChatHandler::HandleMuteCommand, "", NULL },
- { "unmute", SEC_GAMEMASTER, true, &ChatHandler::HandleUnmuteCommand, "", NULL },
+ { "mute", SEC_MODERATOR, true, &ChatHandler::HandleMuteCommand, "", NULL },
+ { "unmute", SEC_MODERATOR, true, &ChatHandler::HandleUnmuteCommand, "", NULL },
{ "movegens", SEC_ADMINISTRATOR, false, &ChatHandler::HandleMovegensCommand, "", NULL },
{ "cometome", SEC_ADMINISTRATOR, false, &ChatHandler::HandleComeToMeCommand, "", NULL },
{ "damage", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDamageCommand, "", NULL },
{ "combatstop", SEC_GAMEMASTER, false, &ChatHandler::HandleCombatStopCommand, "", NULL },
- { "ahbotoptions", SEC_ADMINISTRATOR, true, &ChatHandler::HandleAHBotOptionsCommand, "", NULL },
- { "flusharenapoints", SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL },
- { "chardelete", SEC_CONSOLE, true, &ChatHandler::HandleCharacterDeleteCommand, "", NULL },
- { "sendmessage", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMessageCommand, "", NULL },
- { "playall", SEC_ADMINISTRATOR, false, &ChatHandler::HandlePlayAllCommand, "", NULL },
+ { "flusharenapoints",SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL },
{ "repairitems", SEC_GAMEMASTER, false, &ChatHandler::HandleRepairitemsCommand, "", NULL },
{ "freeze", SEC_ADMINISTRATOR, false, &ChatHandler::HandleFreezeCommand, "", NULL },
{ "unfreeze", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnFreezeCommand, "", NULL },
{ "listfreeze", SEC_ADMINISTRATOR, false, &ChatHandler::HandleListFreezeCommand, "", NULL },
{ "flusharenapoints", SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL },
+
{ "possess", SEC_ADMINISTRATOR, false, &ChatHandler::HandlePossessCommand, "", NULL },
{ "unpossess", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnPossessCommand, "", NULL },
{ "bindsight", SEC_ADMINISTRATOR, false, &ChatHandler::HandleBindSightCommand, "", NULL },
{ "unbindsight", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnbindSightCommand, "", NULL },
+ { "playall", SEC_ADMINISTRATOR, false, &ChatHandler::HandlePlayAllCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
@@ -651,28 +724,9 @@ ChatCommand * ChatHandler::getCommandTable()
{
Field *fields = result->Fetch();
std::string name = fields[0].GetCppString();
- for(uint32 i = 0; commandTable[i].Name != NULL; i++)
- {
- if (name == commandTable[i].Name)
- {
- commandTable[i].SecurityLevel = (uint16)fields[1].GetUInt16();
- commandTable[i].Help = fields[2].GetCppString();
- }
- if(commandTable[i].ChildCommands != NULL)
- {
- ChatCommand *ptable = commandTable[i].ChildCommands;
- for(uint32 j = 0; ptable[j].Name != NULL; j++)
- {
- // first case for "" named subcommand
- if (ptable[j].Name[0]=='\0' && name == commandTable[i].Name ||
- name == fmtstring("%s %s", commandTable[i].Name, ptable[j].Name) )
- {
- ptable[j].SecurityLevel = (uint16)fields[1].GetUInt16();
- ptable[j].Help = fields[2].GetCppString();
- }
- }
- }
- }
+
+ SetDataForCommandInTable(commandTable, name.c_str(), fields[1].GetUInt16(), fields[2].GetCppString(), name);
+
} while(result->NextRow());
delete result;
}
@@ -692,6 +746,55 @@ bool ChatHandler::isAvailable(ChatCommand const& cmd) const
return m_session->GetSecurity() >= cmd.SecurityLevel;
}
+bool ChatHandler::HasLowerSecurity(Player* target, uint64 guid, bool strong)
+{
+ WorldSession* target_session = NULL;
+ uint32 target_account = 0;
+
+ if (target)
+ target_session = target->GetSession();
+ else if (guid)
+ target_account = objmgr.GetPlayerAccountIdByGUID(guid);
+
+ if(!target_session && !target_account)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return true;
+ }
+
+ return HasLowerSecurityAccount(target_session,target_account,strong);
+}
+
+bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_account, bool strong)
+{
+ uint32 target_sec;
+
+ // allow everything from console and RA console
+ if (!m_session)
+ return false;
+
+ // ignore only for non-players for non strong checks (when allow apply command at least to same sec level)
+ if (m_session->GetSecurity() > SEC_PLAYER && !strong && !sWorld.getConfig(CONFIG_GM_LOWER_SECURITY))
+ return false;
+
+ if (target)
+ target_sec = target->GetSecurity();
+ else if (target_account)
+ target_sec = accmgr.GetSecurity(target_account);
+ else
+ return true; // caller must report error for (target==NULL && target_account==0)
+
+ if (m_session->GetSecurity() < target_sec || (strong && m_session->GetSecurity() <= target_sec))
+ {
+ SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
+ SetSentErrorMessage(true);
+ return true;
+ }
+
+ return false;
+}
+
bool ChatHandler::hasStringAbbr(const char* name, const char* part)
{
// non "" command
@@ -777,9 +880,9 @@ void ChatHandler::PSendSysMessage(int32 entry, ...)
{
const char *format = GetTrinityString(entry);
va_list ap;
- char str [1024];
+ char str [2048];
va_start(ap, entry);
- vsnprintf(str,1024,format, ap );
+ vsnprintf(str,2048,format, ap );
va_end(ap);
SendSysMessage(str);
}
@@ -787,9 +890,9 @@ void ChatHandler::PSendSysMessage(int32 entry, ...)
void ChatHandler::PSendSysMessage(const char *format, ...)
{
va_list ap;
- char str [1024];
+ char str [2048];
va_start(ap, format);
- vsnprintf(str,1024,format, ap );
+ vsnprintf(str,2048,format, ap );
va_end(ap);
SendSysMessage(str);
}
@@ -807,7 +910,7 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, co
while (*text == ' ') ++text;
- for(uint32 i = 0; table[i].Name != NULL; i++)
+ for(uint32 i = 0; table[i].Name != NULL; ++i)
{
if( !hasStringAbbr(table[i].Name, cmd.c_str()) )
continue;
@@ -864,6 +967,61 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, co
return false;
}
+bool ChatHandler::SetDataForCommandInTable(ChatCommand *table, const char* text, uint32 security, std::string const& help, std::string const& fullcommand )
+{
+ std::string cmd = "";
+
+ while (*text != ' ' && *text != '\0')
+ {
+ cmd += *text;
+ ++text;
+ }
+
+ while (*text == ' ') ++text;
+
+ for(uint32 i = 0; table[i].Name != NULL; i++)
+ {
+ // for data fill use full explicit command names
+ if( table[i].Name != cmd )
+ continue;
+
+ // select subcommand from child commands list (including "")
+ if(table[i].ChildCommands != NULL)
+ {
+ if(SetDataForCommandInTable(table[i].ChildCommands, text, security, help, fullcommand))
+ return true;
+ else if(*text)
+ return false;
+
+ // fail with "" subcommands, then use normal level up command instead
+ }
+ // expected subcommand by full name DB content
+ else if(*text)
+ {
+ sLog.outErrorDb("Table `command` have unexpected subcommand '%s' in command '%s', skip.",text,fullcommand.c_str());
+ return false;
+ }
+
+ if(table[i].SecurityLevel != security)
+ sLog.outDetail("Table `command` overwrite for command '%s' default security (%u) by %u",fullcommand.c_str(),table[i].SecurityLevel,security);
+
+ table[i].SecurityLevel = security;
+ table[i].Help = help;
+ return true;
+ }
+
+ // in case "" command let process by caller
+ if(!cmd.empty())
+ {
+ if(table==getCommandTable())
+ sLog.outErrorDb("Table `command` have not existed command '%s', skip.",cmd.c_str());
+ else
+ sLog.outErrorDb("Table `command` have not existed subcommand '%s' in command '%s', skip.",cmd.c_str(),fullcommand.c_str());
+ }
+
+ return false;
+}
+
int ChatHandler::ParseCommands(const char* text)
{
ASSERT(text);
@@ -872,28 +1030,28 @@ int ChatHandler::ParseCommands(const char* text)
std::string fullcmd = text;
/// chat case (.command or !command format)
- if(m_session)
+ if (m_session)
{
if(text[0] != '!' && text[0] != '.')
return 0;
}
/// ignore single . and ! in line
- if(strlen(text) < 2)
+ if (strlen(text) < 2)
return 0;
// original `text` can't be used. It content destroyed in command code processing.
/// ignore messages staring from many dots.
- if(text[0] == '.' && text[1] == '.' || text[0] == '!' && text[1] == '!')
+ if ((text[0] == '.' && text[1] == '.') || (text[0] == '!' && text[1] == '!'))
return 0;
/// skip first . or ! (in console allowed use command with . and ! and without its)
- if(text[0] == '!' || text[0] == '.')
+ if (text[0] == '!' || text[0] == '.')
++text;
if(!ExecuteCommandInTable(getCommandTable(), text, fullcmd))
{
- if(m_session && m_session->GetSecurity() == SEC_PLAYER)
+ if(m_session && m_session->GetSecurity() == SEC_PLAYER)
return 0;
SendSysMessage(LANG_NO_CMD);
}
@@ -1105,7 +1263,7 @@ Creature* ChatHandler::getSelectedCreature()
if(!m_session)
return NULL;
- return ObjectAccessor::GetCreatureOrPet(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelection());
+ return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelection());
}
char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1)
@@ -1176,12 +1334,23 @@ char* ChatHandler::extractKeyFromLink(char* text, char const* const* linkTypes,
// [name] Shift-click form |color|linkType:key|h[name]|h|r
// or
// [name] Shift-click form |color|linkType:key:something1:...:somethingN|h[name]|h|r
+ // or
+ // [name] Shift-click form |linkType:key|h[name]|h|r
- char* check = strtok(text, "|"); // skip color
- if(!check)
- return NULL; // end of data
+ char* tail;
- char* cLinkType = strtok(NULL, ":"); // linktype
+ if(text[1]=='c')
+ {
+ char* check = strtok(text, "|"); // skip color
+ if(!check)
+ return NULL; // end of data
+
+ tail = strtok(NULL, ""); // tail
+ }
+ else
+ tail = text+1; // skip first |
+
+ char* cLinkType = strtok(tail, ":"); // linktype
if(!cLinkType)
return NULL; // end of data
@@ -1248,7 +1417,7 @@ GameObject* ChatHandler::GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid
Player* pl = m_session->GetPlayer();
- GameObject* obj = ObjectAccessor::GetGameObject(*pl, MAKE_NEW_GUID(lowguid, entry, HIGHGUID_GAMEOBJECT));
+ GameObject* obj = pl->GetMap()->GetGameObject(MAKE_NEW_GUID(lowguid, entry, HIGHGUID_GAMEOBJECT));
if(!obj && objmgr.GetGOData(lowguid)) // guid is DB guid of object
{
@@ -1257,20 +1426,29 @@ GameObject* ChatHandler::GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
- Trinity::GameObjectWithDbGUIDCheck go_check(*pl,lowguid);
- Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck> checker(obj,go_check);
+ MaNGOS::GameObjectWithDbGUIDCheck go_check(*pl,lowguid);
+ MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(pl,obj,go_check);
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(pl->GetMapId(), pl));
+ cell_lock->Visit(cell_lock, object_checker, *pl->GetMap());
}
return obj;
}
-static char const* const spellTalentKeys[] = {
- "Hspell",
- "Htalent",
+enum SpellLinkType
+{
+ SPELL_LINK_SPELL = 0,
+ SPELL_LINK_TALENT = 1,
+ SPELL_LINK_TRADE = 2
+};
+
+static char const* const spellKeys[] =
+{
+ "Hspell", // normal spell
+ "Htalent", // talent spell
+ "Htrade", // profession/skill spell
0
};
@@ -1278,31 +1456,41 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text)
{
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
// number or [name] Shift-click form |color|Htalent:talent_id,rank|h[name]|h|r
+ // number or [name] Shift-click form |color|Htrade:spell_id,skill_id,max_value,cur_value|h[name]|h|r
int type = 0;
- char* rankS = NULL;
- char* idS = extractKeyFromLink(text,spellTalentKeys,&type,&rankS);
+ char* param1_str = NULL;
+ char* idS = extractKeyFromLink(text,spellKeys,&type,&param1_str);
if(!idS)
return 0;
uint32 id = (uint32)atol(idS);
- // spell
- if(type==0)
- return id;
+ switch(type)
+ {
+ case SPELL_LINK_SPELL:
+ return id;
+ case SPELL_LINK_TALENT:
+ {
+ // talent
+ TalentEntry const* talentEntry = sTalentStore.LookupEntry(id);
+ if(!talentEntry)
+ return 0;
- // talent
- TalentEntry const* talentEntry = sTalentStore.LookupEntry(id);
- if(!talentEntry)
- return 0;
+ int32 rank = param1_str ? (uint32)atol(param1_str) : 0;
+ if(rank >= MAX_TALENT_RANK)
+ return 0;
- int32 rank = rankS ? (uint32)atol(rankS) : 0;
- if(rank >= 5)
- return 0;
+ if(rank < 0)
+ rank = 0;
- if(rank < 0)
- rank = 0;
+ return talentEntry->RankID[rank];
+ }
+ case SPELL_LINK_TRADE:
+ return id;
+ }
- return talentEntry->RankID[rank];
+ // unknown type?
+ return 0;
}
GameTele const* ChatHandler::extractGameTeleFromLink(char* text)
@@ -1320,9 +1508,84 @@ GameTele const* ChatHandler::extractGameTeleFromLink(char* text)
return objmgr.GetGameTele(cId);
}
-const char *ChatHandler::GetName() const
+enum GuidLinkType
+{
+ SPELL_LINK_PLAYER = 0, // must be first for selection in not link case
+ SPELL_LINK_CREATURE = 1,
+ SPELL_LINK_GAMEOBJECT = 2
+};
+
+static char const* const guidKeys[] =
{
- return m_session->GetPlayer()->GetName();
+ "Hplayer",
+ "Hcreature",
+ "Hgameobject",
+ 0
+};
+
+uint64 ChatHandler::extractGuidFromLink(char* text)
+{
+ int type = 0;
+
+ // |color|Hcreature:creature_guid|h[name]|h|r
+ // |color|Hgameobject:go_guid|h[name]|h|r
+ // |color|Hplayer:name|h[name]|h|r
+ char* idS = extractKeyFromLink(text,guidKeys,&type);
+ if(!idS)
+ return 0;
+
+ switch(type)
+ {
+ case SPELL_LINK_PLAYER:
+ {
+ std::string name = idS;
+ if(!normalizePlayerName(name))
+ return 0;
+
+ if(Player* player = objmgr.GetPlayer(name.c_str()))
+ return player->GetGUID();
+
+ if(uint64 guid = objmgr.GetPlayerGUIDByName(name))
+ return guid;
+
+ return 0;
+ }
+ case SPELL_LINK_CREATURE:
+ {
+ uint32 lowguid = (uint32)atol(idS);
+
+ if(CreatureData const* data = objmgr.GetCreatureData(lowguid) )
+ return MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT);
+ else
+ return 0;
+ }
+ case SPELL_LINK_GAMEOBJECT:
+ {
+ uint32 lowguid = (uint32)atol(idS);
+
+ if(GameObjectData const* data = objmgr.GetGOData(lowguid) )
+ return MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_GAMEOBJECT);
+ else
+ return 0;
+ }
+ }
+
+ // unknown type?
+ return 0;
+}
+
+std::string ChatHandler::extractPlayerNameFromLink(char* text)
+{
+ // |color|Hplayer:name|h[name]|h|r
+ char* name_str = extractKeyFromLink(text,"Hplayer");
+ if(!name_str)
+ return "";
+
+ std::string name = name_str;
+ if(!normalizePlayerName(name))
+ return "";
+
+ return name;
}
bool ChatHandler::needReportToTarget(Player* chr) const
@@ -1348,7 +1611,7 @@ void CliHandler::SendSysMessage(const char *str)
m_print("\r\n");
}
-const char *CliHandler::GetName() const
+std::string CliHandler::GetNameLink() const
{
return GetTrinityString(LANG_CONSOLE_COMMAND);
}
diff --git a/src/game/Chat.h b/src/game/Chat.h
index a8dbb5b98a5..6675094e942 100644
--- a/src/game/Chat.h
+++ b/src/game/Chat.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -72,8 +72,6 @@ class ChatHandler
int ParseCommands(const char* text);
- virtual char const* GetName() const;
-
protected:
explicit ChatHandler() : m_session(NULL) {} // for CLI subclass
@@ -81,10 +79,13 @@ class ChatHandler
virtual bool isAvailable(ChatCommand const& cmd) const;
virtual bool needReportToTarget(Player* chr) const;
+ bool HasLowerSecurity(Player* target, uint64 guid, bool strong = false);
+ bool HasLowerSecurityAccount(WorldSession* target, uint32 account, bool strong = false);
void SendGlobalSysMessage(const char *str);
void SendGlobalGMSysMessage(const char *str);
+ bool SetDataForCommandInTable(ChatCommand *table, const char* text, uint32 security, std::string const& help, std::string const& fullcommand );
bool ExecuteCommandInTable(ChatCommand *table, const char* text, const std::string& fullcommand);
bool ShowHelpForCommand(ChatCommand *table, const char* cmd);
bool ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd);
@@ -94,48 +95,128 @@ class ChatHandler
bool HandleAccountCommand(const char* args);
bool HandleAccountCreateCommand(const char* args);
bool HandleAccountDeleteCommand(const char* args);
+ bool HandleAccountLockCommand(const char* args);
bool HandleAccountOnlineListCommand(const char* args);
+ bool HandleAccountPasswordCommand(const char* args);
bool HandleAccountSetAddonCommand(const char* args);
bool HandleAccountSetGmLevelCommand(const char* args);
bool HandleAccountSetPasswordCommand(const char* args);
- bool HandleHelpCommand(const char* args);
bool HandleAHBotOptionsCommand(const char * args);
- bool HandleCommandsCommand(const char* args);
- bool HandleStartCommand(const char* args);
- bool HandleDismountCommand(const char* args);
- bool HandleSaveCommand(const char* args);
- bool HandleGMListIngameCommand(const char* args);
- bool HandleGMListFullCommand(const char* args);
-
- bool HandleNamegoCommand(const char* args);
- bool HandleGonameCommand(const char* args);
- bool HandleGroupgoCommand(const char* args);
- bool HandleRecallCommand(const char* args);
bool HandleNameAnnounceCommand(const char* args);
bool HandleGMNameAnnounceCommand(const char* args);
- bool HandleAnnounceCommand(const char* args);
bool HandleGMAnnounceCommand(const char* args);
- bool HandleNotifyCommand(const char* args);
bool HandleGMNotifyCommand(const char* args);
- bool HandleGMmodeCommand(const char* args);
- bool HandleGMChatCommand(const char* args);
- bool HandleVisibleCommand(const char* args);
- bool HandleGPSCommand(const char* args);
- bool HandleTaxiCheatCommand(const char* args);
- bool HandleWhispersCommand(const char* args);
- bool HandleNameTeleCommand(const char* args);
- bool HandleGroupTeleCommand(const char* args);
- bool HandleDrunkCommand(const char* args);
- bool HandleSendItemsCommand(const char* args);
- bool HandleSendMailCommand(const char* args);
- bool HandleSendMoneyCommand(const char* args);
+
+ bool HandleBanAccountCommand(const char* args);
+ bool HandleBanCharacterCommand(const char* args);
+ bool HandleBanIPCommand(const char* args);
+ bool HandleBanInfoAccountCommand(const char* args);
+ bool HandleBanInfoCharacterCommand(const char* args);
+ bool HandleBanInfoIPCommand(const char* args);
+ bool HandleBanListAccountCommand(const char* args);
+ bool HandleBanListCharacterCommand(const char* args);
+ bool HandleBanListIPCommand(const char* args);
+
+ bool HandleCastCommand(const char *args);
+ bool HandleCastBackCommand(const char *args);
+ bool HandleCastDistCommand(const char *args);
+ bool HandleCastSelfCommand(const char *args);
+ bool HandleCastTargetCommand(const char *args);
+
+ bool HandleCharacterCustomizeCommand(const char * args);
+ bool HandleCharacterDeleteCommand(const char* args);
+ bool HandleCharacterRenameCommand(const char * args);
+ bool HandleCharacterLevelCommand(const char* args);
+
+ bool HandleDebugAnimCommand(const char* args);
+ bool HandleDebugArenaCommand(const char * args);
+ bool HandleDebugBattlegroundCommand(const char * args);
+ bool HandleDebugGetItemState(const char * args);
+ bool HandleDebugGetLootRecipient(const char * args);
+ bool HandleDebugGetValue(const char* args);
+ bool HandleDebugMod32Value(const char* args);
+ bool HandleDebugSetValue(const char* args);
+ bool HandleDebugSetItemFlagCommand(const char * args);
+ bool HandleDebugSetVehicleId(const char * args);
+ bool HandleDebugSpawnVehicle(const char * args);
+ bool HandleDebugEnterVehicle(const char * args);
+ bool HandleDebugUpdate(const char* args);
+ bool HandleDebugUpdateWorldStateCommand(const char* args);
+
+ bool HandleDebugSet32Bit(const char* args);
+ bool HandleDebugThreatList(const char * args);
+ bool HandleDebugHostilRefList(const char * args);
+ bool HandlePossessCommand(const char* args);
+ bool HandleUnPossessCommand(const char* args);
+ bool HandleBindSightCommand(const char* args);
+ bool HandleUnbindSightCommand(const char* args);
+
+ bool HandleDebugPlayCinematicCommand(const char* args);
+ bool HandleDebugPlayMovieCommand(const char* args);
+ bool HandleDebugPlaySoundCommand(const char* args);
+
+ bool HandleDebugSendBuyErrorCommand(const char* args);
+ bool HandleDebugSendChannelNotifyCommand(const char* args);
+ bool HandleDebugSendChatMsgCommand(const char* args);
+ bool HandleDebugSendEquipErrorCommand(const char* args);
+ bool HandleDebugSendLargePacketCommand(const char * args);
+ bool HandleDebugSendOpcodeCommand(const char* args);
+ bool HandleDebugSendPoiCommand(const char* args);
+ bool HandleDebugSendQuestPartyMsgCommand(const char* args);
+ bool HandleDebugSendQuestInvalidMsgCommand(const char* args);
+ bool HandleDebugSendSellErrorCommand(const char* args);
+ bool HandleDebugSendSetPhaseShiftCommand(const char * args);
+ bool HandleDebugSendSpellFailCommand(const char* args);
bool HandleEventActiveListCommand(const char* args);
bool HandleEventStartCommand(const char* args);
bool HandleEventStopCommand(const char* args);
bool HandleEventInfoCommand(const char* args);
+ bool HandleGameObjectAddCommand(const char* args);
+ bool HandleGameObjectDeleteCommand(const char* args);
+ bool HandleGameObjectMoveCommand(const char* args);
+ bool HandleGameObjectNearCommand(const char* args);
+ bool HandleGameObjectPhaseCommand(const char* args);
+ bool HandleGameObjectStateCommand(const char* args);
+ bool HandleGameObjectTargetCommand(const char* args);
+ bool HandleGameObjectTurnCommand(const char* args);
+
+ bool HandleGMCommand(const char* args);
+ bool HandleGMChatCommand(const char* args);
+ bool HandleGMFlyCommand(const char* args);
+ bool HandleGMListFullCommand(const char* args);
+ bool HandleGMListIngameCommand(const char* args);
+ bool HandleGMVisibleCommand(const char* args);
+
+ bool HandleGoCommand(const char* args);
+ bool HandleGoCreatureCommand(const char* args);
+ bool HandleGoGraveyardCommand(const char* args);
+ bool HandleGoGridCommand(const char* args);
+ bool HandleGoObjectCommand(const char* args);
+ bool HandleGoTriggerCommand(const char* args);
+ bool HandleGoXYCommand(const char* args);
+ bool HandleGoXYZCommand(const char* args);
+ bool HandleGoZoneXYCommand(const char* args);
+
+ bool HandleGoTicketCommand(const char* args);
+
+ bool HandleGuildCreateCommand(const char* args);
+ bool HandleGuildInviteCommand(const char* args);
+ bool HandleGuildUninviteCommand(const char* args);
+ bool HandleGuildRankCommand(const char* args);
+ bool HandleGuildDeleteCommand(const char* args);
+
+ bool HandleHonorAddCommand(const char* args);
+ bool HandleHonorAddKillCommand(const char* args);
+ bool HandleHonorUpdateCommand(const char* args);
+
+ bool HandleInstanceListBindsCommand(const char* args);
+ bool HandleInstanceUnbindCommand(const char* args);
+ bool HandleInstanceStatsCommand(const char* args);
+ bool HandleInstanceSaveDataCommand(const char * args);
+
bool HandleLearnCommand(const char* args);
bool HandleLearnAllCommand(const char* args);
bool HandleLearnAllGMCommand(const char* args);
@@ -144,9 +225,15 @@ class ChatHandler
bool HandleLearnAllDefaultCommand(const char* args);
bool HandleLearnAllLangCommand(const char* args);
bool HandleLearnAllMyClassCommand(const char* args);
+ bool HandleLearnAllMyPetTalentsCommand(const char* args);
bool HandleLearnAllMySpellsCommand(const char* args);
bool HandleLearnAllMyTalentsCommand(const char* args);
+ bool HandleListAurasCommand(const char * args);
+ bool HandleListCreatureCommand(const char* args);
+ bool HandleListItemCommand(const char* args);
+ bool HandleListObjectCommand(const char* args);
+
bool HandleLookupAreaCommand(const char* args);
bool HandleLookupCreatureCommand(const char* args);
bool HandleLookupEventCommand(const char* args);
@@ -166,6 +253,7 @@ class ChatHandler
bool HandleModifyHPCommand(const char* args);
bool HandleModifyManaCommand(const char* args);
bool HandleModifyRageCommand(const char* args);
+ bool HandleModifyRunicPowerCommand(const char* args);
bool HandleModifyEnergyCommand(const char* args);
bool HandleModifyMoneyCommand(const char* args);
bool HandleModifyASpeedCommand(const char* args);
@@ -182,12 +270,18 @@ class ChatHandler
bool HandleModifyHonorCommand (const char* args);
bool HandleModifyRepCommand(const char* args);
bool HandleModifyArenaCommand(const char* args);
+ bool HandleModifyPhaseCommand(const char* args);
bool HandleModifyGenderCommand(const char* args);
+ //-----------------------Npc Commands-----------------------
bool HandleNpcAddCommand(const char* args);
bool HandleNpcAddMoveCommand(const char* args);
+ bool HandleNpcAddVendorItemCommand(const char* args);
+ bool HandleNpcAllowMovementCommand(const char* args);
bool HandleNpcChangeEntryCommand(const char *args);
+ bool HandleNpcChangeLevelCommand(const char* args);
bool HandleNpcDeleteCommand(const char* args);
+ bool HandleNpcDelVendorItemCommand(const char* args);
bool HandleNpcFactionIdCommand(const char* args);
bool HandleNpcFlagCommand(const char* args);
bool HandleNpcFollowCommand(const char* args);
@@ -195,8 +289,10 @@ class ChatHandler
bool HandleNpcMoveCommand(const char* args);
bool HandleNpcPlayEmoteCommand(const char* args);
bool HandleNpcSayCommand(const char* args);
+ bool HandleNpcSetDeathStateCommand(const char* args);
bool HandleNpcSetModelCommand(const char* args);
bool HandleNpcSetMoveTypeCommand(const char* args);
+ bool HandleNpcSetPhaseCommand(const char* args);
bool HandleNpcSpawnDistCommand(const char* args);
bool HandleNpcSpawnTimeCommand(const char* args);
bool HandleNpcTameCommand(const char* args);
@@ -207,8 +303,21 @@ class ChatHandler
bool HandleNpcAddFormationCommand(const char* args);
bool HandleNpcSetLinkCommand(const char* args);
- bool HandleReloadCommand(const char* args);
+ //TODO: NpcCommands that needs to be fixed :
+ bool HandleNpcAddWeaponCommand(const char* args);
+ bool HandleNpcNameCommand(const char* args);
+ bool HandleNpcSubNameCommand(const char* args);
+ //----------------------------------------------------------
+
+ bool HandlePDumpLoadCommand(const char *args);
+ bool HandlePDumpWriteCommand(const char *args);
+
+ bool HandleQuestAdd(const char * args);
+ bool HandleQuestRemove(const char * args);
+ bool HandleQuestComplete(const char * args);
+
bool HandleReloadAllCommand(const char* args);
+ bool HandleReloadAllAchievementCommand(const char* args);
bool HandleReloadAllAreaCommand(const char* args);
bool HandleReloadAllItemCommand(const char* args);
bool HandleReloadAllLootCommand(const char* args);
@@ -220,7 +329,8 @@ class ChatHandler
bool HandleReloadConfigCommand(const char* args);
- bool HandleReloadWpScriptsCommand(const char* args);
+ bool HandleReloadAchievementCriteriaDataCommand(const char* args);
+ bool HandleReloadAchievementRewardCommand(const char* args);
bool HandleReloadAreaTriggerTavernCommand(const char* args);
bool HandleReloadAreaTriggerTeleportCommand(const char* args);
bool HandleReloadAccessRequirementCommand(const char* args);
@@ -235,21 +345,35 @@ class ChatHandler
bool HandleReloadGameTeleCommand(const char* args);
bool HandleReloadGOQuestRelationsCommand(const char* args);
bool HandleReloadGOQuestInvRelationsCommand(const char* args);
+ bool HandleReloadItemEnchantementsCommand(const char* args);
+ bool HandleReloadLocalesAchievementRewardCommand(const char* args);
+ bool HandleReloadLocalesCreatureCommand(const char* args);
+ bool HandleReloadLocalesGameobjectCommand(const char* args);
+ bool HandleReloadLocalesItemCommand(const char* args);
+ bool HandleReloadLocalesNpcTextCommand(const char* args);
+ bool HandleReloadLocalesPageTextCommand(const char* args);
+ bool HandleReloadLocalesPointsOfInterestCommand(const char* args);
+ bool HandleReloadLocalesQuestCommand(const char* args);
+// bool HandleReloadAuctionsCommand(const char* args);
bool HandleReloadLootTemplatesCreatureCommand(const char* args);
bool HandleReloadLootTemplatesDisenchantCommand(const char* args);
bool HandleReloadLootTemplatesFishingCommand(const char* args);
bool HandleReloadLootTemplatesGameobjectCommand(const char* args);
bool HandleReloadLootTemplatesItemCommand(const char* args);
+ bool HandleReloadLootTemplatesMillingCommand(const char* args);
bool HandleReloadLootTemplatesPickpocketingCommand(const char* args);
bool HandleReloadLootTemplatesProspectingCommand(const char* args);
bool HandleReloadLootTemplatesReferenceCommand(const char* args);
bool HandleReloadLootTemplatesQuestMailCommand(const char* args);
bool HandleReloadLootTemplatesSkinningCommand(const char* args);
+ bool HandleReloadLootTemplatesSpellCommand(const char* args);
bool HandleReloadTrinityStringCommand(const char* args);
bool HandleReloadNpcGossipCommand(const char* args);
bool HandleReloadNpcOptionCommand(const char* args);
bool HandleReloadNpcTrainerCommand(const char* args);
bool HandleReloadNpcVendorCommand(const char* args);
+ bool HandleReloadPageTextsCommand(const char* args);
+ bool HandleReloadPointsOfInterestCommand(const char* args);
bool HandleReloadQuestAreaTriggersCommand(const char* args);
bool HandleReloadQuestEndScriptsCommand(const char* args);
bool HandleReloadQuestStartScriptsCommand(const char* args);
@@ -260,30 +384,33 @@ class ChatHandler
bool HandleReloadSkillFishingBaseLevelCommand(const char* args);
bool HandleReloadSpellAffectCommand(const char* args);
bool HandleReloadSpellRequiredCommand(const char* args);
+ bool HandleReloadSpellAreaCommand(const char* args);
bool HandleReloadSpellElixirCommand(const char* args);
bool HandleReloadSpellLearnSpellCommand(const char* args);
bool HandleReloadSpellLinkedSpellCommand(const char* args);
bool HandleReloadSpellProcEventCommand(const char* args);
+ bool HandleReloadSpellBonusesCommand(const char* args);
bool HandleReloadSpellScriptTargetCommand(const char* args);
bool HandleReloadSpellScriptsCommand(const char* args);
bool HandleReloadSpellTargetPositionCommand(const char* args);
bool HandleReloadSpellThreatsCommand(const char* args);
bool HandleReloadSpellPetAurasCommand(const char* args);
bool HandleReloadSpellDisabledCommand(const char* args);
- bool HandleReloadPageTextsCommand(const char* args);
- bool HandleReloadItemEnchantementsCommand(const char* args);
- bool HandleReloadLocalesCreatureCommand(const char* args);
- bool HandleReloadLocalesGameobjectCommand(const char* args);
- bool HandleReloadLocalesItemCommand(const char* args);
- bool HandleReloadLocalesNpcTextCommand(const char* args);
- bool HandleReloadLocalesPageTextCommand(const char* args);
- bool HandleReloadLocalesQuestCommand(const char* args);
bool HandleReloadAuctionsCommand(const char* args);
+ bool HandleReloadWpScriptsCommand(const char* args);
- bool HandleInstanceListBindsCommand(const char* args);
- bool HandleInstanceUnbindCommand(const char* args);
- bool HandleInstanceStatsCommand(const char* args);
- bool HandleInstanceSaveDataCommand(const char * args);
+ bool HandleResetAchievementsCommand(const char * args);
+ bool HandleResetAllCommand(const char * args);
+ bool HandleResetHonorCommand(const char * args);
+ bool HandleResetLevelCommand(const char * args);
+ bool HandleResetSpellsCommand(const char * args);
+ bool HandleResetStatsCommand(const char * args);
+ bool HandleResetTalentsCommand(const char * args);
+
+ bool HandleSendItemsCommand(const char* args);
+ bool HandleSendMailCommand(const char* args);
+ bool HandleSendMessageCommand(const char * args);
+ bool HandleSendMoneyCommand(const char* args);
bool HandleServerCorpsesCommand(const char* args);
bool HandleServerExitCommand(const char* args);
@@ -291,46 +418,58 @@ class ChatHandler
bool HandleServerIdleShutDownCommand(const char* args);
bool HandleServerInfoCommand(const char* args);
bool HandleServerMotdCommand(const char* args);
+ bool HandleServerPLimitCommand(const char* args);
bool HandleServerRestartCommand(const char* args);
- bool HandleServerSetMotdCommand(const char* args);
bool HandleServerSetLogLevelCommand(const char* args);
- bool HandleServerSetDiffTimeCommand(const char* args);
+ bool HandleServerSetMotdCommand(const char* args);
bool HandleServerShutDownCommand(const char* args);
bool HandleServerShutDownCancelCommand(const char* args);
+ bool HandleServerSetClosedCommand(const char* args);
- bool HandleAddHonorCommand(const char* args);
- bool HandleHonorAddKillCommand(const char* args);
- bool HandleUpdateHonorFieldsCommand(const char* args);
+ bool HandleServerSetLogFileLevelCommand(const char* args);
+ bool HandleServerSetDiffTimeCommand(const char* args);
- bool HandleLoadScriptsCommand(const char* args);
- bool HandleSendQuestPartyMsgCommand(const char* args);
- bool HandleSendQuestInvalidMsgCommand(const char* args);
+ bool HandleTeleCommand(const char * args);
+ bool HandleTeleAddCommand(const char * args);
+ bool HandleTeleDelCommand(const char * args);
+ bool HandleTeleGroupCommand(const char* args);
+ bool HandleTeleNameCommand(const char* args);
- bool HandleDebugInArcCommand(const char* args);
- bool HandleDebugSpellFailCommand(const char* args);
+ bool HandleUnBanAccountCommand(const char* args);
+ bool HandleUnBanCharacterCommand(const char* args);
+ bool HandleUnBanIPCommand(const char* args);
+
+ bool HandleWpAddCommand(const char* args);
+ bool HandleWpLoadPathCommand(const char* args);
+ bool HandleWpUnLoadPathCommand(const char* args);
+ bool HandleWpModifyCommand(const char* args);
+ bool HandleWpEventCommand(const char* args);
+ bool HandleWpShowCommand(const char* args);
+ bool HandleReloadAllPaths(const char *args);
+
+ bool HandleHelpCommand(const char* args);
+ bool HandleCommandsCommand(const char* args);
+ bool HandleStartCommand(const char* args);
+ bool HandleDismountCommand(const char* args);
+ bool HandleSaveCommand(const char* args);
+
+ bool HandleNamegoCommand(const char* args);
+ bool HandleGonameCommand(const char* args);
+ bool HandleGroupgoCommand(const char* args);
+ bool HandleRecallCommand(const char* args);
+ bool HandleAnnounceCommand(const char* args);
+ bool HandleNotifyCommand(const char* args);
+ bool HandleGPSCommand(const char* args);
+ bool HandleTaxiCheatCommand(const char* args);
+ bool HandleWhispersCommand(const char* args);
+ bool HandleModifyDrunkCommand(const char* args);
+
+ bool HandleLoadScriptsCommand(const char* args);
bool HandleGUIDCommand(const char* args);
- bool HandleNameCommand(const char* args);
- bool HandleSubNameCommand(const char* args);
bool HandleItemMoveCommand(const char* args);
bool HandleDeMorphCommand(const char* args);
- bool HandleAddVendorItemCommand(const char* args);
- bool HandleDelVendorItemCommand(const char* args);
- bool HandleChangeLevelCommand(const char* args);
- bool HandleSetPoiCommand(const char* args);
- bool HandleEquipErrorCommand(const char* args);
- bool HandleGoCreatureCommand(const char* args);
- bool HandleGoObjectCommand(const char* args);
- bool HandleGoTicketCommand(const char* args);
- bool HandleGoTriggerCommand(const char* args);
- bool HandleGoGraveyardCommand(const char* args);
- bool HandleTargetObjectCommand(const char* args);
- bool HandleDelObjectCommand(const char* args);
- bool HandleMoveObjectCommand(const char* args);
- bool HandleTurnObjectCommand(const char* args);
- bool HandleObjectStateCommand(const char* args);
bool HandlePInfoCommand(const char* args);
- bool HandlePLimitCommand(const char* args);
bool HandleMuteCommand(const char* args);
bool HandleUnmuteCommand(const char* args);
bool HandleMovegensCommand(const char* args);
@@ -338,38 +477,14 @@ class ChatHandler
bool HandleUnFreezeCommand(const char *args);
bool HandleListFreezeCommand(const char* args);
- bool HandleCharacterDeleteCommand(const char* args);
- bool HandleBanAccountCommand(const char* args);
- bool HandleBanCharacterCommand(const char* args);
- bool HandleBanIPCommand(const char* args);
- bool HandleUnBanAccountCommand(const char* args);
- bool HandleUnBanCharacterCommand(const char* args);
- bool HandleUnBanIPCommand(const char* args);
- bool HandleBanInfoAccountCommand(const char* args);
- bool HandleBanInfoCharacterCommand(const char* args);
- bool HandleBanInfoIPCommand(const char* args);
- bool HandleBanListAccountCommand(const char* args);
- bool HandleBanListCharacterCommand(const char* args);
- bool HandleBanListIPCommand(const char* args);
- bool HandleGoXYCommand(const char* args);
- bool HandleGoXYZCommand(const char* args);
- bool HandleGoZoneXYCommand(const char* args);
- bool HandleGoGridCommand(const char* args);
- bool HandleAddWeaponCommand(const char* args);
- bool HandleAllowMovementCommand(const char* args);
- bool HandleGoCommand(const char* args);
-
bool HandleCooldownCommand(const char* args);
bool HandleUnLearnCommand(const char* args);
bool HandleGetDistanceCommand(const char* args);
- bool HandleGameObjectCommand(const char* args);
- bool HandleAnimCommand(const char* args);
- bool HandlePlaySoundCommand(const char* args);
- bool HandleStandStateCommand(const char* args);
+ bool HandleModifyStandStateCommand(const char* args);
bool HandleDieCommand(const char* args);
bool HandleDamageCommand(const char *args);
bool HandleReviveCommand(const char* args);
- bool HandleMorphCommand(const char* args);
+ bool HandleModifyMorphCommand(const char* args);
bool HandleAuraCommand(const char* args);
bool HandleUnAuraCommand(const char* args);
bool HandleLinkGraveCommand(const char* args);
@@ -393,29 +508,9 @@ class ChatHandler
bool HandleGroupDisbandCommand(const char* args);
bool HandleGroupRemoveCommand(const char* args);
- bool HandleGuildCreateCommand(const char* args);
- bool HandleGuildInviteCommand(const char* args);
- bool HandleGuildUninviteCommand(const char* args);
- bool HandleGuildRankCommand(const char* args);
- bool HandleGuildDeleteCommand(const char* args);
- bool HandleUpdate(const char* args);
bool HandleBankCommand(const char* args);
bool HandleChangeWeather(const char* args);
bool HandleKickPlayerCommand(const char * args);
- bool HandleTeleCommand(const char * args);
- bool HandleAddTeleCommand(const char * args);
- bool HandleDelTeleCommand(const char * args);
- bool HandleListAurasCommand(const char * args);
-
- bool HandleResetHonorCommand(const char * args);
- bool HandleResetLevelCommand(const char * args);
- bool HandleResetSpellsCommand(const char * args);
-
- bool HandleResetStatsCommand(const char * args);
- bool HandleResetTalentsCommand(const char * args);
-
- bool HandleResetAllCommand(const char * args);
-
// GM ticket command handlers
bool HandleGMTicketListCommand(const char* args);
@@ -432,43 +527,13 @@ class ChatHandler
bool HandleMaxSkillCommand(const char* args);
bool HandleSetSkillCommand(const char* args);
- bool HandleListCreatureCommand(const char* args);
- bool HandleListItemCommand(const char* args);
- bool HandleListObjectCommand(const char* args);
- bool HandleNearObjectCommand(const char* args);
- bool HandlePasswordCommand(const char* args);
- bool HandleLockAccountCommand(const char* args);
bool HandleRespawnCommand(const char* args);
-
- //New Wp Commands
- bool HandleWpAddCommand(const char* args);
- bool HandleWpLoadPathCommand(const char* args);
- bool HandleWpUnLoadPathCommand(const char* args);
- bool HandleWpModifyCommand(const char* args);
- bool HandleWpEventCommand(const char* args);
- bool HandleWpShowCommand(const char* args);
- bool HandleReloadAllPaths(const char *args);
-
- bool HandleFlyModeCommand(const char* args);
- bool HandleSendOpcodeCommand(const char* args);
- bool HandleSellErrorCommand(const char* args);
- bool HandleBuyErrorCommand(const char* args);
- bool HandleUpdateWorldStateCommand(const char* args);
- bool HandlePlaySound2Command(const char* args);
- bool HandleSendChannelNotifyCommand(const char* args);
- bool HandleSendChatMsgCommand(const char* args);
- bool HandleRenameCommand(const char * args);
- bool HandleLoadPDumpCommand(const char *args);
- bool HandleWritePDumpCommand(const char *args);
- bool HandleCastCommand(const char *args);
- bool HandleCastBackCommand(const char *args);
- bool HandleCastDistCommand(const char *args);
- bool HandleCastSelfCommand(const char *args);
- bool HandleCastTargetCommand(const char *args);
bool HandleComeToMeCommand(const char *args);
bool HandleCombatStopCommand(const char *args);
- bool HandleCharDeleteCommand(const char *args);
- bool HandleSendMessageCommand(const char * args);
+
+ /*bool HandleCharDeleteCommand(const char *args);
+ bool HandleSendMessageCommand(const char * args);*/
+
bool HandleFlushArenaPointsCommand(const char *args);
bool HandlePlayAllCommand(const char* args);
bool HandleRepairitemsCommand(const char* args);
@@ -477,32 +542,30 @@ class ChatHandler
bool HandleTempAddSpwCommand(const char* args);
//! Development Commands
- bool HandleSetValue(const char* args);
- bool HandleGetValue(const char* args);
+
+ /*bool HandleQuestAdd(const char * args);
+ bool HandleQuestRemove(const char * args);
+ bool HandleQuestComplete(const char * args);*/
+
bool HandleSet32Bit(const char* args);
- bool HandleMod32Value(const char* args);
- bool HandleAddQuest(const char * args);
- bool HandleRemoveQuest(const char * args);
- bool HandleCompleteQuest(const char * args);
bool HandleSaveAllCommand(const char* args);
- bool HandleGetItemState(const char * args);
- bool HandleGetLootRecipient(const char * args);
- bool HandleDebugArenaCommand(const char * args);
- bool HandleDebugThreatList(const char * args);
- bool HandleDebugHostilRefList(const char * args);
- bool HandlePossessCommand(const char* args);
- bool HandleUnPossessCommand(const char* args);
- bool HandleBindSightCommand(const char* args);
- bool HandleUnbindSightCommand(const char* args);
Player* getSelectedPlayer();
Creature* getSelectedCreature();
Unit* getSelectedUnit();
+
char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL);
char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL);
+
uint32 extractSpellIdFromLink(char* text);
+ uint64 extractGuidFromLink(char* text);
GameTele const* extractGameTeleFromLink(char* text);
bool GetPlayerGroupAndGUIDByName(const char* cname, Player* &plr, Group* &group, uint64 &guid, bool offline = false);
+ std::string extractPlayerNameFromLink(char* text);
+
+ std::string playerLink(std::string const& name) const { return m_session ? "|cffffffff|Hplayer:"+name+"|h["+name+"]|h|r" : name; }
+ virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); }
+ std::string GetNameLink(Player* chr) const { return playerLink(chr->GetName()); }
GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry);
@@ -512,6 +575,7 @@ class ChatHandler
bool HandleBanHelper(BanMode mode,char const* args);
bool HandleBanInfoHelper(uint32 accountid, char const* accountname);
bool HandleUnBanHelper(BanMode mode,char const* args);
+ void HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel);
void SetSentErrorMessage(bool val){ sentErrorMessage = val;};
private:
@@ -532,7 +596,7 @@ class CliHandler : public ChatHandler
const char *GetTrinityString(int32 entry) const;
bool isAvailable(ChatCommand const& cmd) const;
void SendSysMessage(const char *str);
- char const* GetName() const;
+ std::string GetNameLink() const;
bool needReportToTarget(Player* chr) const;
private:
diff --git a/src/game/ChatHandler.cpp b/src/game/ChatHandler.cpp
index 22b58cccdf3..142de50b059 100644
--- a/src/game/ChatHandler.cpp
+++ b/src/game/ChatHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -30,13 +30,14 @@
#include "ChannelMgr.h"
#include "Group.h"
#include "Guild.h"
-#include "MapManager.h"
#include "ObjectAccessor.h"
#include "ScriptCalls.h"
#include "Player.h"
#include "SpellAuras.h"
#include "Language.h"
#include "Util.h"
+#include "GridNotifiersImpl.h"
+#include "CellImpl.h"
void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
{
@@ -66,11 +67,11 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
if(langDesc->skill_id != 0 && !_player->HasSkill(langDesc->skill_id))
{
// also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
- Unit::AuraList const& langAuras = _player->GetAurasByType(SPELL_AURA_COMPREHEND_LANGUAGE);
+ Unit::AuraEffectList const& langAuras = _player->GetAurasByType(SPELL_AURA_COMPREHEND_LANGUAGE);
bool foundAura = false;
- for(Unit::AuraList::const_iterator i = langAuras.begin();i != langAuras.end(); ++i)
+ for(Unit::AuraEffectList::const_iterator i = langAuras.begin();i != langAuras.end(); ++i)
{
- if((*i)->GetModifier()->m_miscvalue == lang)
+ if((*i)->GetMiscValue() == int32(lang))
{
foundAura = true;
break;
@@ -85,6 +86,21 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
if(lang == LANG_ADDON)
{
+ if(sWorld.getConfig(CONFIG_CHATLOG_ADDON))
+ {
+ std::string msg = "";
+ recv_data >> msg;
+
+ if(msg.empty())
+ {
+ sLog.outDebug("Player %s send empty addon msg", GetPlayer()->GetName());
+ return;
+ }
+
+ sLog.outChat("[ADDON] Player %s sends: %s",
+ GetPlayer()->GetName(), msg.c_str());
+ }
+
// Disabled addon channel?
if(!sWorld.getConfig(CONFIG_ADDON_CHANNEL))
return;
@@ -122,9 +138,9 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
}
// but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used)
- Unit::AuraList const& ModLangAuras = _player->GetAurasByType(SPELL_AURA_MOD_LANGUAGE);
+ Unit::AuraEffectList const& ModLangAuras = _player->GetAurasByType(SPELL_AURA_MOD_LANGUAGE);
if(!ModLangAuras.empty())
- lang = ModLangAuras.front()->GetModifier()->m_miscvalue;
+ lang = ModLangAuras.front()->GetMiscValue();
}
if (!_player->CanSpeak())
@@ -192,8 +208,8 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
Player *player = objmgr.GetPlayer(to.c_str());
uint32 tSecurity = GetSecurity();
- uint32 pSecurity = player ? player->GetSession()->GetSecurity() : 0;
- if(!player || tSecurity == SEC_PLAYER && pSecurity > SEC_PLAYER && !player->isAcceptWhispers())
+ uint32 pSecurity = player ? player->GetSession()->GetSecurity() : SEC_PLAYER;
+ if (!player || (tSecurity == SEC_PLAYER && pSecurity > SEC_PLAYER && !player->isAcceptWhispers()))
{
WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, (to.size()+1));
data<<to;
@@ -235,13 +251,19 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
if(msg.empty())
break;
- Group *group = GetPlayer()->GetGroup();
- if(!group)
+ // if player is in battleground, he cannot say to battleground members by /p
+ Group *group = GetPlayer()->GetOriginalGroup();
+ // so if player hasn't OriginalGroup and his player->GetGroup() is BG raid, then return
+ if( !group && (!(group = GetPlayer()->GetGroup()) || group->isBGGroup()) )
return;
WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_PARTY, lang, NULL, 0, msg.c_str(),NULL);
- group->BroadcastPacket(&data, group->GetMemberGroup(GetPlayer()->GetGUID()));
+ group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID()));
+
+ if(sWorld.getConfig(CONFIG_CHATLOG_PARTY))
+ sLog.outChat("[PARTY] Player %s tells group with leader %s: %s",
+ GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str());
}
break;
case CHAT_MSG_GUILD:
@@ -267,6 +289,17 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
if (guild)
guild->BroadcastToGuild(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
+
+ if(lang != LANG_ADDON && sWorld.getConfig(CONFIG_CHATLOG_GUILD))
+ {
+ sLog.outChat("[GUILD] Player %s tells guild %s: %s",
+ GetPlayer()->GetName(), guild->GetName().c_str(), msg.c_str());
+ }
+ else if (lang == LANG_ADDON && sWorld.getConfig(CONFIG_CHATLOG_ADDON))
+ {
+ sLog.outChat("[ADDON] Player %s sends to guild %s: %s",
+ GetPlayer()->GetName(), guild->GetName().c_str(), msg.c_str());
+ }
}
break;
@@ -294,6 +327,10 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
if (guild)
guild->BroadcastToOfficers(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
+
+ if(sWorld.getConfig(CONFIG_CHATLOG_GUILD))
+ sLog.outChat("[OFFICER] Player %s tells guild %s officers: %s",
+ GetPlayer()->GetName(), guild->GetName().c_str(), msg.c_str());
}
break;
}
@@ -315,13 +352,19 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
if(msg.empty())
break;
- Group *group = GetPlayer()->GetGroup();
- if(!group || !group->isRaidGroup() || group->isBGGroup())
+ // if player is in battleground, he cannot say to battleground members by /ra
+ Group *group = GetPlayer()->GetOriginalGroup();
+ // so if player hasn't OriginalGroup and his player->GetGroup() is BG raid or his group isn't raid, then return
+ if ((!group && !(group = GetPlayer()->GetGroup())) || group->isBGGroup() || !group->isRaidGroup())
return;
WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID, lang, "", 0, msg.c_str(),NULL);
- group->BroadcastPacket(&data);
+ group->BroadcastPacket(&data, false);
+
+ if(sWorld.getConfig(CONFIG_CHATLOG_RAID))
+ sLog.outChat("[RAID] Player %s tells raid with leader %s: %s",
+ GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str());
} break;
case CHAT_MSG_RAID_LEADER:
{
@@ -341,13 +384,18 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
if(msg.empty())
break;
- Group *group = GetPlayer()->GetGroup();
- if(!group || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID()) || group->isBGGroup())
+ // if player is in battleground, he cannot say to battleground members by /ra
+ Group *group = GetPlayer()->GetOriginalGroup();
+ if( !group && !(group = GetPlayer()->GetGroup()) || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
return;
WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_LEADER, lang, "", 0, msg.c_str(),NULL);
- group->BroadcastPacket(&data);
+ group->BroadcastPacket(&data, false);
+
+ if(sWorld.getConfig(CONFIG_CHATLOG_RAID))
+ sLog.outChat("[RAID] Leader player %s tells raid: %s",
+ GetPlayer()->GetName(), msg.c_str());
} break;
case CHAT_MSG_RAID_WARNING:
{
@@ -366,8 +414,13 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
return;
WorldPacket data;
+ //in battleground, raid warning is sent only to players in battleground - code is ok
ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_WARNING, lang, "", 0, msg.c_str(),NULL);
- group->BroadcastPacket(&data);
+ group->BroadcastPacket(&data, false);
+
+ if(sWorld.getConfig(CONFIG_CHATLOG_RAID))
+ sLog.outChat("[RAID] Leader player %s warns raid with: %s",
+ GetPlayer()->GetName(), msg.c_str());
} break;
case CHAT_MSG_BATTLEGROUND:
@@ -382,13 +435,18 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
if(msg.empty())
break;
+ //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
Group *group = GetPlayer()->GetGroup();
- if(!group || !group->isRaidGroup() || !group->isBGGroup())
+ if(!group || !group->isBGGroup())
return;
WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND, lang, "", 0, msg.c_str(),NULL);
- group->BroadcastPacket(&data);
+ group->BroadcastPacket(&data, false);
+
+ if(sWorld.getConfig(CONFIG_CHATLOG_BGROUND))
+ sLog.outChat("[BATTLEGROUND] Player %s tells battleground with leader %s: %s",
+ GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str());
} break;
case CHAT_MSG_BATTLEGROUND_LEADER:
@@ -403,13 +461,18 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
if(msg.empty())
break;
+ //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
Group *group = GetPlayer()->GetGroup();
- if(!group || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID()) || !group->isBGGroup())
+ if(!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
return;
WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND_LEADER, lang, "", 0, msg.c_str(),NULL);
- group->BroadcastPacket(&data);
+ group->BroadcastPacket(&data, false);
+
+ if(sWorld.getConfig(CONFIG_CHATLOG_BGROUND))
+ sLog.outChat("[RAID] Leader player %s tells battleground: %s",
+ GetPlayer()->GetName(), msg.c_str());
} break;
case CHAT_MSG_CHANNEL:
@@ -431,8 +494,22 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
{
- if(Channel *chn = cMgr->GetChannel(channel,_player))
+ Channel *chn = cMgr->GetChannel(channel,_player);
+ if(chn)
+ {
chn->Say(_player->GetGUID(),msg.c_str(),lang);
+
+ if((chn->HasFlag(CHANNEL_FLAG_TRADE) ||
+ chn->HasFlag(CHANNEL_FLAG_GENERAL) ||
+ chn->HasFlag(CHANNEL_FLAG_CITY) ||
+ chn->HasFlag(CHANNEL_FLAG_LFG)) &&
+ sWorld.getConfig(CONFIG_CHATLOG_SYSCHAN))
+ sLog.outChat("[SYSCHAN] Player %s tells channel %s: %s",
+ GetPlayer()->GetName(), chn->GetName().c_str(), msg.c_str());
+ else if(sWorld.getConfig(CONFIG_CHATLOG_CHANNEL))
+ sLog.outChat("[CHANNEL] Player %s tells channel %s: %s",
+ GetPlayer()->GetName(), chn->GetName().c_str(), msg.c_str());
+ }
}
} break;
@@ -491,6 +568,38 @@ void WorldSession::HandleEmoteOpcode( WorldPacket & recv_data )
GetPlayer()->HandleEmoteCommand(emote);
}
+namespace MaNGOS
+{
+ class EmoteChatBuilder
+ {
+ public:
+ EmoteChatBuilder(Player const& pl, uint32 text_emote, uint32 emote_num, Unit const* target)
+ : i_player(pl), i_text_emote(text_emote), i_emote_num(emote_num), i_target(target) {}
+
+ void operator()(WorldPacket& data, int32 loc_idx)
+ {
+ char const* nam = i_target ? i_target->GetNameForLocaleIdx(loc_idx) : NULL;
+ uint32 namlen = (nam ? strlen(nam) : 0) + 1;
+
+ data.Initialize(SMSG_TEXT_EMOTE, (20+namlen));
+ data << i_player.GetGUID();
+ data << (uint32)i_text_emote;
+ data << i_emote_num;
+ data << (uint32)namlen;
+ if( namlen > 1 )
+ data.append(nam, namlen);
+ else
+ data << (uint8)0x00;
+ }
+
+ private:
+ Player const& i_player;
+ uint32 i_text_emote;
+ uint32 i_emote_num;
+ Unit const* i_target;
+ };
+} // namespace MaNGOS
+
void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
{
if(!GetPlayer()->isAlive())
@@ -512,56 +621,44 @@ void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
recv_data >> emoteNum;
recv_data >> guid;
- const char *nam = 0;
- uint32 namlen = 1;
+ EmotesTextEntry const *em = sEmotesTextStore.LookupEntry(text_emote);
+ if (!em)
+ return;
- Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
- Creature *pCreature = dynamic_cast<Creature *>(unit);
- if(unit)
+ uint32 emote_anim = em->textid;
+
+ switch(emote_anim)
{
- nam = unit->GetName();
- namlen = (nam ? strlen(nam) : 0) + 1;
+ case EMOTE_STATE_SLEEP:
+ case EMOTE_STATE_SIT:
+ case EMOTE_STATE_KNEEL:
+ case EMOTE_ONESHOT_NONE:
+ break;
+ default:
+ GetPlayer()->HandleEmoteCommand(emote_anim);
+ break;
}
- EmotesTextEntry const *em = sEmotesTextStore.LookupEntry(text_emote);
- if (em)
- {
- uint32 emote_anim = em->textid;
+ Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
- WorldPacket data;
+ CellPair p = MaNGOS::ComputeCellPair(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
- switch(emote_anim)
- {
- case EMOTE_STATE_SLEEP:
- case EMOTE_STATE_SIT:
- case EMOTE_STATE_KNEEL:
- case EMOTE_ONESHOT_NONE:
- break;
- default:
- GetPlayer()->HandleEmoteCommand(emote_anim);
- break;
- }
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
- data.Initialize(SMSG_TEXT_EMOTE, (20+namlen));
- data << GetPlayer()->GetGUID();
- data << (uint32)text_emote;
- data << emoteNum;
- data << (uint32)namlen;
- if( namlen > 1 )
- {
- data.append(nam, namlen);
- }
- else
- {
- data << (uint8)0x00;
- }
+ MaNGOS::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
+ MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > emote_do(emote_builder);
+ MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > > emote_worker(GetPlayer(),sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),emote_do);
+ TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > >, WorldTypeMapContainer > message(emote_worker);
+ CellLock<GridReadGuard> cell_lock(cell, p);
+ cell_lock->Visit(cell_lock, message, *GetPlayer()->GetMap());
- GetPlayer()->SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true);
+ GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
- //Send scripted event call
- if (pCreature && Script)
- Script->ReceiveEmote(GetPlayer(),pCreature,text_emote);
- }
+ //Send scripted event call
+ if (unit && unit->GetTypeId()==TYPEID_UNIT && ((Creature*)unit)->AI())
+ ((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(),text_emote);
}
void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data )
diff --git a/src/game/CombatHandler.cpp b/src/game/CombatHandler.cpp
index f9fb4fd7ee0..f732f128fd0 100644
--- a/src/game/CombatHandler.cpp
+++ b/src/game/CombatHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,7 +22,6 @@
#include "Log.h"
#include "WorldPacket.h"
#include "WorldSession.h"
-#include "World.h"
#include "ObjectAccessor.h"
#include "CreatureAI.h"
#include "ObjectDefines.h"
diff --git a/src/game/ConfusedMovementGenerator.cpp b/src/game/ConfusedMovementGenerator.cpp
index bb7b56fdca7..bbb0b9ebc6a 100644
--- a/src/game/ConfusedMovementGenerator.cpp
+++ b/src/game/ConfusedMovementGenerator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -56,11 +56,12 @@ ConfusedMovementGenerator<T>::Initialize(T &unit)
bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z);
// if generated wrong path just ignore
- if( is_water && !is_water_ok || !is_water && !is_land_ok )
+ if ((is_water && !is_water_ok) || (!is_water && !is_land_ok))
{
i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x;
i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y;
}
+
unit.UpdateGroundPositionZ(i_waypoints[idx][0],i_waypoints[idx][1],z);
i_waypoints[idx][2] = z;
}
diff --git a/src/game/ConfusedMovementGenerator.h b/src/game/ConfusedMovementGenerator.h
index 4940c4bcaea..ad47b13cb39 100644
--- a/src/game/ConfusedMovementGenerator.h
+++ b/src/game/ConfusedMovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/Corpse.cpp b/src/game/Corpse.cpp
index fe4794dea41..3df7838cf60 100644
--- a/src/game/Corpse.cpp
+++ b/src/game/Corpse.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,12 +22,9 @@
#include "Corpse.h"
#include "Player.h"
#include "UpdateMask.h"
-#include "MapManager.h"
#include "ObjectAccessor.h"
#include "Database/DatabaseEnv.h"
#include "Opcodes.h"
-#include "WorldSession.h"
-#include "WorldPacket.h"
#include "GossipDef.h"
#include "World.h"
@@ -36,7 +33,7 @@ Corpse::Corpse(CorpseType type) : WorldObject()
m_objectType |= TYPEMASK_CORPSE;
m_objectTypeId = TYPEID_CORPSE;
// 2.3.2 - 0x58
- m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION);
+ m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);
m_valuesCount = CORPSE_END;
@@ -71,26 +68,26 @@ bool Corpse::Create( uint32 guidlow )
return true;
}
-bool Corpse::Create( uint32 guidlow, Player *owner, uint32 mapid, float x, float y, float z, float ang )
+bool Corpse::Create( uint32 guidlow, Player *owner)
{
SetInstanceId(owner->GetInstanceId());
- WorldObject::_Create(guidlow, HIGHGUID_CORPSE, mapid);
+ WorldObject::_Create(guidlow, HIGHGUID_CORPSE, owner->GetMapId(), owner->GetPhaseMask());
- Relocate(x,y,z,ang);
+ Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
if(!IsPositionValid())
{
- sLog.outError("ERROR: Corpse (guidlow %d, owner %s) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
- guidlow,owner->GetName(),x,y);
+ sLog.outError("Corpse (guidlow %d, owner %s) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
+ guidlow,owner->GetName(),owner->GetPositionX(), owner->GetPositionY());
return false;
}
SetFloatValue( OBJECT_FIELD_SCALE_X, 1 );
- SetFloatValue( CORPSE_FIELD_POS_X, x );
- SetFloatValue( CORPSE_FIELD_POS_Y, y );
- SetFloatValue( CORPSE_FIELD_POS_Z, z );
- SetFloatValue( CORPSE_FIELD_FACING, ang );
+ SetFloatValue( CORPSE_FIELD_POS_X, GetPositionX() );
+ SetFloatValue( CORPSE_FIELD_POS_Y, GetPositionY() );
+ SetFloatValue( CORPSE_FIELD_POS_Z, GetPositionZ() );
+ SetFloatValue( CORPSE_FIELD_FACING, GetOrientation() );
SetUInt64Value( CORPSE_FIELD_OWNER, owner->GetGUID() );
m_grid = Trinity::ComputeGridPair(GetPositionX(), GetPositionY());
@@ -100,17 +97,27 @@ bool Corpse::Create( uint32 guidlow, Player *owner, uint32 mapid, float x, float
void Corpse::SaveToDB()
{
- // prevent DB data inconsistance problems and duplicates
+ // prevent DB data inconsistence problems and duplicates
CharacterDatabase.BeginTransaction();
DeleteFromDB();
std::ostringstream ss;
- ss << "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,data,time,corpse_type,instance) VALUES ("
- << GetGUIDLow() << ", " << GUID_LOPART(GetOwnerGUID()) << ", " << GetPositionX() << ", " << GetPositionY() << ", " << GetPositionZ() << ", "
- << GetOrientation() << ", " << GetZoneId() << ", " << GetMapId() << ", '";
- for(uint16 i = 0; i < m_valuesCount; i++ )
+ ss << "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,data,time,corpse_type,instance,phaseMask) VALUES ("
+ << GetGUIDLow() << ", "
+ << GUID_LOPART(GetOwnerGUID()) << ", "
+ << GetPositionX() << ", "
+ << GetPositionY() << ", "
+ << GetPositionZ() << ", "
+ << GetOrientation() << ", "
+ << GetZoneId() << ", "
+ << GetMapId() << ", '";
+ for(uint16 i = 0; i < m_valuesCount; ++i )
ss << GetUInt32Value(i) << " ";
- ss << "'," << uint64(m_time) <<", " << uint32(GetType()) << ", " << int(GetInstanceId()) << ")";
+ ss << "',"
+ << uint64(m_time) <<", "
+ << uint32(GetType()) << ", "
+ << int(GetInstanceId()) << ", "
+ << uint16(GetPhaseMask()) << ")"; // prevent out of range error
CharacterDatabase.Execute( ss.str().c_str() );
CharacterDatabase.CommitTransaction();
}
@@ -143,12 +150,12 @@ bool Corpse::LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId)
{
bool external = (result != NULL);
if (!external)
- // 0 1 2 3 4 5 6 7 8
- result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance FROM corpse WHERE guid = '%u'",guid);
+ // 0 1 2 3 4 5 6 7 8 9
+ result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance,phaseMask FROM corpse WHERE guid = '%u'",guid);
if( ! result )
{
- sLog.outError("ERROR: Corpse (GUID: %u) not found in table `corpse`, can't load. ",guid);
+ sLog.outError("Corpse (GUID: %u) not found in table `corpse`, can't load. ",guid);
return false;
}
@@ -166,8 +173,8 @@ bool Corpse::LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId)
bool Corpse::LoadFromDB(uint32 guid, Field *fields)
{
- // 0 1 2 3 4 5 6 7 8
- //result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance FROM corpse WHERE guid = '%u'",guid);
+ // 0 1 2 3 4 5 6 7 8 9
+ //result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance,phaseMask FROM corpse WHERE guid = '%u'",guid);
float positionX = fields[0].GetFloat();
float positionY = fields[1].GetFloat();
float positionZ = fields[2].GetFloat();
@@ -176,7 +183,7 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
if(!LoadValues( fields[5].GetString() ))
{
- sLog.outError("ERROR: Corpse #%d have broken data in `data` field. Can't be loaded.",guid);
+ sLog.outError("Corpse #%d have broken data in `data` field. Can't be loaded.",guid);
return false;
}
@@ -184,10 +191,11 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
m_type = CorpseType(fields[7].GetUInt32());
if(m_type >= MAX_CORPSE_TYPE)
{
- sLog.outError("ERROR: Corpse (guidlow %d, owner %d) have wrong corpse type, not load.",GetGUIDLow(),GUID_LOPART(GetOwnerGUID()));
+ sLog.outError("Corpse (guidlow %d, owner %d) have wrong corpse type, not load.",GetGUIDLow(),GUID_LOPART(GetOwnerGUID()));
return false;
}
uint32 instanceid = fields[8].GetUInt32();
+ uint32 phaseMask = fields[9].GetUInt32();
// overwrite possible wrong/corrupted guid
SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_CORPSE));
@@ -195,11 +203,12 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
// place
SetInstanceId(instanceid);
SetMapId(mapid);
+ SetPhaseMask(phaseMask,false);
Relocate(positionX,positionY,positionZ,ort);
if(!IsPositionValid())
{
- sLog.outError("ERROR: Corpse (guidlow %d, owner %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
+ sLog.outError("Corpse (guidlow %d, owner %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
GetGUIDLow(),GUID_LOPART(GetOwnerGUID()),GetPositionX(),GetPositionY());
return false;
}
@@ -211,6 +220,6 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
bool Corpse::isVisibleForInState(Player const* u, bool inVisibleList) const
{
- return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
+ return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u->m_seer,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
}
diff --git a/src/game/Corpse.h b/src/game/Corpse.h
index 91131c1cb85..da3511abfbb 100644
--- a/src/game/Corpse.h
+++ b/src/game/Corpse.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -58,7 +58,7 @@ class Corpse : public WorldObject
void RemoveFromWorld();
bool Create( uint32 guidlow );
- bool Create( uint32 guidlow, Player *owner, uint32 mapid, float x, float y, float z, float ang );
+ bool Create( uint32 guidlow, Player *owner );
void SaveToDB();
bool LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId);
@@ -82,14 +82,11 @@ class Corpse : public WorldObject
Player* lootRecipient;
bool lootForBody;
- void Say(const char* text, uint32 language, uint64 TargetGuid) { MonsterSay(text,language,TargetGuid); }
- void Yell(const char* text, uint32 language, uint64 TargetGuid) { MonsterYell(text,language,TargetGuid); }
- void TextEmote(const char* text, uint64 TargetGuid) { MonsterTextEmote(text,TargetGuid); }
- void Whisper(const char* text, uint64 receiver) { MonsterWhisper(text,receiver); }
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
void TextEmote(int32 textId, uint64 TargetGuid) { MonsterTextEmote(textId,TargetGuid); }
void Whisper(int32 textId,uint64 receiver) { MonsterWhisper(textId,receiver); }
+ void YellToZone(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYellToZone(textId,language,TargetGuid); }
GridReference<Corpse> &GetGridRef() { return m_gridRef; }
private:
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 520e5cb62c3..fc3e7ad7bac 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,7 +21,6 @@
#include "Common.h"
#include "Database/DatabaseEnv.h"
#include "WorldPacket.h"
-#include "WorldSession.h"
#include "World.h"
#include "ObjectMgr.h"
#include "SpellMgr.h"
@@ -29,6 +28,7 @@
#include "QuestDef.h"
#include "GossipDef.h"
#include "Player.h"
+#include "PoolHandler.h"
#include "Opcodes.h"
#include "Log.h"
#include "LootMgr.h"
@@ -36,32 +36,24 @@
#include "CreatureAI.h"
#include "CreatureAISelector.h"
#include "Formulas.h"
-#include "SpellAuras.h"
#include "WaypointMovementGenerator.h"
#include "InstanceData.h"
-#include "BattleGround.h"
+#include "BattleGroundMgr.h"
#include "Util.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
#include "OutdoorPvPMgr.h"
-#include "GameEvent.h"
+#include "GameEventMgr.h"
#include "CreatureGroups.h"
// apply implementation of the singletons
#include "Policies/SingletonImp.h"
-void TrainerSpellData::Clear()
-{
- for (TrainerSpellList::iterator itr = spellList.begin(); itr != spellList.end(); ++itr)
- delete (*itr);
- spellList.empty();
-}
-
TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const
{
- for(TrainerSpellList::const_iterator itr = spellList.begin(); itr != spellList.end(); ++itr)
- if((*itr)->spell == spell_id)
- return *itr;
+ TrainerSpellMap::const_iterator itr = spellList.find(spell_id);
+ if (itr != spellList.end())
+ return &itr->second;
return NULL;
}
@@ -144,14 +136,15 @@ Unit(),
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0),
m_lootMoney(0), m_lootRecipient(0),
m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f),
-m_gossipOptionLoaded(false), m_emoteState(0), m_isPet(false), m_isTotem(false), m_reactState(REACT_AGGRESSIVE),
-m_regenTimer(2000), m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0),
-m_AlreadyCallAssistance(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false),
-m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),m_creatureInfo(NULL), m_DBTableGuid(0), m_formation(NULL)
+m_gossipOptionLoaded(false),
+m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_AlreadyCallAssistance(false),
+m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
+m_creatureInfo(NULL), m_reactState(REACT_AGGRESSIVE), m_formation(NULL), m_summonMask(SUMMON_MASK_NONE)
{
+ m_regenTimer = 200;
m_valuesCount = UNIT_END;
- for(int i =0; i<4; ++i)
+ for(int i =0; i<CREATURE_MAX_SPELLS; ++i)
m_spells[i] = 0;
m_CreatureSpellCooldowns.clear();
@@ -183,34 +176,34 @@ void Creature::AddToWorld()
ObjectAccessor::Instance().AddObject(this);
Unit::AddToWorld();
SearchFormation();
+ AIM_Initialize();
}
}
void Creature::RemoveFromWorld()
{
- ///- Remove the creature from the accessor
if(IsInWorld())
{
+ // Clear formation info
if(m_formation)
formation_mgr.RemoveCreatureFromGroup(m_formation, this);
- ObjectAccessor::Instance().RemoveObject(this);
Unit::RemoveFromWorld();
+ ObjectAccessor::Instance().RemoveObject(this);
}
}
void Creature::SearchFormation()
{
- if(isPet())
+ if(isSummon())
return;
uint32 lowguid = GetDBTableGUIDLow();
if(!lowguid)
- return;
+ return;
CreatureGroupInfoType::iterator frmdata = CreatureGroupMap.find(lowguid);
if(frmdata != CreatureGroupMap.end())
formation_mgr.AddCreatureToGroup(frmdata->second->leaderGUID, this);
-
}
void Creature::RemoveCorpse()
@@ -311,10 +304,8 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data )
if(!m_respawnradius && m_defaultMovementType==RANDOM_MOTION_TYPE)
m_defaultMovementType = IDLE_MOTION_TYPE;
- m_spells[0] = GetCreatureInfo()->spell1;
- m_spells[1] = GetCreatureInfo()->spell2;
- m_spells[2] = GetCreatureInfo()->spell3;
- m_spells[3] = GetCreatureInfo()->spell4;
+ for(int i=0; i < CREATURE_MAX_SPELLS; ++i)
+ m_spells[i] = GetCreatureInfo()->spells[i];
return true;
}
@@ -328,7 +319,6 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data )
// creatures always have melee weapon ready if any
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
- SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_AURAS );
SelectLevel(GetCreatureInfo());
if (team == HORDE)
@@ -606,19 +596,37 @@ bool Creature::AIM_Initialize(CreatureAI* ai)
return false;
}
- if(i_AI) delete i_AI;
- i_motionMaster.Initialize();
+ UnitAI *oldAI = i_AI;
+
+ Motion_Initialize();
+
i_AI = ai ? ai : FactorySelector::selectAI(this);
+ if(oldAI) delete oldAI;
IsAIEnabled = true;
i_AI->InitializeAI();
return true;
}
-bool Creature::Create (uint32 guidlow, Map *map, uint32 Entry, uint32 team, const CreatureData *data)
+void Creature::Motion_Initialize()
+{
+ if(!m_formation)
+ i_motionMaster.Initialize();
+ else if(m_formation->getLeader() == this)
+ {
+ m_formation->FormationReset(false);
+ i_motionMaster.Initialize();
+ }
+ else if(m_formation->isFormed())
+ i_motionMaster.MoveIdle(MOTION_SLOT_IDLE); //wait the order of leader
+ else
+ i_motionMaster.Initialize();
+}
+
+bool Creature::Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 team, const CreatureData *data)
{
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
- //m_DBTableGuid = guidlow;
+ SetPhaseMask(phaseMask,false);
//oX = x; oY = y; dX = x; dY = y; m_moveTime = 0; m_startMove = 0;
const bool bResult = CreateFromProto(guidlow, Entry, team, data);
@@ -739,7 +747,7 @@ bool Creature::isCanInteractWithBattleMaster(Player* pPlayer, bool msg) const
if(!isBattleMaster())
return false;
- uint32 bgTypeId = objmgr.GetBattleMasterBG(GetEntry());
+ BattleGroundTypeId bgTypeId = sBattleGroundMgr.GetBattleMasterBG(GetEntry());
if(!msg)
return pPlayer->GetBGAccessByLevel(bgTypeId);
@@ -755,8 +763,11 @@ bool Creature::isCanInteractWithBattleMaster(Player* pPlayer, bool msg) const
case BATTLEGROUND_NA:
case BATTLEGROUND_BE:
case BATTLEGROUND_AA:
- case BATTLEGROUND_RL: pPlayer->PlayerTalkClass->SendGossipMenu(10024,GetGUID()); break;
- break;
+ case BATTLEGROUND_RL:
+ case BATTLEGROUND_SA:
+ case BATTLEGROUND_DS:
+ case BATTLEGROUND_RV: pPlayer->PlayerTalkClass->SendGossipMenu(10024,GetGUID()); break;
+ default: break;
}
return false;
}
@@ -792,7 +803,7 @@ void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid )
if(gso->Id==1)
{
uint32 textid=GetNpcTextId();
- GossipText * gossiptext=objmgr.GetGossipText(textid);
+ GossipText const* gossiptext=objmgr.GetGossipText(textid);
if(!gossiptext)
cantalking=false;
}
@@ -903,13 +914,11 @@ void Creature::sendPreparedGossip(Player* player)
if(!player)
return;
- GossipMenu& gossipmenu = player->PlayerTalkClass->GetGossipMenu();
-
if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_WORLDEVENT) // if world event npc then
gameeventmgr.HandleWorldEventGossip(player, this); // update world state with progress
- // in case empty gossip menu open quest menu if any
- if (gossipmenu.Empty() && GetNpcTextId() == 0)
+ // in case no gossip flag and quest menu not empty, open quest menu (client expect gossip menu with this flag)
+ if (!HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_GOSSIP) && !player->PlayerTalkClass->GetQuestMenu().Empty())
{
player->SendPreparedQuest(GetGUID());
return;
@@ -1010,7 +1019,7 @@ void Creature::OnGossipSelect(Player* player, uint32 option)
break;
case GOSSIP_OPTION_BATTLEFIELD:
{
- uint32 bgTypeId = objmgr.GetBattleMasterBG(GetEntry());
+ BattleGroundTypeId bgTypeId = sBattleGroundMgr.GetBattleMasterBG(GetEntry());
player->GetSession()->SendBattlegGroundList( GetGUID(), bgTypeId );
break;
}
@@ -1025,12 +1034,12 @@ void Creature::OnPoiSelect(Player* player, GossipOption const *gossip)
{
if(gossip->GossipId==GOSSIP_GUARD_SPELLTRAINER || gossip->GossipId==GOSSIP_GUARD_SKILLTRAINER)
{
- Poi_Icon icon = ICON_POI_0;
+ Poi_Icon icon = ICON_POI_BLANK;
//need add more case.
switch(gossip->Action)
{
case GOSSIP_GUARD_BANK:
- icon=ICON_POI_HOUSE;
+ icon=ICON_POI_SMALL_HOUSE;
break;
case GOSSIP_GUARD_RIDE:
icon=ICON_POI_RWHORSE;
@@ -1039,7 +1048,7 @@ void Creature::OnPoiSelect(Player* player, GossipOption const *gossip)
icon=ICON_POI_BLUETOWER;
break;
default:
- icon=ICON_POI_TOWER;
+ icon=ICON_POI_GREYTOWER;
break;
}
uint32 textid = GetGossipTextId( gossip->Action, GetZoneId() );
@@ -1173,10 +1182,10 @@ void Creature::SaveToDB()
return;
}
- SaveToDB(GetMapId(), data->spawnMask);
+ SaveToDB(GetMapId(), data->spawnMask,GetPhaseMask());
}
-void Creature::SaveToDB(uint32 mapid, uint8 spawnMask)
+void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
{
// update in loaded data
if (!m_DBTableGuid)
@@ -1196,6 +1205,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask)
// data->guid = guid don't must be update at save
data.id = GetEntry();
data.mapid = mapid;
+ data.phaseMask = phaseMask;
data.displayid = displayId;
data.equipmentId = GetEquipmentId();
data.posX = GetPositionX();
@@ -1224,7 +1234,8 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask)
<< m_DBTableGuid << ","
<< GetEntry() << ","
<< mapid <<","
- << (uint32)spawnMask << ","
+ << uint32(spawnMask) << "," // cast to prevent save as symbol
+ << uint16(GetPhaseMask()) << "," // prevent out of range error
<< displayId <<","
<< GetEquipmentId() <<","
<< GetPositionX() << ","
@@ -1358,7 +1369,7 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const
CreatureInfo const *cinfo = objmgr.GetCreatureTemplate(Entry);
if(!cinfo)
{
- sLog.outErrorDb("Error: creature entry %u does not exist.", Entry);
+ sLog.outErrorDb("Creature entry %u does not exist.", Entry);
return false;
}
m_originalEntry = Entry;
@@ -1390,18 +1401,22 @@ bool Creature::LoadFromDB(uint32 guid, Map *map)
return false;
}
+ if(const CreatureInfo *cInfo = objmgr.GetCreatureTemplate(data->id))
+ if(cInfo->VehicleId)
+ return false;
+
m_DBTableGuid = guid;
if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT);
uint16 team = 0;
- if(!Create(guid,map,data->id,team,data))
+ if(!Create(guid,map,data->phaseMask,data->id,team,data))
return false;
Relocate(data->posX,data->posY,data->posZ,data->orientation);
if(!IsPositionValid())
{
- sLog.outError("ERROR: Creature (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)",GetGUIDLow(),GetEntry(),GetPositionX(),GetPositionY());
+ sLog.outError("Creature (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)",GetGUIDLow(),GetEntry(),GetPositionX(),GetPositionY());
return false;
}
//We should set first home position, because then AI calls home movement
@@ -1439,7 +1454,6 @@ bool Creature::LoadFromDB(uint32 guid, Map *map)
// checked at creature_template loading
m_defaultMovementType = MovementGeneratorType(data->movementType);
- AIM_Initialize();
return true;
}
@@ -1449,12 +1463,8 @@ void Creature::LoadEquipment(uint32 equip_entry, bool force)
{
if (force)
{
- for (uint8 i = 0; i < 3; i++)
- {
- SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + i, 0);
- SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2), 0);
- SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2) + 1, 0);
- }
+ for (uint8 i = 0; i < 3; ++i)
+ SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i, 0);
m_equipmentId = 0;
}
return;
@@ -1465,12 +1475,8 @@ void Creature::LoadEquipment(uint32 equip_entry, bool force)
return;
m_equipmentId = equip_entry;
- for (uint8 i = 0; i < 3; i++)
- {
- SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + i, einfo->equipmodel[i]);
- SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2), einfo->equipinfo[i]);
- SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2) + 1, einfo->equipslot[i]);
- }
+ for (uint8 i = 0; i < 3; ++i)
+ SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i, einfo->equipentry[i]);
}
bool Creature::hasQuest(uint32 quest_id) const
@@ -1528,6 +1534,10 @@ bool Creature::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bo
if (u == this)
return true;
+ // phased visibility (both must phased in same way)
+ if(!InSamePhase(u))
+ return false;
+
// always seen by owner
if(GetGUID() == u->GetCharmerOrOwnerGUID())
return true;
@@ -1563,7 +1573,7 @@ bool Creature::IsWithinSightDist(Unit const* u) const
bool Creature::canStartAttack(Unit const* who) const
{
- if(isCivilian()
+ if(isCivilian() || IsNeutralToAll()
|| !who->isInAccessiblePlaceFor(this)
|| !canFly() && GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE
|| !IsWithinDistInMap(who, GetAttackDistance(who)))
@@ -1617,7 +1627,7 @@ void Creature::setDeathState(DeathState s)
{
if((s == JUST_DIED && !m_isDeadByDefault)||(s == JUST_ALIVED && m_isDeadByDefault))
{
- m_deathTimer = m_corpseDelay*1000;
+ m_deathTimer = m_corpseDelay*IN_MILISECONDS;
// always save boss respawn time at death to prevent crash cheating
if(sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY) || isWorldBoss())
@@ -1643,6 +1653,10 @@ void Creature::setDeathState(DeathState s)
return;
Unit::setDeathState(CORPSE);
+
+ //Dismiss group if is leader
+ if(m_formation && m_formation->getLeader() == this)
+ m_formation->FormationReset(true);
}
if(s == JUST_ALIVED)
{
@@ -1656,9 +1670,9 @@ void Creature::setDeathState(DeathState s)
AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
SetUInt32Value(UNIT_NPC_FLAGS, cinfo->npcflag);
clearUnitState(UNIT_STAT_ALL_STATE);
- i_motionMaster.Initialize();
SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool));
LoadCreaturesAddon(true);
+ Motion_Initialize();
}
}
@@ -1721,11 +1735,15 @@ void Creature::Respawn()
//Call AI respawn virtual function
AI()->JustRespawned();
- GetMap()->Add(this);
+ uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), GetTypeId());
+ if (poolid)
+ poolhandler.UpdatePool(poolid, GetGUIDLow(), GetTypeId());
+ else
+ GetMap()->Add(this);
}
}
-bool Creature::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges)
+bool Creature::IsImmunedToSpell(SpellEntry const* spellInfo)
{
if (!spellInfo)
return false;
@@ -1733,15 +1751,15 @@ bool Creature::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges)
if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1)))
return true;
- return Unit::IsImmunedToSpell(spellInfo, useCharges);
+ return Unit::IsImmunedToSpell(spellInfo);
}
-bool Creature::IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const
+bool Creature::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const
{
- if (GetCreatureInfo()->MechanicImmuneMask & (1 << (mechanic-1)))
+ if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->EffectMechanic[index] - 1)))
return true;
- return Unit::IsImmunedToSpellEffect(effect, mechanic);
+ return Unit::IsImmunedToSpellEffect(spellInfo, index);
}
SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim)
@@ -1749,14 +1767,14 @@ SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim)
if(!pVictim)
return NULL;
- for(uint32 i=0; i < CREATURE_MAX_SPELLS; i++)
+ for(uint32 i=0; i < CREATURE_MAX_SPELLS; ++i)
{
if(!m_spells[i])
continue;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_spells[i] );
if(!spellInfo)
{
- sLog.outError("WORLD: unknown spell id %i\n", m_spells[i]);
+ sLog.outError("WORLD: unknown spell id %i", m_spells[i]);
continue;
}
@@ -1778,14 +1796,16 @@ SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim)
if(spellInfo->manaCost > GetPower(POWER_MANA))
continue;
SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);
- float range = GetSpellMaxRange(srange);
- float minrange = GetSpellMinRange(srange);
+ float range = GetSpellMaxRangeForHostile(srange);
+ float minrange = GetSpellMinRangeForHostile(srange);
float dist = GetDistance(pVictim);
//if(!isInFront( pVictim, range ) && spellInfo->AttributesEx )
// continue;
if( dist > range || dist < minrange )
continue;
- if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
+ if(spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
+ continue;
+ if(spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED))
continue;
return spellInfo;
}
@@ -1797,14 +1817,14 @@ SpellEntry const *Creature::reachWithSpellCure(Unit *pVictim)
if(!pVictim)
return NULL;
- for(uint32 i=0; i < CREATURE_MAX_SPELLS; i++)
+ for(uint32 i=0; i < CREATURE_MAX_SPELLS; ++i)
{
if(!m_spells[i])
continue;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_spells[i] );
if(!spellInfo)
{
- sLog.outError("WORLD: unknown spell id %i\n", m_spells[i]);
+ sLog.outError("WORLD: unknown spell id %i", m_spells[i]);
continue;
}
@@ -1822,14 +1842,16 @@ SpellEntry const *Creature::reachWithSpellCure(Unit *pVictim)
if(spellInfo->manaCost > GetPower(POWER_MANA))
continue;
SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);
- float range = GetSpellMaxRange(srange);
- float minrange = GetSpellMinRange(srange);
+ float range = GetSpellMaxRangeForFriend(srange);
+ float minrange = GetSpellMinRangeForFriend( srange);
float dist = GetDistance(pVictim);
//if(!isInFront( pVictim, range ) && spellInfo->AttributesEx )
// continue;
if( dist > range || dist < minrange )
continue;
- if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
+ if(spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
+ continue;
+ if(spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED))
continue;
return spellInfo;
}
@@ -1877,7 +1899,7 @@ void Creature::DoFleeToGetAssistance(float radius) // Optional parameter
Creature* pCreature = NULL;
Trinity::NearestAssistCreatureInCreatureRangeCheck u_check(this,getVictim(),radius);
- Trinity::CreatureLastSearcher<Trinity::NearestAssistCreatureInCreatureRangeCheck> searcher(pCreature, u_check);
+ Trinity::CreatureLastSearcher<Trinity::NearestAssistCreatureInCreatureRangeCheck> searcher(this, pCreature, u_check);
VisitNearbyGridObject(radius, searcher);
if(!pCreature)
@@ -1897,7 +1919,7 @@ Unit* Creature::SelectNearestTarget(float dist) const
{
Trinity::NearestHostileUnitInAttackDistanceCheck u_check(this, dist);
- Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck> searcher(target, u_check);
+ Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck> searcher(this, target, u_check);
TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
@@ -1910,13 +1932,15 @@ Unit* Creature::SelectNearestTarget(float dist) const
return target;
}
-void Creature::CallAssistance()
+void Creature::CallAssistance(float radius)
{
if( !m_AlreadyCallAssistance && getVictim() && !isPet() && !isCharmed())
{
SetNoCallAssistance(true);
- float radius = sWorld.getConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS);
+ if(!radius)
+ radius = sWorld.getConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS);
+
if(radius > 0)
{
std::list<Creature*> assistList;
@@ -1927,8 +1951,8 @@ void Creature::CallAssistance()
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
- Trinity::AnyAssistCreatureInRangeCheck u_check(this, getVictim(), radius);
- Trinity::CreatureListSearcher<Trinity::AnyAssistCreatureInRangeCheck> searcher(assistList, u_check);
+ MaNGOS::AnyAssistCreatureInRangeCheck u_check(this, getVictim(), radius);
+ MaNGOS::CreatureListSearcher<MaNGOS::AnyAssistCreatureInRangeCheck> searcher(this, assistList, u_check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AnyAssistCreatureInRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
@@ -1988,7 +2012,7 @@ void Creature::SaveRespawnTime()
if(m_respawnTime > time(NULL)) // dead (no corpse)
objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),m_respawnTime);
else if(m_deathTimer > 0) // dead (corpse)
- objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),time(NULL)+m_respawnDelay+m_deathTimer/1000);
+ objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),time(NULL)+m_respawnDelay+m_deathTimer/IN_MILISECONDS);
}
bool Creature::IsOutOfThreatArea(Unit* pVictim) const
@@ -2069,7 +2093,7 @@ bool Creature::LoadCreaturesAddon(bool reload)
}
// skip already applied aura
- if(HasAura(cAura->spell_id,cAura->effect_idx))
+ if(HasAuraEffect(cAura->spell_id,cAura->effect_idx))
{
if(!reload)
sLog.outErrorDb("Creature (GUIDLow: %u Entry: %u ) has duplicate aura (spell %u effect %u) in `auras` field.",GetGUIDLow(),GetEntry(),cAura->spell_id,cAura->effect_idx);
@@ -2077,9 +2101,8 @@ bool Creature::LoadCreaturesAddon(bool reload)
continue;
}
- Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, cAura->effect_idx, NULL, this, this, 0);
- AddAura(AdditionalAura);
- sLog.outDebug("Spell: %u with Aura %u added to creature (GUIDLow: %u Entry: %u )", cAura->spell_id, AdditionalSpellInfo->EffectApplyAuraName[0],GetGUIDLow(),GetEntry());
+ AddAuraEffect(AdditionalSpellInfo->Id, cAura->effect_idx, this);
+ sLog.outDebug("Spell: %u with Aura %u added to creature (GUIDLow: %u Entry: %u )", cAura->spell_id, AdditionalSpellInfo->EffectApplyAuraName[cAura->effect_idx],GetGUIDLow(),GetEntry());
}
}
return true;
@@ -2113,7 +2136,7 @@ void Creature::AddCreatureSpellCooldown(uint32 spellid)
uint32 cooldown = GetSpellRecoveryTime(spellInfo);
if(cooldown)
- _AddCreatureSpellCooldown(spellid, time(NULL) + cooldown/1000);
+ _AddCreatureSpellCooldown(spellid, time(NULL) + cooldown/IN_MILISECONDS);
if(spellInfo->Category)
_AddCreatureCategoryCooldown(spellInfo->Category, time(NULL));
@@ -2132,7 +2155,7 @@ bool Creature::HasCategoryCooldown(uint32 spell_id) const
return true;
CreatureSpellCooldowns::const_iterator itr = m_CreatureCategoryCooldowns.find(spellInfo->Category);
- return(itr != m_CreatureCategoryCooldowns.end() && time_t(itr->second + (spellInfo->CategoryRecoveryTime / 1000)) > time(NULL));
+ return(itr != m_CreatureCategoryCooldowns.end() && time_t(itr->second + (spellInfo->CategoryRecoveryTime / IN_MILISECONDS)) > time(NULL));
}
bool Creature::HasSpellCooldown(uint32 spell_id) const
@@ -2161,7 +2184,7 @@ time_t Creature::GetRespawnTimeEx() const
if(m_respawnTime > now) // dead (no corpse)
return m_respawnTime;
else if(m_deathTimer > 0) // dead (corpse)
- return now+m_respawnDelay+m_deathTimer/1000;
+ return now+m_respawnDelay+m_deathTimer/IN_MILISECONDS;
else
return now;
}
@@ -2203,7 +2226,7 @@ void Creature::AllLootRemovedFromCorpse()
// corpse was not skinnable -> apply corpse looted timer
if (!cinfo || !cinfo->SkinLootId)
- nDeathTimer = (uint32)((m_corpseDelay * 1000) * sWorld.getRate(RATE_CORPSE_DECAY_LOOTED));
+ nDeathTimer = (uint32)((m_corpseDelay * IN_MILISECONDS) * sWorld.getRate(RATE_CORPSE_DECAY_LOOTED));
// corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update
else
nDeathTimer = 0;
@@ -2227,12 +2250,17 @@ uint32 Creature::getLevelForTarget( Unit const* target ) const
return level;
}
-std::string Creature::GetScriptName()
+std::string Creature::GetAIName() const
+{
+ return ObjectMgr::GetCreatureTemplate(GetEntry())->AIName;
+}
+
+std::string Creature::GetScriptName() const
{
return objmgr.GetScriptName(GetScriptId());
}
-uint32 Creature::GetScriptId()
+uint32 Creature::GetScriptId() const
{
return ObjectMgr::GetCreatureTemplate(GetEntry())->ScriptID;
}
@@ -2367,4 +2395,4 @@ time_t Creature::GetLinkedCreatureRespawnTime() const
}
return 0;
-}
+} \ No newline at end of file
diff --git a/src/game/Creature.h b/src/game/Creature.h
index 5a8fd48f97d..2dfc0d8a0cf 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -28,7 +28,6 @@
#include "LootMgr.h"
#include "Database/DatabaseEnv.h"
#include "Cell.h"
-#include "CreatureGroups.h"
#include <list>
@@ -138,6 +137,16 @@ enum CreatureFlagsExtra
CREATURE_FLAG_EXTRA_NO_CRIT = 0x00020000, // creature can't do critical strikes
};
+enum SummonMask
+{
+ SUMMON_MASK_NONE = 0x00000000,
+ SUMMON_MASK_SUMMON = 0x00000001,
+ SUMMON_MASK_GUARDIAN = 0x00000002,
+ SUMMON_MASK_TOTEM = 0x00000004,
+ SUMMON_MASK_PET = 0x00000008,
+ SUMMON_MASK_VEHICLE = 0x00000010,
+};
+
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
#if defined( __GNUC__ )
#pragma pack(1)
@@ -178,7 +187,7 @@ struct CreatureInfo
uint32 rangeattacktime;
uint32 unit_flags; // enum UnitFlags mask values
uint32 dynamicflags;
- uint32 family; // enum CreatureFamily values for type==CREATURE_TYPE_BEAST, or 0 in another cases
+ uint32 family; // enum CreatureFamily values (optional)
uint32 trainer_type;
uint32 trainer_spell;
uint32 classNum;
@@ -197,16 +206,16 @@ struct CreatureInfo
int32 resistance4;
int32 resistance5;
int32 resistance6;
- uint32 spell1;
- uint32 spell2;
- uint32 spell3;
- uint32 spell4;
+ uint32 spells[CREATURE_MAX_SPELLS];
uint32 PetSpellDataId;
+ uint32 VehicleId;
uint32 mingold;
uint32 maxgold;
char const* AIName;
uint32 MovementType;
uint32 InhabitType;
+ float unk16;
+ float unk17;
bool RacialLeader;
bool RegenHealth;
uint32 equipmentId;
@@ -223,6 +232,8 @@ struct CreatureInfo
return SKILL_HERBALISM;
else if(type_flags & CREATURE_TYPEFLAGS_MININGLOOT)
return SKILL_MINING;
+ else if(type_flags & CREATURE_TYPEFLAGS_ENGINEERLOOT)
+ return SKILL_ENGINERING;
else
return SKILL_SKINNING; // normal case
}
@@ -245,12 +256,15 @@ struct NpcOptionLocale
std::vector<std::string> BoxText;
};
+struct PointOfInterestLocale
+{
+ std::vector<std::string> IconName;
+};
+
struct EquipmentInfo
{
uint32 entry;
- uint32 equipmodel[3];
- uint32 equipinfo[3];
- uint32 equipslot[3];
+ uint32 equipentry[3];
};
// from `creature` table
@@ -258,6 +272,7 @@ struct CreatureData
{
uint32 id; // entry in creature_template
uint16 mapid;
+ uint16 phaseMask;
uint32 displayid;
int32 equipmentId;
float posX;
@@ -311,6 +326,31 @@ enum InhabitTypeValues
INHABIT_ANYWHERE = INHABIT_GROUND | INHABIT_WATER | INHABIT_AIR
};
+// Enums used by StringTextData::Type (CreatureEventAI)
+enum ChatType
+{
+ CHAT_TYPE_SAY = 0,
+ CHAT_TYPE_YELL = 1,
+ CHAT_TYPE_TEXT_EMOTE = 2,
+ CHAT_TYPE_BOSS_EMOTE = 3,
+ CHAT_TYPE_WHISPER = 4,
+ CHAT_TYPE_BOSS_WHISPER = 5,
+ CHAT_TYPE_ZONE_YELL = 6
+};
+
+//Selection method used by SelectTarget (CreatureEventAI)
+enum AttackingTarget
+{
+ ATTACKING_TARGET_RANDOM = 0, //Just selects a random target
+ ATTACKING_TARGET_TOPAGGRO, //Selects targes from top aggro to bottom
+ ATTACKING_TARGET_BOTTOMAGGRO, //Selects targets from bottom aggro to top
+ /* not implemented
+ ATTACKING_TARGET_RANDOM_PLAYER, //Just selects a random target (player only)
+ ATTACKING_TARGET_TOPAGGRO_PLAYER, //Selects targes from top aggro to bottom (player only)
+ ATTACKING_TARGET_BOTTOMAGGRO_PLAYER, //Selects targets from bottom aggro to top (player only)
+ */
+};
+
// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
#if defined( __GNUC__ )
#pragma pack()
@@ -352,8 +392,9 @@ struct VendorItemData
void Clear()
{
- for (VendorItemList::iterator itr = m_items.begin(); itr != m_items.end(); ++itr)
+ for (VendorItemList::const_iterator itr = m_items.begin(); itr != m_items.end(); ++itr)
delete (*itr);
+ m_items.clear();
}
};
@@ -371,25 +412,34 @@ typedef std::list<VendorItemCount> VendorItemCounts;
struct TrainerSpell
{
+ TrainerSpell() : spell(0), spellCost(0), reqSkill(0), reqSkillValue(0), reqLevel(0), learnedSpell(0) {}
+
+ TrainerSpell(uint32 _spell, uint32 _spellCost, uint32 _reqSkill, uint32 _reqSkillValue, uint32 _reqLevel, uint32 _learnedspell)
+ : spell(_spell), spellCost(_spellCost), reqSkill(_reqSkill), reqSkillValue(_reqSkillValue), reqLevel(_reqLevel), learnedSpell(_learnedspell)
+ {}
+
uint32 spell;
- uint32 spellcost;
- uint32 reqskill;
- uint32 reqskillvalue;
- uint32 reqlevel;
+ uint32 spellCost;
+ uint32 reqSkill;
+ uint32 reqSkillValue;
+ uint32 reqLevel;
+ uint32 learnedSpell;
+
+ // helpers
+ bool IsCastable() const { return learnedSpell != spell; }
};
-typedef std::vector<TrainerSpell*> TrainerSpellList;
+typedef UNORDERED_MAP<uint32 /*spellid*/, TrainerSpell> TrainerSpellMap;
struct TrainerSpellData
{
TrainerSpellData() : trainerType(0) {}
- TrainerSpellList spellList;
+ TrainerSpellMap spellList;
uint32 trainerType; // trainer type based at trainer spells, can be different from creature_template value.
// req. for correct show non-prof. trainers like weaponmaster, allowed values 0 and 2.
-
- void Clear();
TrainerSpell const* Find(uint32 spell_id) const;
+ void Clear() { spellList.clear(); }
};
typedef std::list<GossipOption> GossipOptionList;
@@ -411,7 +461,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
void AddToWorld();
void RemoveFromWorld();
- bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 team, const CreatureData *data = NULL);
+ bool Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 team, const CreatureData *data = NULL);
bool LoadCreaturesAddon(bool reload = false);
void SelectLevel(const CreatureInfo *cinfo);
void LoadEquipment(uint32 equip_entry, bool force=false);
@@ -423,9 +473,13 @@ class TRINITY_DLL_SPEC Creature : public Unit
void GetRespawnCoord(float &x, float &y, float &z, float* ori = NULL, float* dist =NULL) const;
uint32 GetEquipmentId() const { return m_equipmentId; }
- bool isPet() const { return m_isPet; }
+ uint32 HasSummonMask(uint32 mask) const { return mask & m_summonMask; }
+ bool isSummon() const { return m_summonMask & SUMMON_MASK_SUMMON; }
+ bool isPet() const { return m_summonMask & SUMMON_MASK_PET; }
+ bool isVehicle() const { return m_summonMask & SUMMON_MASK_VEHICLE; }
+ bool isWorldCreature() const { return m_summonMask & SUMMON_MASK_PET; }
+ bool isTotem() const { return m_summonMask & SUMMON_MASK_TOTEM; }
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
- bool isTotem() const { return m_isTotem; }
bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; }
bool isCivilian() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN; }
bool isTrigger() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER; }
@@ -440,9 +494,9 @@ class TRINITY_DLL_SPEC Creature : public Unit
bool isCanInteractWithBattleMaster(Player* player, bool msg) const;
bool isCanTrainingAndResetTalentsOf(Player* pPlayer) const;
bool IsOutOfThreatArea(Unit* pVictim) const;
- bool IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges = false);
+ bool IsImmunedToSpell(SpellEntry const* spellInfo);
// redefine Unit::IsImmunedToSpell
- bool IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const;
+ bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const;
// redefine Unit::IsImmunedToSpellEffect
bool isElite() const
{
@@ -466,6 +520,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
bool IsInEvadeMode() const;
bool AIM_Initialize(CreatureAI* ai = NULL);
+ void Motion_Initialize();
void AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type);
CreatureAI* AI() { return (CreatureAI*)i_AI; }
@@ -507,8 +562,9 @@ class TRINITY_DLL_SPEC Creature : public Unit
CreatureInfo const *GetCreatureInfo() const { return m_creatureInfo; }
CreatureDataAddon const* GetCreatureAddon() const;
- std::string GetScriptName();
- uint32 GetScriptId();
+ std::string GetAIName() const;
+ std::string GetScriptName() const;
+ uint32 GetScriptId() const;
void prepareGossipMenu( Player *pPlayer, uint32 gossipid = 0 );
void sendPreparedGossip( Player* player );
@@ -522,15 +578,11 @@ class TRINITY_DLL_SPEC Creature : public Unit
GossipOption const* GetGossipOption( uint32 id ) const;
void addGossipOption(GossipOption const& gso) { m_goptions.push_back(gso); }
- void setEmoteState(uint8 emote) { m_emoteState = emote; };
- void Say(const char* text, uint32 language, uint64 TargetGuid) { MonsterSay(text,language,TargetGuid); }
- void Yell(const char* text, uint32 language, uint64 TargetGuid) { MonsterYell(text,language,TargetGuid); }
- void TextEmote(const char* text, uint64 TargetGuid, bool IsBossEmote = false) { MonsterTextEmote(text,TargetGuid,IsBossEmote); }
- void Whisper(const char* text, uint64 receiver, bool IsBossWhisper = false) { MonsterWhisper(text,receiver,IsBossWhisper); }
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
void TextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote = false) { MonsterTextEmote(textId,TargetGuid,IsBossEmote); }
void Whisper(int32 textId, uint64 receiver, bool IsBossWhisper = false) { MonsterWhisper(textId,receiver,IsBossWhisper); }
+ void YellToZone(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYellToZone(textId,language,TargetGuid); }
// overwrite WorldObject function for proper name localization
const char* GetNameForLocaleIdx(int32 locale_idx) const;
@@ -541,7 +593,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
bool LoadFromDB(uint32 guid, Map *map);
void SaveToDB();
// overwrited in Pet
- virtual void SaveToDB(uint32 mapid, uint8 spawnMask);
+ virtual void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);
virtual void DeleteFromDB(); // overwrited in Pet
Loot loot;
@@ -567,7 +619,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
float GetAttackDistance(Unit const* pl) const;
Unit* SelectNearestTarget(float dist = 0) const;
- void CallAssistance();
+ void CallAssistance(float radius = 0);
void SetNoCallAssistance(bool val) { m_AlreadyCallAssistance = val; }
bool CanAssistTo(const Unit* u, const Unit* enemy) const;
void DoFleeToGetAssistance(float radius = 50);
@@ -630,10 +682,11 @@ class TRINITY_DLL_SPEC Creature : public Unit
void UpdateWaypointID(uint32 wpID){m_waypointID = wpID;}
void SearchFormation();
- CreatureGroup *GetFormation(){return m_formation;}
+ CreatureGroup *GetFormation() {return m_formation;}
void SetFormation(CreatureGroup *formation) {m_formation = formation;}
Unit *SelectVictim();
+ void SetDeadByDefault (bool death_state) {m_isDeadByDefault = death_state;}
void SetDisableReputationGain(bool disable) { DisableReputationGain = disable; }
bool IsReputationGainDisabled() { return DisableReputationGain; }
@@ -662,13 +715,10 @@ class TRINITY_DLL_SPEC Creature : public Unit
bool m_gossipOptionLoaded;
GossipOptionList m_goptions;
- uint8 m_emoteState;
- bool m_isPet; // set only in Pet::Pet
- bool m_isTotem; // set only in Totem::Totem
+ uint32 m_summonMask;
ReactStates m_reactState; // for AI, not charmInfo
void RegenerateMana();
void RegenerateHealth();
- uint32 m_regenTimer;
MovementGeneratorType m_defaultMovementType;
Cell m_currentCell; // store current cell where creature listed
uint32 m_DBTableGuid; ///< For new or temporary creatures is 0 for saved it is lowguid
diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp
index d21fe43fcaa..4668578c1be 100644
--- a/src/game/CreatureAI.cpp
+++ b/src/game/CreatureAI.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -71,6 +71,42 @@ void CreatureAI::OnCharmed(bool apply)
me->IsAIEnabled = false;
}
+void CreatureAI::DoZoneInCombat(Creature* pUnit)
+{
+ if (!pUnit)
+ pUnit = me;
+
+ Map *map = pUnit->GetMap();
+
+ if (!map->IsDungeon()) //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated
+ {
+ sLog.outError("DoZoneInCombat call for map that isn't an instance (pUnit entry = %d)", pUnit->GetTypeId() == TYPEID_UNIT ? ((Creature*)pUnit)->GetEntry() : 0);
+ return;
+ }
+
+ if(!pUnit->getVictim())
+ if(Unit *target = pUnit->SelectNearestTarget())
+ AttackStart(target);
+
+ if (!pUnit->CanHaveThreatList() || pUnit->getThreatManager().isThreatListEmpty())
+ {
+ sLog.outError("DoZoneInCombat called for creature that either cannot have threat list or has empty threat list (pUnit entry = %d)", pUnit->GetTypeId() == TYPEID_UNIT ? ((Creature*)pUnit)->GetEntry() : 0);
+ return;
+ }
+
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+ for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (Player* i_pl = i->getSource())
+ if (i_pl->isAlive())
+ {
+ pUnit->SetInCombatWith(i_pl);
+ i_pl->SetInCombatWith(pUnit);
+ pUnit->AddThreat(i_pl, 0.0f);
+ }
+ }
+}
+
void CreatureAI::MoveInLineOfSight(Unit *who)
{
if(me->getVictim())
@@ -112,9 +148,9 @@ void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/)
//kill self if charm aura has infinite duration
if(charmer->IsInEvadeMode())
{
- Unit::AuraList const& auras = me->GetAurasByType(SPELL_AURA_MOD_CHARM);
- for(Unit::AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
- if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->IsPermanent())
+ Unit::AuraEffectList const& auras = me->GetAurasByType(SPELL_AURA_MOD_CHARM);
+ for(Unit::AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
+ if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetParentAura()->IsPermanent())
{
charmer->Kill(me);
return;
@@ -129,3 +165,8 @@ void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/)
AttackStart(charmer->SelectNearestTarget());
}
+/*void CreatureAI::AttackedBy( Unit* attacker )
+{
+ if(!m_creature->getVictim())
+ AttackStart(attacker);
+}*/
diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h
index b7a584fd36e..cae7026f6c7 100644
--- a/src/game/CreatureAI.h
+++ b/src/game/CreatureAI.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -27,6 +27,7 @@
#include "Dynamic/ObjectRegistry.h"
#include "Dynamic/FactoryHolder.h"
+class WorldObject;
class Unit;
class Creature;
class Player;
@@ -70,12 +71,88 @@ enum SelectAggroTarget
SELECT_TARGET_FARTHEST,
};
+enum SCEquip
+{
+ EQUIP_NO_CHANGE = -1,
+ EQUIP_UNEQUIP = 0
+};
+
+class EventMap : private std::map<uint32, uint32>
+{
+ private:
+ uint32 m_time, m_phase;
+ public:
+ explicit EventMap() : m_phase(0), m_time(0) {}
+
+ void Reset() { clear(); m_time = 0; m_phase = 0; }
+
+ void Update(uint32 time) { m_time += time; }
+
+ void SetPhase(uint32 phase)
+ {
+ if(phase && phase < 9)
+ m_phase = (1 << (phase + 24));
+ }
+
+ void ScheduleEvent(uint32 eventId, uint32 time, uint32 gcd = 0, uint32 phase = 0)
+ {
+ time += m_time;
+ if(gcd && gcd < 9)
+ eventId |= (1 << (gcd + 16));
+ if(phase && phase < 9)
+ eventId |= (1 << (phase + 24));
+ iterator itr = find(time);
+ while(itr != end())
+ {
+ ++time;
+ itr = find(time);
+ }
+ insert(std::make_pair(time, eventId));
+ }
+
+ uint32 ExecuteEvent()
+ {
+ while(!empty())
+ {
+ if(begin()->first > m_time)
+ return 0;
+ else if(m_phase && (begin()->second & 0xFF000000) && !(begin()->second & m_phase))
+ erase(begin());
+ else
+ {
+ uint32 eventId = (begin()->second & 0x0000FFFF);
+ erase(begin());
+ return eventId;
+ }
+ }
+ return 0;
+ }
+
+ void DelayEvents(uint32 time, uint32 gcd)
+ {
+ time += m_time;
+ gcd = (1 << (gcd + 16));
+ for(iterator itr = begin(); itr != end();)
+ {
+ if(itr->first >= time)
+ break;
+ if(itr->second & gcd)
+ {
+ ScheduleEvent(time, itr->second);
+ erase(itr++);
+ }
+ else
+ ++itr;
+ }
+ }
+};
+
class TRINITY_DLL_SPEC UnitAI
{
protected:
- Unit *me;
+ Unit* const me;
public:
- UnitAI(Unit *u) : me(u) {}
+ explicit UnitAI(Unit *u) : me(u) {}
virtual void AttackStart(Unit *);
virtual void UpdateAI(const uint32 diff) = 0;
@@ -96,9 +173,9 @@ class TRINITY_DLL_SPEC UnitAI
class TRINITY_DLL_SPEC PlayerAI : public UnitAI
{
protected:
- Player *me;
+ Player* const me;
public:
- PlayerAI(Player *p) : UnitAI((Unit*)p), me(p) {}
+ explicit PlayerAI(Player *p) : UnitAI((Unit*)p), me(p) {}
void OnCharmed(bool apply);
};
@@ -112,21 +189,29 @@ class TRINITY_DLL_SPEC SimpleCharmedAI : public PlayerAI
class TRINITY_DLL_SPEC CreatureAI : public UnitAI
{
protected:
- Creature *me;
+ Creature* const me;
+ Creature* const m_creature;
bool UpdateVictim();
public:
- CreatureAI(Creature *c) : UnitAI((Unit*)c), me(c) {}
+ explicit CreatureAI(Creature *c) : UnitAI((Unit*)c), me(c), m_creature(c) {}
virtual ~CreatureAI() {}
- // Called if IsVisible(Unit *who) is true at each *who move
+ ///== Reactions At =================================
+
+ // Called if IsVisible(Unit *who) is true at each *who move, reaction at visibility zone enter
virtual void MoveInLineOfSight(Unit *);
- // Called at stopping attack by any attacker
+ // Called for reaction at stopping attack at no attackers or targets
virtual void EnterEvadeMode();
+ // Called for reaction at enter to combat if not in combat yet (enemy can be NULL)
+ virtual void EnterCombat(Unit* /*enemy*/) {}
+
// Called at any Damage from any attacker (before damage apply)
+ // Note: it for recalculation damage or special reaction at damage
+ // for attack reaction use AttackedBy called for not DOT damage in Unit::DealDamage also
virtual void DamageTaken(Unit *done_by, uint32 & /*damage*/) {}
// Called when the creature is killed
@@ -146,8 +231,8 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI
// Called when spell hits a target
virtual void SpellHitTarget(Unit* target, const SpellEntry*) {}
- // Called when vitim entered water and creature can not enter water
- virtual bool canReachByRangeAttack(Unit*) { return false; }
+ // Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc)
+ //virtual void AttackedBy(Unit* attacker);
// Called when creature is spawned or respawned (for reseting variables)
virtual void JustRespawned() {}
@@ -156,6 +241,36 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI
virtual void MovementInform(uint32 /*MovementType*/, uint32 /*Data*/) {}
void OnCharmed(bool apply);
+
+ // Called at reaching home after evade
+ virtual void JustReachedHome() {}
+
+ void DoZoneInCombat(Creature* pUnit = NULL);
+
+ // Called at text emote receive from player
+ virtual void ReceiveEmote(Player* pPlayer, uint32 text_emote) {}
+
+ ///== Triggered Actions Requested ==================
+
+ // Called when creature attack expected (if creature can and no have current victim)
+ // Note: for reaction at hostile action must be called AttackedBy function.
+ //virtual void AttackStart(Unit *) {}
+
+ // Called at World update tick
+ //virtual void UpdateAI(const uint32 diff ) {}
+
+ ///== State checks =================================
+
+ // Is unit visible for MoveInLineOfSight
+ //virtual bool IsVisible(Unit *) const { return false; }
+
+ // Called when victim entered water and creature can not enter water
+ virtual bool canReachByRangeAttack(Unit*) { return false; }
+
+ ///== Fields =======================================
+
+ // Pointer to controlled by AI creature
+ //Creature* const m_creature;
};
struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature>
diff --git a/src/game/CreatureAIImpl.h b/src/game/CreatureAIImpl.h
index 2f82522f426..a8b8271c5ff 100644
--- a/src/game/CreatureAIImpl.h
+++ b/src/game/CreatureAIImpl.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/CreatureAIRegistry.cpp b/src/game/CreatureAIRegistry.cpp
index 2ac73da702b..6253c06b8bc 100644
--- a/src/game/CreatureAIRegistry.cpp
+++ b/src/game/CreatureAIRegistry.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -18,7 +18,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "CreatureAIRegistry.h"
#include "NullCreatureAI.h"
#include "ReactorAI.h"
#include "AggressorAI.h"
@@ -27,10 +26,10 @@
#include "PossessedAI.h"
#include "TotemAI.h"
#include "OutdoorPvPObjectiveAI.h"
+#include "CreatureEventAI.h"
#include "RandomMovementGenerator.h"
#include "CreatureAIImpl.h"
#include "MovementGeneratorImpl.h"
-#include "MapManager.h"
#include "CreatureAIRegistry.h"
#include "WaypointMovementGenerator.h"
@@ -48,6 +47,7 @@ namespace AIRegistry
(new CreatureAIFactory<TotemAI>("TotemAI"))->RegisterSelf();
(new CreatureAIFactory<OutdoorPvPObjectiveAI>("OutdoorPvPObjectiveAI"))->RegisterSelf();
(new CreatureAIFactory<PossessedAI>("PossessedAI"))->RegisterSelf();
+ (new CreatureAIFactory<CreatureEventAI>("EventAI"))->RegisterSelf();
(new MovementGeneratorFactory<RandomMovementGenerator<Creature> >(RANDOM_MOTION_TYPE))->RegisterSelf();
(new MovementGeneratorFactory<WaypointMovementGenerator<Creature> >(WAYPOINT_MOTION_TYPE))->RegisterSelf();
diff --git a/src/game/CreatureAIRegistry.h b/src/game/CreatureAIRegistry.h
index b4155403e9b..2b92a096731 100644
--- a/src/game/CreatureAIRegistry.h
+++ b/src/game/CreatureAIRegistry.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp
index a2f3d39fcc7..a698d094e18 100644
--- a/src/game/CreatureAISelector.cpp
+++ b/src/game/CreatureAISelector.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -26,6 +26,7 @@
#include "MovementGenerator.h"
#include "ScriptCalls.h"
#include "Pet.h"
+#include "TemporarySummon.h"
INSTANTIATE_SINGLETON_1(CreatureAIRegistry);
INSTANTIATE_SINGLETON_1(MovementGeneratorRegistry);
@@ -34,32 +35,31 @@ namespace FactorySelector
{
CreatureAI* selectAI(Creature *creature)
{
- //if(creature->isPossessed())
- // creature->InitPossessedAI();
-
- // Allow scripting AI for normal creatures and not controlled pets (guardians and mini-pets)
- if((!creature->isPet() || !((Pet*)creature)->isControlled()) && !creature->isCharmed())
- if(CreatureAI* scriptedAI = Script->GetAI(creature))
- return scriptedAI;
-
+ const CreatureAICreator *ai_factory = NULL;
CreatureAIRegistry &ai_registry(CreatureAIRepository::Instance());
- assert( creature->GetCreatureInfo() != NULL );
- CreatureInfo const *cinfo=creature->GetCreatureInfo();
- const CreatureAICreator *ai_factory = NULL;
+ //player-controlled guardians with pet bar
+ if(creature->HasSummonMask(SUMMON_MASK_GUARDIAN) && ((Guardian*)creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)
+ ai_factory = ai_registry.GetRegistryItem("PetAI");
- std::string ainame=cinfo->AIName;
+ //scriptname in db
+ if(!ai_factory)
+ if(CreatureAI* scriptedAI = Script->GetAI(creature))
+ return scriptedAI;
- // select by script name
- if( !ainame.empty())
+ // AIname in db
+ std::string ainame=creature->GetAIName();
+ if(!ai_factory && !ainame.empty())
ai_factory = ai_registry.GetRegistryItem( ainame.c_str() );
// select by NPC flags
if(!ai_factory)
{
- if( creature->isGuard() )
+ if(creature->isVehicle())
+ ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
+ else if(creature->isGuard())
ai_factory = ai_registry.GetRegistryItem("GuardAI");
- else if(creature->isPet() || (creature->isCharmed() && !creature->isPossessed()))
+ else if(creature->HasSummonMask(SUMMON_MASK_GUARDIAN))
ai_factory = ai_registry.GetRegistryItem("PetAI");
else if(creature->isTotem())
ai_factory = ai_registry.GetRegistryItem("TotemAI");
diff --git a/src/game/CreatureAISelector.h b/src/game/CreatureAISelector.h
index c7b4e541f3c..436233b5b21 100644
--- a/src/game/CreatureAISelector.h
+++ b/src/game/CreatureAISelector.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp
new file mode 100644
index 00000000000..5ce6e4855a7
--- /dev/null
+++ b/src/game/CreatureEventAI.cpp
@@ -0,0 +1,1634 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 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 "CreatureEventAI.h"
+#include "CreatureEventAIMgr.h"
+#include "ObjectMgr.h"
+#include "Spell.h"
+#include "World.h"
+#include "Cell.h"
+#include "CellImpl.h"
+#include "GameEventMgr.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
+#include "WorldPacket.h"
+#include "InstanceData.h"
+
+int CreatureEventAI::Permissible(const Creature *creature)
+{
+ if( creature->GetAIName() == "EventAI" )
+ return PERMIT_BASE_SPECIAL;
+ return PERMIT_BASE_NO;
+}
+
+CreatureEventAI::CreatureEventAI(Creature *c ) : CreatureAI(c)
+{
+ CreatureEventAI_Event_Map::const_iterator CreatureEvents = CreatureEAI_Mgr.GetCreatureEventAIMap().find(m_creature->GetEntry());
+ if (CreatureEvents != CreatureEAI_Mgr.GetCreatureEventAIMap().end())
+ {
+ std::vector<CreatureEventAI_Event>::const_iterator i;
+ for (i = (*CreatureEvents).second.begin(); i != (*CreatureEvents).second.end(); ++i)
+ {
+
+ //Debug check
+ #ifndef MANGOS_DEBUG
+ if ((*i).event_flags & EFLAG_DEBUG_ONLY)
+ continue;
+ #endif
+ if(((*i).event_flags & (EFLAG_HEROIC | EFLAG_NORMAL)) && m_creature->GetMap()->IsDungeon() )
+ {
+ if( (m_creature->GetMap()->IsHeroic() && (*i).event_flags & EFLAG_HEROIC) ||
+ (!m_creature->GetMap()->IsHeroic() && (*i).event_flags & EFLAG_NORMAL))
+ {
+ //event flagged for instance mode
+ CreatureEventAIList.push_back(CreatureEventAIHolder(*i));
+ }
+ continue;
+ }
+ CreatureEventAIList.push_back(CreatureEventAIHolder(*i));
+ }
+ //EventMap had events but they were not added because they must be for instance
+ if (CreatureEventAIList.empty())
+ sLog.outError("CreatureEventAI: Creature %u has events but no events added to list because of instance flags.", m_creature->GetEntry());
+ }
+ else
+ sLog.outError("CreatureEventAI: EventMap for Creature %u is empty but creature is using CreatureEventAI.", m_creature->GetEntry());
+
+ bEmptyList = CreatureEventAIList.empty();
+ Phase = 0;
+ CombatMovementEnabled = true;
+ MeleeEnabled = true;
+ AttackDistance = 0;
+ AttackAngle = 0.0f;
+
+ IsFleeing = false;
+
+ //Handle Spawned Events
+ if (!bEmptyList)
+ {
+ for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
+ {
+ if ((*i).Event.event_type == EVENT_T_SPAWNED)
+ ProcessEvent(*i);
+ }
+ }
+}
+
+bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pActionInvoker)
+{
+ if (!pHolder.Enabled || pHolder.Time)
+ return false;
+
+ //Check the inverse phase mask (event doesn't trigger if current phase bit is set in mask)
+ if (pHolder.Event.event_inverse_phase_mask & (1 << Phase))
+ return false;
+
+ //Store random here so that all random actions match up
+ uint32 rnd = rand();
+
+ //Return if chance for event is not met
+ if (pHolder.Event.event_chance <= rnd % 100)
+ return false;
+
+ uint32 param1 = pHolder.Event.event_param1;
+ uint32 param2 = pHolder.Event.event_param2;
+ uint32 param3 = pHolder.Event.event_param3;
+ uint32 param4 = pHolder.Event.event_param4;
+
+ //Check event conditions based on the event type, also reset events
+ switch (pHolder.Event.event_type)
+ {
+ case EVENT_T_TIMER:
+ {
+ if (!m_creature->isInCombat())
+ return false;
+
+ //Repeat Timers
+ if (param3 == param4)
+ {
+ pHolder.Time = param3;
+
+ }else if (param4 > param3)
+ pHolder.Time = urand(param3, param4);
+ else
+ {
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ pHolder.Enabled = false;
+ }
+ }
+ break;
+ case EVENT_T_TIMER_OOC:
+ {
+ if (m_creature->isInCombat())
+ return false;
+
+ //Repeat Timers
+ if (param3 == param4)
+ {
+ pHolder.Time = param3;
+
+ }else if (param4 > param3)
+ pHolder.Time = urand(param3, param4);
+ else
+ {
+
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ pHolder.Enabled = false;
+ }
+ }
+ break;
+ case EVENT_T_HP:
+ {
+ if (!m_creature->isInCombat() || !m_creature->GetMaxHealth())
+ return false;
+
+ uint32 perc = (m_creature->GetHealth()*100) / m_creature->GetMaxHealth();
+
+ if (perc > param1 || perc < param2)
+ return false;
+
+ //Repeat Timers
+ if (param3 == param4)
+ {
+ pHolder.Time = param3;
+
+ }else if (param4 > param3)
+ pHolder.Time = urand(param3, param4);
+ else
+ {
+
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ pHolder.Enabled = false;
+ }
+ }
+ break;
+ case EVENT_T_MANA:
+ {
+ if (!m_creature->isInCombat() || !m_creature->GetMaxPower(POWER_MANA))
+ return false;
+
+ uint32 perc = (m_creature->GetPower(POWER_MANA)*100) / m_creature->GetMaxPower(POWER_MANA);
+
+ if (perc > param1 || perc < param2)
+ return false;
+
+ //Repeat Timers
+ if (param3 == param4)
+ {
+ pHolder.Time = param3;
+
+ }else if (param4 > param3)
+ pHolder.Time = urand(param3, param4);
+ else
+ {
+
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ pHolder.Enabled = false;
+ }
+ }
+ break;
+ case EVENT_T_AGGRO:
+ {
+ }
+ break;
+ case EVENT_T_KILL:
+ {
+ //Repeat Timers
+ if (param1 == param2)
+ {
+ pHolder.Time = param1;
+
+ }else if (param2 > param1)
+ pHolder.Time = urand(param1, param2);
+ else
+ {
+
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ pHolder.Enabled = false;
+ }
+ }
+ case EVENT_T_DEATH:
+ {
+ }
+ break;
+ case EVENT_T_EVADE:
+ {
+ }
+ break;
+ case EVENT_T_SPELLHIT:
+ {
+ //Spell hit is special case, param1 and param2 handled within CreatureEventAI::SpellHit
+
+ //Repeat Timers
+ if (param3 == param4)
+ {
+ pHolder.Time = param3;
+
+ }else if (param4 > param3)
+ pHolder.Time = urand(param3, param4);
+ else
+ {
+
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ pHolder.Enabled = false;
+ }
+ }
+ break;
+ case EVENT_T_RANGE:
+ {
+ //Repeat Timers
+ if (param3 == param4)
+ {
+ pHolder.Time = param3;
+
+ }else if (param4 > param3)
+ pHolder.Time = urand(param3, param4);
+ else
+ {
+
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ pHolder.Enabled = false;
+ }
+ }
+ break;
+ case EVENT_T_OOC_LOS:
+ {
+ //Repeat Timers
+ if (param3 == param4)
+ {
+ pHolder.Time = param3;
+
+ }else if (param4 > param3)
+ pHolder.Time = urand(param3, param4);
+ else
+ {
+
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ pHolder.Enabled = false;
+ }
+ }
+ break;
+ case EVENT_T_SPAWNED:
+ {
+ }
+ break;
+ case EVENT_T_TARGET_HP:
+ {
+ if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->GetMaxHealth())
+ return false;
+
+ uint32 perc = (m_creature->getVictim()->GetHealth()*100) / m_creature->getVictim()->GetMaxHealth();
+
+ if (perc > param1 || perc < param2)
+ return false;
+
+ //Repeat Timers
+ if (param3 == param4)
+ {
+ pHolder.Time = param3;
+
+ }else if (param4 > param3)
+ pHolder.Time = urand(param3, param4);
+ else
+ {
+
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ pHolder.Enabled = false;
+ }
+ }
+ break;
+ case EVENT_T_TARGET_CASTING:
+ {
+ if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->IsNonMeleeSpellCasted(false, false, true))
+ return false;
+
+ //Repeat Timers
+ if (param1 == param2)
+ {
+ pHolder.Time = param1;
+
+ }else if (param2 > param1)
+ pHolder.Time = urand(param1, param2);
+ else
+ {
+
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ pHolder.Enabled = false;
+ }
+ }
+ break;
+ case EVENT_T_FRIENDLY_HP:
+ {
+ if (!m_creature->isInCombat())
+ return false;
+
+ Unit* pUnit = DoSelectLowestHpFriendly(param2, param1);
+
+ if (!pUnit)
+ return false;
+
+ pActionInvoker = pUnit;
+
+ //Repeat Timers
+ if (param3 == param4)
+ {
+ pHolder.Time = param3;
+
+ }else if (param4 > param3)
+ pHolder.Time = urand(param3, param4);
+ else
+ {
+
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ pHolder.Enabled = false;
+ }
+ }
+ break;
+ case EVENT_T_FRIENDLY_IS_CC:
+ {
+ if (!m_creature->isInCombat())
+ return false;
+
+ std::list<Creature*> pList;
+ DoFindFriendlyCC(pList, param2);
+
+ //List is empty
+ if (pList.empty())
+ return false;
+
+ //We don't really care about the whole list, just return first available
+ pActionInvoker = *(pList.begin());
+
+ //Repeat Timers
+ if (param3 == param4)
+ {
+ pHolder.Time = param3;
+
+ }else if (param4 > param3)
+ pHolder.Time = urand(param3, param4);
+ else
+ {
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ pHolder.Enabled = false;
+ }
+ }
+ break;
+ case EVENT_T_FRIENDLY_MISSING_BUFF:
+ {
+ std::list<Creature*> pList;
+ DoFindFriendlyMissingBuff(pList, param2, param1);
+
+ //List is empty
+ if (pList.empty())
+ return false;
+
+ //We don't really care about the whole list, just return first available
+ pActionInvoker = *(pList.begin());
+
+ //Repeat Timers
+ if (param3 == param4)
+ {
+ pHolder.Time = param3;
+
+ }else if (param4 > param3)
+ pHolder.Time = urand(param3, param4);
+ else
+ {
+
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ pHolder.Enabled = false;
+ }
+ }
+ break;
+ case EVENT_T_SUMMONED_UNIT:
+ {
+ //Prevent event from occuring on no unit or non creatures
+ if (!pActionInvoker || pActionInvoker->GetTypeId()!=TYPEID_UNIT)
+ return false;
+
+ //Creature id doesn't match up
+ if (param1 && ((Creature*)pActionInvoker)->GetEntry() != param1)
+ return false;
+
+ //Repeat Timers
+ if (param2 == param3)
+ {
+ pHolder.Time = param2;
+
+ }else if (param3 > param2)
+ pHolder.Time = urand(param2, param3);
+ else
+ {
+
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ pHolder.Enabled = false;
+ }
+ }
+ break;
+ case EVENT_T_REACHED_HOME:
+ {
+ }
+ break;
+ case EVENT_T_RECEIVE_EMOTE:
+ {
+ }
+ break;
+ default:
+
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u has invalid Event Type(%u), missing from ProcessEvent() Switch.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ break;
+ }
+
+ //Disable non-repeatable events
+ if (!(pHolder.Event.event_flags & EFLAG_REPEATABLE))
+ pHolder.Enabled = false;
+
+ //Process actions
+ for (uint32 j = 0; j < MAX_ACTIONS; j++)
+ ProcessAction(pHolder.Event.action[j].type, pHolder.Event.action[j].param1, pHolder.Event.action[j].param2, pHolder.Event.action[j].param3, rnd, pHolder.Event.event_id, pActionInvoker);
+
+ return true;
+}
+
+void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, uint32 param3, uint32 rnd, uint32 EventId, Unit* pActionInvoker)
+{
+ switch (type)
+ {
+ case ACTION_T_TEXT:
+ {
+ if (!param1)
+ return;
+
+ uint32 temp = 0;
+
+ if (param2 && param3)
+ {
+ switch( rand()%3 )
+ {
+ case 0: temp = param1; break;
+ case 2: temp = param2; break;
+ case 3: temp = param3; break;
+ }
+ }else if ( param2 && urand(0,1) )
+ {
+ temp = param2;
+ }else
+ {
+ temp = param1;
+ }
+
+ if (temp)
+ {
+ Unit* target = NULL;
+
+ if (pActionInvoker)
+ {
+ if (pActionInvoker->GetTypeId() == TYPEID_PLAYER)
+ target = pActionInvoker;
+ else if (Unit* owner = pActionInvoker->GetOwner())
+ {
+ if (owner->GetTypeId() == TYPEID_PLAYER)
+ target = owner;
+ }
+ }
+ else if (target = m_creature->getVictim())
+ {
+ if (target->GetTypeId() != TYPEID_PLAYER)
+ if (Unit* owner = target->GetOwner())
+ if (owner->GetTypeId() == TYPEID_PLAYER)
+ target = owner;
+ }
+
+ DoScriptText(temp, m_creature, target);
+ }
+ }
+ break;
+ case ACTION_T_SET_FACTION:
+ {
+ if (param1)
+ m_creature->setFaction(param1);
+ else
+ {
+ if (CreatureInfo const* ci = GetCreatureTemplateStore(m_creature->GetEntry()))
+ {
+ //if no id provided, assume reset and then use default
+ if (m_creature->getFaction() != ci->faction_A)
+ m_creature->setFaction(ci->faction_A);
+ }
+ }
+ }
+ break;
+ case ACTION_T_MORPH_TO_ENTRY_OR_MODEL:
+ {
+ if (param1 || param2)
+ {
+ //set model based on entry from creature_template
+ if (param1)
+ {
+ if (CreatureInfo const* ci = GetCreatureTemplateStore(param1))
+ {
+ //use default display
+ if (ci->Modelid_A1)
+ m_creature->SetDisplayId(ci->Modelid_A1);
+ }
+ }
+ //if no param1, then use value from param2 (modelId)
+ else
+ m_creature->SetDisplayId(param2);
+ }
+ else
+ m_creature->DeMorph();
+ }
+ break;
+ case ACTION_T_SOUND:
+ m_creature->PlayDirectSound(param1);
+ break;
+ case ACTION_T_EMOTE:
+ m_creature->HandleEmoteCommand(param1);
+ break;
+ case ACTION_T_RANDOM_SOUND:
+ {
+ uint32 temp = GetRandActionParam(rnd, param1, param2, param3);
+
+ if (temp != uint32(0xffffffff))
+ m_creature->PlayDirectSound( temp );
+ }
+ break;
+ case ACTION_T_RANDOM_EMOTE:
+ {
+ uint32 temp = GetRandActionParam(rnd, param1, param2, param3);
+
+ if (temp != uint32(0xffffffff))
+ m_creature->HandleEmoteCommand(temp);
+ }
+ break;
+ case ACTION_T_CAST:
+ {
+ Unit* target = GetTargetByType(param2, pActionInvoker);
+ Unit* caster = m_creature;
+
+ if (!target)
+ return;
+
+ //Cast is always triggered if target is forced to cast on self
+ if (param3 & CAST_FORCE_TARGET_SELF)
+ {
+ param3 |= CAST_TRIGGERED;
+ caster = target;
+ }
+
+ //Allowed to cast only if not casting (unless we interrupt ourself) or if spell is triggered
+ bool canCast = !caster->IsNonMeleeSpellCasted(false) || (param3 & (CAST_TRIGGERED | CAST_INTURRUPT_PREVIOUS));
+
+ // If cast flag CAST_AURA_NOT_PRESENT is active, check if target already has aura on them
+ if(param3 & CAST_AURA_NOT_PRESENT)
+ {
+ if(target->HasAura(param1))
+ return;
+ }
+
+ if (canCast)
+ {
+ const SpellEntry* tSpell = GetSpellStore()->LookupEntry(param1);
+
+ //Verify that spell exists
+ if (tSpell)
+ {
+ //Check if cannot cast spell
+ if (!(param3 & (CAST_FORCE_TARGET_SELF | CAST_FORCE_CAST)) &&
+ !CanCast(target, tSpell, (param3 & CAST_TRIGGERED)))
+ {
+ //Melee current victim if flag not set
+ if (!(param3 & CAST_NO_MELEE_IF_OOM))
+ {
+ if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
+ {
+ AttackDistance = 0;
+ AttackAngle = 0;
+
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle);
+ }
+ }
+
+ }
+ else
+ {
+ //Interrupt any previous spell
+ if (caster->IsNonMeleeSpellCasted(false) && param3 & CAST_INTURRUPT_PREVIOUS)
+ caster->InterruptNonMeleeSpells(false);
+
+ caster->CastSpell(target, param1, (param3 & CAST_TRIGGERED));
+ }
+
+ }else
+ sLog.outErrorDb("CreatureEventAI: event %d creature %d attempt to cast spell that doesn't exist %d", EventId, m_creature->GetEntry(), param1);
+ }
+ }
+ break;
+ case ACTION_T_SUMMON:
+ {
+ Unit* target = GetTargetByType(param2, pActionInvoker);
+
+ Creature* pCreature = NULL;
+
+ if (param3)
+ pCreature = m_creature->SummonCreature(param1, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, param3);
+ else
+ pCreature = m_creature->SummonCreature(param1, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+
+ if (!pCreature)
+ {
+
+ sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Spawn event %d is on creature %d", param1, EventId, m_creature->GetEntry());
+ }
+ else if (param2 != TARGET_T_SELF && target)
+ pCreature->AI()->AttackStart(target);
+ }
+ break;
+ case ACTION_T_THREAT_SINGLE_PCT:
+ {
+ Unit* target = GetTargetByType(param2, pActionInvoker);
+
+ if (target)
+ m_creature->getThreatManager().modifyThreatPercent(target, param1);
+ }
+ break;
+ case ACTION_T_THREAT_ALL_PCT:
+ {
+ Unit* Temp = NULL;
+
+ std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
+ for (; i != m_creature->getThreatManager().getThreatList().end(); ++i)
+ {
+ Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
+ if (Temp)
+ m_creature->getThreatManager().modifyThreatPercent(Temp, param1);
+ }
+ }
+ break;
+ case ACTION_T_QUEST_EVENT:
+ {
+ Unit* target = GetTargetByType(param2, pActionInvoker);
+
+ if (target && target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)target)->AreaExploredOrEventHappens(param1);
+ }
+ break;
+ case ACTION_T_CASTCREATUREGO:
+ {
+ Unit* target = GetTargetByType(param3, pActionInvoker);
+
+ if (target && target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)target)->CastedCreatureOrGO(param1, m_creature->GetGUID(), param2);
+ }
+ break;
+ case ACTION_T_SET_UNIT_FIELD:
+ {
+ Unit* target = GetTargetByType(param3, pActionInvoker);
+
+ if (param1 < OBJECT_END || param1 >= UNIT_END)
+ return;
+
+ if (target)
+ target->SetUInt32Value(param1, param2);
+ }
+ break;
+ case ACTION_T_SET_UNIT_FLAG:
+ {
+ Unit* target = GetTargetByType(param2, pActionInvoker);
+
+ if (target)
+ target->SetFlag(UNIT_FIELD_FLAGS, param1);
+ }
+ break;
+ case ACTION_T_REMOVE_UNIT_FLAG:
+ {
+ Unit* target = GetTargetByType(param2, pActionInvoker);
+
+ if (target)
+ target->RemoveFlag(UNIT_FIELD_FLAGS, param1);
+ }
+ break;
+ case ACTION_T_AUTO_ATTACK:
+ {
+ if (param1)
+ MeleeEnabled = true;
+ else MeleeEnabled = false;
+ }
+ break;
+ case ACTION_T_COMBAT_MOVEMENT:
+ {
+ CombatMovementEnabled = param1;
+
+ //Allow movement (create new targeted movement gen only if idle)
+ if (CombatMovementEnabled)
+ {
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle);
+ }
+ else
+ {
+ m_creature->GetMotionMaster()->MoveIdle();
+ }
+ }
+ break;
+ case ACTION_T_SET_PHASE:
+ {
+ Phase = param1;
+ }
+ break;
+ case ACTION_T_INC_PHASE:
+ {
+ Phase += param1;
+
+ if (Phase > 31)
+
+ sLog.outErrorDb( "CreatureEventAI: Event %d incremented Phase above 31. Phase mask cannot be used with phases past 31. CreatureEntry = %d", EventId, m_creature->GetEntry());
+ }
+ break;
+ case ACTION_T_EVADE:
+ {
+ EnterEvadeMode();
+ }
+ break;
+ case ACTION_T_FLEE:
+ {
+ if(m_creature->HasAuraType(SPELL_AURA_PREVENTS_FLEEING))
+ break;
+ TimetoFleeLeft = 8000;
+ m_creature->DoFleeToGetAssistance();
+ IsFleeing = true;
+ }
+ break;
+ case ACTION_T_QUEST_EVENT_ALL:
+ {
+ Unit* Temp = NULL;
+ if( pActionInvoker && pActionInvoker->GetTypeId() == TYPEID_PLAYER )
+ {
+ Temp = Unit::GetUnit(*m_creature,pActionInvoker->GetGUID());
+ if( Temp )
+ ((Player*)Temp)->GroupEventHappens(param1,m_creature);
+ }
+ }
+ break;
+ case ACTION_T_CASTCREATUREGO_ALL:
+ {
+ Unit* Temp = NULL;
+
+ std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
+ for (; i != m_creature->getThreatManager().getThreatList().end(); ++i)
+ {
+ Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
+ if (Temp && Temp->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)Temp)->CastedCreatureOrGO(param1, m_creature->GetGUID(), param2);
+ }
+ }
+ break;
+ case ACTION_T_REMOVEAURASFROMSPELL:
+ {
+ Unit* target = GetTargetByType(param1, pActionInvoker);
+
+ if (target)
+ target->RemoveAurasDueToSpell(param2);
+ }
+ break;
+ case ACTION_T_RANGED_MOVEMENT:
+ {
+ AttackDistance = param1;
+ AttackAngle = ((float)param2/180)*M_PI;
+
+ if (CombatMovementEnabled)
+ {
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle);
+ }
+ }
+ break;
+ case ACTION_T_RANDOM_PHASE:
+ {
+ uint32 temp = GetRandActionParam(rnd, param1, param2, param3);
+
+ Phase = temp;
+ }
+ break;
+ case ACTION_T_RANDOM_PHASE_RANGE:
+ {
+ if (param2 > param1)
+ {
+ Phase = param1 + (rnd % (param2 - param1));
+ }
+ else
+ sLog.outErrorDb( "CreatureEventAI: ACTION_T_RANDOM_PHASE_RANGE cannot have Param2 <= Param1. Divide by Zero. Event = %d. CreatureEntry = %d", EventId, m_creature->GetEntry());
+ }
+ break;
+ case ACTION_T_SUMMON_ID:
+ {
+ Unit* target = GetTargetByType(param2, pActionInvoker);
+
+ //Duration
+ Creature* pCreature = NULL;
+
+ CreatureEventAI_Summon_Map::const_iterator i = CreatureEAI_Mgr.GetCreatureEventAISummonMap().find(param3);
+ if (i == CreatureEAI_Mgr.GetCreatureEventAISummonMap().end())
+ {
+
+ sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Summon map index %u does not exist. EventID %d. CreatureID %d", param1, param3, EventId, m_creature->GetEntry());
+ return;
+ }
+
+ if ((*i).second.SpawnTimeSecs)
+ pCreature = m_creature->SummonCreature(param1, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, (*i).second.SpawnTimeSecs);
+ else pCreature = m_creature->SummonCreature(param1, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+
+ if (!pCreature)
+ {
+
+ sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. EventId %d.Creature %d", param1, EventId, m_creature->GetEntry());
+ }
+ else if (param2 != TARGET_T_SELF && target)
+ pCreature->AI()->AttackStart(target);
+ }
+ break;
+ case ACTION_T_KILLED_MONSTER:
+ {
+ //first attempt player who tapped creature
+ if (Player* pPlayer = m_creature->GetLootRecipient())
+ pPlayer->RewardPlayerAndGroupAtEvent(param1, m_creature);
+ else
+ {
+ //if not available, use pActionInvoker
+ if (Unit* pTarget = GetTargetByType(param2, pActionInvoker))
+ {
+ if (Player* pPlayer2 = pTarget->GetCharmerOrOwnerPlayerOrPlayerItself())
+ pPlayer2->RewardPlayerAndGroupAtEvent(param1, m_creature);
+ }
+ }
+ }
+ break;
+ case ACTION_T_SET_INST_DATA:
+ {
+ InstanceData* pInst = (InstanceData*)m_creature->GetInstanceData();
+ if (!pInst)
+ {
+ sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data without instance script. Creature %d", EventId, m_creature->GetEntry());
+ return;
+ }
+
+ pInst->SetData(param1, param2);
+ }
+ break;
+ case ACTION_T_SET_INST_DATA64:
+ {
+ Unit* target = GetTargetByType(param2, pActionInvoker);
+ if (!target)
+ {
+ sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 but Target == NULL. Creature %d", EventId, m_creature->GetEntry());
+ return;
+ }
+
+ InstanceData* pInst = (InstanceData*)m_creature->GetInstanceData();
+ if (!pInst)
+ {
+ sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 without instance script. Creature %d", EventId, m_creature->GetEntry());
+ return;
+ }
+
+ pInst->SetData64(param1, target->GetGUID());
+ }
+ break;
+ case ACTION_T_UPDATE_TEMPLATE:
+ {
+ if (m_creature->GetEntry() == param1)
+ {
+
+ sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_UPDATE_TEMPLATE call with param1 == current entry. Creature %d", EventId, m_creature->GetEntry());
+ return;
+ }
+
+ m_creature->UpdateEntry(param1, param2 ? HORDE : ALLIANCE);
+ }
+ break;
+ case ACTION_T_DIE:
+ {
+ if (m_creature->isDead())
+ {
+
+ sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_DIE on dead creature. Creature %d", EventId, m_creature->GetEntry());
+ return;
+ }
+ m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ break;
+ case ACTION_T_ZONE_COMBAT_PULSE:
+ {
+ if (!m_creature->isInCombat() || !m_creature->GetMap()->IsDungeon())
+ {
+
+ sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_ZONE_COMBAT_PULSE on creature out of combat or in non-dungeon map. Creature %d", EventId, m_creature->GetEntry());
+ return;
+ }
+
+ DoZoneInCombat(m_creature);
+ }
+ break;
+
+ // TRINITY ONLY
+ case ACTION_T_SET_ACTIVE:
+ me->setActive(param1 ? true : false);
+ break;
+ case ACTION_T_SET_AGGRESSIVE:
+ me->SetReactState(ReactStates(param1));
+ break;
+ case ACTION_T_ATTACK_START_PULSE:
+ AttackStart(me->SelectNearestTarget((float)param1));
+ break;
+ case ACTION_T_SUMMON_GO:
+ {
+ GameObject* pObject = NULL;
+
+ float x,y,z;
+ m_creature->GetPosition(x,y,z);
+ pObject = m_creature->SummonGameObject(param1, x, y, z, 0, 0, 0, 0, 0, param2);
+ if (!pObject)
+ {
+ sLog.outErrorDb("TSCR: EventAI failed to spawn object %u. Spawn event %d is on creature %d", param1, EventId, m_creature->GetEntry());
+ }
+ break;
+ }
+ case ACTION_T_CALL_ASSISTANCE:
+ m_creature->SetNoCallAssistance(false);
+ m_creature->CallAssistance(param1);
+ break;
+ }
+}
+
+void CreatureEventAI::JustRespawned()
+{
+ IsFleeing = false;
+ Reset();
+
+ if (bEmptyList)
+ return;
+
+ //Handle Spawned Events
+ for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
+ {
+ if ((*i).Event.event_type == EVENT_T_SPAWNED)
+ ProcessEvent(*i);
+ }
+}
+
+void CreatureEventAI::Reset()
+{
+ EventUpdateTime = EVENT_UPDATE_TIME;
+ EventDiff = 0;
+
+ TimetoFleeLeft = 0;
+ IsFleeing = false;
+
+ if (bEmptyList)
+ return;
+
+ //Reset all events to enabled
+ for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
+ {
+ switch ((*i).Event.event_type)
+ {
+ //Reset all out of combat timers
+ case EVENT_T_TIMER_OOC:
+ {
+ if ((*i).Event.event_param2 == (*i).Event.event_param1)
+ {
+ (*i).Time = (*i).Event.event_param1;
+ (*i).Enabled = true;
+ }
+ else if ((*i).Event.event_param2 > (*i).Event.event_param1)
+ {
+ (*i).Time = urand((*i).Event.event_param1, (*i).Event.event_param2);
+ (*i).Enabled = true;
+ }
+ else
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has InitialMax < InitialMin. Event disabled.", m_creature->GetEntry(), (*i).Event.event_id, (*i).Event.event_type);
+ }
+ break;
+ //default:
+ //TODO: enable below code line / verify this is correct to enable events previously disabled (ex. aggro yell), instead of enable this in void EnterCombat()
+ //(*i).Enabled = true;
+ //(*i).Time = 0;
+ //break;
+ }
+ }
+}
+
+void CreatureEventAI::JustReachedHome()
+{
+ m_creature->LoadCreaturesAddon();
+
+ if (!bEmptyList)
+ {
+ for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
+ {
+ if ((*i).Event.event_type == EVENT_T_REACHED_HOME)
+ ProcessEvent(*i);
+ }
+ }
+
+ Reset();
+}
+
+void CreatureEventAI::EnterEvadeMode()
+{
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+
+ if (m_creature->isAlive())
+ m_creature->GetMotionMaster()->MoveTargetedHome();
+
+ m_creature->SetLootRecipient(NULL);
+
+ if (bEmptyList)
+ return;
+
+ //Handle Evade events
+ for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
+ {
+ if ((*i).Event.event_type == EVENT_T_EVADE)
+ ProcessEvent(*i);
+ }
+}
+
+void CreatureEventAI::JustDied(Unit* killer)
+{
+ IsFleeing = false;
+ Reset();
+
+ if (bEmptyList)
+ return;
+
+ //Handle Evade events
+ for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
+ {
+ if ((*i).Event.event_type == EVENT_T_DEATH)
+ ProcessEvent(*i, killer);
+ }
+}
+
+void CreatureEventAI::KilledUnit(Unit* victim)
+{
+ if (bEmptyList || victim->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
+ {
+ if ((*i).Event.event_type == EVENT_T_KILL)
+ ProcessEvent(*i, victim);
+ }
+}
+
+void CreatureEventAI::JustSummoned(Creature* pUnit)
+{
+ if (bEmptyList || !pUnit)
+ return;
+
+ for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
+ {
+ if ((*i).Event.event_type == EVENT_T_SUMMONED_UNIT)
+ ProcessEvent(*i, pUnit);
+ }
+}
+
+void CreatureEventAI::EnterCombat(Unit *enemy)
+{
+ //Check for on combat start events
+ if (!bEmptyList)
+ {
+ for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
+ {
+ switch ((*i).Event.event_type)
+ {
+ case EVENT_T_AGGRO:
+ (*i).Enabled = true;
+ ProcessEvent(*i, enemy);
+ break;
+ //Reset all in combat timers
+ case EVENT_T_TIMER:
+ if ((*i).Event.event_param2 == (*i).Event.event_param1)
+ {
+ (*i).Time = (*i).Event.event_param1;
+ (*i).Enabled = true;
+ }
+ else if ((*i).Event.event_param2 > (*i).Event.event_param1)
+ {
+ (*i).Time = urand((*i).Event.event_param1, (*i).Event.event_param2);
+ (*i).Enabled = true;
+ }
+ else
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has InitialMax < InitialMin. Event disabled.", m_creature->GetEntry(), (*i).Event.event_id, (*i).Event.event_type);
+ break;
+ //All normal events need to be re-enabled and their time set to 0
+ default:
+ (*i).Enabled = true;
+ (*i).Time = 0;
+ break;
+ }
+ }
+ }
+
+ EventUpdateTime = EVENT_UPDATE_TIME;
+ EventDiff = 0;
+}
+
+void CreatureEventAI::AttackStart(Unit *who)
+{
+ if (!who)
+ return;
+
+ if (m_creature->Attack(who, MeleeEnabled))
+ {
+ if (CombatMovementEnabled)
+ {
+ m_creature->GetMotionMaster()->MoveChase(who, AttackDistance, AttackAngle);
+ }
+ else
+ {
+ m_creature->GetMotionMaster()->MoveIdle();
+ }
+ }
+}
+
+void CreatureEventAI::MoveInLineOfSight(Unit *who)
+{
+ if (!who)
+ return;
+
+ //Check for OOC LOS Event
+ if (!bEmptyList && !m_creature->getVictim())
+ {
+ for (std::list<CreatureEventAIHolder>::iterator itr = CreatureEventAIList.begin(); itr != CreatureEventAIList.end(); ++itr)
+ {
+ if ((*itr).Event.event_type == EVENT_T_OOC_LOS)
+ {
+ //can trigger if closer than fMaxAllowedRange
+ float fMaxAllowedRange = (*itr).Event.event_param2;
+
+ //if range is ok and we are actually in LOS
+ if (m_creature->IsWithinDistInMap(who, fMaxAllowedRange) && m_creature->IsWithinLOSInMap(who))
+ {
+ //if friendly event&&who is not hostile OR hostile event&&who is hostile
+ if (((*itr).Event.event_param1 && !m_creature->IsHostileTo(who)) ||
+ ((!(*itr).Event.event_param1) && m_creature->IsHostileTo(who)))
+ ProcessEvent(*itr, who);
+ }
+ }
+ }
+ }
+
+ //if (m_creature->isCivilian() && m_creature->IsNeutralToAll())
+ // return;
+
+ if(me->canStartAttack(who))
+ AttackStart(who);
+}
+
+void CreatureEventAI::SpellHit(Unit* pUnit, const SpellEntry* pSpell)
+{
+
+ if (bEmptyList)
+ return;
+
+ for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
+ {
+ if ((*i).Event.event_type == EVENT_T_SPELLHIT)
+ {
+ //If spell id matches (or no spell id) & if spell school matches (or no spell school)
+ if (!(*i).Event.event_param1 || pSpell->Id == (*i).Event.event_param1)
+ {
+ if ((*i).Event.event_param2_s == -1 || pSpell->SchoolMask == (*i).Event.event_param2)
+ ProcessEvent(*i, pUnit);
+ }
+ }
+ }
+}
+
+void CreatureEventAI::UpdateAI(const uint32 diff)
+{
+ //Check if we are in combat (also updates calls threat update code)
+ bool Combat = UpdateVictim();
+
+ //Must return if creature isn't alive. Normally select hostil target and get victim prevent this
+ if (!m_creature->isAlive())
+ return;
+
+ if (IsFleeing)
+ {
+ if(TimetoFleeLeft < diff)
+ {
+ me->SetControlled(false, UNIT_STAT_FLEEING);
+ me->SetNoCallAssistance(false);
+ me->CallAssistance();
+ if(me->getVictim())
+ me->GetMotionMaster()->MoveChase(me->getVictim());
+ IsFleeing = false;
+ }
+ else
+ TimetoFleeLeft -= diff;
+
+ return;
+ }
+
+ if (!bEmptyList)
+ {
+ //Events are only updated once every EVENT_UPDATE_TIME ms to prevent lag with large amount of events
+ if (EventUpdateTime < diff)
+ {
+ EventDiff += diff;
+
+ //Check for time based events
+ for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
+ {
+ //Decrement Timers
+ if ((*i).Time)
+ {
+ if ((*i).Time > EventDiff)
+ {
+ //Do not decrement timers if event cannot trigger in this phase
+ if (!((*i).Event.event_inverse_phase_mask & (1 << Phase)))
+ (*i).Time -= EventDiff;
+
+ //Skip processing of events that have time remaining
+ continue;
+ }
+ else (*i).Time = 0;
+ }
+
+ //Events that are updated every EVENT_UPDATE_TIME
+ switch ((*i).Event.event_type)
+ {
+ case EVENT_T_TIMER_OOC:
+ ProcessEvent(*i);
+ break;
+ case EVENT_T_TIMER:
+ case EVENT_T_MANA:
+ case EVENT_T_HP:
+ case EVENT_T_TARGET_HP:
+ case EVENT_T_TARGET_CASTING:
+ case EVENT_T_FRIENDLY_HP:
+ if (Combat)
+ ProcessEvent(*i);
+ break;
+ case EVENT_T_RANGE:
+ if (Combat)
+ {
+ if (m_creature->IsWithinDistInMap(m_creature->getVictim(),(float)(*i).Event.event_param2))
+ {
+ if (m_creature->GetDistance(m_creature->getVictim()) >= (float)(*i).Event.event_param1)
+ ProcessEvent(*i);
+ }
+ }
+ break;
+ }
+ }
+
+ EventDiff = 0;
+ EventUpdateTime = EVENT_UPDATE_TIME;
+ }
+ else
+ {
+ EventDiff += diff;
+ EventUpdateTime -= diff;
+ }
+ }
+
+ //Melee Auto-Attack
+ if (Combat && MeleeEnabled)
+ DoMeleeAttackIfReady();
+}
+
+inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position)
+{
+ //ThreatList m_threatlist;
+ std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
+ std::list<HostilReference*>::iterator i = m_threatlist.begin();
+ std::list<HostilReference*>::reverse_iterator r = m_threatlist.rbegin();
+
+ if (position >= m_threatlist.size() || !m_threatlist.size())
+ return NULL;
+
+ switch (target)
+ {
+ case ATTACKING_TARGET_RANDOM:
+ {
+ advance ( i , position + (rand() % (m_threatlist.size() - position ) ));
+ return Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
+ }
+ case ATTACKING_TARGET_TOPAGGRO:
+ {
+ advance ( i , position);
+ return Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
+ }
+ case ATTACKING_TARGET_BOTTOMAGGRO:
+ {
+ advance ( r , position);
+ return Unit::GetUnit(*m_creature,(*r)->getUnitGuid());
+ }
+ }
+ return NULL;
+}
+
+inline uint32 CreatureEventAI::GetRandActionParam(uint32 rnd, uint32 param1, uint32 param2, uint32 param3)
+{
+ switch (rnd % 3)
+ {
+ case 0:
+ return param1;
+ break;
+ case 1:
+ return param2;
+ break;
+ case 2:
+ return param3;
+ break;
+ }
+ return 0;
+}
+
+inline Unit* CreatureEventAI::GetTargetByType(uint32 Target, Unit* pActionInvoker)
+{
+ switch (Target)
+ {
+ case TARGET_T_SELF:
+ return m_creature;
+ break;
+ case TARGET_T_HOSTILE:
+ return m_creature->getVictim();
+ break;
+ case TARGET_T_HOSTILE_SECOND_AGGRO:
+ return SelectUnit(ATTACKING_TARGET_TOPAGGRO,1);
+ break;
+ case TARGET_T_HOSTILE_LAST_AGGRO:
+ return SelectUnit(ATTACKING_TARGET_BOTTOMAGGRO,0);
+ break;
+ case TARGET_T_HOSTILE_RANDOM:
+ return SelectUnit(ATTACKING_TARGET_RANDOM,0);
+ break;
+ case TARGET_T_HOSTILE_RANDOM_NOT_TOP:
+ return SelectUnit(ATTACKING_TARGET_RANDOM,1);
+ break;
+ case TARGET_T_ACTION_INVOKER:
+ return pActionInvoker;
+ break;
+ default:
+ return NULL;
+ break;
+ };
+}
+
+Unit* CreatureEventAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
+{
+ CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ Unit* pUnit = NULL;
+
+ MaNGOS::MostHPMissingInRange u_check(m_creature, range, MinHPDiff);
+ MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange> searcher(m_creature, pUnit, u_check);
+
+ /*
+ typedef TYPELIST_4(GameObject, Creature*except pets*, DynamicObject, Corpse*Bones*) AllGridObjectTypes;
+ This means that if we only search grid then we cannot possibly return pets or players so this is safe
+ */
+ TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange>, GridTypeMapContainer > grid_unit_searcher(searcher);
+
+ CellLock<GridReadGuard> cell_lock(cell, p);
+ cell_lock->Visit(cell_lock, grid_unit_searcher, *m_creature->GetMap());
+ return pUnit;
+}
+
+void CreatureEventAI::DoFindFriendlyCC(std::list<Creature*>& _list, float range)
+{
+ CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ MaNGOS::FriendlyCCedInRange u_check(m_creature, range);
+ MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange> searcher(m_creature, _list, u_check);
+
+ TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
+
+ CellLock<GridReadGuard> cell_lock(cell, p);
+ cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap());
+}
+
+void CreatureEventAI::DoFindFriendlyMissingBuff(std::list<Creature*>& _list, float range, uint32 spellid)
+{
+ CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ MaNGOS::FriendlyMissingBuffInRange u_check(m_creature, range, spellid);
+ MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange> searcher(m_creature, _list, u_check);
+
+ TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
+
+ CellLock<GridReadGuard> cell_lock(cell, p);
+ cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap());
+}
+
+//*********************************
+//*** Functions used globally ***
+
+void CreatureEventAI::DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target)
+{
+ if (!pSource)
+ {
+ sLog.outErrorDb("CreatureEventAI: DoScriptText entry %i, invalid Source pointer.",textEntry);
+ return;
+ }
+
+ if (textEntry >= 0)
+ {
+ sLog.outErrorDb("CreatureEventAI: DoScriptText with source entry %u (TypeId=%u, guid=%u) attempts to process text entry %i, but text entry must be negative.",pSource->GetEntry(),pSource->GetTypeId(),pSource->GetGUIDLow(),textEntry);
+ return;
+ }
+
+ CreatureEventAI_TextMap::const_iterator i = CreatureEAI_Mgr.GetCreatureEventAITextMap().find(textEntry);
+
+ if (i == CreatureEAI_Mgr.GetCreatureEventAITextMap().end())
+ {
+ sLog.outErrorDb("CreatureEventAI: DoScriptText with source entry %u (TypeId=%u, guid=%u) could not find text entry %i.",pSource->GetEntry(),pSource->GetTypeId(),pSource->GetGUIDLow(),textEntry);
+ return;
+ }
+
+ sLog.outDebug("CreatureEventAI: DoScriptText: text entry=%i, Sound=%u, Type=%u, Language=%u, Emote=%u",textEntry,(*i).second.SoundId,(*i).second.Type,(*i).second.Language,(*i).second.Emote);
+
+ if((*i).second.SoundId)
+ {
+ if (GetSoundEntriesStore()->LookupEntry((*i).second.SoundId))
+ pSource->PlayDirectSound((*i).second.SoundId);
+ else
+ sLog.outErrorDb("CreatureEventAI: DoScriptText entry %i tried to process invalid sound id %u.",textEntry,(*i).second.SoundId);
+ }
+
+ if((*i).second.Emote)
+ {
+ if (pSource->GetTypeId() == TYPEID_UNIT || pSource->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Unit*)pSource)->HandleEmoteCommand((*i).second.Emote);
+ }
+ else
+ sLog.outErrorDb("CreatureEventAI: DoScriptText entry %i tried to process emote for invalid TypeId (%u).",textEntry,pSource->GetTypeId());
+ }
+
+ switch((*i).second.Type)
+ {
+ case CHAT_TYPE_SAY:
+ pSource->MonsterSay(textEntry, (*i).second.Language, target ? target->GetGUID() : 0);
+ break;
+ case CHAT_TYPE_YELL:
+ pSource->MonsterYell(textEntry, (*i).second.Language, target ? target->GetGUID() : 0);
+ break;
+ case CHAT_TYPE_TEXT_EMOTE:
+ pSource->MonsterTextEmote(textEntry, target ? target->GetGUID() : 0);
+ break;
+ case CHAT_TYPE_BOSS_EMOTE:
+ pSource->MonsterTextEmote(textEntry, target ? target->GetGUID() : 0, true);
+ break;
+ case CHAT_TYPE_WHISPER:
+ {
+ if (target && target->GetTypeId() == TYPEID_PLAYER)
+ pSource->MonsterWhisper(textEntry, target->GetGUID());
+ else sLog.outErrorDb("CreatureEventAI: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", textEntry);
+ }break;
+ case CHAT_TYPE_BOSS_WHISPER:
+ {
+ if (target && target->GetTypeId() == TYPEID_PLAYER)
+ pSource->MonsterWhisper(textEntry, target->GetGUID(), true);
+ else sLog.outErrorDb("CreatureEventAI: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", textEntry);
+ }break;
+ case CHAT_TYPE_ZONE_YELL:
+ pSource->MonsterYellToZone(textEntry, (*i).second.Language, target ? target->GetGUID() : 0);
+ break;
+ }
+}
+
+bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered)
+{
+ //No target so we can't cast
+ if (!Target || !Spell)
+ return false;
+
+ //Silenced so we can't cast
+ if (!Triggered && me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
+ return false;
+
+ //Check for power
+ if (!Triggered && me->GetPower((Powers)Spell->powerType) < Spell->manaCost)
+ return false;
+
+ SpellRangeEntry const *TempRange = NULL;
+
+ TempRange = GetSpellRangeStore()->LookupEntry(Spell->rangeIndex);
+
+ //Spell has invalid range store so we can't use it
+ if (!TempRange)
+ return false;
+
+ //Unit is out of range of this spell
+ if (me->GetDistance(Target) > me->GetSpellMaxRangeForTarget(Target, TempRange)
+ || me->GetDistance(Target) < me->GetSpellMinRangeForTarget(Target, TempRange))
+ return false;
+
+ return true;
+}
+
+void CreatureEventAI::ReceiveEmote(Player* pPlayer, uint32 text_emote)
+{
+ if (bEmptyList)
+ return;
+
+ for (std::list<CreatureEventAIHolder>::iterator itr = CreatureEventAIList.begin(); itr != CreatureEventAIList.end(); ++itr)
+ {
+ if ((*itr).Event.event_type == EVENT_T_RECEIVE_EMOTE)
+ {
+ if ((*itr).Event.event_param1 != text_emote)
+ return;
+
+ bool bProcess = false;
+
+ switch((*itr).Event.event_param2)
+ {
+ //enum ConditionType
+ case CONDITION_NONE: // 0 0
+ bProcess = true;
+ break;
+ case CONDITION_AURA: // spell_id effindex
+ if (pPlayer->HasAuraEffect((*itr).Event.event_param3,(*itr).Event.event_param4))
+ bProcess = true;
+ break;
+ case CONDITION_ITEM: // item_id count
+ if (pPlayer->HasItemCount((*itr).Event.event_param3,(*itr).Event.event_param4))
+ bProcess = true;
+ break;
+ case CONDITION_ITEM_EQUIPPED: // item_id count
+ if (pPlayer->HasItemOrGemWithIdEquipped((*itr).Event.event_param3,(*itr).Event.event_param4))
+ bProcess = true;
+ break;
+ case CONDITION_ZONEID: // zone_id 0
+ if (pPlayer->GetZoneId() == (*itr).Event.event_param3)
+ bProcess = true;
+ break;
+ case CONDITION_REPUTATION_RANK: // faction_id min_rank
+ if (pPlayer->GetReputationRank((*itr).Event.event_param3) >= (*itr).Event.event_param4)
+ bProcess = true;
+ break;
+ case CONDITION_TEAM: // player_team 0, (469 - Alliance 67 - Horde)
+ if (pPlayer->GetTeam() == (*itr).Event.event_param3)
+ bProcess = true;
+ break;
+ case CONDITION_SKILL: // skill_id min skill_value
+ if (pPlayer->HasSkill((*itr).Event.event_param3) && pPlayer->GetSkillValue((*itr).Event.event_param3) >= (*itr).Event.event_param4)
+ bProcess = true;
+ break;
+ case CONDITION_QUESTREWARDED: // quest_id 0
+ if (pPlayer->GetQuestRewardStatus((*itr).Event.event_param3))
+ bProcess = true;
+ break;
+ case CONDITION_QUESTTAKEN: // quest_id 0, for condition true while quest active.
+ if (pPlayer->GetQuestStatus((*itr).Event.event_param3) == QUEST_STATUS_INCOMPLETE)
+ bProcess = true;
+ break;
+ case CONDITION_ACTIVE_EVENT: // event_id 0
+ if (IsHolidayActive(HolidayIds((*itr).Event.event_param3)))
+ bProcess = true;
+ break;
+ }
+
+ if (bProcess)
+ {
+ sLog.outDebug("CreatureEventAI: ReceiveEmote CreatureEventAI: Condition ok, processing");
+ ProcessEvent(*itr, pPlayer);
+ }
+ }
+ }
+}
diff --git a/src/game/CreatureEventAI.h b/src/game/CreatureEventAI.h
new file mode 100644
index 00000000000..7e67dffefcd
--- /dev/null
+++ b/src/game/CreatureEventAI.h
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2005-2009 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 MANGOS_CREATURE_EAI_H
+#define MANGOS_CREATURE_EAI_H
+
+#include "Common.h"
+#include "Creature.h"
+#include "CreatureAI.h"
+#include "Unit.h"
+
+class Player;
+class WorldObject;
+
+#define EVENT_UPDATE_TIME 500
+#define SPELL_RUN_AWAY 8225
+#define MAX_ACTIONS 3
+#define TEXT_SOURCE_RANGE -1000000 //the amount of entries each text source has available
+
+enum EventAI_Type
+{
+ EVENT_T_TIMER = 0, // InitialMin, InitialMax, RepeatMin, RepeatMax
+ EVENT_T_TIMER_OOC = 1, // InitialMin, InitialMax, RepeatMin, RepeatMax
+ EVENT_T_HP = 2, // HPMax%, HPMin%, RepeatMin, RepeatMax
+ EVENT_T_MANA = 3, // ManaMax%,ManaMin% RepeatMin, RepeatMax
+ EVENT_T_AGGRO = 4, // NONE
+ EVENT_T_KILL = 5, // RepeatMin, RepeatMax
+ EVENT_T_DEATH = 6, // NONE
+ EVENT_T_EVADE = 7, // NONE
+ EVENT_T_SPELLHIT = 8, // SpellID, School, RepeatMin, RepeatMax
+ EVENT_T_RANGE = 9, // MinDist, MaxDist, RepeatMin, RepeatMax
+ EVENT_T_OOC_LOS = 10, // NoHostile, NoFriendly, RepeatMin, RepeatMax
+ EVENT_T_SPAWNED = 11, // NONE
+ EVENT_T_TARGET_HP = 12, // HPMax%, HPMin%, RepeatMin, RepeatMax
+ EVENT_T_TARGET_CASTING = 13, // RepeatMin, RepeatMax
+ EVENT_T_FRIENDLY_HP = 14, // HPDeficit, Radius, RepeatMin, RepeatMax
+ EVENT_T_FRIENDLY_IS_CC = 15, // DispelType, Radius, RepeatMin, RepeatMax
+ EVENT_T_FRIENDLY_MISSING_BUFF = 16, // SpellId, Radius, RepeatMin, RepeatMax
+ EVENT_T_SUMMONED_UNIT = 17, // CreatureId, RepeatMin, RepeatMax
+ EVENT_T_TARGET_MANA = 18, // ManaMax%, ManaMin%, RepeatMin, RepeatMax
+ EVENT_T_QUEST_ACCEPT = 19, // QuestID
+ EVENT_T_QUEST_COMPLETE = 20, //
+ EVENT_T_REACHED_HOME = 21, // NONE
+ EVENT_T_RECEIVE_EMOTE = 22, // EmoteId, Condition, CondValue1, CondValue2
+
+ EVENT_T_END,
+};
+
+enum EventAI_ActionType
+{
+ ACTION_T_NONE = 0, //*No action
+ ACTION_T_TEXT = 1, //*-TextId1, optionally -TextId2, optionally -TextId3(if -TextId2 exist). If more than just -TextId1 is defined, randomize. Negative values.
+ ACTION_T_SET_FACTION = 2, //*FactionId (or 0 for default)
+ ACTION_T_MORPH_TO_ENTRY_OR_MODEL = 3, //*Creature_template entry(param1) OR ModelId (param2) (or 0 for both to demorph)
+ ACTION_T_SOUND = 4, //*SoundId
+ ACTION_T_EMOTE = 5, //*EmoteId
+ ACTION_T_RANDOM_SAY = 6, //*UNUSED
+ ACTION_T_RANDOM_YELL = 7, //*UNUSED
+ ACTION_T_RANDOM_TEXTEMOTE = 8, //*UNUSED
+ ACTION_T_RANDOM_SOUND = 9, //SoundId1, SoundId2, SoundId3 (-1 in any field means no output if randomed that field)
+ ACTION_T_RANDOM_EMOTE = 10, //*EmoteId1, EmoteId2, EmoteId3 (-1 in any field means no output if randomed that field)
+ ACTION_T_CAST = 11, //*SpellId, Target, CastFlags
+ ACTION_T_SUMMON = 12, //*CreatureID, Target, Duration in ms
+ ACTION_T_THREAT_SINGLE_PCT = 13, //*Threat%, Target
+ ACTION_T_THREAT_ALL_PCT = 14, //Threat%
+ ACTION_T_QUEST_EVENT = 15, //*QuestID, Target
+ ACTION_T_CASTCREATUREGO = 16, //*QuestID, SpellId, Target
+ ACTION_T_SET_UNIT_FIELD = 17, //*Field_Number, Value, Target
+ ACTION_T_SET_UNIT_FLAG = 18, //*Flags (may be more than one field OR'd together), Target
+ ACTION_T_REMOVE_UNIT_FLAG = 19, //*Flags (may be more than one field OR'd together), Target
+ ACTION_T_AUTO_ATTACK = 20, //AllowAttackState (0 = stop attack, anything else means continue attacking)
+ ACTION_T_COMBAT_MOVEMENT = 21, //AllowCombatMovement (0 = stop combat based movement, anything else continue attacking)
+ ACTION_T_SET_PHASE = 22, //*Phase
+ ACTION_T_INC_PHASE = 23, //*Value (may be negative to decrement phase, should not be 0)
+ ACTION_T_EVADE = 24, //No Params
+ ACTION_T_FLEE = 25, //No Params
+ ACTION_T_QUEST_EVENT_ALL = 26, //*QuestID
+ ACTION_T_CASTCREATUREGO_ALL = 27, //*QuestId, SpellId
+ ACTION_T_REMOVEAURASFROMSPELL = 28, //*Target, Spellid
+ ACTION_T_RANGED_MOVEMENT = 29, //Distance, Angle
+ ACTION_T_RANDOM_PHASE = 30, //PhaseId1, PhaseId2, PhaseId3
+ ACTION_T_RANDOM_PHASE_RANGE = 31, //PhaseMin, PhaseMax
+ ACTION_T_SUMMON_ID = 32, //*CreatureId, Target, SpawnId
+ ACTION_T_KILLED_MONSTER = 33, //*CreatureId, Target
+ ACTION_T_SET_INST_DATA = 34, //*Field, Data
+ ACTION_T_SET_INST_DATA64 = 35, //*Field, Target
+ ACTION_T_UPDATE_TEMPLATE = 36, //*Entry, Team
+ ACTION_T_DIE = 37, //No Params
+ ACTION_T_ZONE_COMBAT_PULSE = 38, //No Params
+
+ ACTION_T_SET_ACTIVE = 101, //Apply
+ ACTION_T_SET_AGGRESSIVE = 102, //Apply
+ ACTION_T_ATTACK_START_PULSE = 103, //Distance
+ ACTION_T_SUMMON_GO = 104, //GameObjectID, DespawnTime in ms
+ ACTION_T_CALL_ASSISTANCE = 105, //Radius
+
+ ACTION_T_END,
+};
+
+enum Target
+{
+ //Self (m_creature)
+ TARGET_T_SELF = 0, //Self cast
+
+ //Hostile targets (if pet then returns pet owner)
+ TARGET_T_HOSTILE, //Our current target (ie: highest aggro)
+ TARGET_T_HOSTILE_SECOND_AGGRO, //Second highest aggro (generaly used for cleaves and some special attacks)
+ TARGET_T_HOSTILE_LAST_AGGRO, //Dead last on aggro (no idea what this could be used for)
+ TARGET_T_HOSTILE_RANDOM, //Just any random target on our threat list
+ TARGET_T_HOSTILE_RANDOM_NOT_TOP, //Any random target except top threat
+
+ //Invoker targets (if pet then returns pet owner)
+ TARGET_T_ACTION_INVOKER, //Unit who caused this Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP, EVENT_T_FRIENDLY_IS_CC, EVENT_T_FRIENDLY_MISSING_BUFF)
+
+ //Hostile targets (including pets)
+ TARGET_T_HOSTILE_WPET, //Current target (can be a pet)
+ TARGET_T_HOSTILE_WPET_SECOND_AGGRO, //Second highest aggro (generaly used for cleaves and some special attacks)
+ TARGET_T_HOSTILE_WPET_LAST_AGGRO, //Dead last on aggro (no idea what this could be used for)
+ TARGET_T_HOSTILE_WPET_RANDOM, //Just any random target on our threat list
+ TARGET_T_HOSTILE_WPET_RANDOM_NOT_TOP, //Any random target except top threat
+
+ TARGET_T_ACTION_INVOKER_WPET,
+
+ TARGET_T_END
+};
+
+enum CastFlags
+{
+ CAST_INTURRUPT_PREVIOUS = 0x01, //Interrupt any spell casting
+ CAST_TRIGGERED = 0x02, //Triggered (this makes spell cost zero mana and have no cast time)
+ CAST_FORCE_CAST = 0x04, //Forces cast even if creature is out of mana or out of range
+ CAST_NO_MELEE_IF_OOM = 0x08, //Prevents creature from entering melee if out of mana or out of range
+ CAST_FORCE_TARGET_SELF = 0x10, //Forces the target to cast this spell on itself
+ CAST_AURA_NOT_PRESENT = 0x20, //Only casts the spell if the target does not have an aura from the spell
+};
+
+enum EventFlags
+{
+ EFLAG_REPEATABLE = 0x01, //Event repeats
+ EFLAG_NORMAL = 0x02, //Event only occurs in Normal instance difficulty
+ EFLAG_HEROIC = 0x04, //Event only occurs in Heroic instance difficulty
+ EFLAG_RESERVED_3 = 0x08,
+ EFLAG_RESERVED_4 = 0x10,
+ EFLAG_RESERVED_5 = 0x20,
+ EFLAG_RESERVED_6 = 0x40,
+ EFLAG_DEBUG_ONLY = 0x80, //Event only occurs in debug build
+};
+
+// String text additional data, used in (CreatureEventAI)
+struct StringTextData
+{
+ uint32 SoundId;
+ uint8 Type;
+ uint32 Language;
+ uint32 Emote;
+};
+// Text Maps
+typedef UNORDERED_MAP<int32, StringTextData> CreatureEventAI_TextMap;
+
+struct CreatureEventAI_Event
+{
+ uint32 event_id;
+
+ uint32 creature_id;
+
+ uint32 event_inverse_phase_mask;
+
+ EventAI_Type event_type : 16;
+ uint8 event_chance : 8;
+ uint8 event_flags : 8;
+
+ union
+ {
+ uint32 event_param1;
+ int32 event_param1_s;
+ };
+ union
+ {
+ uint32 event_param2;
+ int32 event_param2_s;
+ };
+ union
+ {
+ uint32 event_param3;
+ int32 event_param3_s;
+ };
+ union
+ {
+ uint32 event_param4;
+ int32 event_param4_s;
+ };
+
+ struct _action
+ {
+ EventAI_ActionType type: 16;
+ union
+ {
+ uint32 param1;
+ int32 param1_s;
+ };
+ union
+ {
+ uint32 param2;
+ int32 param2_s;
+ };
+ union
+ {
+ uint32 param3;
+ int32 param3_s;
+ };
+ }action[MAX_ACTIONS];
+};
+//Event_Map
+typedef UNORDERED_MAP<uint32, std::vector<CreatureEventAI_Event> > CreatureEventAI_Event_Map;
+
+struct CreatureEventAI_Summon
+{
+ uint32 id;
+
+ float position_x;
+ float position_y;
+ float position_z;
+ float orientation;
+ uint32 SpawnTimeSecs;
+};
+
+//EventSummon_Map
+typedef UNORDERED_MAP<uint32, CreatureEventAI_Summon> CreatureEventAI_Summon_Map;
+
+struct CreatureEventAIHolder
+{
+ CreatureEventAIHolder(CreatureEventAI_Event p) : Event(p), Time(0), Enabled(true){}
+
+ CreatureEventAI_Event Event;
+ uint32 Time;
+ bool Enabled;
+};
+
+class TRINITY_DLL_SPEC CreatureEventAI : public CreatureAI
+{
+
+ public:
+ explicit CreatureEventAI(Creature *c);
+ ~CreatureEventAI()
+ {
+ CreatureEventAIList.clear();
+ }
+ void JustRespawned();
+ void Reset();
+ void JustReachedHome();
+ void EnterCombat(Unit *enemy);
+ void EnterEvadeMode();
+ void JustDied(Unit* killer);
+ void KilledUnit(Unit* victim);
+ void JustSummoned(Creature* pUnit);
+ void AttackStart(Unit *who);
+ void MoveInLineOfSight(Unit *who);
+ void SpellHit(Unit* pUnit, const SpellEntry* pSpell);
+ void UpdateAI(const uint32 diff);
+ void ReceiveEmote(Player* pPlayer, uint32 text_emote);
+ static int Permissible(const Creature *);
+
+ bool ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pActionInvoker = NULL);
+ void ProcessAction(uint16 type, uint32 param1, uint32 param2, uint32 param3, uint32 rnd, uint32 EventId, Unit* pActionInvoker);
+ inline uint32 GetRandActionParam(uint32 rnd, uint32 param1, uint32 param2, uint32 param3);
+ inline Unit* GetTargetByType(uint32 Target, Unit* pActionInvoker);
+ inline Unit* SelectUnit(AttackingTarget target, uint32 position);
+
+ void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target);
+ bool CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered);
+
+ Unit* DoSelectLowestHpFriendly(float range, uint32 MinHPDiff);
+ void DoFindFriendlyMissingBuff(std::list<Creature*>& _list, float range, uint32 spellid);
+ void DoFindFriendlyCC(std::list<Creature*>& _list, float range);
+
+ //Holder for events (stores enabled, time, and eventid)
+ std::list<CreatureEventAIHolder> CreatureEventAIList;
+ uint32 EventUpdateTime; //Time between event updates
+ uint32 EventDiff; //Time between the last event call
+ bool bEmptyList;
+
+ //Variables used by Events themselves
+ uint8 Phase; //Current phase, max 32 phases
+ bool CombatMovementEnabled; //If we allow targeted movment gen (movement twoards top threat)
+ bool MeleeEnabled; //If we allow melee auto attack
+ uint32 AttackDistance; //Distance to attack from
+ float AttackAngle; //Angle of attack
+
+ uint32 TimetoFleeLeft;
+ bool IsFleeing;
+};
+#endif
diff --git a/src/game/CreatureEventAIMgr.cpp b/src/game/CreatureEventAIMgr.cpp
new file mode 100644
index 00000000000..48c6082a4d4
--- /dev/null
+++ b/src/game/CreatureEventAIMgr.cpp
@@ -0,0 +1,702 @@
+/*
+ * Copyright (C) 2005-2009 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 "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "Database/SQLStorage.h"
+#include "CreatureEventAI.h"
+#include "CreatureEventAIMgr.h"
+#include "ObjectMgr.h"
+#include "ProgressBar.h"
+#include "Policies/SingletonImp.h"
+#include "ObjectDefines.h"
+#include "GridDefines.h"
+
+INSTANTIATE_SINGLETON_1(CreatureEventAIMgr);
+
+// -------------------
+void CreatureEventAIMgr::LoadCreatureEventAI_Texts()
+{
+ // Drop Existing Text Map, only done once and we are ready to add data from multiple sources.
+ m_CreatureEventAI_TextMap.clear();
+
+ // Load EventAI Text
+ LoadTrinityStrings(WorldDatabase,"creature_ai_texts",-1,1+(TEXT_SOURCE_RANGE));
+
+ // Gather Additional data from EventAI Texts
+ QueryResult *result = WorldDatabase.PQuery("SELECT entry, sound, type, language, emote FROM creature_ai_texts");
+
+ sLog.outString("Loading EventAI Texts additional data...");
+ if (result)
+ {
+ barGoLink bar(result->GetRowCount());
+ uint32 count = 0;
+
+ do
+ {
+ bar.step();
+ Field* fields = result->Fetch();
+ StringTextData temp;
+
+ int32 i = fields[0].GetInt32();
+ temp.SoundId = fields[1].GetInt32();
+ temp.Type = fields[2].GetInt32();
+ temp.Language = fields[3].GetInt32();
+ temp.Emote = fields[4].GetInt32();
+
+ if (i >= 0)
+ {
+ sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` is not a negative value.",i);
+ continue;
+ }
+
+ if (i <= TEXT_SOURCE_RANGE)
+ {
+ sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` is out of accepted entry range for table.",i);
+ continue;
+ }
+
+ if (temp.SoundId)
+ {
+ if (!sSoundEntriesStore.LookupEntry(temp.SoundId))
+ sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` has Sound %u but sound does not exist.",i,temp.SoundId);
+ }
+
+ if (!GetLanguageDescByID(temp.Language))
+ sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` using Language %u but Language does not exist.",i,temp.Language);
+
+ if (temp.Type > CHAT_TYPE_ZONE_YELL)
+ sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` has Type %u but this Chat Type does not exist.",i,temp.Type);
+
+ if (temp.Emote)
+ {
+ if (!sEmotesStore.LookupEntry(temp.Emote))
+ sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` has Emote %u but emote does not exist.",i,temp.Emote);
+ }
+
+ m_CreatureEventAI_TextMap[i] = temp;
+ ++count;
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u additional CreatureEventAI Texts data.", count);
+ }
+ else
+ {
+ barGoLink bar(1);
+ bar.step();
+ sLog.outString();
+ sLog.outString(">> Loaded 0 additional CreatureEventAI Texts data. DB table `creature_ai_texts` is empty.");
+ }
+
+}
+
+// -------------------
+void CreatureEventAIMgr::LoadCreatureEventAI_Summons()
+{
+
+ //Drop Existing EventSummon Map
+ m_CreatureEventAI_Summon_Map.clear();
+
+ //Gather additional data for EventAI
+ QueryResult *result = WorldDatabase.PQuery("SELECT id, position_x, position_y, position_z, orientation, spawntimesecs FROM creature_ai_summons");
+ if (result)
+ {
+ barGoLink bar(result->GetRowCount());
+ uint32 Count = 0;
+
+ do
+ {
+ bar.step();
+ Field *fields = result->Fetch();
+
+ CreatureEventAI_Summon temp;
+
+ uint32 i = fields[0].GetUInt32();
+ temp.position_x = fields[1].GetFloat();
+ temp.position_y = fields[2].GetFloat();
+ temp.position_z = fields[3].GetFloat();
+ temp.orientation = fields[4].GetFloat();
+ temp.SpawnTimeSecs = fields[5].GetUInt32();
+
+ if(!MaNGOS::IsValidMapCoord(temp.position_x,temp.position_y,temp.position_z,temp.orientation))
+ {
+ sLog.outErrorDb("CreatureEventAI: Summon id %u have wrong coordinates (%f,%f,%f,%f), skipping.", i,temp.position_x,temp.position_y,temp.position_z,temp.orientation);
+ continue;
+ }
+
+ //Add to map
+ m_CreatureEventAI_Summon_Map[i] = temp;
+ ++Count;
+ }while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u CreatureEventAI summon definitions", Count);
+ }else
+ {
+ barGoLink bar(1);
+ bar.step();
+ sLog.outString();
+ sLog.outString(">> Loaded 0 CreatureEventAI Summon definitions. DB table `creature_ai_summons` is empty.");
+ }
+
+}
+
+// -------------------
+void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
+{
+ //Drop Existing EventAI List
+ m_CreatureEventAI_Event_Map.clear();
+
+ //Gather event data
+ QueryResult *result = WorldDatabase.PQuery("SELECT id, creature_id, event_type, event_inverse_phase_mask, event_chance, event_flags, "
+ "event_param1, event_param2, event_param3, event_param4, "
+ "action1_type, action1_param1, action1_param2, action1_param3, "
+ "action2_type, action2_param1, action2_param2, action2_param3, "
+ "action3_type, action3_param1, action3_param2, action3_param3 "
+ "FROM creature_ai_scripts");
+ if (result)
+ {
+ barGoLink bar(result->GetRowCount());
+ uint32 Count = 0;
+
+ do
+ {
+ bar.step();
+ Field *fields = result->Fetch();
+
+ CreatureEventAI_Event temp;
+ temp.event_id = EventAI_Type(fields[0].GetUInt32());
+ uint32 i = temp.event_id;
+
+ temp.creature_id = fields[1].GetUInt32();
+ uint32 creature_id = temp.creature_id;
+
+ uint32 e_type = fields[2].GetUInt32();
+ //Report any errors in event
+ if (e_type >= EVENT_T_END)
+ {
+ sLog.outErrorDb("CreatureEventAI: Event %u have wrong type (%u), skipping.", i,e_type);
+ continue;
+ }
+ temp.event_type = EventAI_Type(e_type);
+
+ temp.event_inverse_phase_mask = fields[3].GetUInt32();
+ temp.event_chance = fields[4].GetUInt8();
+ temp.event_flags = fields[5].GetUInt8();
+ temp.event_param1 = fields[6].GetUInt32();
+ temp.event_param2 = fields[7].GetUInt32();
+ temp.event_param3 = fields[8].GetUInt32();
+ temp.event_param4 = fields[9].GetUInt32();
+
+ //Creature does not exist in database
+ if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.creature_id))
+ {
+ sLog.outErrorDb("CreatureEventAI: Event %u has script for non-existing creature entry (%u), skipping.", i, temp.creature_id);
+ continue;
+ }
+
+ //No chance of this event occuring
+ if (temp.event_chance == 0)
+ sLog.outErrorDb("CreatureEventAI: Event %u has 0 percent chance. Event will never trigger!", i);
+ //Chance above 100, force it to be 100
+ else if (temp.event_chance > 100)
+ {
+ sLog.outErrorDb("CreatureEventAI: Creature %u are using event %u with more than 100 percent chance. Adjusting to 100 percent.", temp.creature_id, i);
+ temp.event_chance = 100;
+ }
+
+ //Individual event checks
+ switch (temp.event_type)
+ {
+ case EVENT_T_TIMER:
+ case EVENT_T_TIMER_OOC:
+ {
+ if (temp.event_param2 < temp.event_param1)
+ sLog.outErrorDb("CreatureEventAI: Creature %u are using timed event(%u) with param2 < param1 (InitialMax < InitialMin). Event will never repeat.", temp.creature_id, i);
+
+ if (temp.event_param4 < temp.event_param3)
+ sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
+
+ break;
+ }
+
+ case EVENT_T_HP:
+ case EVENT_T_MANA:
+ case EVENT_T_TARGET_HP:
+ {
+ if (temp.event_param2 > 100)
+ sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i);
+
+ if (temp.event_param1 <= temp.event_param2)
+ sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param1 <= param2 (MaxPercent <= MinPercent). Event will never trigger! ", temp.creature_id, i);
+
+ if (temp.event_flags & EFLAG_REPEATABLE && !temp.event_param3 && !temp.event_param4)
+ {
+ sLog.outErrorDb("CreatureEventAI: Creature %u has param3 and param4=0 (RepeatMin/RepeatMax) but cannot be repeatable without timers. Removing EFLAG_REPEATABLE for event %u.", temp.creature_id, i);
+ temp.event_flags &= ~EFLAG_REPEATABLE;
+ }
+ break;
+ }
+
+ case EVENT_T_SPELLHIT:
+ {
+ if (temp.event_param1)
+ {
+ SpellEntry const* pSpell = sSpellStore.LookupEntry(temp.event_param1);
+ if (!pSpell)
+ {
+ sLog.outErrorDb("CreatureEventAI: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.event_param1, i);
+ continue;
+ }
+
+ if (temp.event_param2_s != -1 && temp.event_param2 != pSpell->SchoolMask)
+ sLog.outErrorDb("CreatureEventAI: Creature %u has param1(spellId %u) but param2 is not -1 and not equal to spell's school mask. Event %u can never trigger.", temp.creature_id, temp.event_param1, i);
+ }
+
+ //TODO: fix this system with SPELL_SCHOOL_MASK. Current complicate things, using int32(-1) instead of just 0
+ //SPELL_SCHOOL_MASK_NONE = 0 and does not exist, thus it can not ever trigger or be used in SpellHit()
+ if (temp.event_param2_s != -1 && temp.event_param2_s > SPELL_SCHOOL_MASK_ALL)
+ sLog.outErrorDb("CreatureEventAI: Creature %u is using invalid SpellSchoolMask(%u) defined in event %u.", temp.creature_id, temp.event_param2, i);
+
+ if (temp.event_param4 < temp.event_param3)
+ sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
+ break;
+ }
+
+ case EVENT_T_RANGE:
+ case EVENT_T_OOC_LOS:
+ case EVENT_T_FRIENDLY_HP:
+ case EVENT_T_FRIENDLY_IS_CC:
+ case EVENT_T_FRIENDLY_MISSING_BUFF:
+ {
+ //Disabled check for now. Check code related to events and adjust accordingly before enable.
+ //Events should have min/max or alternative set to a static value.
+ /*if (!temp.event_param3 && !temp.event_param4)
+ {
+ sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) without param3/param4 (RepeatMin/RepeatMax). Using minimum values.", temp.creature_id, i);
+ temp.event_param3 = 2500;
+ temp.event_param4 = 2500;
+ }*/
+
+ if (temp.event_param4 < temp.event_param3)
+ sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
+ break;
+ }
+
+ case EVENT_T_KILL:
+ case EVENT_T_TARGET_CASTING:
+ {
+ if (temp.event_param2 < temp.event_param1)
+ sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
+
+ break;
+ }
+
+ case EVENT_T_AGGRO:
+ case EVENT_T_DEATH:
+ case EVENT_T_EVADE:
+ case EVENT_T_SPAWNED:
+ case EVENT_T_REACHED_HOME:
+ {
+ if (temp.event_flags & EFLAG_REPEATABLE)
+ {
+ sLog.outErrorDb("CreatureEventAI: Creature %u has EFLAG_REPEATABLE set. Event can never be repeatable. Removing flag for event %u.", temp.creature_id, i);
+ temp.event_flags &= ~EFLAG_REPEATABLE;
+ }
+
+ break;
+ }
+
+ case EVENT_T_RECEIVE_EMOTE:
+ {
+ if (!sEmotesTextStore.LookupEntry(temp.event_param1))
+ {
+ sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param1 (EmoteTextId: %u) are not valid.",temp.creature_id, i, temp.event_param1);
+ continue;
+ }
+
+ if (temp.event_param2 == CONDITION_AD_COMMISSION_AURA || temp.event_param2 == CONDITION_NO_AURA)
+ {
+ sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param2 (Condition: %u) are not implemented for EventAI.",temp.creature_id, i, temp.event_param2);
+ continue;
+ }
+
+ if (!PlayerCondition::IsValid(ConditionType(temp.event_param2), temp.event_param3, temp.event_param4))
+ {
+ sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param2 (Condition: %u) are not valid.",temp.creature_id, i, temp.event_param2);
+ continue;
+ }
+
+ if (!(temp.event_flags & EFLAG_REPEATABLE))
+ {
+ sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: EFLAG_REPEATABLE not set. Event must always be repeatable. Flag applied.", temp.creature_id, i);
+ temp.event_flags |= EFLAG_REPEATABLE;
+ }
+
+ break;
+ }
+
+ case EVENT_T_SUMMONED_UNIT:
+ {
+ if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.event_param1))
+ sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with not existed creature template id (%u) in param1, skipped.", temp.creature_id, i, temp.event_param1);
+
+ if (temp.event_param3 < temp.event_param2)
+ sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param3 < param2 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
+
+ break;
+ }
+
+ case EVENT_T_QUEST_ACCEPT:
+ case EVENT_T_QUEST_COMPLETE:
+ sLog.outErrorDb("CreatureEventAI: Creature %u using not implemented event (%u) in event %u.", temp.creature_id, temp.event_id, i);
+ continue;
+ default:
+ sLog.outErrorDb("CreatureEventAI: Creature %u using not checked at load event (%u) in event %u. Need check code update?", temp.creature_id, temp.event_id, i);
+ break;
+ }
+
+ for (uint32 j = 0; j < MAX_ACTIONS; j++)
+ {
+ uint16 action_type = fields[10+(j*4)].GetUInt16();
+ if (action_type >= ACTION_T_END)
+ {
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u has incorrect action type (%u), replace by ACTION_T_NONE.", i, j+1, action_type);
+ temp.action[j].type = ACTION_T_NONE;
+ continue;
+ }
+
+ temp.action[j].type = EventAI_ActionType(action_type);
+ temp.action[j].param1 = fields[11+(j*4)].GetUInt32();
+ temp.action[j].param2 = fields[12+(j*4)].GetUInt32();
+ temp.action[j].param3 = fields[13+(j*4)].GetUInt32();
+
+ //Report any errors in actions
+ switch (temp.action[j].type)
+ {
+ case ACTION_T_NONE:
+ break;
+ case ACTION_T_TEXT:
+ {
+ if (temp.action[j].param1_s < 0)
+ {
+ if (m_CreatureEventAI_TextMap.find(temp.action[j].param1_s) == m_CreatureEventAI_TextMap.end())
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 refrences non-existing entry in texts table.", i, j+1);
+ }
+ if (temp.action[j].param2_s < 0)
+ {
+ if (m_CreatureEventAI_TextMap.find(temp.action[j].param2_s) == m_CreatureEventAI_TextMap.end())
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 refrences non-existing entry in texts table.", i, j+1);
+
+ if (!temp.action[j].param1_s)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u has param2, but param1 is not set. Required for randomized text.", i, j+1);
+ }
+ if (temp.action[j].param3_s < 0)
+ {
+ if (m_CreatureEventAI_TextMap.find(temp.action[j].param3_s) == m_CreatureEventAI_TextMap.end())
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 refrences non-existing entry in texts table.", i, j+1);
+
+ if (!temp.action[j].param1_s || !temp.action[j].param2_s)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u has param3, but param1 and/or param2 is not set. Required for randomized text.", i, j+1);
+ }
+ break;
+ }
+ case ACTION_T_SET_FACTION:
+ if (temp.action[j].param1 !=0 && !sFactionStore.LookupEntry(temp.action[j].param1))
+ {
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant FactionId %u.", i, j+1, temp.action[j].param1);
+ temp.action[j].param1 = 0;
+ }
+ break;
+ case ACTION_T_MORPH_TO_ENTRY_OR_MODEL:
+ if (temp.action[j].param1 !=0 || temp.action[j].param2 !=0)
+ {
+ if (temp.action[j].param1 && !sCreatureStorage.LookupEntry<CreatureInfo>(temp.action[j].param1))
+ {
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Creature entry %u.", i, j+1, temp.action[j].param1);
+ temp.action[j].param1 = 0;
+ }
+
+ if (temp.action[j].param2 && !sCreatureDisplayInfoStore.LookupEntry(temp.action[j].param2))
+ {
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant ModelId %u.", i, j+1, temp.action[j].param2);
+ temp.action[j].param2 = 0;
+ }
+ }
+ break;
+ case ACTION_T_SOUND:
+ if (!sSoundEntriesStore.LookupEntry(temp.action[j].param1))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SoundID %u.", i, j+1, temp.action[j].param1);
+ break;
+ case ACTION_T_RANDOM_SOUND:
+ if (!sSoundEntriesStore.LookupEntry(temp.action[j].param1))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 uses non-existant SoundID %u.", i, j+1, temp.action[j].param1);
+ if (temp.action[j].param2_s >= 0 && !sSoundEntriesStore.LookupEntry(temp.action[j].param2))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 uses non-existant SoundID %u.", i, j+1, temp.action[j].param2);
+ if (temp.action[j].param3_s >= 0 && !sSoundEntriesStore.LookupEntry(temp.action[j].param3))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 uses non-existant SoundID %u.", i, j+1, temp.action[j].param3);
+ break;
+ case ACTION_T_EMOTE:
+ if (!sEmotesStore.LookupEntry(temp.action[j].param1))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (EmoteId: %u) are not valid.", i, j+1, temp.action[j].param1);
+ break;
+ case ACTION_T_RANDOM_EMOTE:
+ if (!sEmotesStore.LookupEntry(temp.action[j].param1))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (EmoteId: %u) are not valid.", i, j+1, temp.action[j].param1);
+ if (temp.action[j].param2_s >= 0 && !sEmotesStore.LookupEntry(temp.action[j].param2))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 (EmoteId: %u) are not valid.", i, j+1, temp.action[j].param2);
+ if (temp.action[j].param3_s >= 0 && !sEmotesStore.LookupEntry(temp.action[j].param3))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 (EmoteId: %u) are not valid.", i, j+1, temp.action[j].param3);
+ break;
+ case ACTION_T_CAST:
+ {
+ const SpellEntry *spell = sSpellStore.LookupEntry(temp.action[j].param1);
+ if (!spell)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param1);
+ else
+ {
+ if (spell->RecoveryTime > 0 && temp.event_flags & EFLAG_REPEATABLE)
+ {
+ //output as debug for now, also because there's no general rule all spells have RecoveryTime
+ if (temp.event_param3 < spell->RecoveryTime)
+ sLog.outDebug("CreatureEventAI: Event %u Action %u uses SpellID %u but cooldown is longer(%u) than minumum defined in event param3(%u).", i, j+1,temp.action[j].param1, spell->RecoveryTime, temp.event_param3);
+ }
+ }
+
+ if (temp.action[j].param2 >= TARGET_T_END)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
+ break;
+ }
+ case ACTION_T_REMOVEAURASFROMSPELL:
+ {
+ if (!sSpellStore.LookupEntry(temp.action[j].param2))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2);
+
+ if (temp.action[j].param1 >= TARGET_T_END)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
+ break;
+ }
+ case ACTION_T_QUEST_EVENT:
+ {
+ if (Quest const* qid = objmgr.GetQuestTemplate(temp.action[j].param1))
+ {
+ if (!qid->HasFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u. SpecialFlags for quest entry %u does not include |2, Action will not have any effect.", i, j+1, temp.action[j].param1);
+ }
+ else
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Quest entry %u.", i, j+1, temp.action[j].param1);
+
+ if (temp.action[j].param2 >= TARGET_T_END)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
+
+ break;
+ }
+ case ACTION_T_QUEST_EVENT_ALL:
+ {
+ if (Quest const* qid = objmgr.GetQuestTemplate(temp.action[j].param1))
+ {
+ if (!qid->HasFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u. SpecialFlags for quest entry %u does not include |2, Action will not have any effect.", i, j+1, temp.action[j].param1);
+ }
+ else
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Quest entry %u.", i, j+1, temp.action[j].param1);
+ break;
+ }
+ case ACTION_T_CASTCREATUREGO:
+ {
+ if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.action[j].param1))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
+
+ if (!sSpellStore.LookupEntry(temp.action[j].param2))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2);
+
+ if (temp.action[j].param3 >= TARGET_T_END)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
+ break;
+ }
+ case ACTION_T_CASTCREATUREGO_ALL:
+ {
+ if (!objmgr.GetQuestTemplate(temp.action[j].param1))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Quest entry %u.", i, j+1, temp.action[j].param1);
+
+ if (!sSpellStore.LookupEntry(temp.action[j].param2))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2);
+ break;
+ }
+
+ //2nd param target
+ case ACTION_T_SUMMON_ID:
+ {
+ if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.action[j].param1))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
+
+ if (m_CreatureEventAI_Summon_Map.find(temp.action[j].param3) == m_CreatureEventAI_Summon_Map.end())
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u summons missing CreatureEventAI_Summon %u", i, j+1, temp.action[j].param3);
+
+ if (temp.action[j].param2 >= TARGET_T_END)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
+ break;
+ }
+ case ACTION_T_KILLED_MONSTER:
+ {
+ if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.action[j].param1))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
+
+ if (temp.action[j].param2 >= TARGET_T_END)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
+ break;
+ }
+ case ACTION_T_SUMMON:
+ {
+ if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.action[j].param1))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
+
+ if (temp.action[j].param2 >= TARGET_T_END)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
+ break;
+ }
+ case ACTION_T_THREAT_SINGLE_PCT:
+ case ACTION_T_SET_UNIT_FLAG:
+ case ACTION_T_REMOVE_UNIT_FLAG:
+ if (temp.action[j].param2 >= TARGET_T_END)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
+ break;
+ //3rd param target
+ case ACTION_T_SET_UNIT_FIELD:
+ if (temp.action[j].param1 < OBJECT_END || temp.action[j].param1 >= UNIT_END)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (UNIT_FIELD*). Index out of range for intended use.", i, j+1);
+ if (temp.action[j].param3 >= TARGET_T_END)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
+ break;
+
+ case ACTION_T_SET_PHASE:
+ if (temp.action[j].param1 > 31)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phase > 31. Phase mask cannot be used past phase 31.", i, j+1);
+ break;
+
+ case ACTION_T_INC_PHASE:
+ if (!temp.action[j].param1)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u is incrementing phase by 0. Was this intended?", i, j+1);
+ break;
+
+ case ACTION_T_SET_INST_DATA:
+ {
+ if (!(temp.event_flags & EFLAG_NORMAL) && !(temp.event_flags & EFLAG_HEROIC))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u. Cannot set instance data without event flags (normal/heroic).", i, j+1);
+
+ if (temp.action[j].param2 > 4/*SPECIAL*/)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set instance data above encounter state 4. Custom case?", i, j+1);
+
+ break;
+ }
+ case ACTION_T_SET_INST_DATA64:
+ {
+ if (!(temp.event_flags & EFLAG_NORMAL) && !(temp.event_flags & EFLAG_HEROIC))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u. Cannot set instance data without event flags (normal/heroic).", i, j+1);
+
+ if (temp.action[j].param2 >= TARGET_T_END)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
+
+ break;
+ }
+ case ACTION_T_UPDATE_TEMPLATE:
+ {
+ if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.action[j].param1))
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
+ break;
+ }
+
+ case ACTION_T_THREAT_ALL_PCT:
+ if (abs(temp.action[j].param1_s) > 100)
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses invalid percent value %u.", i, j+1, temp.action[j].param1);
+ break;
+
+ case ACTION_T_EVADE: //No Params
+ case ACTION_T_FLEE: //No Params
+ case ACTION_T_DIE: //No Params
+ case ACTION_T_ZONE_COMBAT_PULSE: //No Params
+ case ACTION_T_AUTO_ATTACK: //AllowAttackState (0 = stop attack, anything else means continue attacking)
+ case ACTION_T_COMBAT_MOVEMENT: //AllowCombatMovement (0 = stop combat based movement, anything else continue attacking)
+ case ACTION_T_RANGED_MOVEMENT: //Distance, Angle
+ break;
+
+ case ACTION_T_RANDOM_PHASE: //PhaseId1, PhaseId2, PhaseId3
+ case ACTION_T_RANDOM_PHASE_RANGE: //PhaseMin, PhaseMax
+ // check not implemented
+ break;
+
+ case ACTION_T_RANDOM_SAY:
+ case ACTION_T_RANDOM_YELL:
+ case ACTION_T_RANDOM_TEXTEMOTE:
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u currently unused ACTION type. Did you forget to update database?", i, j+1);
+ break;
+
+ case ACTION_T_SET_ACTIVE:
+ case ACTION_T_SET_AGGRESSIVE:
+ case ACTION_T_ATTACK_START_PULSE:
+ case ACTION_T_SUMMON_GO:
+ case ACTION_T_CALL_ASSISTANCE:
+ break;
+
+ default:
+ sLog.outErrorDb("CreatureEventAI: Event %u Action %u have currently not checked at load action type (%u). Need check code update?", i, j+1, temp.action[j].type);
+ break;
+ }
+ }
+
+ //Add to list
+ m_CreatureEventAI_Event_Map[creature_id].push_back(temp);
+ ++Count;
+
+ if(CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(temp.creature_id))
+ {
+ if(!cInfo->AIName || !cInfo->AIName[0])
+ {
+ //sLog.outErrorDb("CreatureEventAI: Creature Entry %u has EventAI script but its AIName is empty. Set to EventAI as default.", cInfo->Entry);
+ size_t len = strlen("EventAI")+1;
+ const_cast<CreatureInfo*>(cInfo)->AIName = new char[len];
+ strncpy(const_cast<char*>(cInfo->AIName), "EventAI", len);
+ }
+ if(strcmp(cInfo->AIName, "EventAI"))
+ {
+ //sLog.outErrorDb("CreatureEventAI: Creature Entry %u has EventAI script but it has AIName %s. EventAI script will be overriden.", cInfo->Entry, cInfo->AIName);
+ }
+ if(cInfo->ScriptID)
+ {
+ //sLog.outErrorDb("CreatureEventAI: Creature Entry %u has EventAI script but it also has C++ script. EventAI script will be overriden.", cInfo->Entry);
+ }
+ }
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u CreatureEventAI scripts", Count);
+ }else
+ {
+ barGoLink bar(1);
+ bar.step();
+ sLog.outString();
+ sLog.outString(">> Loaded 0 CreatureEventAI scripts. DB table `creature_ai_scripts` is empty.");
+ }
+}
diff --git a/src/game/CreatureEventAIMgr.h b/src/game/CreatureEventAIMgr.h
new file mode 100644
index 00000000000..b4672460cc6
--- /dev/null
+++ b/src/game/CreatureEventAIMgr.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2005-2009 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 MANGOS_CREATURE_EAI_MGR_H
+#define MANGOS_CREATURE_EAI_MGR_H
+
+#include "Common.h"
+#include "CreatureEventAI.h"
+
+class CreatureEventAIMgr
+{
+ public:
+ CreatureEventAIMgr(){};
+ ~CreatureEventAIMgr(){};
+
+ void LoadCreatureEventAI_Texts();
+ void LoadCreatureEventAI_Summons();
+ void LoadCreatureEventAI_Scripts();
+
+ CreatureEventAI_Event_Map const& GetCreatureEventAIMap() const { return m_CreatureEventAI_Event_Map; }
+ CreatureEventAI_Summon_Map const& GetCreatureEventAISummonMap() const { return m_CreatureEventAI_Summon_Map; }
+ CreatureEventAI_TextMap const& GetCreatureEventAITextMap() const { return m_CreatureEventAI_TextMap; }
+
+ private:
+ CreatureEventAI_Event_Map m_CreatureEventAI_Event_Map;
+ CreatureEventAI_Summon_Map m_CreatureEventAI_Summon_Map;
+ CreatureEventAI_TextMap m_CreatureEventAI_TextMap;
+};
+
+#define CreatureEAI_Mgr MaNGOS::Singleton<CreatureEventAIMgr>::Instance()
+#endif
diff --git a/src/game/DBCEnums.h b/src/game/DBCEnums.h
new file mode 100644
index 00000000000..655c9967989
--- /dev/null
+++ b/src/game/DBCEnums.h
@@ -0,0 +1,331 @@
+/*
+* Copyright (C) 2005-2009 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
+
+// client supported max level for player/pets/etc. Avoid overflow or client stability affected.
+// also see GT_MAX_LEVEL define
+#define MAX_LEVEL 100
+
+// Server side limitation. Base at used code requirements.
+// also see MAX_LEVEL and GT_MAX_LEVEL define
+#define STRONG_MAX_LEVEL 255
+
+enum AreaTeams
+{
+ AREATEAM_NONE = 0,
+ AREATEAM_ALLY = 2,
+ AREATEAM_HORDE = 4
+};
+
+enum AchievementFactionFlags
+{
+ ACHIEVEMENT_FACTION_FLAG_HORDE = 0x00000000,
+ ACHIEVEMENT_FACTION_FLAG_ALLIANCE = 0x00000001,
+};
+
+enum AchievementFlags
+{
+ ACHIEVEMENT_FLAG_COUNTER = 0x00000001, // Just count statistic (never stop and complete)
+ ACHIEVEMENT_FLAG_UNK2 = 0x00000002, // not used
+ ACHIEVEMENT_FLAG_STORE_MAX_VALUE = 0x00000004, // Store only max value? used only in "Reach level xx"
+ ACHIEVEMENT_FLAG_SUMM = 0x00000008, // Use summ criteria value from all reqirements (and calculate max value)
+ ACHIEVEMENT_FLAG_MAX_USED = 0x00000010, // Show max criteria (and calculate max value ??)
+ ACHIEVEMENT_FLAG_REQ_COUNT = 0x00000020, // Use not zero req count (and calculate max value)
+ ACHIEVEMENT_FLAG_AVERANGE = 0x00000040, // Show as averange value (value / time_in_days) depend from other flag (by def use last criteria value)
+ ACHIEVEMENT_FLAG_BAR = 0x00000080, // Show as progress bar (value / max vale) depend from other flag (by def use last criteria value)
+ ACHIEVEMENT_FLAG_REALM_FIRST_REACH = 0x00000100, //
+ ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, //
+};
+
+enum AchievementCriteriaCondition
+{
+ ACHIEVEMENT_CRITERIA_CONDITION_NONE = 0,
+ ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH = 1,
+ ACHIEVEMENT_CRITERIA_CONDITION_UNK1 = 2, // only used in "Complete a daily quest every day for five consecutive days"
+ ACHIEVEMENT_CRITERIA_CONDITION_MAP = 3, // requires you to be on specific map
+ ACHIEVEMENT_CRITERIA_CONDITION_NO_LOOSE = 4, // only used in "Win 10 arenas without losing"
+ ACHIEVEMENT_CRITERIA_CONDITION_UNK2 = 9, // unk
+ ACHIEVEMENT_CRITERIA_CONDITION_UNK3 = 13, // unk
+};
+
+enum AchievementCriteriaCompletionFlags
+{
+ ACHIEVEMENT_CRITERIA_FLAG_SHOW_PROGRESS_BAR = 0x00000001, // Show progress as bar
+ ACHIEVEMENT_CRITERIA_FLAG_HIDE_CRITERIA = 0x00000002, // Not show criteria in client
+ ACHIEVEMENT_CRITERIA_FLAG_UNK3 = 0x00000004, // BG related??
+ ACHIEVEMENT_CRITERIA_FLAG_UNK4 = 0x00000008, //
+ ACHIEVEMENT_CRITERIA_FLAG_UNK5 = 0x00000010, // not used
+ ACHIEVEMENT_CRITERIA_FLAG_MONEY_COUNTER = 0x00000020, // Displays counter as money
+};
+
+enum AchievementCriteriaGroupFlags
+{
+ // you mustn't be in a group while fulfilling this achievement
+ ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP = 2,
+};
+
+enum AchievementCriteriaTypes
+{
+ ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0,
+ ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1,
+ ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5,
+ ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL = 7,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT = 8,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT = 9,
+ // you have to complete a daily quest x times in a row
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11,
+ ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND= 15,
+ ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP= 16,
+ ACHIEVEMENT_CRITERIA_TYPE_DEATH= 17,
+ ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON = 18,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID = 19,
+ ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE = 20,
+ ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER = 23,
+ ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING = 24,
+ ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM = 26,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST = 27,
+ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET = 28,
+ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL= 29,
+ ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE = 30,
+ ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA = 31,
+ ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32,
+ ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33,
+ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL = 34,
+ // TODO: this criteria has additional conditions which can not be found in the dbcs
+ ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL = 35,
+ ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36,
+ // TODO: the archievements 1162 and 1163 requires a special rating which can't be found in the dbc
+ ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA = 37,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING = 38,
+ ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING = 39,
+ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40,
+ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM = 41,
+ ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM= 42,
+ ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA = 43,
+ ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK= 44,
+ ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT= 45,
+ ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION= 46,
+ ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION= 47,
+ // noted: rewarded as soon as the player payed, not at taking place at the seat
+ ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP= 48,
+ ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM = 49,
+ // TODO: itemlevel is mentioned in text but not present in dbc
+ ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT = 50,
+ ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT= 51,
+ ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52,
+ ACHIEVEMENT_CRITERIA_TYPE_HK_RACE = 53,
+ ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE = 54,
+ ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55,
+ // TODO: in some cases map not present, and in some cases need do without die
+ ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS = 56,
+ ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM = 57,
+ ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS = 59,
+ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS = 60,
+ ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS = 61,
+ ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD = 62,
+ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING = 63,
+ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER = 65,
+ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL = 66,
+ ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY = 67,
+ ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT = 68,
+ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2= 69,
+ ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL= 70,
+ ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72,
+ // TODO: title id is not mentioned in dbc
+ ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE = 74,
+ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS= 75,
+ ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76,
+ ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL = 77,
+ // TODO: creature type (demon, undead etc.) is not stored in dbc
+ ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE = 78,
+ ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS= 80,
+ ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION= 82,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID= 83,
+ ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS= 84,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD = 85,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED = 86,
+ ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION = 87,
+ ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION = 88,
+ ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS = 89,
+ ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM = 90,
+ ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM = 91,
+ ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED = 93,
+ ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED = 94,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH = 95,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_POWER = 96,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_STAT = 97,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER = 98,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_ARMOR = 99,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING = 100,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT = 101,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED = 102,
+ ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED = 103,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED = 104,
+ ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED = 105,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED = 106,
+ ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED = 107,
+ ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN = 108,
+ ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE = 109,
+ // TODO: target entry is missing
+ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110,
+ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE= 112,
+ ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113,
+ ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS = 114,
+ // 0..114 => 115 criteria types total
+ ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 115,
+};
+
+enum AreaFlags
+{
+ AREA_FLAG_SNOW = 0x00000001, // snow (only Dun Morogh, Naxxramas, Razorfen Downs and Winterspring)
+ AREA_FLAG_UNK1 = 0x00000002, // may be necropolis?
+ AREA_FLAG_UNK2 = 0x00000004, // Only used for areas on map 571 (development before)
+ AREA_FLAG_SLAVE_CAPITAL = 0x00000008, // city and city subsones
+ AREA_FLAG_UNK3 = 0x00000010, // can't find common meaning
+ 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, // expansion 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 3.0.3)
+ AREA_FLAG_OUTLAND2 = 0x00004000, // expansion 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 3.0.3)
+ AREA_FLAG_UNK5 = 0x00040000, // only used for Amani Pass, Hatchet Hills
+ AREA_FLAG_UNK6 = 0x00080000, // Valgarde and Acherus: The Ebon Hold
+ AREA_FLAG_LOWLEVEL = 0x00100000, // used for some starting areas with area_level <=15
+ AREA_FLAG_TOWN = 0x00200000, // small towns with Inn
+ AREA_FLAG_UNK7 = 0x00400000, // Warsong Hold, Acherus: The Ebon Hold, New Agamand Inn, Vengeance Landing Inn
+ AREA_FLAG_UNK8 = 0x00800000, // Westguard Inn, Acherus: The Ebon Hold, Valgarde
+ AREA_FLAG_OUTDOOR_PVP = 0x01000000, // Wintergrasp and it's subzones
+ AREA_FLAG_UNK9 = 0x02000000, // unknown
+ AREA_FLAG_UNK10 = 0x04000000, // unknown
+ AREA_FLAG_OUTDOOR_PVP2 = 0x08000000 // Wintergrasp and it's subzones
+};
+
+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,
+ ITEM_ENCHANTMENT_TYPE_USE_SPELL = 7,
+ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET = 8
+};
+
+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
+};
+
+// SummonProperties.dbc, col 1
+enum SummonPropGroup
+{
+ SUMMON_PROP_GROUP_UNKNOWN1 = 0, // 1160 spells in 3.0.3
+ SUMMON_PROP_GROUP_UNKNOWN2 = 1, // 861 spells in 3.0.3
+ SUMMON_PROP_GROUP_PETS = 2, // 52 spells in 3.0.3, pets mostly
+ SUMMON_PROP_GROUP_CONTROLLABLE = 3, // 13 spells in 3.0.3, mostly controllable
+ SUMMON_PROP_GROUP_UNKNOWN3 = 4 // 86 spells in 3.0.3, taxi/mounts
+};
+
+// SummonProperties.dbc, col 3
+enum SummonPropType
+{
+ SUMMON_PROP_TYPE_UNKNOWN = 0, // different summons, 1330 spells in 3.0.3
+ SUMMON_PROP_TYPE_SUMMON = 1, // generic summons, 49 spells in 3.0.3
+ SUMMON_PROP_TYPE_GUARDIAN = 2, // summon guardian, 393 spells in 3.0.3
+ SUMMON_PROP_TYPE_ARMY = 3, // summon army, 5 spells in 3.0.3
+ SUMMON_PROP_TYPE_TOTEM = 4, // summon totem, 169 spells in 3.0.3
+ SUMMON_PROP_TYPE_CRITTER = 5, // critter/minipet, 195 spells in 3.0.3
+ SUMMON_PROP_TYPE_DK = 6, // summon DRW/Ghoul, 2 spells in 3.0.3
+ SUMMON_PROP_TYPE_BOMB = 7, // summon bot/bomb, 4 spells in 3.0.3
+ SUMMON_PROP_TYPE_PHASING = 8, // something todo with DK prequest line, 2 spells in 3.0.3
+ SUMMON_PROP_TYPE_SIEGE_VEH = 9, // summon different vehicles, 14 spells in 3.0.3
+ SUMMON_PROP_TYPE_DRAKE_VEH = 10, // summon drake (vehicle), 3 spells
+ SUMMON_PROP_TYPE_LIGHTWELL = 11 // summon lightwell, 6 spells in 3.0.3
+};
+
+// SummonProperties.dbc, col 5
+enum SummonPropFlags
+{
+ SUMMON_PROP_FLAG_NONE = 0x0000, // 1342 spells in 3.0.3
+ SUMMON_PROP_FLAG_UNK1 = 0x0001, // 75 spells in 3.0.3, something unfriendly
+ SUMMON_PROP_FLAG_UNK2 = 0x0002, // 616 spells in 3.0.3, something friendly
+ SUMMON_PROP_FLAG_UNK3 = 0x0004, // 22 spells in 3.0.3, no idea...
+ SUMMON_PROP_FLAG_UNK4 = 0x0008, // 49 spells in 3.0.3, some mounts
+ SUMMON_PROP_FLAG_UNK5 = 0x0010, // 25 spells in 3.0.3, quest related?
+ SUMMON_PROP_FLAG_UNK6 = 0x0020, // 0 spells in 3.0.3, unused
+ SUMMON_PROP_FLAG_UNK7 = 0x0040, // 12 spells in 3.0.3, no idea
+ SUMMON_PROP_FLAG_UNK8 = 0x0080, // 4 spells in 3.0.3, no idea
+ SUMMON_PROP_FLAG_UNK9 = 0x0100, // 51 spells in 3.0.3, no idea, many quest related
+ SUMMON_PROP_FLAG_UNK10 = 0x0200, // 51 spells in 3.0.3, something defensive
+ SUMMON_PROP_FLAG_UNK11 = 0x0400, // 3 spells, requires something near?
+ SUMMON_PROP_FLAG_UNK12 = 0x0800, // 30 spells in 3.0.3, no idea
+ SUMMON_PROP_FLAG_UNK13 = 0x1000, // 8 spells in 3.0.3, siege vehicle
+ SUMMON_PROP_FLAG_UNK14 = 0x2000, // 2 spells in 3.0.3, escort?
+};
+
+#endif
+
diff --git a/src/shared/Database/DBCStores.cpp b/src/game/DBCStores.cpp
index 2031457ceaf..92c0a28cff4 100644
--- a/src/shared/Database/DBCStores.cpp
+++ b/src/game/DBCStores.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -19,12 +19,12 @@
*/
#include "DBCStores.h"
-//#include "DataStore.h"
#include "Policies/SingletonImp.h"
#include "Log.h"
#include "ProgressBar.h"
+#include "SharedDefines.h"
-#include "DBCfmt.cpp"
+#include "DBCfmt.h"
#include <map>
@@ -32,26 +32,34 @@ typedef std::map<uint16,uint32> AreaFlagByAreaID;
typedef std::map<uint32,uint32> AreaFlagByMapID;
DBCStorage <AreaTableEntry> sAreaStore(AreaTableEntryfmt);
+DBCStorage <AreaGroupEntry> sAreaGroupStore(AreaGroupEntryfmt);
static AreaFlagByAreaID sAreaFlagByAreaID;
static AreaFlagByMapID sAreaFlagByMapID; // for instances without generated *.map files
+DBCStorage <AchievementEntry> sAchievementStore(Achievementfmt);
+DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore(AchievementCriteriafmt);
DBCStorage <AreaTriggerEntry> sAreaTriggerStore(AreaTriggerEntryfmt);
DBCStorage <AuctionHouseEntry> sAuctionHouseStore(AuctionHouseEntryfmt);
DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt);
DBCStorage <BattlemasterListEntry> sBattlemasterListStore(BattlemasterListEntryfmt);
+DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore(BarberShopStyleEntryfmt);
DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore(CharStartOutfitEntryfmt);
DBCStorage <CharTitlesEntry> sCharTitlesStore(CharTitlesEntryfmt);
DBCStorage <ChatChannelsEntry> sChatChannelsStore(ChatChannelsEntryfmt);
DBCStorage <ChrClassesEntry> sChrClassesStore(ChrClassesEntryfmt);
DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt);
+DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore(CinematicSequencesEntryfmt);
DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt);
DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt);
DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt);
+DBCStorage <CreatureTypeEntry> sCreatureTypeStore(CreatureTypefmt);
+DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore(CurrencyTypesfmt);
DBCStorage <DurabilityQualityEntry> sDurabilityQualityStore(DurabilityQualityfmt);
DBCStorage <DurabilityCostsEntry> sDurabilityCostsStore(DurabilityCostsfmt);
-DBCStorage <EmotesTextEntry> sEmotesTextStore(EmoteEntryfmt);
+DBCStorage <EmotesEntry> sEmotesStore(EmotesEntryfmt);
+DBCStorage <EmotesTextEntry> sEmotesTextStore(EmotesTextEntryfmt);
typedef std::map<uint32,SimpleFactionsList> FactionTeamMap;
static FactionTeamMap sFactionTeamMap;
@@ -59,7 +67,10 @@ DBCStorage <FactionEntry> sFactionStore(FactionEntryfmt);
DBCStorage <FactionTemplateEntry> sFactionTemplateStore(FactionTemplateEntryfmt);
DBCStorage <GemPropertiesEntry> sGemPropertiesStore(GemPropertiesEntryfmt);
+DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore(GlyphPropertiesfmt);
+DBCStorage <GlyphSlotEntry> sGlyphSlotStore(GlyphSlotfmt);
+DBCStorage <GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore(GtBarberShopCostBasefmt);
DBCStorage <GtCombatRatingsEntry> sGtCombatRatingsStore(GtCombatRatingsfmt);
DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore(GtChanceToMeleeCritBasefmt);
DBCStorage <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore(GtChanceToMeleeCritfmt);
@@ -69,10 +80,15 @@ DBCStorage <GtOCTRegenHPEntry> sGtOCTRegenHPStore(GtOCTRegenHPfmt);
//DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore(GtOCTRegenMPfmt); -- not used currently
DBCStorage <GtRegenHPPerSptEntry> sGtRegenHPPerSptStore(GtRegenHPPerSptfmt);
DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore(GtRegenMPPerSptfmt);
+
+DBCStorage <HolidaysEntry> sHolidaysStore(Holidaysfmt);
+
DBCStorage <ItemEntry> sItemStore(Itemfmt);
+DBCStorage <ItemBagFamilyEntry> sItemBagFamilyStore(ItemBagFamilyfmt);
//DBCStorage <ItemCondExtCostsEntry> sItemCondExtCostsStore(ItemCondExtCostsEntryfmt);
//DBCStorage <ItemDisplayInfoEntry> sItemDisplayInfoStore(ItemDisplayTemplateEntryfmt); -- not used currently
DBCStorage <ItemExtendedCostEntry> sItemExtendedCostStore(ItemExtendedCostEntryfmt);
+DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore(ItemLimitCategoryEntryfmt);
DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore(ItemRandomPropertiesfmt);
DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore(ItemRandomSuffixfmt);
DBCStorage <ItemSetEntry> sItemSetStore(ItemSetEntryfmt);
@@ -81,10 +97,13 @@ DBCStorage <LockEntry> sLockStore(LockEntryfmt);
DBCStorage <MailTemplateEntry> sMailTemplateStore(MailTemplateEntryfmt);
DBCStorage <MapEntry> sMapStore(MapEntryfmt);
+DBCStorage <MovieEntry> sMovieStore(MovieEntryfmt);
DBCStorage <QuestSortEntry> sQuestSortStore(QuestSortEntryfmt);
DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore(RandomPropertiesPointsfmt);
+DBCStorage <ScalingStatDistributionEntry> sScalingStatDistributionStore(ScalingStatDistributionfmt);
+DBCStorage <ScalingStatValuesEntry> sScalingStatValuesStore(ScalingStatValuesfmt);
DBCStorage <SkillLineEntry> sSkillLineStore(SkillLinefmt);
DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore(SkillLineAbilityfmt);
@@ -102,8 +121,10 @@ DBCStorage <SpellDurationEntry> sSpellDurationStore(SpellDurationfmt);
DBCStorage <SpellFocusObjectEntry> sSpellFocusObjectStore(SpellFocusObjectfmt);
DBCStorage <SpellRadiusEntry> sSpellRadiusStore(SpellRadiusfmt);
DBCStorage <SpellRangeEntry> sSpellRangeStore(SpellRangefmt);
+DBCStorage <SpellRuneCostEntry> sSpellRuneCostStore(SpellRuneCostfmt);
DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore(SpellShapeshiftfmt);
DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore(StableSlotPricesfmt);
+DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore(SummonPropertiesfmt);
DBCStorage <TalentEntry> sTalentStore(TalentEntryfmt);
TalentSpellPosMap sTalentSpellPosMap;
DBCStorage <TalentTabEntry> sTalentTabStore(TalentTabEntryfmt);
@@ -116,6 +137,7 @@ static uint32 sTalentTabPages[12/*MAX_CLASSES*/][3];
DBCStorage <TaxiNodesEntry> sTaxiNodesStore(TaxiNodesEntryfmt);
TaxiMask sTaxiNodesMask;
+TaxiMask sOldContinentsNodesMask;
// DBC used only for initialization sTaxiPathSetBySource at startup.
TaxiPathSetBySource sTaxiPathSetBySource;
@@ -126,7 +148,10 @@ TaxiPathNodesByPath sTaxiPathNodesByPath;
static DBCStorage <TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt);
DBCStorage <TotemCategoryEntry> sTotemCategoryStore(TotemCategoryEntryfmt);
+DBCStorage <VehicleEntry> sVehicleStore(VehicleEntryfmt);
+DBCStorage <VehicleSeatEntry> sVehicleSeatStore(VehicleSeatEntryfmt);
DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore(WorldMapAreaEntryfmt);
+DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore(WorldMapOverlayEntryfmt);
DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore(WorldSafeLocsEntryfmt);
typedef std::list<std::string> StoreProblemList;
@@ -143,7 +168,7 @@ template<class T>
inline void LoadDBC(uint32& availableDbcLocales,barGoLink& bar, StoreProblemList& errlist, DBCStorage<T>& storage, const std::string& dbc_path, const std::string& filename)
{
// compatibility format and C++ structure sizes
- assert(DBCFile::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDBC_assert_print(DBCFile::GetFormatRecordSize(storage.GetFormat()),sizeof(T),filename));
+ assert(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDBC_assert_print(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()),sizeof(T),filename));
std::string dbc_filename = dbc_path + filename;
if(storage.Load(dbc_filename.c_str()))
@@ -179,7 +204,7 @@ void LoadDBCStores(const std::string& dataPath)
{
std::string dbcPath = dataPath+"dbc/";
- const uint32 DBCFilesCount = 57;
+ const uint32 DBCFilesCount = 78;
barGoLink bar( DBCFilesCount );
@@ -197,26 +222,34 @@ void LoadDBCStores(const std::string& dataPath)
sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID),area->exploreFlag));
// fill MapId->DBC records ( skip sub zones and continents )
- if(area->zone==0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 )
+ if(area->zone==0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 && area->mapid != 571 )
sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid,area->exploreFlag));
}
}
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementStore, dbcPath,"Achievement.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementCriteriaStore, dbcPath,"Achievement_Criteria.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaTriggerStore, dbcPath,"AreaTrigger.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaGroupStore, dbcPath,"AreaGroup.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAuctionHouseStore, dbcPath,"AuctionHouse.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBankBagSlotPricesStore, dbcPath,"BankBagSlotPrices.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBarberShopStyleStore, dbcPath,"BarberShopStyle.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharStartOutfitStore, dbcPath,"CharStartOutfit.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrRacesStore, dbcPath,"ChrRaces.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCinematicSequencesStore, dbcPath,"CinematicSequences.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureDisplayInfoStore, dbcPath,"CreatureDisplayInfo.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureFamilyStore, dbcPath,"CreatureFamily.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureSpellDataStore, dbcPath,"CreatureSpellData.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureTypeStore, dbcPath,"CreatureType.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCurrencyTypesStore, dbcPath,"CurrencyTypes.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityCostsStore, dbcPath,"DurabilityCosts.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityQualityStore, dbcPath,"DurabilityQuality.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesStore, dbcPath,"Emotes.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesTextStore, dbcPath,"EmotesText.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionStore, dbcPath,"Faction.dbc");
for (uint32 i=0;i<sFactionStore.GetNumRows(); ++i)
@@ -231,7 +264,10 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionTemplateStore, dbcPath,"FactionTemplate.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGemPropertiesStore, dbcPath,"GemProperties.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphPropertiesStore, dbcPath,"GlyphProperties.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphSlotStore, dbcPath,"GlyphSlot.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtBarberShopCostBaseStore,dbcPath,"gtBarberShopCostBase.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtCombatRatingsStore, dbcPath,"gtCombatRatings.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritBaseStore, dbcPath,"gtChanceToMeleeCritBase.dbc");
@@ -244,18 +280,24 @@ void LoadDBCStores(const std::string& dataPath)
//LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenMPStore, dbcPath,"gtOCTRegenMP.dbc"); -- not used currently
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenHPPerSptStore, dbcPath,"gtRegenHPPerSpt.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenMPPerSptStore, dbcPath,"gtRegenMPPerSpt.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sHolidaysStore, dbcPath,"Holidays.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemStore, dbcPath,"Item.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemBagFamilyStore, dbcPath,"ItemBagFamily.dbc");
//LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemDisplayInfoStore, dbcPath,"ItemDisplayInfo.dbc"); -- not used currently
//LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemCondExtCostsStore, dbcPath,"ItemCondExtCosts.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemExtendedCostStore, dbcPath,"ItemExtendedCost.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemLimitCategoryStore, dbcPath,"ItemLimitCategory.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomPropertiesStore,dbcPath,"ItemRandomProperties.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomSuffixStore, dbcPath,"ItemRandomSuffix.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemSetStore, dbcPath,"ItemSet.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLockStore, dbcPath,"Lock.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMailTemplateStore, dbcPath,"MailTemplate.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore, dbcPath,"Map.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMovieStore, dbcPath,"Movie.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatDistributionStore, dbcPath,"ScalingStatDistribution.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatValuesStore, dbcPath,"ScalingStatValues.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineStore, dbcPath,"SkillLine.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineAbilityStore, dbcPath,"SkillLineAbility.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSoundEntriesStore, dbcPath,"SoundEntries.dbc");
@@ -266,11 +308,11 @@ void LoadDBCStores(const std::string& dataPath)
if(spell && spell->Category)
sSpellCategoryStore[spell->Category].insert(i);
- // DBC not support uint64 fields but SpellEntry have SpellFamilyFlags mapped at 2 uint32 fields
+ /*// DBC not support uint64 fields but SpellEntry have SpellFamilyFlags mapped at 2 uint32 fields
// uint32 field already converted to bigendian if need, but must be swapped for correct uint64 bigendian view
#if TRINITY_ENDIAN == TRINITY_BIGENDIAN
std::swap(*((uint32*)(&spell->SpellFamilyFlags)),*(((uint32*)(&spell->SpellFamilyFlags))+1));
- #endif
+ #endif*/
}
for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
@@ -284,7 +326,7 @@ void LoadDBCStores(const std::string& dataPath)
if(spellInfo && (spellInfo->Attributes & 0x1D0) == 0x1D0)
{
- for (unsigned int i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i)
+ for (uint32 i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i)
{
CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i);
if(!cFamily)
@@ -292,6 +334,12 @@ void LoadDBCStores(const std::string& dataPath)
if(skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1])
continue;
+ if(spellInfo->spellLevel)
+ continue;
+
+ // Passive spell has to have spellfamilyflags if name present (need to not apply 20782)
+ //if (spellInfo->Attributes & SPELL_ATTR_UNK18 && spellInfo->SpellFamilyName && !spellInfo->SpellFamilyFlags)
+ // continue;
sPetFamilySpellsStore[i].insert(spellInfo->Id);
}
@@ -305,8 +353,10 @@ void LoadDBCStores(const std::string& dataPath)
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");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRuneCostStore, dbcPath,"SpellRuneCost.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellShapeshiftStore, dbcPath,"SpellShapeshiftForm.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sStableSlotPricesStore, dbcPath,"StableSlotPrices.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSummonPropertiesStore, dbcPath,"SummonProperties.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentStore, dbcPath,"Talent.dbc");
// create talent spells set
@@ -314,7 +364,7 @@ void LoadDBCStores(const std::string& dataPath)
{
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
if (!talentInfo) continue;
- for (int j = 0; j < 5; j++)
+ for (int j = 0; j < MAX_TALENT_RANK; j++)
if(talentInfo->RankID[j])
sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i,j);
}
@@ -338,7 +388,7 @@ void LoadDBCStores(const std::string& dataPath)
// find talent rank
uint32 curtalent_maxrank = 0;
- for(uint32 k = 5; k > 0; --k)
+ for(uint32 k = MAX_TALENT_RANK; k > 0; --k)
{
if(talentInfo->RankID[k-1])
{
@@ -358,9 +408,13 @@ void LoadDBCStores(const std::string& dataPath)
if(!talentTabInfo)
continue;
+ // prevent memory corruption; otherwise cls will become 12 below
+ if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE)==0)
+ continue;
+
// store class talent tab pages
uint32 cls = 1;
- for(uint32 m=1;!(m & talentTabInfo->ClassMask) && cls < 12 /*MAX_CLASSES*/;m <<=1, ++cls) {}
+ for(uint32 m=1;!(m & talentTabInfo->ClassMask) && cls < MAX_CLASSES;m <<=1, ++cls) {}
sTalentTabPages[cls][talentTabInfo->tabpage]=talentTabId;
@@ -384,18 +438,6 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiNodesStore, dbcPath,"TaxiNodes.dbc");
- // Initialize global taxinodes mask
- memset(sTaxiNodesMask,0,sizeof(sTaxiNodesMask));
- for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
- {
- if(sTaxiNodesStore.LookupEntry(i))
- {
- uint8 field = (uint8)((i - 1) / 32);
- uint32 submask = 1<<((i-1)%32);
- sTaxiNodesMask[field] |= submask;
- }
- }
-
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathStore, dbcPath,"TaxiPath.dbc");
for(uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i)
if(TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i))
@@ -409,7 +451,10 @@ void LoadDBCStores(const std::string& dataPath)
pathLength.resize(pathCount); // 0 and some other indexes not used
for(uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i)
if(TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i))
- ++pathLength[entry->path];
+ {
+ if (pathLength[entry->path] < entry->index + 1)
+ pathLength[entry->path] = entry->index + 1;
+ }
// Set path length
sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used
for(uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i)
@@ -420,8 +465,58 @@ void LoadDBCStores(const std::string& dataPath)
sTaxiPathNodesByPath[entry->path][entry->index] = TaxiPathNode(entry->mapid,entry->x,entry->y,entry->z,entry->actionFlag,entry->delay);
sTaxiPathNodeStore.Clear();
+ // Initialize global taxinodes mask
+ // include existed nodes that have at least single not spell base (scripted) path
+ {
+ std::set<uint32> spellPaths;
+ for(uint32 i = 1; i < sSpellStore.GetNumRows (); ++i)
+ if(SpellEntry const* sInfo = sSpellStore.LookupEntry (i))
+ for(int j=0; j < 3; ++j)
+ if(sInfo->Effect[j]==123 /*SPELL_EFFECT_SEND_TAXI*/)
+ spellPaths.insert(sInfo->EffectMiscValue[j]);
+
+ memset(sTaxiNodesMask,0,sizeof(sTaxiNodesMask));
+ memset(sOldContinentsNodesMask,0,sizeof(sTaxiNodesMask));
+ for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
+ {
+ TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i);
+ if(!node)
+ continue;
+
+ TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(i);
+ if(src_i!=sTaxiPathSetBySource.end() && !src_i->second.empty())
+ {
+ bool ok = false;
+ for(TaxiPathSetForSource::const_iterator dest_i = src_i->second.begin();dest_i != src_i->second.end(); ++dest_i)
+ {
+ // not spell path
+ if(spellPaths.find(dest_i->second.ID)==spellPaths.end())
+ {
+ ok = true;
+ break;
+ }
+ }
+
+ if(!ok)
+ continue;
+ }
+
+ // valid taxi network node
+ uint8 field = (uint8)((i - 1) / 32);
+ uint32 submask = 1<<((i-1)%32);
+ sTaxiNodesMask[field] |= submask;
+
+ // old continent node (+ nodes virtually at old continents, check explicitly to avoid loading map files for zone info)
+ if (node->map_id < 2 || i == 82 || i == 83 || i == 93 || i == 94)
+ sOldContinentsNodesMask[field] |= submask;
+ }
+ }
+
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTotemCategoryStore, dbcPath,"TotemCategory.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleStore, dbcPath,"Vehicle.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleSeatStore, dbcPath,"VehicleSeat.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapAreaStore, dbcPath,"WorldMapArea.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapOverlayStore, dbcPath,"WorldMapOverlay.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldSafeLocsStore, dbcPath,"WorldSafeLocs.dbc");
// error checks
@@ -436,32 +531,25 @@ void LoadDBCStores(const std::string& dataPath)
for(std::list<std::string>::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i)
str += *i + "\n";
- sLog.outError("\nSome required *.dbc files (%u from %d) not found or not compatible:\n%s",bad_dbc_files.size(),DBCFilesCount,str.c_str());
+ sLog.outError("\nSome required *.dbc files (%u from %d) not found or not compatible:\n%s",(uint32)bad_dbc_files.size(),DBCFilesCount,str.c_str());
exit(1);
}
- // check at up-to-date DBC files (53085 is last added spell in 2.4.3)
- // check at up-to-date DBC files (17514 is last ID in SkillLineAbilities in 2.4.3)
- // check at up-to-date DBC files (598 is last map added in 2.4.3)
- // check at up-to-date DBC files (1127 is last gem property added in 2.4.3)
- // 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) ||
- !sMapStore.LookupEntry(598) ||
- !sGemPropertiesStore.LookupEntry(1127) ||
- !sItemExtendedCostStore.LookupEntry(2425) ||
- !sCharTitlesStore.LookupEntry(71) ||
- !sAreaStore.LookupEntry(1768) )
+ // Check loaded DBC files proper version
+ if( !sSpellStore.LookupEntry(62735) || // last added spell in 3.0.9
+ !sMapStore.LookupEntry(624) || // last map added in 3.0.8a/3.0.9
+ !sGemPropertiesStore.LookupEntry(1557) || // last gem property added in 3.0.8a/3.0.9
+ !sItemExtendedCostStore.LookupEntry(2589) || // last item extended cost added in 3.0.8a/3.0.9
+ !sCharTitlesStore.LookupEntry(144) || // last char title added in 3.0.8a/3.0.9
+ !sAreaStore.LookupEntry(2769) || // last area (areaflag) added in 3.0.8a/3.0.9
+ !sItemStore.LookupEntry(45037) ) // last client known item added in 3.0.9
{
sLog.outError("\nYou have _outdated_ DBC files. Please extract correct versions from current using client.");
exit(1);
}
sLog.outString();
- sLog.outString( ">> Loaded %d data stores", DBCFilesCount );
- sLog.outString();
+ sLog.outString( ">> Initialized %d data stores", DBCFilesCount );
}
SimpleFactionsList const* GetFactionTeamList(uint32 faction)
@@ -539,7 +627,7 @@ uint32 GetAreaFlagByMapId(uint32 mapid)
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId)
{
- if(mapid != 530) // speed for most cases
+ if(mapid != 530 && mapid != 571) // speed for most cases
return mapid;
if(WorldMapAreaEntry const* wma = sWorldMapAreaStore.LookupEntry(zoneId))
@@ -651,4 +739,8 @@ uint32 const* GetTalentTabPages(uint32 cls)
TRINITY_DLL_SPEC DBCStorage <SoundEntriesEntry> const* GetSoundEntriesStore() { return &sSoundEntriesStore; }
TRINITY_DLL_SPEC DBCStorage <SpellEntry> const* GetSpellStore() { return &sSpellStore; }
TRINITY_DLL_SPEC DBCStorage <SpellRangeEntry> const* GetSpellRangeStore() { return &sSpellRangeStore; }
-
+TRINITY_DLL_SPEC DBCStorage <FactionEntry> const* GetFactionStore() { return &sFactionStore; }
+TRINITY_DLL_SPEC DBCStorage <ItemEntry> const* GetItemDisplayStore() { return &sItemStore; }
+TRINITY_DLL_SPEC DBCStorage <CreatureDisplayInfoEntry> const* GetCreatureDisplayStore() { return &sCreatureDisplayInfoStore; }
+TRINITY_DLL_SPEC DBCStorage <EmotesEntry> const* GetEmotesStore() { return &sEmotesStore; }
+TRINITY_DLL_SPEC DBCStorage <EmotesTextEntry> const* GetEmotesTextStore() { return &sEmotesTextStore; }
diff --git a/src/shared/Database/DBCStores.h b/src/game/DBCStores.h
index 4ad275653e7..4d7a9324ea2 100644
--- a/src/shared/Database/DBCStores.h
+++ b/src/game/DBCStores.h
@@ -1,7 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
- *
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 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
@@ -18,12 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef DBCSTORES_H
-#define DBCSTORES_H
+#ifndef MANGOS_DBCSTORES_H
+#define MANGOS_DBCSTORES_H
#include "Common.h"
-//#include "DataStore.h"
-#include "dbcfile.h"
+#include "Database/DBCStore.h"
#include "DBCStructure.h"
#include <list>
@@ -61,97 +58,37 @@ uint32 GetTalentInspectBitPosInTab(uint32 talentId);
uint32 GetTalentTabInspectBitSize(uint32 talentTabId);
uint32 const* /*[3]*/ GetTalentTabPages(uint32 cls);
-template<class T>
-class DBCStorage
-{
- typedef std::list<char*> StringPoolList;
- public:
- explicit DBCStorage(const char *f) : nCount(0), fieldCount(0), fmt(f), indexTable(NULL), m_dataTable(NULL) { }
- ~DBCStorage() { Clear(); }
-
- T const* LookupEntry(uint32 id) const { return (id>=nCount)?NULL:indexTable[id]; }
- uint32 GetNumRows() const { return nCount; }
- char const* GetFormat() const { return fmt; }
- uint32 GetFieldCount() const { return fieldCount; }
-
- bool Load(char const* fn)
- {
- DBCFile dbc;
- // Check if load was sucessful, only then continue
- if(!dbc.Load(fn, fmt))
- return false;
-
- fieldCount = dbc.GetCols();
- m_dataTable = (T*)dbc.AutoProduceData(fmt,nCount,(char**&)indexTable);
- m_stringPoolList.push_back(dbc.AutoProduceStrings(fmt,(char*)m_dataTable));
-
- // error in dbc file at loading if NULL
- return indexTable!=NULL;
- }
-
- bool LoadStringsFrom(char const* fn)
- {
- // DBC must be already loaded using Load
- if(!indexTable)
- return false;
-
- DBCFile dbc;
- // Check if load was successful, only then continue
- if(!dbc.Load(fn, fmt))
- return false;
-
- m_stringPoolList.push_back(dbc.AutoProduceStrings(fmt,(char*)m_dataTable));
-
- return true;
- }
-
- void Clear()
- {
- if (!indexTable)
- return;
-
- delete[] ((char*)indexTable);
- indexTable = NULL;
- delete[] ((char*)m_dataTable);
- m_dataTable = NULL;
-
- while(!m_stringPoolList.empty())
- {
- delete[] m_stringPoolList.front();
- m_stringPoolList.pop_front();
- }
- nCount = 0;
- }
-
- private:
- uint32 nCount;
- uint32 fieldCount;
- char const* fmt;
- T** indexTable;
- T* m_dataTable;
- StringPoolList m_stringPoolList;
-};
-
+extern DBCStorage <AchievementEntry> sAchievementStore;
+extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore;
extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access using functions
+extern DBCStorage <AreaGroupEntry> sAreaGroupStore;
extern DBCStorage <AreaTriggerEntry> sAreaTriggerStore;
extern DBCStorage <AuctionHouseEntry> sAuctionHouseStore;
extern DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore;
+extern DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore;
extern DBCStorage <BattlemasterListEntry> sBattlemasterListStore;
//extern DBCStorage <ChatChannelsEntry> sChatChannelsStore; -- accessed using function, no usable index
extern DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore;
extern DBCStorage <CharTitlesEntry> sCharTitlesStore;
extern DBCStorage <ChrClassesEntry> sChrClassesStore;
extern DBCStorage <ChrRacesEntry> sChrRacesStore;
+extern DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore;
extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore;
extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore;
extern DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore;
+extern DBCStorage <CreatureTypeEntry> sCreatureTypeStore;
+extern DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore;
extern DBCStorage <DurabilityCostsEntry> sDurabilityCostsStore;
extern DBCStorage <DurabilityQualityEntry> sDurabilityQualityStore;
+extern DBCStorage <EmotesEntry> sEmotesStore;
extern DBCStorage <EmotesTextEntry> sEmotesTextStore;
extern DBCStorage <FactionEntry> sFactionStore;
extern DBCStorage <FactionTemplateEntry> sFactionTemplateStore;
extern DBCStorage <GemPropertiesEntry> sGemPropertiesStore;
+extern DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore;
+extern DBCStorage <GlyphSlotEntry> sGlyphSlotStore;
+extern DBCStorage <GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore;
extern DBCStorage <GtCombatRatingsEntry> sGtCombatRatingsStore;
extern DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore;
extern DBCStorage <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore;
@@ -161,17 +98,23 @@ extern DBCStorage <GtOCTRegenHPEntry> sGtOCTRegenHPStore;
//extern DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore; -- not used currently
extern DBCStorage <GtRegenHPPerSptEntry> sGtRegenHPPerSptStore;
extern DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore;
+extern DBCStorage <HolidaysEntry> sHolidaysStore;
extern DBCStorage <ItemEntry> sItemStore;
+extern DBCStorage <ItemBagFamilyEntry> sItemBagFamilyStore;
//extern DBCStorage <ItemDisplayInfoEntry> sItemDisplayInfoStore; -- not used currently
extern DBCStorage <ItemExtendedCostEntry> sItemExtendedCostStore;
+extern DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore;
extern DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore;
extern DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore;
extern DBCStorage <ItemSetEntry> sItemSetStore;
extern DBCStorage <LockEntry> sLockStore;
extern DBCStorage <MailTemplateEntry> sMailTemplateStore;
extern DBCStorage <MapEntry> sMapStore;
+extern DBCStorage <MovieEntry> sMovieStore;
extern DBCStorage <QuestSortEntry> sQuestSortStore;
extern DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore;
+extern DBCStorage <ScalingStatDistributionEntry> sScalingStatDistributionStore;
+extern DBCStorage <ScalingStatValuesEntry> sScalingStatValuesStore;
extern DBCStorage <SkillLineEntry> sSkillLineStore;
extern DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore;
extern DBCStorage <SoundEntriesEntry> sSoundEntriesStore;
@@ -184,25 +127,35 @@ extern SpellCategoryStore sSpellCategoryStore;
extern PetFamilySpellsStore sPetFamilySpellsStore;
extern DBCStorage <SpellRadiusEntry> sSpellRadiusStore;
extern DBCStorage <SpellRangeEntry> sSpellRangeStore;
+extern DBCStorage <SpellRuneCostEntry> sSpellRuneCostStore;
extern DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore;
extern DBCStorage <SpellEntry> sSpellStore;
extern DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore;
+extern DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore;
extern DBCStorage <TalentEntry> sTalentStore;
extern DBCStorage <TalentTabEntry> sTalentTabStore;
extern DBCStorage <TaxiNodesEntry> sTaxiNodesStore;
extern DBCStorage <TaxiPathEntry> sTaxiPathStore;
extern TaxiMask sTaxiNodesMask;
+extern TaxiMask sOldContinentsNodesMask;
extern TaxiPathSetBySource sTaxiPathSetBySource;
extern TaxiPathNodesByPath sTaxiPathNodesByPath;
extern DBCStorage <TotemCategoryEntry> sTotemCategoryStore;
+extern DBCStorage <VehicleEntry> sVehicleStore;
+extern DBCStorage <VehicleSeatEntry> sVehicleSeatStore;
//extern DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore; -- use Zone2MapCoordinates and Map2ZoneCoordinates
+extern DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore;
extern DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore;
void LoadDBCStores(const std::string& dataPath);
// script support functions
-TRINITY_DLL_SPEC DBCStorage <SoundEntriesEntry> const* GetSoundEntriesStore();
-TRINITY_DLL_SPEC DBCStorage <SpellEntry> const* GetSpellStore();
-TRINITY_DLL_SPEC DBCStorage <SpellRangeEntry> const* GetSpellRangeStore();
+TRINITY_DLL_SPEC DBCStorage <SoundEntriesEntry> const* GetSoundEntriesStore();
+TRINITY_DLL_SPEC DBCStorage <SpellEntry> const* GetSpellStore();
+TRINITY_DLL_SPEC DBCStorage <SpellRangeEntry> const* GetSpellRangeStore();
+TRINITY_DLL_SPEC DBCStorage <FactionEntry> const* GetFactionStore();
+TRINITY_DLL_SPEC DBCStorage <ItemEntry> const* GetItemDisplayStore();
+TRINITY_DLL_SPEC DBCStorage <CreatureDisplayInfoEntry> const* GetCreatureDisplayStore();
+TRINITY_DLL_SPEC DBCStorage <EmotesEntry> const* GetEmotesStore();
+TRINITY_DLL_SPEC DBCStorage <EmotesTextEntry> const* GetEmotesTextStore();
#endif
-
diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
new file mode 100644
index 00000000000..506c4efa37c
--- /dev/null
+++ b/src/game/DBCStructure.h
@@ -0,0 +1,1727 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 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 MANGOS_DBCSTRUCTURE_H
+#define MANGOS_DBCSTRUCTURE_H
+
+#include "DBCEnums.h"
+#include "Platform/Define.h"
+#include "Util.h"
+
+#include <map>
+#include <set>
+#include <vector>
+
+// Structures using to access raw DBC data and required packing to portability
+
+// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
+#if defined( __GNUC__ )
+#pragma pack(1)
+#else
+#pragma pack(push,1)
+#endif
+
+struct AchievementEntry
+{
+ uint32 ID; // 0
+ uint32 factionFlag; // 1 -1=all, 0=horde, 1=alliance
+ uint32 mapID; // 2 -1=none
+ //uint32 parentAchievement; // 3 its Achievement parent (can`t start while parent uncomplete, use its Criteria if don`t have own, use its progress on begin)
+ //char *name[16]; // 4-19
+ //uint32 name_flags; // 20
+ //char *description[16]; // 21-36
+ //uint32 desc_flags; // 37
+ uint32 categoryId; // 38
+ uint32 points; // 39 reward points
+ //uint32 OrderInCategory; // 40
+ uint32 flags; // 41
+ //uint32 icon; // 42 icon (from SpellIcon.dbc)
+ //char *titleReward[16]; // 43-58
+ //uint32 titleReward_flags; // 59
+ uint32 count; // 60 - need this count of completed criterias (own or referenced achievement criterias)
+ uint32 refAchievement; // 61 - referenced achievement (counting of all completed criterias)
+};
+
+struct AchievementCategoryEntry
+{
+ uint32 ID; // 0
+ uint32 parentCategory; // 1 -1 for main category
+ //char *name[16]; // 2-17
+ //uint32 name_flags; // 18
+ //uint32 sortOrder; // 19
+};
+
+struct AchievementCriteriaEntry
+{
+ uint32 ID; // 0
+ uint32 referredAchievement; // 1
+ uint32 requiredType; // 2
+ union
+ {
+ // ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0
+ // TODO: also used for player deaths..
+ struct
+ {
+ uint32 creatureID; // 3
+ uint32 creatureCount; // 4
+ } kill_creature;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1
+ // TODO: there are further criterias instead just winning
+ struct
+ {
+ uint32 bgMapID; // 3
+ uint32 winCount; // 4
+ } win_bg;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5
+ struct
+ {
+ uint32 unused; // 3
+ uint32 level; // 4
+ } reach_level;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL = 7
+ struct
+ {
+ uint32 skillID; // 3
+ uint32 skillLevel; // 4
+ } reach_skill_level;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT = 8
+ struct
+ {
+ uint32 linkedAchievement; // 3
+ } complete_achievement;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT = 9
+ struct
+ {
+ uint32 unused; // 3
+ uint32 totalQuestCount; // 4
+ } complete_quest_count;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10
+ struct
+ {
+ uint32 unused; // 3
+ uint32 numberOfDays; // 4
+ } complete_daily_quest_daily;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11
+ struct
+ {
+ uint32 zoneID; // 3
+ uint32 questCount; // 4
+ } complete_quests_in_zone;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14
+ struct
+ {
+ uint32 unused; // 3
+ uint32 questCount; // 4
+ } complete_daily_quest;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND = 15
+ struct
+ {
+ uint32 mapID; // 3
+ } complete_battleground;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP = 16
+ struct
+ {
+ uint32 mapID; // 3
+ } death_at_map;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON = 18
+ struct
+ {
+ uint32 manLimit; // 3
+ } death_in_dungeon;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID = 19
+ struct
+ {
+ uint32 groupSize; // 3 can be 5, 10 or 25
+ } complete_raid;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE = 20
+ struct
+ {
+ uint32 creatureEntry; // 3
+ } killed_by_creature;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING = 24
+ struct
+ {
+ uint32 unused; // 3
+ uint32 fallHeight; // 4
+ } fall_without_dying;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM = 26
+ struct
+ {
+ uint32 type; // 3, see enum EnviromentalDamage
+ } death_from;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST = 27
+ struct
+ {
+ uint32 questID; // 3
+ uint32 questCount; // 4
+ } complete_quest;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET = 28
+ // ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2 = 69
+ struct
+ {
+ uint32 spellID; // 3
+ uint32 spellCount; // 4
+ } be_spell_target;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL = 29
+ // ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110
+ struct
+ {
+ uint32 spellID; // 3
+ uint32 castCount; // 4
+ } cast_spell;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA = 31
+ struct
+ {
+ uint32 areaID; // 3 Reference to AreaTable.dbc
+ uint32 killCount; // 4
+ } honorable_kill_at_area;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32
+ struct
+ {
+ uint32 mapID; // 3 Reference to Map.dbc
+ } win_arena;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33
+ struct
+ {
+ uint32 mapID; // 3 Reference to Map.dbc
+ } play_arena;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL = 34
+ struct
+ {
+ uint32 spellID; // 3 Reference to Map.dbc
+ } learn_spell;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36
+ struct
+ {
+ uint32 itemID; // 3
+ uint32 itemCount; // 4
+ } own_item;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA = 37
+ struct
+ {
+ uint32 unused; // 3
+ uint32 count; // 4
+ uint32 flag; // 5 4=in a row
+ } win_rated_arena;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING = 38
+ struct
+ {
+ uint32 teamtype; // 3 {2,3,5}
+ } highest_team_rating;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING = 39
+ struct
+ {
+ uint32 teamtype; // 3 {2,3,5}
+ uint32 teamrating; // 4
+ } reach_team_rating;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40
+ struct
+ {
+ uint32 skillID; // 3
+ uint32 skillLevel; // 4 apprentice=1, journeyman=2, expert=3, artisan=4, master=5, grand master=6
+ } learn_skill_level;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM = 41
+ struct
+ {
+ uint32 itemID; // 3
+ uint32 itemCount; // 4
+ } use_item;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM = 42
+ struct
+ {
+ uint32 itemID; // 3
+ uint32 itemCount; // 4
+ } loot_item;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA = 43
+ struct
+ {
+ // TODO: This rank is _NOT_ the index from AreaTable.dbc
+ uint32 areaReference; // 3
+ } explore_area;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK = 44
+ struct
+ {
+ // TODO: This rank is _NOT_ the index from CharTitles.dbc
+ uint32 rank; // 3
+ } own_rank;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT = 45
+ struct
+ {
+ uint32 unused; // 3
+ uint32 numberOfSlots; // 4
+ } buy_bank_slot;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION = 46
+ struct
+ {
+ uint32 factionID; // 3
+ uint32 reputationAmount; // 4 Total reputation amount, so 42000 = exalted
+ } gain_reputation;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION= 47
+ struct
+ {
+ uint32 unused; // 3
+ uint32 numberOfExaltedFactions; // 4
+ } gain_exalted_reputation;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP = 48
+ struct
+ {
+ uint32 unused; // 3
+ uint32 numberOfVisits; // 4
+ } visit_barber;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM = 49
+ // TODO: where is the required itemlevel stored?
+ struct
+ {
+ uint32 itemSlot; // 3
+ } equip_epic_item;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT = 50
+ struct
+ {
+ uint32 rollValue; // 3
+ uint32 count; // 4
+ } roll_need_on_loot;
+ // ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT = 51
+ struct
+ {
+ uint32 rollValue; // 3
+ uint32 count; // 4
+ } roll_greed_on_loot;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52
+ struct
+ {
+ uint32 classID; // 3
+ uint32 count; // 4
+ } hk_class;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HK_RACE = 53
+ struct
+ {
+ uint32 raceID; // 3
+ uint32 count; // 4
+ } hk_race;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE = 54
+ // TODO: where is the information about the target stored?
+ struct
+ {
+ uint32 emoteID; // 3 enum TextEmotes
+ uint32 count; // 4 count of emotes, always required special target or requirements
+ } do_emote;
+ // ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13
+ // ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55
+ // ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS = 56
+ struct
+ {
+ uint32 unused; // 3
+ uint32 count; // 4
+ uint32 flag; // 5 =3 for battleground healing
+ uint32 mapid; // 6
+ } healing_done;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM = 57
+ struct
+ {
+ uint32 itemID; // 3
+ uint32 count; // 4
+ } equip_item;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD= 62
+ struct
+ {
+ uint32 unused; // 3
+ uint32 goldInCopper; // 4
+ } quest_reward_money;
+
+
+ // ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY = 67
+ struct
+ {
+ uint32 unused; // 3
+ uint32 goldInCopper; // 4
+ } loot_money;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT = 68
+ struct
+ {
+ uint32 goEntry; // 3
+ uint32 useCount; // 4
+ } use_gameobject;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL = 70
+ // TODO: are those special criteria stored in the dbc or do we have to add another sql table?
+ struct
+ {
+ uint32 unused; // 3
+ uint32 killCount; // 4
+ } special_pvp_kill;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72
+ struct
+ {
+ uint32 goEntry; // 3
+ uint32 lootCount; // 4
+ } fish_in_gameobject;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS = 75
+ struct
+ {
+ uint32 skillLine; // 3
+ uint32 spellCount; // 4
+ } learn_skillline_spell;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76
+ struct
+ {
+ uint32 unused; // 3
+ uint32 duelCount; // 4
+ } win_duel;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_POWER = 96
+ struct
+ {
+ uint32 powerType; // 3 mana=0, 1=rage, 3=energy, 6=runic power
+ } highest_power;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_STAT = 97
+ struct
+ {
+ uint32 statType; // 3 4=spirit, 3=int, 2=stamina, 1=agi, 0=strength
+ } highest_stat;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER = 98
+ struct
+ {
+ uint32 spellSchool; // 3
+ } highest_spellpower;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING = 100
+ struct
+ {
+ uint32 ratingType; // 3
+ } highest_rating;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE = 109
+ struct
+ {
+ uint32 lootType; // 3 3=fishing, 2=pickpocket, 4=disentchant
+ uint32 lootTypeCount; // 4
+ } loot_type;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE = 112
+ struct
+ {
+ uint32 skillLine; // 3
+ uint32 spellCount; // 4
+ } learn_skill_line;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113
+ struct
+ {
+ uint32 unused; // 3
+ uint32 killCount; // 4
+ } honorable_kill;
+
+ struct
+ {
+ uint32 field3; // 3 main requirement
+ uint32 count; // 4 main requirement count
+ uint32 additionalRequirement1_type; // 5 additional requirement 1 type
+ uint32 additionalRequirement1_value; // 6 additional requirement 1 value
+ uint32 additionalRequirement2_type; // 7 additional requirement 2 type
+ uint32 additionalRequirement2_value; // 8 additional requirement 1 value
+ } raw;
+ };
+ //char* name[16]; // 9-24
+ //uint32 name_flags; // 25
+ uint32 completionFlag; // 26
+ uint32 groupFlag; // 27
+ //uint32 unk1; // 28
+ uint32 timeLimit; // 29 time limit in seconds
+ //uint32 showOrder; // 30 show order
+};
+
+struct AreaTableEntry
+{
+ uint32 ID; // 0
+ uint32 mapid; // 1
+ uint32 zone; // 2 if 0 then it's zone, else it's zone id of this area
+ uint32 exploreFlag; // 3, main index
+ uint32 flags; // 4, unknown value but 312 for all cities
+ // 5-9 unused
+ int32 area_level; // 10
+ char* area_name[16]; // 11-26
+ // 27, string flags, unused
+ uint32 team; // 28
+};
+
+struct AreaGroupEntry
+{
+ uint32 AreaGroupId; // 0
+ uint32 AreaId[6]; // 1-6
+ uint32 nextGroup; // 7 index of next group
+};
+
+struct AreaTriggerEntry
+{
+ uint32 id; // 0 m_ID
+ uint32 mapid; // 1 m_ContinentID
+ float x; // 2 m_x
+ float y; // 3 m_y
+ float z; // 4 m_z
+ float radius; // 5 m_radius
+ float box_x; // 6 m_box_length
+ float box_y; // 7 m_box_width
+ float box_z; // 8 m_box_heigh
+ float box_orientation; // 9 m_box_yaw
+};
+
+struct AuctionHouseEntry
+{
+ uint32 houseId; // 0 index
+ uint32 faction; // 1 id of faction.dbc for player factions associated with city
+ uint32 depositPercent; // 2 1/3 from real
+ uint32 cutPercent; // 3
+ //char* name[16]; // 4-19
+ // 20 string flag, unused
+};
+
+struct BankBagSlotPricesEntry
+{
+ uint32 ID;
+ uint32 price;
+};
+
+struct BarberShopStyleEntry
+{
+ uint32 Id; // 0
+ uint32 type; // 1 value 0 -> hair, value 2 -> facialhair
+ //char* name[16]; // 2-17 name of hair style
+ //uint32 name_flags; // 18
+ //uint32 unk_name[16]; // 19-34, all empty
+ //uint32 unk_flags; // 35
+ //float CostMultiplier; // 36 values 1 and 0.75
+ uint32 race; // 37 race
+ uint32 gender; // 38 0 -> male, 1 -> female
+ uint32 hair_id; // 39 real ID to hair/facial hair
+};
+
+struct BattlemasterListEntry
+{
+ uint32 id; // 0
+ int32 mapid[8]; // 1-8 mapid
+ uint32 type; // 9 (3 - BG, 4 - arena)
+ uint32 minlvl; // 10
+ uint32 maxlvl; // 11
+ uint32 maxplayersperteam; // 12
+ // 13 minplayers
+ // 14 0 or 9
+ // 15
+ char* name[16]; // 16-31
+ // 32 string flag, unused
+ // 33 unused
+};
+
+#define MAX_OUTFIT_ITEMS 24
+
+struct CharStartOutfitEntry
+{
+ //uint32 Id; // 0
+ uint32 RaceClassGender; // 1 (UNIT_FIELD_BYTES_0 & 0x00FFFFFF) comparable (0 byte = race, 1 byte = class, 2 byte = gender)
+ int32 ItemId[MAX_OUTFIT_ITEMS]; // 2-13
+ //int32 ItemDisplayId[MAX_OUTFIT_ITEMS]; // 14-25 not required at server side
+ //int32 ItemInventorySlot[MAX_OUTFIT_ITEMS]; // 26-37 not required at server side
+ //uint32 Unknown1; // 38, unique values (index-like with gaps ordered in other way as ids)
+ //uint32 Unknown2; // 39
+ //uint32 Unknown3; // 40
+};
+
+struct CharTitlesEntry
+{
+ uint32 ID; // 0, title ids, for example in Quest::GetCharTitleId()
+ //uint32 unk1; // 1 flags?
+ //char* name[16]; // 2-17, unused
+ // 18 string flag, unused
+ //char* name2[16]; // 19-34, unused
+ // 35 string flag, unused
+ uint32 bit_index; // 36 used in PLAYER_CHOSEN_TITLE and 1<<index in PLAYER__FIELD_KNOWN_TITLES
+};
+
+struct ChatChannelsEntry
+{
+ uint32 ChannelID; // 0
+ uint32 flags; // 1
+ char* pattern[16]; // 3-18
+ // 19 string flags, unused
+ //char* name[16]; // 20-35 unused
+ // 36 string flag, unused
+};
+
+struct ChrClassesEntry
+{
+ uint32 ClassID; // 0
+ // 1, unused
+ uint32 powerType; // 2
+ // 3-4, unused
+ //char* name[16]; // 5-20 unused
+ // 21 string flag, unused
+ //char* nameFemale[16]; // 21-36 unused, if different from base (male) case
+ // 37 string flag, unused
+ //char* nameNeutralGender[16]; // 38-53 unused, if different from base (male) case
+ // 54 string flag, unused
+ // 55, unused
+ uint32 spellfamily; // 56
+ // 57, unused
+ uint32 CinematicSequence; // 58 id from CinematicSequences.dbc
+ uint32 addon; // 59 (0 - original race, 1 - tbc addon, ...)
+};
+
+struct ChrRacesEntry
+{
+ uint32 RaceID; // 0
+ // 1 unused
+ uint32 FactionID; // 2 facton template id
+ // 3 unused
+ uint32 model_m; // 4
+ uint32 model_f; // 5
+ // 6-7 unused
+ uint32 TeamID; // 8 (7-Alliance 1-Horde)
+ // 9-12 unused
+ uint32 CinematicSequence; // 13 id from CinematicSequences.dbc
+ char* name[16]; // 14-29 used for DBC language detection/selection
+ // 30 string flags, unused
+ //char* nameFemale[16]; // 31-46, if different from base (male) case
+ // 47 string flags, unused
+ //char* nameNeutralGender[16]; // 48-63, if different from base (male) case
+ // 64 string flags, unused
+ // 65-67 unused
+ uint32 addon; // 68 (0 - original race, 1 - tbc addon, ...)
+};
+
+/* not used
+struct CinematicCameraEntry
+{
+ uint32 id; // 0 index
+ char* filename; // 1
+ uint32 soundid; // 2 in SoundEntries.dbc or 0
+ float start_x; // 3
+ float start_y; // 4
+ float start_z; // 5
+ float unk6; // 6 speed?
+};
+*/
+
+struct CinematicSequencesEntry
+{
+ uint32 Id; // 0 index
+ //uint32 unk1; // 1 always 0
+ //uint32 cinematicCamera; // 2 id in CinematicCamera.dbc
+ // 3-9 always 0
+};
+
+struct CreatureDisplayInfoEntry
+{
+ uint32 Displayid; // 0 m_ID
+ // 1 m_modelID
+ // 2 m_soundID
+ // 3 m_extendedDisplayInfoID
+ float scale; // 4 m_creatureModelScale
+ // 5 m_creatureModelAlpha
+ // 6-8 m_textureVariation[3]
+ // 9 m_portraitTextureName
+ // 10 m_sizeClass
+ // 11 m_bloodID
+ // 12 m_NPCSoundID
+ // 13 m_particleColorID
+ // 14 m_creatureGeosetData
+ // 15 m_objectEffectPackageID
+};
+
+struct CreatureFamilyEntry
+{
+ uint32 ID; // 0 m_ID
+ float minScale; // 1 m_minScale
+ uint32 minScaleLevel; // 2 m_minScaleLevel
+ float maxScale; // 3 m_maxScale
+ uint32 maxScaleLevel; // 4 m_maxScaleLevel
+ uint32 skillLine[2]; // 5-6 m_skillLine
+ uint32 petFoodMask; // 7 m_petFoodMask
+ int32 petTalentType; // 8 m_petTalentType
+ // 9 m_categoryEnumID
+ char* Name[16]; // 10-25 m_name_lang
+ // 26 string flags
+ // 27 m_iconFile
+};
+
+struct CreatureSpellDataEntry
+{
+ uint32 ID; // 0 m_ID
+ //uint32 spellId[4]; // 1-4 m_spells[4]
+ //uint32 availability[4]; // 4-7 m_availability[4]
+};
+
+struct CreatureTypeEntry
+{
+ uint32 ID; // 0 m_ID
+ //char* Name[16]; // 1-16 name
+ // 17 string flags
+ //uint32 no_expirience; // 18 no exp? critters, non-combat pets, gas cloud.
+};
+
+/* not used
+struct CurrencyCategoryEntry
+{
+ uint32 ID; // 0
+ uint32 Unk1; // 1 0 for known categories and 3 for unknown one (3.0.9)
+ char* Name[16]; // 2-17 name
+ // // 18 string flags
+};
+*/
+
+struct CurrencyTypesEntry
+{
+ //uint32 ID; // 0 not used
+ uint32 ItemId; // 1 used as real index
+ uint32 BitIndex; // 2 bit index in PLAYER_FIELD_KNOWN_CURRENCIES (1 << (index-1))
+};
+
+struct DurabilityCostsEntry
+{
+ uint32 Itemlvl; // 0
+ uint32 multiplier[29]; // 1-29
+};
+
+struct DurabilityQualityEntry
+{
+ uint32 Id; // 0
+ float quality_mod; // 1
+};
+
+struct EmotesEntry
+{
+ uint32 Id; // 0
+ //char* Name; // 1, internal name
+ //uint32 AnimationId; // 2, ref to animationData
+ uint32 Flags; // 3, bitmask, may be unit_flags
+ uint32 EmoteType; // 4, Can be 0, 1 or 2 (determine how emote are shown)
+ uint32 UnitStandState; // 5, uncomfirmed, may be enum UnitStandStateType
+ //uint32 SoundId; // 6, ref to soundEntries
+};
+
+struct EmotesTextEntry
+{
+ uint32 Id;
+ uint32 textid;
+};
+
+struct FactionEntry
+{
+ uint32 ID; // 0 m_ID
+ int32 reputationListID; // 1 m_reputationIndex
+ uint32 BaseRepRaceMask[4]; // 2-5 m_reputationRaceMask
+ uint32 BaseRepClassMask[4]; // 6-9 m_reputationClassMask
+ int32 BaseRepValue[4]; // 10-13 m_reputationBase
+ uint32 ReputationFlags[4]; // 14-17 m_reputationFlags
+ uint32 team; // 18 m_parentFactionID
+ char* name[16]; // 19-34 m_name_lang
+ // 35 string flags
+ //char* description[16]; // 36-51 m_description_lang
+ // 52 string flags
+};
+
+struct FactionTemplateEntry
+{
+ uint32 ID; // 0 m_ID
+ uint32 faction; // 1 m_faction
+ uint32 factionFlags; // 2 m_flags
+ uint32 ourMask; // 3 m_factionGroup
+ uint32 friendlyMask; // 4 m_friendGroup
+ uint32 hostileMask; // 5 m_enemyGroup
+ uint32 enemyFaction[4]; // 6 m_enemies[4]
+ uint32 friendFaction[4]; // 10 m_friend[4]
+ //------------------------------------------------------- end structure
+
+ // helpers
+ bool IsFriendlyTo(FactionTemplateEntry const& entry) const
+ {
+ if(ID == entry.ID)
+ return true;
+ if(entry.faction)
+ {
+ for(int i = 0; i < 4; ++i)
+ if (enemyFaction[i] == entry.faction)
+ return false;
+ for(int i = 0; i < 4; ++i)
+ if (friendFaction[i] == entry.faction)
+ return true;
+ }
+ return (friendlyMask & entry.ourMask) || (ourMask & entry.friendlyMask);
+ }
+ bool IsHostileTo(FactionTemplateEntry const& entry) const
+ {
+ if(ID == entry.ID)
+ return false;
+ if(entry.faction)
+ {
+ for(int i = 0; i < 4; ++i)
+ if (enemyFaction[i] == entry.faction)
+ return true;
+ for(int i = 0; i < 4; ++i)
+ if (friendFaction[i] == entry.faction)
+ return false;
+ }
+ return (hostileMask & entry.ourMask) != 0;
+ }
+ bool IsHostileToPlayers() const { return (hostileMask & FACTION_MASK_PLAYER) !=0; }
+ bool IsNeutralToAll() const
+ {
+ for(int i = 0; i < 4; ++i)
+ if (enemyFaction[i] != 0)
+ return false;
+ return hostileMask == 0 && friendlyMask == 0;
+ }
+ bool IsContestedGuardFaction() const { return (factionFlags & FACTION_TEMPLATE_FLAG_CONTESTED_GUARD)!=0; }
+};
+
+struct GemPropertiesEntry
+{
+ uint32 ID;
+ uint32 spellitemenchantement;
+ uint32 color;
+};
+
+struct GlyphPropertiesEntry
+{
+ uint32 Id;
+ uint32 SpellId;
+ uint32 TypeFlags;
+ uint32 Unk1; // GlyphIconId (SpellIcon.dbc)
+};
+
+struct GlyphSlotEntry
+{
+ uint32 Id;
+ uint32 TypeFlags;
+ uint32 Order;
+};
+
+// All Gt* DBC store data for 100 levels, some by 100 per class/race
+#define GT_MAX_LEVEL 100
+
+struct GtBarberShopCostBaseEntry
+{
+ float cost;
+};
+
+struct GtCombatRatingsEntry
+{
+ float ratio;
+};
+
+struct GtChanceToMeleeCritBaseEntry
+{
+ float base;
+};
+
+struct GtChanceToMeleeCritEntry
+{
+ float ratio;
+};
+
+struct GtChanceToSpellCritBaseEntry
+{
+ float base;
+};
+
+struct GtChanceToSpellCritEntry
+{
+ float ratio;
+};
+
+struct GtOCTRegenHPEntry
+{
+ float ratio;
+};
+
+//struct GtOCTRegenMPEntry
+//{
+// float ratio;
+//};
+
+struct GtRegenHPPerSptEntry
+{
+ float ratio;
+};
+
+struct GtRegenMPPerSptEntry
+{
+ float ratio;
+};
+
+/* no used
+struct HolidayDescriptionsEntry
+{
+ uint32 ID; // 0, this is NOT holiday id
+ //char* name[16] // 1-16 m_name_lang
+ // 17 name flags
+};
+*/
+
+/* no used
+struct HolidayNamesEntry
+{
+ uint32 ID; // 0, this is NOT holiday id
+ //char* name[16] // 1-16 m_name_lang
+ // 17 name flags
+};
+*/
+
+struct HolidaysEntry
+{
+ uint32 ID; // 0, holiday id
+ //uint32 unk1; // 1
+ //uint32 unk2; // 2
+ //uint32 unk3[8] // 3-10, empty fields
+ //uint32 unk11[13] // 11-23, some unknown data (bit strings?)
+ //uint32 unk11[13] // 24-36, some empty fields (continue prev?)
+ //uint32 unk11[12] // 37-48, counters?
+ //uint32 holidayNameId; // 49, id for HolidayNames.dbc
+ //uint32 holidayDescriptionId; // 50, id for HolidayDescriptions.dbc
+ //uint32 unk51; // 51
+ //uint32 unk52; // 52
+ //uint32 unk53; // 53
+};
+
+struct ItemEntry
+{
+ uint32 ID; // 0
+ uint32 Class; // 1
+ //uint32 SubClass; // 2 some items have strnage subclasses
+ int32 Unk0; // 3
+ int32 Material; // 4
+ uint32 DisplayId; // 5
+ uint32 InventoryType; // 6
+ uint32 Sheath; // 7
+};
+
+struct ItemBagFamilyEntry
+{
+ uint32 ID; // 0
+ //char* name[16] // 1-16 m_name_lang
+ // // 17 name flags
+};
+
+struct ItemDisplayInfoEntry
+{
+ uint32 ID; // 0 m_ID
+ // 1 m_modelName[2]
+ // 2 m_modelTexture[2]
+ // 3 m_inventoryIcon
+ // 4 m_geosetGroup[3]
+ // 5 m_flags
+ // 6 m_spellVisualID
+ // 7 m_groupSoundIndex
+ // 8 m_helmetGeosetVis[2]
+ // 9 m_texture[2]
+ // 10 m_itemVisual[8]
+ // 11 m_particleColorID
+};
+
+//struct ItemCondExtCostsEntry
+//{
+// uint32 ID;
+// uint32 condExtendedCost; // ItemPrototype::CondExtendedCost
+// uint32 itemextendedcostentry; // ItemPrototype::ExtendedCost
+// uint32 arenaseason; // arena season number(1-4)
+//};
+
+struct ItemExtendedCostEntry
+{
+ uint32 ID; // 0 extended-cost entry id
+ uint32 reqhonorpoints; // 1 required honor points
+ uint32 reqarenapoints; // 2 required arena points
+ uint32 reqitem[5]; // 3-7 required item id
+ uint32 reqitemcount[5]; // 8-12 required count of 1st item
+ uint32 reqpersonalarenarating; // 13 required personal arena rating
+};
+
+struct ItemLimitCategoryEntry
+{
+ uint32 ID; // 0 Id
+ //char* name[16] // 1-16 m_name_lang
+ // 17 name flags
+ uint32 maxCount; // max allowed equipped as item or in gem slot
+ //uint32 unk; // 1 for prismatic gems only...
+};
+
+struct ItemRandomPropertiesEntry
+{
+ uint32 ID; // 0 m_ID
+ //char* internalName // 1 m_Name
+ uint32 enchant_id[5]; // 2-6 m_Enchantment
+ //char* nameSuffix[16] // 7-22 m_name_lang
+ // 23 name flags
+};
+
+struct ItemRandomSuffixEntry
+{
+ uint32 ID; // 0 m_ID
+ //char* name[16] // 1-16 m_name_lang
+ // 17, name flags
+ // 18 m_internalName
+ uint32 enchant_id[5]; // 19-21 m_enchantment
+ uint32 prefix[5]; // 22-24 m_allocationPct
+};
+
+struct ItemSetEntry
+{
+ //uint32 id // 0 m_ID
+ char* name[16]; // 1-16 m_name_lang
+ // 17 string flags, unused
+ //uint32 itemId[17]; // 18-34 m_itemID
+ uint32 spells[8]; // 35-42 m_setSpellID
+ uint32 items_to_triggerspell[8]; // 43-50 m_setThreshold
+ uint32 required_skill_id; // 51 m_requiredSkill
+ uint32 required_skill_value; // 52 m_requiredSkillRank
+};
+
+#define MAX_LOCK_CASE 8
+
+struct LockEntry
+{
+ uint32 ID; // 0 m_ID
+ uint32 Type[MAX_LOCK_CASE]; // 1-8 m_Type
+ uint32 Index[MAX_LOCK_CASE]; // 9-16 m_Index
+ uint32 Skill[MAX_LOCK_CASE]; // 17-24 m_Skill
+ //uint32 Action[MAX_LOCK_CASE]; // 25-32 m_Action
+};
+
+struct MailTemplateEntry
+{
+ uint32 ID; // 0
+ //char* subject[16]; // 1-16
+ // 17 name flags, unused
+ //char* content[16]; // 18-33
+};
+
+struct MapEntry
+{
+ uint32 MapID; // 0
+ //char* internalname; // 1 unused
+ uint32 map_type; // 2
+ // 3 0 or 1 for battlegrounds (not arenas)
+ char* name[16]; // 4-19
+ // 20 name flags, unused
+ uint32 linked_zone; // 21 common zone for instance and continent map
+ //char* hordeIntro[16]; // 23-37 text for PvP Zones
+ // 38 intro text flags
+ //char* allianceIntro[16]; // 39-54 text for PvP Zones
+ // 55 intro text flags
+ uint32 multimap_id; // 56
+ // 57
+ //chat* unknownText1[16]; // 58-73 unknown empty text fields, possible normal Intro text.
+ // 74 text flags
+ //chat* heroicIntroText[16]; // 75-90 heroic mode requirement text
+ // 91 text flags
+ //chat* unknownText2[16]; // 92-107 unknown empty text fields
+ // 108 text flags
+ int32 entrance_map; // 109 map_id of entrance map
+ float entrance_x; // 110 entrance x coordinate (if exist single entry)
+ float entrance_y; // 111 entrance y coordinate (if exist single entry)
+ uint32 resetTimeRaid; // 112
+ uint32 resetTimeHeroic; // 113
+ // 114 all 0
+ // 115 -1, 0 and 720
+ uint32 addon; // 116 (0-original maps,1-tbc addon)
+ // 117 some kind of time?
+
+ // Helpers
+ uint32 Expansion() const { return addon; }
+
+
+ bool IsDungeon() const { return map_type == MAP_INSTANCE || map_type == MAP_RAID; }
+ bool Instanceable() const { return map_type == MAP_INSTANCE || map_type == MAP_RAID || map_type == MAP_BATTLEGROUND || map_type == MAP_ARENA; }
+ bool IsRaid() const { return map_type == MAP_RAID; }
+ bool IsBattleGround() const { return map_type == MAP_BATTLEGROUND; }
+ bool IsBattleArena() const { return map_type == MAP_ARENA; }
+ bool IsBattleGroundOrArena() const { return map_type == MAP_BATTLEGROUND || map_type == MAP_ARENA; }
+ bool SupportsHeroicMode() const { return resetTimeHeroic != 0; }
+ bool HasResetTime() const { return resetTimeHeroic || resetTimeRaid; }
+
+ bool IsMountAllowed() const
+ {
+ return !IsDungeon() ||
+ MapID==209 || MapID==269 || MapID==309 || // TanarisInstance, CavernsOfTime, Zul'gurub
+ MapID==509 || MapID==534 || MapID==560 || // AhnQiraj, HyjalPast, HillsbradPast
+ MapID==568 || MapID==580 || MapID==615 || // ZulAman, Sunwell Plateau, Obsidian Sanctrum
+ MapID==616; // Eye Of Eternity
+ }
+
+ bool IsContinent() const
+ {
+ return MapID == 0 || MapID == 1 || MapID == 530 || MapID == 571;
+ }
+};
+
+struct MovieEntry
+{
+ uint32 Id; // 0 index
+ //char* filename; // 1
+ //uint32 unk2; // 2 always 100
+};
+
+struct QuestSortEntry
+{
+ uint32 id; // 0 m_ID
+ //char* name[16]; // 1-16 m_SortName_lang
+ // 17 name flags
+};
+
+struct RandomPropertiesPointsEntry
+{
+ //uint32 Id; // 0 hidden key
+ uint32 itemLevel; // 1
+ uint32 EpicPropertiesPoints[5]; // 2-6
+ uint32 RarePropertiesPoints[5]; // 7-11
+ uint32 UncommonPropertiesPoints[5]; // 12-16
+};
+
+struct ScalingStatDistributionEntry
+{
+ uint32 Id;
+ uint32 StatMod[10];
+ uint32 Modifier[10];
+ uint32 MaxLevel;
+};
+
+struct ScalingStatValuesEntry
+{
+ uint32 Id;
+ uint32 Level;
+ uint32 Multiplier[17];
+};
+
+//struct SkillLineCategoryEntry{
+// uint32 id; // 0 m_ID
+// char* name[16]; // 1-17 m_name_lang
+// // 18 string flag
+// uint32 displayOrder; // 19 m_sortIndex
+//};
+
+//struct SkillRaceClassInfoEntry{
+// uint32 id; // 0 m_ID
+// uint32 skillId; // 1 m_skillID
+// uint32 raceMask; // 2 m_raceMask
+// uint32 classMask; // 3 m_classMask
+// uint32 flags; // 4 m_flags
+// uint32 reqLevel; // 5 m_minLevel
+// uint32 skillTierId; // 6 m_skillTierID
+// uint32 skillCostID; // 7 m_skillCostIndex
+//};
+
+//struct SkillTiersEntry{
+// uint32 id; // 0 m_ID
+// uint32 skillValue[16]; // 1-17 m_cost
+// uint32 maxSkillValue[16]; // 18-32 m_valueMax
+//};
+
+struct SkillLineEntry
+{
+ uint32 id; // 0 m_ID
+ int32 categoryId; // 1 m_categoryID
+ //uint32 skillCostID; // 2 m_skillCostsID
+ char* name[16]; // 3-18 m_displayName_lang
+ // 19 string flags
+ //char* description[16]; // 20-35 m_description_lang
+ // 36 string flags
+ uint32 spellIcon; // 37 m_spellIconID
+ //char* alternateVerb[16]; // 38-53 m_alternateVerb_lang
+ // 54 string flags
+ // 55 m_canLink
+};
+
+struct SkillLineAbilityEntry
+{
+ uint32 id; // 0 m_ID
+ uint32 skillId; // 1 m_skillLine
+ uint32 spellId; // 2 m_spell
+ uint32 racemask; // 3 m_raceMask
+ uint32 classmask; // 4 m_classMask
+ //uint32 racemaskNot; // 5 m_excludeRace
+ //uint32 classmaskNot; // 6 m_excludeClass
+ uint32 req_skill_value; // 7 m_minSkillLineRank
+ uint32 forward_spellid; // 8 m_supercededBySpell
+ uint32 learnOnGetSkill; // 9 m_acquireMethod
+ uint32 max_value; // 10 m_trivialSkillLineRankHigh
+ uint32 min_value; // 11 m_trivialSkillLineRankLow
+ //uint32 characterPoints[2]; // 12-13 m_characterPoints[2]
+};
+
+struct SoundEntriesEntry
+{
+ uint32 Id; // 0 m_ID
+ //uint32 Type; // 1 m_soundType
+ //char* InternalName; // 2 m_name
+ //char* FileName[10]; // 3-12 m_File[10]
+ //uint32 Unk13[10]; // 13-22 m_Freq[10]
+ //char* Path; // 23 m_DirectoryBase
+ // 24 m_volumeFloat
+ // 25 m_flags
+ // 26 m_minDistance
+ // 27 m_distanceCutoff
+ // 28 m_EAXDef
+};
+
+#define MAX_SPELL_EFFECTS 3
+
+struct SpellEntry
+{
+ uint32 Id; // 0 m_ID
+ uint32 Category; // 1 m_category
+ uint32 Dispel; // 2 m_dispelType
+ uint32 Mechanic; // 3 m_mechanic
+ uint32 Attributes; // 4 m_attribute
+ uint32 AttributesEx; // 5 m_attributesEx
+ uint32 AttributesEx2; // 6 m_attributesExB
+ uint32 AttributesEx3; // 7 m_attributesExC
+ uint32 AttributesEx4; // 8 m_attributesExD
+ uint32 AttributesEx5; // 9 m_attributesExE
+ //uint32 AttributesEx6; // 10 m_attributesExF not used
+ uint32 Stances; // 11 m_shapeshiftMask
+ uint32 StancesNot; // 12 m_shapeshiftExclude
+ uint32 Targets; // 13 m_targets
+ uint32 TargetCreatureType; // 14 m_targetCreatureType
+ uint32 RequiresSpellFocus; // 15 m_requiresSpellFocus
+ uint32 FacingCasterFlags; // 16 m_facingCasterFlags
+ uint32 CasterAuraState; // 17 m_casterAuraState
+ uint32 TargetAuraState; // 18 m_targetAuraState
+ uint32 CasterAuraStateNot; // 19 m_excludeCasterAuraState
+ uint32 TargetAuraStateNot; // 20 m_excludeTargetAuraState
+ uint32 casterAuraSpell; // 21 m_casterAuraSpell
+ uint32 targetAuraSpell; // 22 m_targetAuraSpell
+ uint32 excludeCasterAuraSpell; // 23 m_excludeCasterAuraSpell
+ uint32 excludeTargetAuraSpell; // 24 m_excludeTargetAuraSpell
+ uint32 CastingTimeIndex; // 25 m_castingTimeIndex
+ uint32 RecoveryTime; // 26 m_recoveryTime
+ uint32 CategoryRecoveryTime; // 27 m_categoryRecoveryTime
+ uint32 InterruptFlags; // 28 m_interruptFlags
+ uint32 AuraInterruptFlags; // 29 m_auraInterruptFlags
+ uint32 ChannelInterruptFlags; // 30 m_channelInterruptFlags
+ uint32 procFlags; // 31 m_procTypeMask
+ uint32 procChance; // 32 m_procChance
+ uint32 procCharges; // 33 m_procCharges
+ uint32 maxLevel; // 34 m_maxLevel
+ uint32 baseLevel; // 35 m_baseLevel
+ uint32 spellLevel; // 36 m_spellLevel
+ uint32 DurationIndex; // 37 m_durationIndex
+ uint32 powerType; // 38 m_powerType
+ uint32 manaCost; // 39 m_manaCost
+ uint32 manaCostPerlevel; // 40 m_manaCostPerLevel
+ uint32 manaPerSecond; // 41 m_manaPerSecond
+ uint32 manaPerSecondPerLevel; // 42 m_manaPerSecondPerLeve
+ uint32 rangeIndex; // 43 m_rangeIndex
+ float speed; // 44 m_speed
+ //uint32 modalNextSpell; // 45 m_modalNextSpell not used
+ uint32 StackAmount; // 46 m_cumulativeAura
+ uint32 Totem[2]; // 47-48 m_totem
+ int32 Reagent[8]; // 49-56 m_reagent
+ uint32 ReagentCount[8]; // 57-64 m_reagentCount
+ int32 EquippedItemClass; // 65 m_equippedItemClass (value)
+ int32 EquippedItemSubClassMask; // 66 m_equippedItemSubclass (mask)
+ int32 EquippedItemInventoryTypeMask; // 67 m_equippedItemInvTypes (mask)
+ uint32 Effect[MAX_SPELL_EFFECTS]; // 68-70 m_effect
+ int32 EffectDieSides[MAX_SPELL_EFFECTS]; // 71-73 m_effectDieSides
+ uint32 EffectBaseDice[MAX_SPELL_EFFECTS]; // 74-76 m_effectBaseDice
+ float EffectDicePerLevel[MAX_SPELL_EFFECTS]; // 77-79 m_effectDicePerLevel
+ float EffectRealPointsPerLevel[MAX_SPELL_EFFECTS]; // 80-82 m_effectRealPointsPerLevel
+ int32 EffectBasePoints[MAX_SPELL_EFFECTS]; // 83-85 m_effectBasePoints (don't must be used in spell/auras explicitly, must be used cached Spell::m_currentBasePoints)
+ uint32 EffectMechanic[MAX_SPELL_EFFECTS]; // 86-88 m_effectMechanic
+ uint32 EffectImplicitTargetA[MAX_SPELL_EFFECTS]; // 89-91 m_implicitTargetA
+ uint32 EffectImplicitTargetB[MAX_SPELL_EFFECTS]; // 92-94 m_implicitTargetB
+ uint32 EffectRadiusIndex[MAX_SPELL_EFFECTS]; // 95-97 m_effectRadiusIndex - spellradius.dbc
+ uint32 EffectApplyAuraName[MAX_SPELL_EFFECTS]; // 98-100 m_effectAura
+ uint32 EffectAmplitude[MAX_SPELL_EFFECTS]; // 101-103 m_effectAuraPeriod
+ float EffectMultipleValue[MAX_SPELL_EFFECTS]; // 104-106 m_effectAmplitude
+ uint32 EffectChainTarget[MAX_SPELL_EFFECTS]; // 107-109 m_effectChainTargets
+ uint32 EffectItemType[MAX_SPELL_EFFECTS]; // 110-112 m_effectItemType
+ int32 EffectMiscValue[MAX_SPELL_EFFECTS]; // 113-115 m_effectMiscValue
+ int32 EffectMiscValueB[MAX_SPELL_EFFECTS]; // 116-118 m_effectMiscValueB
+ uint32 EffectTriggerSpell[MAX_SPELL_EFFECTS]; // 119-121 m_effectTriggerSpell
+ float EffectPointsPerComboPoint[MAX_SPELL_EFFECTS]; // 122-124 m_effectPointsPerCombo
+ flag96 EffectSpellClassMask[MAX_SPELL_EFFECTS]; //
+ uint32 SpellVisual[2]; // 134-135 m_spellVisualID
+ uint32 SpellIconID; // 136 m_spellIconID
+ uint32 activeIconID; // 137 m_activeIconID
+ //uint32 spellPriority; // 138 not used
+ char* SpellName[16]; // 139-154 m_name_lang
+ //uint32 SpellNameFlag; // 155 not used
+ char* Rank[16]; // 156-171 m_nameSubtext_lang
+ //uint32 RankFlags; // 172 not used
+ //char* Description[16]; // 173-188 m_description_lang not used
+ //uint32 DescriptionFlags; // 189 not used
+ //char* ToolTip[16]; // 190-205 m_auraDescription_lang not used
+ //uint32 ToolTipFlags; // 206 not used
+ uint32 ManaCostPercentage; // 207 m_manaCostPct
+ uint32 StartRecoveryCategory; // 208 m_startRecoveryCategory
+ uint32 StartRecoveryTime; // 209 m_startRecoveryTime
+ uint32 MaxTargetLevel; // 210 m_maxTargetLevel
+ uint32 SpellFamilyName; // 211 m_spellClassSet
+ flag96 SpellFamilyFlags; // 212-214
+ uint32 MaxAffectedTargets; // 215 m_maxTargets
+ uint32 DmgClass; // 216 m_defenseType
+ uint32 PreventionType; // 217 m_preventionType
+ //uint32 StanceBarOrder; // 218 m_stanceBarOrder not used
+ float DmgMultiplier[3]; // 219-221 m_effectChainAmplitude
+ //uint32 MinFactionId; // 222 m_minFactionID not used
+ //uint32 MinReputation; // 223 m_minReputation not used
+ //uint32 RequiredAuraVision; // 224 m_requiredAuraVision not used
+ uint32 TotemCategory[2]; // 225-226 m_requiredTotemCategoryID
+ int32 AreaGroupId; // 227 m_requiredAreaGroupId
+ uint32 SchoolMask; // 228 m_schoolMask
+ uint32 runeCostID; // 229 m_runeCostID
+ //uint32 spellMissileID; // 230 m_spellMissileID not used
+
+ // helpers
+ int32 CalculateSimpleValue(uint8 eff) const { return EffectBasePoints[eff]+int32(EffectBaseDice[eff]); }
+
+ private:
+ // prevent creating custom entries (copy data from original in fact)
+ SpellEntry(SpellEntry const&); // DON'T must have implementation
+};
+
+typedef std::set<uint32> SpellCategorySet;
+typedef std::map<uint32,SpellCategorySet > SpellCategoryStore;
+typedef std::set<uint32> PetFamilySpellsSet;
+typedef std::map<uint32,PetFamilySpellsSet > PetFamilySpellsStore;
+
+struct SpellCastTimesEntry
+{
+ uint32 ID; // 0
+ int32 CastTime; // 1
+ //float CastTimePerLevel; // 2 unsure / per skill?
+ //int32 MinCastTime; // 3 unsure
+};
+
+struct SpellFocusObjectEntry
+{
+ uint32 ID; // 0
+ //char* Name[16]; // 1-15 unused
+ // 16 string flags, unused
+};
+
+// stored in SQL table
+struct SpellThreatEntry
+{
+ uint32 spellId;
+ int32 threat;
+};
+
+struct SpellRadiusEntry
+{
+ uint32 ID;
+ float radiusHostile;
+ //uint32 Unk //always 0
+ float radiusFriend;
+};
+
+struct SpellRangeEntry
+{
+ uint32 ID;
+ float minRangeHostile;
+ float minRangeFriend;
+ float maxRangeHostile;
+ float maxRangeFriend; //friend means unattackable unit here
+ uint32 type;
+ //char* Name[16]; // 7-23 unused
+ // 24 string flags, unused
+ //char* Name2[16]; // 25-40 unused
+ // 41 string flags, unused
+};
+
+struct SpellRuneCostEntry
+{
+ uint32 ID; // 0
+ uint32 RuneCost[3]; // 1-3 (0=blood, 1=frost, 2=unholy)
+ uint32 runePowerGain; // 4
+
+ bool NoRuneCost() const { return RuneCost[0] == 0 && RuneCost[1] == 0 && RuneCost[2] == 0; }
+ bool NoRunicPowerGain() const { return runePowerGain == 0; }
+};
+
+struct SpellShapeshiftEntry
+{
+ uint32 ID; // 0
+ //uint32 buttonPosition; // 1 unused
+ //char* Name[16]; // 2-17 unused
+ //uint32 NameFlags; // 18 unused
+ uint32 flags1; // 19
+ int32 creatureType; // 20 <=0 humanoid, other normal creature types
+ //uint32 unk1; // 21 unused
+ uint32 attackSpeed; // 22
+ //uint32 modelID; // 23 unused, alliance modelid (where horde case?)
+ //uint32 unk2; // 24 unused
+ //uint32 unk3; // 25 unused
+ //uint32 unk4; // 26 unused
+ //uint32 unk5; // 27 unused
+ //uint32 unk6; // 28 unused
+ //uint32 unk7; // 29 unused
+ //uint32 unk8; // 30 unused
+ //uint32 unk9; // 31 unused
+ //uint32 unk10; // 32 unused
+ //uint32 unk11; // 33 unused
+ //uint32 unk12; // 34 unused
+};
+
+struct SpellDurationEntry
+{
+ uint32 ID;
+ int32 Duration[3];
+};
+
+struct SpellItemEnchantmentEntry
+{
+ uint32 ID; // 0 m_ID
+ //uint32 charges; // 1 m_charges
+ uint32 type[3]; // 2-4 m_effect[3]
+ uint32 amount[3]; // 5-7 m_effectPointsMin[3]
+ //uint32 amount2[3] // 8-10 m_effectPointsMax[3]
+ uint32 spellid[3]; // 11-13 m_effectArg[3]
+ char* description[16]; // 14-29 m_name_lang[16]
+ //uint32 descriptionFlags; // 30 name flags
+ uint32 aura_id; // 31 m_itemVisual
+ uint32 slot; // 32 m_flags
+ uint32 GemID; // 33 m_src_itemID
+ uint32 EnchantmentCondition; // 34 m_condition_id
+ //uint32 requiredSkill; // 35 m_requiredSkillID
+ //uint32 requiredSkillValue; // 36 m_requiredSkillRank
+};
+
+struct SpellItemEnchantmentConditionEntry
+{
+ uint32 ID; // 0 m_ID
+ uint8 Color[5]; // 1-5 m_lt_operandType[5]
+ //uint32 LT_Operand[5]; // 6-10 m_lt_operand[5]
+ uint8 Comparator[5]; // 11-15 m_operator[5]
+ uint8 CompareColor[5]; // 15-20 m_rt_operandType[5]
+ uint32 Value[5]; // 21-25 m_rt_operand[5]
+ //uint8 Logic[5] // 25-30 m_logic[5]
+};
+
+struct StableSlotPricesEntry
+{
+ uint32 Slot;
+ uint32 Price;
+};
+
+struct SummonPropertiesEntry
+{
+ uint32 Id; // 0
+ uint32 Category; // 1, 0 - can't be controlled?, 1 - something guardian?, 2 - pet?, 3 - something controllable?, 4 - taxi/mount?
+ uint32 Faction; // 2, 14 rows > 0
+ uint32 Type; // 3, see enum
+ uint32 Slot; // 4, 0-6
+ uint32 Flags; // 5
+};
+
+#define MAX_TALENT_RANK 5
+#define MAX_PET_TALENT_RANK 3 // use in calculations, expected <= MAX_TALENT_RANK
+
+struct TalentEntry
+{
+ uint32 TalentID; // 0
+ uint32 TalentTab; // 1 index in TalentTab.dbc (TalentTabEntry)
+ uint32 Row; // 2
+ uint32 Col; // 3
+ uint32 RankID[MAX_TALENT_RANK]; // 4-8
+ // 9-12 not used, always 0, maybe not used high ranks
+ uint32 DependsOn; // 13 index in Talent.dbc (TalentEntry)
+ // 14-15 not used
+ uint32 DependsOnRank; // 16
+ // 17-18 not used
+ //uint32 unk1; // 19, 0 or 1
+ //uint32 unk2; // 20, all 0
+ //uint32 unkFlags1; // 21, related to hunter pet talents
+ //uint32 unkFlags2; // 22, related to hunter pet talents
+};
+
+struct TalentTabEntry
+{
+ uint32 TalentTabID; // 0
+ //char* name[16]; // 1-16, unused
+ //uint32 nameFlags; // 17, unused
+ //unit32 spellicon; // 18
+ // 19 not used
+ uint32 ClassMask; // 20
+ uint32 petTalentMask; // 21
+ uint32 tabpage; // 22
+ //char* internalname; // 23
+};
+
+struct TaxiNodesEntry
+{
+ uint32 ID; // 0 m_ID
+ uint32 map_id; // 1 m_ContinentID
+ float x; // 2 m_x
+ float y; // 3 m_y
+ float z; // 4 m_z
+ //char* name[16]; // 5-21 m_Name_lang
+ // 22 string flags
+ uint32 MountCreatureID[2]; // 23-24 m_MountCreatureID[2]
+};
+
+struct TaxiPathEntry
+{
+ uint32 ID; // 0 m_ID
+ uint32 from; // 1 m_FromTaxiNode
+ uint32 to; // 2 m_ToTaxiNode
+ uint32 price; // 3 m_Cost
+};
+
+struct TaxiPathNodeEntry
+{
+ // 0 m_ID
+ uint32 path; // 1 m_PathID
+ uint32 index; // 2 m_NodeIndex
+ uint32 mapid; // 3 m_ContinentID
+ float x; // 4 m_LocX
+ float y; // 5 m_LocY
+ float z; // 6 m_LocZ
+ uint32 actionFlag; // 7 m_flags
+ uint32 delay; // 8 m_delay
+ // 9 m_arrivalEventID
+ // 10 m_departureEventID
+};
+
+struct TotemCategoryEntry
+{
+ uint32 ID; // 0
+ //char* name[16]; // 1-16
+ // 17 string flags, unused
+ uint32 categoryType; // 18 (one for specialization)
+ uint32 categoryMask; // 19 (compatibility mask for same type: different for totems, compatible from high to low for rods)
+};
+
+struct VehicleEntry
+{
+ uint32 m_ID; // 0
+ uint32 m_flags; // 1
+ float m_turnSpeed; // 2
+ float m_pitchSpeed; // 3
+ float m_pitchMin; // 4
+ float m_pitchMax; // 5
+ uint32 m_seatID[8]; // 6-13
+ float m_mouseLookOffsetPitch; // 14
+ float m_cameraFadeDistScalarMin; // 15
+ float m_cameraFadeDistScalarMax; // 16
+ float m_cameraPitchOffset; // 17
+ int m_powerType[3]; // 18-20
+ int m_powerToken[3]; // 21-23
+ float m_facingLimitRight; // 24
+ float m_facingLimitLeft; // 25
+ float m_msslTrgtTurnLingering; // 26
+ float m_msslTrgtPitchLingering; // 27
+ float m_msslTrgtMouseLingering; // 28
+ float m_msslTrgtEndOpacity; // 29
+ float m_msslTrgtArcSpeed; // 30
+ float m_msslTrgtArcRepeat; // 31
+ float m_msslTrgtArcWidth; // 32
+ float m_msslTrgtImpactRadius[2]; // 33-34
+ char* m_msslTrgtArcTexture; // 35
+ char* m_msslTrgtImpactTexture; // 36
+ char* m_msslTrgtImpactModel[2]; // 37-38
+ float m_cameraYawOffset; // 39
+ uint32 m_uiLocomotionType; // 40
+ float m_msslTrgtImpactTexRadius; // 41
+ uint32 m_uiSeatIndicatorType; // 42
+};
+
+struct VehicleSeatEntry
+{
+ uint32 m_ID; // 0
+ uint32 m_flags; // 1
+ int32 m_attachmentID; // 2
+ float m_attachmentOffsetX; // 3
+ float m_attachmentOffsetY; // 4
+ float m_attachmentOffsetZ; // 5
+ float m_enterPreDelay; // 6
+ float m_enterSpeed; // 7
+ float m_enterGravity; // 8
+ float m_enterMinDuration; // 9
+ float m_enterMaxDuration; // 10
+ float m_enterMinArcHeight; // 11
+ float m_enterMaxArcHeight; // 12
+ int32 m_enterAnimStart; // 13
+ int32 m_enterAnimLoop; // 14
+ int32 m_rideAnimStart; // 15
+ int32 m_rideAnimLoop; // 16
+ int32 m_rideUpperAnimStart; // 17
+ int32 m_rideUpperAnimLoop; // 18
+ float m_exitPreDelay; // 19
+ float m_exitSpeed; // 20
+ float m_exitGravity; // 21
+ float m_exitMinDuration; // 22
+ float m_exitMaxDuration; // 23
+ float m_exitMinArcHeight; // 24
+ float m_exitMaxArcHeight; // 25
+ int32 m_exitAnimStart; // 26
+ int32 m_exitAnimLoop; // 27
+ int32 m_exitAnimEnd; // 28
+ float m_passengerYaw; // 29
+ float m_passengerPitch; // 30
+ float m_passengerRoll; // 31
+ int32 m_passengerAttachmentID; // 32
+ int32 m_vehicleEnterAnim; // 33
+ int32 m_vehicleExitAnim; // 34
+ int32 m_vehicleRideAnimLoop; // 35
+ int32 m_vehicleEnterAnimBone; // 36
+ int32 m_vehicleExitAnimBone; // 37
+ int32 m_vehicleRideAnimLoopBone; // 38
+ float m_vehicleEnterAnimDelay; // 39
+ float m_vehicleExitAnimDelay; // 40
+ uint32 m_vehicleAbilityDisplay; // 41
+ uint32 m_enterUISoundID; // 42
+ uint32 m_exitUISoundID; // 43
+ int32 m_uiSkin; // 44
+ uint32 m_flagsB; // 45
+};
+
+struct WorldMapAreaEntry
+{
+ //uint32 ID; // 0
+ uint32 map_id; // 1
+ uint32 area_id; // 2 index (continent 0 areas ignored)
+ //char* internal_name // 3
+ float y1; // 4
+ float y2; // 5
+ float x1; // 6
+ float x2; // 7
+ int32 virtual_map_id; // 8 -1 (map_id have correct map) other: virtual map where zone show (map_id - where zone in fact internally)
+ // int32 dungeonMap_id; // 9 pointer to DungeonMap.dbc (owerride x1,x2,y1,y2 coordinates)
+};
+
+#define MAX_WORLD_MAP_OVERLAY_AREA_IDX 4
+
+struct WorldMapOverlayEntry
+{
+ uint32 ID; // 0
+ //uint32 worldMapAreaId; // 1 idx in WorldMapArea.dbc
+ uint32 areatableID[MAX_WORLD_MAP_OVERLAY_AREA_IDX]; // 2-5
+ // 6-7 always 0, possible part of areatableID[]
+ //char* internal_name // 8
+ // 9-16 some ints
+};
+
+struct WorldSafeLocsEntry
+{
+ uint32 ID; // 0
+ uint32 map_id; // 1
+ float x; // 2
+ float y; // 3
+ float z; // 4
+ //char* name[16] // 5-20 name, unused
+ // 21 name flags, unused
+};
+
+// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
+#if defined( __GNUC__ )
+#pragma pack()
+#else
+#pragma pack(pop)
+#endif
+
+// Structures not used for casting to loaded DBC data and not required then packing
+struct TalentSpellPos
+{
+ TalentSpellPos() : talent_id(0), rank(0) {}
+ TalentSpellPos(uint16 _talent_id, uint8 _rank) : talent_id(_talent_id), rank(_rank) {}
+
+ uint16 talent_id;
+ uint8 rank;
+};
+
+typedef std::map<uint32,TalentSpellPos> TalentSpellPosMap;
+
+struct TaxiPathBySourceAndDestination
+{
+ TaxiPathBySourceAndDestination() : ID(0),price(0) {}
+ TaxiPathBySourceAndDestination(uint32 _id,uint32 _price) : ID(_id),price(_price) {}
+
+ uint32 ID;
+ uint32 price;
+};
+typedef std::map<uint32,TaxiPathBySourceAndDestination> TaxiPathSetForSource;
+typedef std::map<uint32,TaxiPathSetForSource> TaxiPathSetBySource;
+
+struct TaxiPathNode
+{
+ TaxiPathNode() : mapid(0), x(0),y(0),z(0),actionFlag(0),delay(0) {}
+ TaxiPathNode(uint32 _mapid, float _x, float _y, float _z, uint32 _actionFlag, uint32 _delay) : mapid(_mapid), x(_x),y(_y),z(_z),actionFlag(_actionFlag),delay(_delay) {}
+
+ uint32 mapid;
+ float x;
+ float y;
+ float z;
+ uint32 actionFlag;
+ uint32 delay;
+};
+typedef std::vector<TaxiPathNode> TaxiPathNodeList;
+typedef std::vector<TaxiPathNodeList> TaxiPathNodesByPath;
+
+#define TaxiMaskSize 12
+typedef uint32 TaxiMask[TaxiMaskSize];
+#endif
+
diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h
new file mode 100644
index 00000000000..ea2198ef22c
--- /dev/null
+++ b/src/game/DBCfmt.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 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 MANGOS_DBCSFRM_H
+#define MANGOS_DBCSFRM_H
+
+const char Achievementfmt[]="niixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxii";
+const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiixix";
+const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx";
+const char AreaGroupEntryfmt[]="niiiiiii";
+const char AreaTriggerEntryfmt[]="niffffffff";
+const char AuctionHouseEntryfmt[]="niiixxxxxxxxxxxxxxxxx";
+const char BankBagSlotPricesEntryfmt[]="ni";
+const char BarberShopStyleEntryfmt[]="nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii";
+const char BattlemasterListEntryfmt[]="niiiiiiiiiiiixxxssssssssssssssssxx";
+const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+const char CharTitlesEntryfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
+const char ChatChannelsEntryfmt[]="iixssssssssssssssssxxxxxxxxxxxxxxxxxx";
+ // ChatChannelsEntryfmt, index not used (more compact store)
+const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
+const char ChrRacesEntryfmt[]="nxixiixxixxxxissssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
+const char CinematicSequencesEntryfmt[]="nxxxxxxxxx";
+const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxxxx";
+const char CreatureFamilyfmt[]="nfifiiiiixssssssssssssssssxx";
+const char CreatureSpellDatafmt[]="nxxxxxxxx";
+const char CreatureTypefmt[]="nxxxxxxxxxxxxxxxxxx";
+const char CurrencyTypesfmt[]="xnxi";
+const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii";
+const char DurabilityQualityfmt[]="nf";
+const char EmotesEntryfmt[]="nxxiiix";
+const char EmotesTextEntryfmt[]="nxixxxxxxxxxxxxxxxx";
+const char FactionEntryfmt[]="niiiiiiiiiiiiiiiiiissssssssssssssssxxxxxxxxxxxxxxxxxx";
+const char FactionTemplateEntryfmt[]="niiiiiiiiiiiii";
+const char GemPropertiesEntryfmt[]="nixxi";
+const char GlyphPropertiesfmt[]="niii";
+const char GlyphSlotfmt[]="nii";
+const char GtBarberShopCostBasefmt[]="f";
+const char GtCombatRatingsfmt[]="f";
+const char GtChanceToMeleeCritBasefmt[]="f";
+const char GtChanceToMeleeCritfmt[]="f";
+const char GtChanceToSpellCritBasefmt[]="f";
+const char GtChanceToSpellCritfmt[]="f";
+const char GtOCTRegenHPfmt[]="f";
+//const char GtOCTRegenMPfmt[]="f";
+const char GtRegenHPPerSptfmt[]="f";
+const char GtRegenMPPerSptfmt[]="f";
+const char Holidaysfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+const char Itemfmt[]="nixiiiii";
+const char ItemBagFamilyfmt[]="nxxxxxxxxxxxxxxxxx";
+//const char ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx";
+//const char ItemCondExtCostsEntryfmt[]="xiii";
+const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiix";
+const char ItemLimitCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxix";
+const char ItemRandomPropertiesfmt[]="nxiiiiixxxxxxxxxxxxxxxxx";
+const char ItemRandomSuffixfmt[]="nxxxxxxxxxxxxxxxxxxiiiiiiiiii";
+const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii";
+const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
+const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+const char MapEntryfmt[]="nxixssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiffiixxix";
+const char MovieEntryfmt[]="nxx";
+const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx";
+const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii";
+const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii";
+const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiii";
+const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxx";
+const char SkillLineAbilityfmt[]="niiiixxiiiiixx";
+const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+const char SpellCastTimefmt[]="nixx";
+const char SpellDurationfmt[]="niii";
+const char SpellEntryfmt[]="niiiiiiiiixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiix";
+const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx";
+const char SpellItemEnchantmentfmt[]="nxiiiiiixxxiiissssssssssssssssxiiiixx";
+const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX";
+const char SpellRadiusfmt[]="nfxf";
+const char SpellRangefmt[]="nffffixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+const char SpellRuneCostfmt[]="niiii";
+const char SpellShapeshiftfmt[]="nxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxx";
+const char StableSlotPricesfmt[] = "ni";
+const char SummonPropertiesfmt[] = "niiiii";
+const char TalentEntryfmt[]="niiiiiiiixxxxixxixxxxxx";
+const char TalentTabEntryfmt[]="nxxxxxxxxxxxxxxxxxxxiiix";
+const char TaxiNodesEntryfmt[]="nifffxxxxxxxxxxxxxxxxxii";
+const char TaxiPathEntryfmt[]="niii";
+const char TaxiPathNodeEntryfmt[]="diiifffiixx";
+const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii";
+const char VehicleEntryfmt[]="niffffiiiiiiiiffffiiiiiifffffffffffssssfifi";
+const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiii";
+const char WorldMapAreaEntryfmt[]="xinxffffix";
+const char WorldMapOverlayEntryfmt[]="nxiiiixxxxxxxxxxx";
+const char WorldSafeLocsEntryfmt[]="nifffxxxxxxxxxxxxxxxxx";
+
+#endif \ No newline at end of file
diff --git a/src/game/Debugcmds.cpp b/src/game/Debugcmds.cpp
index 3bf64188e34..2e3a256a214 100644
--- a/src/game/Debugcmds.cpp
+++ b/src/game/Debugcmds.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,37 +21,23 @@
#include "Common.h"
#include "Database/DatabaseEnv.h"
#include "WorldPacket.h"
-#include "WorldSession.h"
-#include "World.h"
+#include "Vehicle.h"
#include "Player.h"
#include "Opcodes.h"
#include "Chat.h"
#include "Log.h"
#include "Unit.h"
-#include "ObjectAccessor.h"
#include "GossipDef.h"
#include "Language.h"
-#include "MapManager.h"
#include "BattleGroundMgr.h"
#include <fstream>
#include "ObjectMgr.h"
+#include "Cell.h"
+#include "CellImpl.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
-bool ChatHandler::HandleDebugInArcCommand(const char* /*args*/)
-{
- Object *obj = getSelectedUnit();
-
- if(!obj)
- {
- SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
- return true;
- }
-
- SendSysMessage(LANG_NOT_IMPLEMENTED);
-
- return true;
-}
-
-bool ChatHandler::HandleDebugSpellFailCommand(const char* args)
+bool ChatHandler::HandleDebugSendSpellFailCommand(const char* args)
{
if(!args)
return false;
@@ -61,16 +47,31 @@ bool ChatHandler::HandleDebugSpellFailCommand(const char* args)
return false;
uint8 failnum = (uint8)atoi(px);
+ if(failnum==0 && *px!='0')
+ return false;
+
+ char* p1 = strtok(NULL, " ");
+ uint8 failarg1 = p1 ? (uint8)atoi(p1) : 0;
+
+ char* p2 = strtok(NULL, " ");
+ uint8 failarg2 = p2 ? (uint8)atoi(p2) : 0;
+
WorldPacket data(SMSG_CAST_FAILED, 5);
+ data << uint8(0);
data << uint32(133);
data << uint8(failnum);
+ if(p1 || p2)
+ data << uint32(failarg1);
+ if(p2)
+ data << uint32(failarg2);
+
m_session->SendPacket(&data);
return true;
}
-bool ChatHandler::HandleSetPoiCommand(const char* args)
+bool ChatHandler::HandleDebugSendPoiCommand(const char* args)
{
Player *pPlayer = m_session->GetPlayer();
Unit* target = getSelectedUnit();
@@ -89,9 +90,6 @@ bool ChatHandler::HandleSetPoiCommand(const char* args)
return false;
uint32 icon = atol(icon_text);
- if ( icon < 0 )
- icon = 0;
-
uint32 flags = atol(flags_text);
sLog.outDetail("Command : POI, NPC = %u, icon = %u flags = %u", target->GetGUIDLow(), icon,flags);
@@ -99,7 +97,7 @@ bool ChatHandler::HandleSetPoiCommand(const char* args)
return true;
}
-bool ChatHandler::HandleEquipErrorCommand(const char* args)
+bool ChatHandler::HandleDebugSendEquipErrorCommand(const char* args)
{
if(!args)
return false;
@@ -109,7 +107,7 @@ bool ChatHandler::HandleEquipErrorCommand(const char* args)
return true;
}
-bool ChatHandler::HandleSellErrorCommand(const char* args)
+bool ChatHandler::HandleDebugSendSellErrorCommand(const char* args)
{
if(!args)
return false;
@@ -119,7 +117,7 @@ bool ChatHandler::HandleSellErrorCommand(const char* args)
return true;
}
-bool ChatHandler::HandleBuyErrorCommand(const char* args)
+bool ChatHandler::HandleDebugSendBuyErrorCommand(const char* args)
{
if(!args)
return false;
@@ -129,7 +127,7 @@ bool ChatHandler::HandleBuyErrorCommand(const char* args)
return true;
}
-bool ChatHandler::HandleSendOpcodeCommand(const char* /*args*/)
+bool ChatHandler::HandleDebugSendOpcodeCommand(const char* /*args*/)
{
Unit *unit = getSelectedUnit();
Player *player = NULL;
@@ -192,14 +190,22 @@ bool ChatHandler::HandleSendOpcodeCommand(const char* /*args*/)
ifs >> val6;
data << val6;
}
- else if(type == "pguid")
+ else if(type == "appitsguid")
{
data.append(unit->GetPackGUID());
}
- else if(type == "myguid")
+ else if(type == "appmyguid")
{
data.append(player->GetPackGUID());
}
+ else if(type == "myguid")
+ {
+ data << uint64(player->GetGUID());
+ }
+ else if(type == "itsguid")
+ {
+ data << uint64(unit->GetGUID());
+ }
else if(type == "pos")
{
data << unit->GetPositionX();
@@ -221,12 +227,12 @@ bool ChatHandler::HandleSendOpcodeCommand(const char* /*args*/)
ifs.close();
sLog.outDebug("Sending opcode %u", data.GetOpcode());
data.hexlike();
- ((Player*)unit)->GetSession()->SendPacket(&data);
+ player->GetSession()->SendPacket(&data);
PSendSysMessage(LANG_COMMAND_OPCODESENT, data.GetOpcode(), unit->GetName());
return true;
}
-bool ChatHandler::HandleUpdateWorldStateCommand(const char* args)
+bool ChatHandler::HandleDebugUpdateWorldStateCommand(const char* args)
{
char* w = strtok((char*)args, " ");
char* s = strtok(NULL, " ");
@@ -240,18 +246,94 @@ bool ChatHandler::HandleUpdateWorldStateCommand(const char* args)
return true;
}
-bool ChatHandler::HandlePlaySound2Command(const char* args)
+bool ChatHandler::HandleDebugPlayCinematicCommand(const char* args)
{
- if(!args)
+ // USAGE: .debug play cinematic #cinematicid
+ // #cinematicid - ID decimal number from CinemaicSequences.dbc (1st column)
+ if( !*args )
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 dwId = atoi((char*)args);
+
+ if(!sCinematicSequencesStore.LookupEntry(dwId))
+ {
+ PSendSysMessage(LANG_CINEMATIC_NOT_EXIST, dwId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ m_session->GetPlayer()->SendCinematicStart(dwId);
+ return true;
+}
+
+bool ChatHandler::HandleDebugPlayMovieCommand(const char* args)
+{
+ // USAGE: .debug play movie #movieid
+ // #movieid - ID decimal number from Movie.dbc (1st column)
+ if( !*args )
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 dwId = atoi((char*)args);
+
+ if(!sMovieStore.LookupEntry(dwId))
+ {
+ PSendSysMessage(LANG_MOVIE_NOT_EXIST, dwId);
+ SetSentErrorMessage(true);
return false;
+ }
- uint32 soundid = atoi(args);
- m_session->GetPlayer()->PlaySound(soundid, false);
+ m_session->GetPlayer()->SendMovieStart(dwId);
+ return true;
+}
+
+//Play sound
+bool ChatHandler::HandleDebugPlaySoundCommand(const char* args)
+{
+ // USAGE: .debug playsound #soundid
+ // #soundid - ID decimal number from SoundEntries.dbc (1st column)
+ if( !*args )
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 dwSoundId = atoi((char*)args);
+
+ if(!sSoundEntriesStore.LookupEntry(dwSoundId))
+ {
+ PSendSysMessage(LANG_SOUND_NOT_EXIST, dwSoundId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Unit* unit = getSelectedUnit();
+ if(!unit)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if(m_session->GetPlayer()->GetSelection())
+ unit->PlayDistanceSound(dwSoundId,m_session->GetPlayer());
+ else
+ unit->PlayDirectSound(dwSoundId,m_session->GetPlayer());
+
+ PSendSysMessage(LANG_YOU_HEAR_SOUND, dwSoundId);
return true;
}
//Send notification in channel
-bool ChatHandler::HandleSendChannelNotifyCommand(const char* args)
+bool ChatHandler::HandleDebugSendChannelNotifyCommand(const char* args)
{
if(!args)
return false;
@@ -269,7 +351,7 @@ bool ChatHandler::HandleSendChannelNotifyCommand(const char* args)
}
//Send notification in chat
-bool ChatHandler::HandleSendChatMsgCommand(const char* args)
+bool ChatHandler::HandleDebugSendChatMsgCommand(const char* args)
{
if(!args)
return false;
@@ -282,15 +364,14 @@ bool ChatHandler::HandleSendChatMsgCommand(const char* args)
return true;
}
-bool ChatHandler::HandleSendQuestPartyMsgCommand(const char* args)
+bool ChatHandler::HandleDebugSendQuestPartyMsgCommand(const char* args)
{
uint32 msg = atol((char*)args);
- if (msg >= 0)
- m_session->GetPlayer()->SendPushToPartyResponse(m_session->GetPlayer(), msg);
+ m_session->GetPlayer()->SendPushToPartyResponse(m_session->GetPlayer(), msg);
return true;
}
-bool ChatHandler::HandleGetLootRecipient(const char* /*args*/)
+bool ChatHandler::HandleDebugGetLootRecipient(const char* /*args*/)
{
Creature* target = getSelectedCreature();
if(!target)
@@ -300,15 +381,14 @@ bool ChatHandler::HandleGetLootRecipient(const char* /*args*/)
return true;
}
-bool ChatHandler::HandleSendQuestInvalidMsgCommand(const char* args)
+bool ChatHandler::HandleDebugSendQuestInvalidMsgCommand(const char* args)
{
uint32 msg = atol((char*)args);
- if (msg >= 0)
- m_session->GetPlayer()->SendCanTakeQuestResponse(msg);
+ m_session->GetPlayer()->SendCanTakeQuestResponse(msg);
return true;
}
-bool ChatHandler::HandleGetItemState(const char* args)
+bool ChatHandler::HandleDebugGetItemState(const char* args)
{
if (!args)
return false;
@@ -332,7 +412,7 @@ bool ChatHandler::HandleGetItemState(const char* args)
{
state_str = "The player has the following " + state_str + " items: ";
SendSysMessage(state_str.c_str());
- for (uint8 i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; i++)
+ for (uint8 i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i)
{
if(i >= BUYBACK_SLOT_START && i < BUYBACK_SLOT_END)
continue;
@@ -349,9 +429,9 @@ bool ChatHandler::HandleGetItemState(const char* args)
Bag *bag = (Bag*)item;
for (uint8 j = 0; j < bag->GetBagSize(); ++j)
{
- Item* item = bag->GetItemByPos(j);
- if (item && item->GetState() == state)
- PSendSysMessage("bag: 255 slot: %d guid: %d owner: %d", item->GetSlot(), item->GetGUIDLow(), GUID_LOPART(item->GetOwnerGUID()));
+ Item* item2 = bag->GetItemByPos(j);
+ if (item2 && item2->GetState() == state)
+ PSendSysMessage("bag: 255 slot: %d guid: %d owner: %d", item2->GetSlot(), item2->GetGUIDLow(), GUID_LOPART(item2->GetOwnerGUID()));
}
}
}
@@ -360,7 +440,7 @@ bool ChatHandler::HandleGetItemState(const char* args)
if (list_queue)
{
std::vector<Item *> &updateQueue = player->GetItemUpdateQueue();
- for(size_t i = 0; i < updateQueue.size(); i++)
+ for(size_t i = 0; i < updateQueue.size(); ++i)
{
Item *item = updateQueue[i];
if(!item) continue;
@@ -387,7 +467,7 @@ bool ChatHandler::HandleGetItemState(const char* args)
{
bool error = false;
std::vector<Item *> &updateQueue = player->GetItemUpdateQueue();
- for (uint8 i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; i++)
+ for (uint8 i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i)
{
if(i >= BUYBACK_SLOT_START && i < BUYBACK_SLOT_END)
continue;
@@ -445,65 +525,65 @@ bool ChatHandler::HandleGetItemState(const char* args)
Bag *bag = (Bag*)item;
for (uint8 j = 0; j < bag->GetBagSize(); ++j)
{
- Item* item = bag->GetItemByPos(j);
- if (!item) continue;
+ Item* item2 = bag->GetItemByPos(j);
+ if (!item2) continue;
- if (item->GetSlot() != j)
+ if (item2->GetSlot() != j)
{
- PSendSysMessage("the item in bag %d slot %d, guid %d has an incorrect slot value: %d", bag->GetSlot(), j, item->GetGUIDLow(), item->GetSlot());
+ PSendSysMessage("the item in bag %d slot %d, guid %d has an incorrect slot value: %d", bag->GetSlot(), j, item2->GetGUIDLow(), item2->GetSlot());
error = true; continue;
}
- if (item->GetOwnerGUID() != player->GetGUID())
+ if (item2->GetOwnerGUID() != player->GetGUID())
{
- PSendSysMessage("for the item in bag %d at slot %d and itemguid %d, owner's guid (%d) and player's guid (%d) don't match!", bag->GetSlot(), item->GetSlot(), item->GetGUIDLow(), GUID_LOPART(item->GetOwnerGUID()), player->GetGUIDLow());
+ PSendSysMessage("for the item in bag %d at slot %d and itemguid %d, owner's guid (%d) and player's guid (%d) don't match!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), GUID_LOPART(item2->GetOwnerGUID()), player->GetGUIDLow());
error = true; continue;
}
- Bag *container = item->GetContainer();
+ Bag *container = item2->GetContainer();
if (!container)
{
- PSendSysMessage("the item in bag %d at slot %d with guid %d has no container!", bag->GetSlot(), item->GetSlot(), item->GetGUIDLow());
+ PSendSysMessage("the item in bag %d at slot %d with guid %d has no container!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow());
error = true; continue;
}
if (container != bag)
{
- PSendSysMessage("the item in bag %d at slot %d with guid %d has a different container(slot %d guid %d)!", bag->GetSlot(), item->GetSlot(), item->GetGUIDLow(), container->GetSlot(), container->GetGUIDLow());
+ PSendSysMessage("the item in bag %d at slot %d with guid %d has a different container(slot %d guid %d)!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), container->GetSlot(), container->GetGUIDLow());
error = true; continue;
}
- if (item->IsInUpdateQueue())
+ if (item2->IsInUpdateQueue())
{
- uint16 qp = item->GetQueuePos();
+ uint16 qp = item2->GetQueuePos();
if (qp > updateQueue.size())
{
- PSendSysMessage("item in bag: %d at slot: %d guid: %d has a queuepos (%d) larger than the update queue size! ", bag->GetSlot(), item->GetSlot(), item->GetGUIDLow(), qp);
+ PSendSysMessage("item in bag: %d at slot: %d guid: %d has a queuepos (%d) larger than the update queue size! ", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), qp);
error = true; continue;
}
if (updateQueue[qp] == NULL)
{
- PSendSysMessage("item in bag: %d at slot: %d guid: %d has a queuepos (%d) that points to NULL in the queue!", bag->GetSlot(), item->GetSlot(), item->GetGUIDLow(), qp);
+ PSendSysMessage("item in bag: %d at slot: %d guid: %d has a queuepos (%d) that points to NULL in the queue!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), qp);
error = true; continue;
}
- if (updateQueue[qp] != item)
+ if (updateQueue[qp] != item2)
{
- PSendSysMessage("item in bag: %d at slot: %d guid: %d has has a queuepos (%d) that points to another item in the queue (bag: %d, slot: %d, guid: %d)", bag->GetSlot(), item->GetSlot(), item->GetGUIDLow(), qp, updateQueue[qp]->GetBagSlot(), updateQueue[qp]->GetSlot(), updateQueue[qp]->GetGUIDLow());
+ PSendSysMessage("item in bag: %d at slot: %d guid: %d has has a queuepos (%d) that points to another item in the queue (bag: %d, slot: %d, guid: %d)", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), qp, updateQueue[qp]->GetBagSlot(), updateQueue[qp]->GetSlot(), updateQueue[qp]->GetGUIDLow());
error = true; continue;
}
}
- else if (item->GetState() != ITEM_UNCHANGED)
+ else if (item2->GetState() != ITEM_UNCHANGED)
{
- PSendSysMessage("item in bag: %d at slot: %d guid: %d is not in queue but should be (state: %d)!", bag->GetSlot(), item->GetSlot(), item->GetGUIDLow(), item->GetState());
+ PSendSysMessage("item in bag: %d at slot: %d guid: %d is not in queue but should be (state: %d)!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), item2->GetState());
error = true; continue;
}
}
}
}
- for(size_t i = 0; i < updateQueue.size(); i++)
+ for(size_t i = 0; i < updateQueue.size(); ++i)
{
Item *item = updateQueue[i];
if(!item) continue;
@@ -542,6 +622,12 @@ bool ChatHandler::HandleGetItemState(const char* args)
return true;
}
+bool ChatHandler::HandleDebugBattlegroundCommand(const char * /*args*/)
+{
+ sBattleGroundMgr.ToggleTesting();
+ return true;
+}
+
bool ChatHandler::HandleDebugArenaCommand(const char * /*args*/)
{
sBattleGroundMgr.ToggleArenaTesting();
@@ -591,3 +677,158 @@ bool ChatHandler::HandleDebugHostilRefList(const char * /*args*/)
return true;
}
+bool ChatHandler::HandleDebugSetVehicleId(const char *args)
+{
+ Unit* target = getSelectedUnit();
+ if(!target || target->GetTypeId() != TYPEID_UNIT || !((Creature*)target)->isVehicle())
+ return false;
+
+ if(!args)
+ return false;
+
+ char* i = strtok((char*)args, " ");
+ if(!i)
+ return false;
+
+ uint32 id = (uint32)atoi(i);
+ ((Vehicle*)target)->SetVehicleId(id);
+ target->SendUpdateObjectToAllExcept(NULL);
+ PSendSysMessage("Vehicle id set to %u", id);
+ return true;
+}
+
+bool ChatHandler::HandleDebugEnterVehicle(const char * args)
+{
+ Unit* target = getSelectedUnit();
+ if(!target || target->GetTypeId() != TYPEID_UNIT || !((Creature*)target)->isVehicle())
+ return false;
+
+ if(!args)
+ return false;
+
+ char* i = strtok((char*)args, " ");
+ if(!i)
+ return false;
+
+ char* j = strtok(NULL, " ");
+
+ uint32 entry = (uint32)atoi(i);
+ int8 seatId = j ? (int8)atoi(j) : -1;
+
+ Creature *passenger = NULL;
+ Trinity::AllCreaturesOfEntryInRange check(m_session->GetPlayer(), entry, 20.0f);
+ Trinity::CreatureSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(m_session->GetPlayer(), passenger, check);
+ m_session->GetPlayer()->VisitNearbyObject(20.0f, searcher);
+ if(!passenger || passenger == target)
+ return false;
+
+ passenger->EnterVehicle((Vehicle*)target, seatId);
+
+ PSendSysMessage("Creature entered vehicle %d", (uint32)seatId);
+ return true;
+}
+
+bool ChatHandler::HandleDebugSpawnVehicle(const char* args)
+{
+ if(!args)
+ return false;
+
+ char* e = strtok((char*)args, " ");
+ char* i = strtok(NULL, " ");
+
+ if (!e || !i)
+ return false;
+
+ uint32 entry = (uint32)atoi(e);
+ uint32 id = (uint32)atoi(i);
+
+ CreatureInfo const *ci = objmgr.GetCreatureTemplate(entry);
+
+ if(!ci)
+ return false;
+
+ VehicleEntry const *ve = sVehicleStore.LookupEntry(id);
+
+ if(!ve)
+ return false;
+
+ Vehicle *v = new Vehicle;
+ Map *map = m_session->GetPlayer()->GetMap();
+ if(!v->Create(objmgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, m_session->GetPlayer()->GetPhaseMask(), entry, id, m_session->GetPlayer()->GetTeam()))
+ {
+ delete v;
+ return false;
+ }
+
+ float px, py, pz;
+ m_session->GetPlayer()->GetClosePoint(px, py, pz, m_session->GetPlayer()->GetObjectSize());
+
+ v->Relocate(px, py, pz, m_session->GetPlayer()->GetOrientation());
+
+ if(!v->IsPositionValid())
+ {
+ sLog.outError("Vehicle (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
+ v->GetGUIDLow(), v->GetEntry(), v->GetPositionX(), v->GetPositionY());
+ delete v;
+ return false;
+ }
+
+ map->Add((Creature*)v);
+
+ return true;
+}
+
+bool ChatHandler::HandleDebugSendLargePacketCommand(const char* /*args*/)
+{
+ const char* stuffingString = "This is a dummy string to push the packet's size beyond 128000 bytes. ";
+ std::ostringstream ss;
+ while(ss.str().size() < 128000)
+ ss << stuffingString;
+ SendSysMessage(ss.str().c_str());
+ return true;
+}
+
+bool ChatHandler::HandleDebugSendSetPhaseShiftCommand(const char* args)
+{
+ if(!args)
+ return false;
+
+ uint32 PhaseShift = atoi(args);
+ m_session->SendSetPhaseShift(PhaseShift);
+ return true;
+}
+
+bool ChatHandler::HandleDebugSetItemFlagCommand(const char* args)
+{
+ if(!args)
+ return false;
+
+ char* e = strtok((char*)args, " ");
+ char* f = strtok(NULL, " ");
+
+ if (!e || !f)
+ return false;
+
+ uint32 guid = (uint32)atoi(e);
+ uint32 flag = (uint32)atoi(f);
+
+ Item *i = m_session->GetPlayer()->GetItemByGuid(MAKE_NEW_GUID(guid, 0, HIGHGUID_ITEM));
+
+ if(!i)
+ return false;
+
+ i->SetUInt32Value(ITEM_FIELD_FLAGS, flag);
+
+ return true;
+}
+
+//show animation
+bool ChatHandler::HandleDebugAnimCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 anim_id = atoi((char*)args);
+ m_session->GetPlayer()->HandleEmoteCommand(anim_id);
+ return true;
+}
diff --git a/src/game/DestinationHolder.cpp b/src/game/DestinationHolder.cpp
index 904509aeef4..f2158e3b5be 100644
--- a/src/game/DestinationHolder.cpp
+++ b/src/game/DestinationHolder.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/DestinationHolder.h b/src/game/DestinationHolder.h
index 4c259d0dfde..94e12a1757d 100644
--- a/src/game/DestinationHolder.h
+++ b/src/game/DestinationHolder.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/DestinationHolderImp.h b/src/game/DestinationHolderImp.h
index fcc2d946de8..384ad9621a3 100644
--- a/src/game/DestinationHolderImp.h
+++ b/src/game/DestinationHolderImp.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,7 +21,6 @@
#ifndef TRINITY_DESTINATIONHOLDERIMP_H
#define TRINITY_DESTINATIONHOLDERIMP_H
-#include "Creature.h"
#include "MapManager.h"
#include "DestinationHolder.h"
@@ -85,24 +84,7 @@ DestinationHolder<TRAVELLER>::StartTravel(TRAVELLER &traveller, bool sendMove)
i_fromY = traveller.GetPositionY();
i_fromZ = traveller.GetPositionZ();
- float dx = i_destX - i_fromX;
- float dy = i_destY - i_fromY;
- float dz = i_destZ - i_fromZ;
-
- float dist;
- //Should be for Creature Flying and Swimming.
- if(traveller.GetTraveller().hasUnitState(UNIT_STAT_IN_FLIGHT))
- dist = sqrt((dx*dx) + (dy*dy) + (dz*dz));
- else //Walking on the ground
- dist = sqrt((dx*dx) + (dy*dy));
-
- float speed;
- if(traveller.GetTraveller().hasUnitState(UNIT_STAT_CHARGING))
- speed = SPEED_CHARGE * 0.001f;
- else
- speed = traveller.Speed() * 0.001f; // speed is in seconds so convert from second to millisecond
- i_totalTravelTime = static_cast<uint32>(dist/speed);
-
+ i_totalTravelTime = traveller.GetTotalTrevelTimeTo(i_destX,i_destY,i_destZ);
i_timeElapsed = 0;
if(sendMove)
traveller.MoveTo(i_destX, i_destY, i_destZ, i_totalTravelTime);
diff --git a/src/game/DuelHandler.cpp b/src/game/DuelHandler.cpp
index 58506f949e9..aa6563a3f98 100644
--- a/src/game/DuelHandler.cpp
+++ b/src/game/DuelHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,11 +21,9 @@
#include "Common.h"
#include "WorldPacket.h"
#include "WorldSession.h"
-#include "World.h"
#include "Log.h"
#include "Opcodes.h"
#include "UpdateData.h"
-#include "MapManager.h"
#include "Player.h"
void WorldSession::HandleDuelAcceptedOpcode(WorldPacket& recvPacket)
diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp
index 801626d5a9b..d294886619c 100644
--- a/src/game/DynamicObject.cpp
+++ b/src/game/DynamicObject.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -19,16 +19,11 @@
*/
#include "Common.h"
-#include "GameObject.h"
#include "UpdateMask.h"
#include "Opcodes.h"
-#include "WorldPacket.h"
-#include "WorldSession.h"
#include "World.h"
#include "ObjectAccessor.h"
#include "Database/DatabaseEnv.h"
-#include "SpellAuras.h"
-#include "MapManager.h"
#include "GridNotifiers.h"
#include "CellImpl.h"
#include "GridNotifiersImpl.h"
@@ -38,7 +33,7 @@ DynamicObject::DynamicObject() : WorldObject()
m_objectType |= TYPEMASK_DYNAMICOBJECT;
m_objectTypeId = TYPEID_DYNAMICOBJECT;
// 2.3.2 - 0x58
- m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION);
+ m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);
m_valuesCount = DYNAMICOBJECT_END;
}
@@ -58,8 +53,20 @@ void DynamicObject::RemoveFromWorld()
///- Remove the dynamicObject from the accessor
if(IsInWorld())
{
- ObjectAccessor::Instance().RemoveObject(this);
+ if(m_effIndex == 4)
+ {
+ if(Unit *caster = GetCaster())
+ {
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)caster)->SetViewpoint(this, false);
+ }
+ else
+ {
+ sLog.outCrash("DynamicObject::RemoveFromWorld cannot find viewpoint owner");
+ }
+ }
WorldObject::RemoveFromWorld();
+ ObjectAccessor::Instance().RemoveObject(this);
}
}
@@ -67,12 +74,12 @@ bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, uint32
{
SetInstanceId(caster->GetInstanceId());
- WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetMapId());
+ WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetMapId(), caster->GetPhaseMask());
Relocate(x,y,z,0);
if(!IsPositionValid())
{
- sLog.outError("ERROR: DynamicObject (spell %u eff %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",spellId,effIndex,GetPositionX(),GetPositionY());
+ sLog.outError("DynamicObject (spell %u eff %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",spellId,effIndex,GetPositionX(),GetPositionY());
return false;
}
@@ -81,7 +88,7 @@ bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, uint32
SetUInt64Value( DYNAMICOBJECT_CASTER, caster->GetGUID() );
SetUInt32Value( DYNAMICOBJECT_BYTES, 0x00000001 );
SetUInt32Value( DYNAMICOBJECT_SPELLID, spellId );
- SetFloatValue( DYNAMICOBJECT_RADIUS, radius * 2);
+ SetFloatValue( DYNAMICOBJECT_RADIUS, radius * 2); //diameter?
SetFloatValue( DYNAMICOBJECT_POS_X, x );
SetFloatValue( DYNAMICOBJECT_POS_Y, y );
SetFloatValue( DYNAMICOBJECT_POS_Z, z );
@@ -139,6 +146,7 @@ void DynamicObject::Update(uint32 p_time)
void DynamicObject::Delete()
{
SendObjectDeSpawnAnim(GetGUID());
+ RemoveFromWorld();
AddObjectToRemoveList();
}
@@ -147,13 +155,12 @@ void DynamicObject::Delay(int32 delaytime)
m_aliveDuration -= delaytime;
for(AffectedSet::iterator iunit= m_affected.begin();iunit != m_affected.end();++iunit)
if (*iunit)
- (*iunit)->DelayAura(m_spellId, m_effIndex, delaytime);
+ (*iunit)->DelayAura(m_spellId, GetCaster()->GetGUID() , delaytime);
}
bool DynamicObject::isVisibleForInState(Player const* u, bool inVisibleList) const
{
return IsInWorld() && u->IsInWorld()
- && (IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false)
- || GetCasterGUID() == u->GetGUID());
+ && (IsWithinDistInMap(u->m_seer,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false));
}
diff --git a/src/game/DynamicObject.h b/src/game/DynamicObject.h
index 1bcd29998f8..714b639e552 100644
--- a/src/game/DynamicObject.h
+++ b/src/game/DynamicObject.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -50,14 +50,11 @@ class DynamicObject : public WorldObject
void Delay(int32 delaytime);
bool isVisibleForInState(Player const* u, bool inVisibleList) const;
- void Say(const char* text, uint32 language, uint64 TargetGuid) { MonsterSay(text,language,TargetGuid); }
- void Yell(const char* text, uint32 language, uint64 TargetGuid) { MonsterYell(text,language,TargetGuid); }
- void TextEmote(const char* text, uint64 TargetGuid) { MonsterTextEmote(text,TargetGuid); }
- void Whisper(const char* text, uint64 receiver) { MonsterWhisper(text,receiver); }
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
void TextEmote(int32 textId, uint64 TargetGuid) { MonsterTextEmote(textId,TargetGuid); }
void Whisper(int32 textId,uint64 receiver) { MonsterWhisper(textId,receiver); }
+ void YellToZone(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYellToZone(textId,language,TargetGuid); }
GridReference<DynamicObject> &GetGridRef() { return m_gridRef; }
protected:
diff --git a/src/game/FleeingMovementGenerator.cpp b/src/game/FleeingMovementGenerator.cpp
index 87800d2edc1..0b499168538 100644
--- a/src/game/FleeingMovementGenerator.cpp
+++ b/src/game/FleeingMovementGenerator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -79,7 +79,7 @@ FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
float temp_x, temp_y, angle;
const Map * _map = MapManager::Instance().GetBaseMap(owner.GetMapId());
//primitive path-finding
- for(uint8 i = 0; i < 18; i++)
+ for(uint8 i = 0; i < 18; ++i)
{
if(i_only_forward && i > 2)
break;
@@ -301,19 +301,26 @@ FleeingMovementGenerator<T>::Initialize(T &owner)
if(!&owner)
return;
- Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID);
- if(!fright)
- return;
-
_Init(owner);
owner.CastStop();
owner.addUnitState(UNIT_STAT_FLEEING);
owner.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
owner.SetUInt64Value(UNIT_FIELD_TARGET, 0);
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
- i_caster_x = fright->GetPositionX();
- i_caster_y = fright->GetPositionY();
- i_caster_z = fright->GetPositionZ();
+
+ if(Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID))
+ {
+ i_caster_x = fright->GetPositionX();
+ i_caster_y = fright->GetPositionY();
+ i_caster_z = fright->GetPositionZ();
+ }
+ else
+ {
+ i_caster_x = owner.GetPositionX();
+ i_caster_y = owner.GetPositionY();
+ i_caster_z = owner.GetPositionZ();
+ }
+
i_only_forward = true;
i_cur_angle = 0.0f;
i_last_distance_from_caster = 0.0f;
diff --git a/src/game/FleeingMovementGenerator.h b/src/game/FleeingMovementGenerator.h
index 6a4f3593370..a6957545d41 100644
--- a/src/game/FleeingMovementGenerator.h
+++ b/src/game/FleeingMovementGenerator.h
@@ -1,7 +1,7 @@
/*
-* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
-* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+* Copyright (C) 2008-2009 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
@@ -24,7 +24,6 @@
#include "MovementGenerator.h"
#include "DestinationHolder.h"
#include "Traveller.h"
-#include "MapManager.h"
template<class T>
class TRINITY_DLL_SPEC FleeingMovementGenerator
diff --git a/src/game/FollowerRefManager.h b/src/game/FollowerRefManager.h
index 136fdbfeadb..093c85adcee 100644
--- a/src/game/FollowerRefManager.h
+++ b/src/game/FollowerRefManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/FollowerReference.cpp b/src/game/FollowerReference.cpp
index 44c8e8d55de..173f9881c54 100644
--- a/src/game/FollowerReference.cpp
+++ b/src/game/FollowerReference.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/FollowerReference.h b/src/game/FollowerReference.h
index 16fa880bcfe..3c0b3dc9e7c 100644
--- a/src/game/FollowerReference.h
+++ b/src/game/FollowerReference.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/Formulas.h b/src/game/Formulas.h
index f54917be6f3..041c0621c74 100644
--- a/src/game/Formulas.h
+++ b/src/game/Formulas.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -34,7 +34,7 @@ namespace Trinity
}
namespace XP
{
- typedef enum XPColorChar { RED, ORANGE, YELLOW, GREEN, GRAY };
+ enum XPColorChar { RED, ORANGE, YELLOW, GREEN, GRAY };
inline uint32 GetGrayLevel(uint32 pl_level)
{
@@ -80,8 +80,17 @@ namespace Trinity
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;
+ uint32 nBaseExp;
+ switch(content)
+ {
+ case CONTENT_1_60: nBaseExp = 45; break;
+ case CONTENT_61_70: nBaseExp = 235; break;
+ case CONTENT_71_80: nBaseExp = 580; break;
+ default:
+ sLog.outError("BaseGain: Unsupported content level %u",content);
+ nBaseExp = 45; break;
+ }
+
if( mob_level >= pl_level )
{
uint32 nLevelDiff = mob_level - pl_level;
@@ -118,66 +127,6 @@ namespace Trinity
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)
diff --git a/src/game/GameEvent.cpp b/src/game/GameEventMgr.cpp
index ae2dc488b86..dc86f659706 100644
--- a/src/game/GameEvent.cpp
+++ b/src/game/GameEventMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -18,9 +18,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "GameEvent.h"
+#include "GameEventMgr.h"
#include "World.h"
#include "ObjectMgr.h"
+#include "PoolHandler.h"
#include "ProgressBar.h"
#include "Language.h"
#include "Log.h"
@@ -30,9 +31,9 @@
#include "Player.h"
#include "BattleGroundMgr.h"
-INSTANTIATE_SINGLETON_1(GameEvent);
+INSTANTIATE_SINGLETON_1(GameEventMgr);
-bool GameEvent::CheckOneGameEvent(uint16 entry) const
+bool GameEventMgr::CheckOneGameEvent(uint16 entry) const
{
time_t currenttime = time(NULL);
// if the state is conditions or nextphase, then the event should be active
@@ -62,7 +63,7 @@ bool GameEvent::CheckOneGameEvent(uint16 entry) const
return false;
}
-uint32 GameEvent::NextCheck(uint16 entry) const
+uint32 GameEventMgr::NextCheck(uint16 entry) const
{
time_t currenttime = time(NULL);
@@ -96,7 +97,7 @@ uint32 GameEvent::NextCheck(uint16 entry) const
return delay;
}
-bool GameEvent::StartEvent( uint16 event_id, bool overwrite )
+bool GameEventMgr::StartEvent( uint16 event_id, bool overwrite )
{
if(mGameEvent[event_id].state == GAMEEVENT_NORMAL)
{
@@ -135,7 +136,7 @@ bool GameEvent::StartEvent( uint16 event_id, bool overwrite )
}
}
-void GameEvent::StopEvent( uint16 event_id, bool overwrite )
+void GameEventMgr::StopEvent( uint16 event_id, bool overwrite )
{
bool serverwide_evt = mGameEvent[event_id].state != GAMEEVENT_NORMAL;
@@ -167,7 +168,7 @@ void GameEvent::StopEvent( uint16 event_id, bool overwrite )
}
}
-void GameEvent::LoadFromDB()
+void GameEventMgr::LoadFromDB()
{
{
QueryResult *result = WorldDatabase.Query("SELECT MAX(entry) FROM game_event");
@@ -186,54 +187,68 @@ void GameEvent::LoadFromDB()
mGameEvent.resize(max_event_id+1);
}
- QueryResult *result = WorldDatabase.Query("SELECT entry,UNIX_TIMESTAMP(start_time),UNIX_TIMESTAMP(end_time),occurence,length,description,world_event FROM game_event");
+ QueryResult *result = WorldDatabase.Query("SELECT entry,UNIX_TIMESTAMP(start_time),UNIX_TIMESTAMP(end_time),occurence,length,holiday,description,world_event FROM game_event");
if( !result )
{
mGameEvent.clear();
- sLog.outString(">> Table game_event is empty:");
+ sLog.outString(">> Table game_event is empty!");
sLog.outString();
return;
}
uint32 count = 0;
- barGoLink bar( result->GetRowCount() );
- do
{
- ++count;
- Field *fields = result->Fetch();
+ barGoLink bar( result->GetRowCount() );
+ do
+ {
+ ++count;
+ Field *fields = result->Fetch();
- bar.step();
+ bar.step();
- uint16 event_id = fields[0].GetUInt16();
- if(event_id==0)
- {
- sLog.outErrorDb("`game_event` game event id (%i) is reserved and can't be used.",event_id);
- continue;
- }
+ uint16 event_id = fields[0].GetUInt16();
+ if(event_id==0)
+ {
+ sLog.outErrorDb("`game_event` game event id (%i) is reserved and can't be used.",event_id);
+ continue;
+ }
- GameEventData& pGameEvent = mGameEvent[event_id];
- uint64 starttime = fields[1].GetUInt64();
- pGameEvent.start = time_t(starttime);
- uint64 endtime = fields[2].GetUInt64();
- pGameEvent.end = time_t(endtime);
- pGameEvent.occurence = fields[3].GetUInt32();
- pGameEvent.length = fields[4].GetUInt32();
- pGameEvent.description = fields[5].GetCppString();
- pGameEvent.state = (GameEventState)(fields[6].GetUInt8());
- pGameEvent.nextstart = 0;
-
- if(pGameEvent.length==0 && pGameEvent.state == GAMEEVENT_NORMAL) // length>0 is validity check
- {
- sLog.outErrorDb("`game_event` game event id (%i) isn't a world event and has length = 0, thus it can't be used.",event_id);
- continue;
- }
+ GameEventData& pGameEvent = mGameEvent[event_id];
+ uint64 starttime = fields[1].GetUInt64();
+ pGameEvent.start = time_t(starttime);
+ uint64 endtime = fields[2].GetUInt64();
+ pGameEvent.end = time_t(endtime);
+ pGameEvent.occurence = fields[3].GetUInt32();
+ pGameEvent.length = fields[4].GetUInt32();
+ pGameEvent.holiday_id = fields[5].GetUInt32();
- } while( result->NextRow() );
+ pGameEvent.state = (GameEventState)(fields[7].GetUInt8());
+ pGameEvent.nextstart = 0;
- sLog.outString();
- sLog.outString( ">> Loaded %u game events", count );
- delete result;
+ if(pGameEvent.length==0 && pGameEvent.state == GAMEEVENT_NORMAL) // length>0 is validity check
+ {
+ sLog.outErrorDb("`game_event` game event id (%i) isn't a world event and has length = 0, thus it can't be used.",event_id);
+ continue;
+ }
+
+ if(pGameEvent.holiday_id)
+ {
+ if(!sHolidaysStore.LookupEntry(pGameEvent.holiday_id))
+ {
+ sLog.outErrorDb("`game_event` game event id (%i) have not existed holiday id %u.",event_id,pGameEvent.holiday_id);
+ pGameEvent.holiday_id = 0;
+ }
+ }
+
+ pGameEvent.description = fields[6].GetCppString();
+
+ } while( result->NextRow() );
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u game events", count );
+ }
// load game event saves
// 0 1 2
@@ -346,8 +361,8 @@ void GameEvent::LoadFromDB()
count = 0;
if( !result )
{
- barGoLink bar2(1);
- bar2.step();
+ barGoLink bar(1);
+ bar.step();
sLog.outString();
sLog.outString(">> Loaded %u creatures in game events", count );
@@ -355,12 +370,12 @@ void GameEvent::LoadFromDB()
else
{
- barGoLink bar2( result->GetRowCount() );
+ barGoLink bar( result->GetRowCount() );
do
{
Field *fields = result->Fetch();
- bar2.step();
+ bar.step();
uint32 guid = fields[0].GetUInt32();
int16 event_id = fields[1].GetInt16();
@@ -378,9 +393,10 @@ void GameEvent::LoadFromDB()
crelist.push_back(guid);
} while( result->NextRow() );
+ delete result;
+
sLog.outString();
sLog.outString( ">> Loaded %u creatures in game events", count );
- delete result;
}
mGameEventGameobjectGuids.resize(mGameEvent.size()*2-1);
@@ -391,8 +407,8 @@ void GameEvent::LoadFromDB()
count = 0;
if( !result )
{
- barGoLink bar3(1);
- bar3.step();
+ barGoLink bar(1);
+ bar.step();
sLog.outString();
sLog.outString(">> Loaded %u gameobjects in game events", count );
@@ -400,12 +416,12 @@ void GameEvent::LoadFromDB()
else
{
- barGoLink bar3( result->GetRowCount() );
+ barGoLink bar( result->GetRowCount() );
do
{
Field *fields = result->Fetch();
- bar3.step();
+ bar.step();
uint32 guid = fields[0].GetUInt32();
int16 event_id = fields[1].GetInt16();
@@ -423,10 +439,10 @@ void GameEvent::LoadFromDB()
golist.push_back(guid);
} while( result->NextRow() );
+ delete result;
+
sLog.outString();
sLog.outString( ">> Loaded %u gameobjects in game events", count );
-
- delete result;
}
mGameEventModelEquip.resize(mGameEvent.size());
@@ -439,8 +455,8 @@ void GameEvent::LoadFromDB()
count = 0;
if( !result )
{
- barGoLink bar3(1);
- bar3.step();
+ barGoLink bar(1);
+ bar.step();
sLog.outString();
sLog.outString(">> Loaded %u model/equipment changes in game events", count );
@@ -448,12 +464,12 @@ void GameEvent::LoadFromDB()
else
{
- barGoLink bar3( result->GetRowCount() );
+ barGoLink bar( result->GetRowCount() );
do
{
Field *fields = result->Fetch();
- bar3.step();
+ bar.step();
uint32 guid = fields[0].GetUInt32();
uint16 event_id = fields[1].GetUInt16();
@@ -483,10 +499,10 @@ void GameEvent::LoadFromDB()
equiplist.push_back(std::pair<uint32, ModelEquip>(guid, newModelEquipSet));
} while( result->NextRow() );
+ delete result;
+
sLog.outString();
sLog.outString( ">> Loaded %u model/equipment changes in game events", count );
-
- delete result;
}
mGameEventCreatureQuests.resize(mGameEvent.size());
@@ -496,8 +512,8 @@ void GameEvent::LoadFromDB()
count = 0;
if( !result )
{
- barGoLink bar3(1);
- bar3.step();
+ barGoLink bar(1);
+ bar.step();
sLog.outString();
sLog.outString(">> Loaded %u quests additions in game events", count );
@@ -505,12 +521,12 @@ void GameEvent::LoadFromDB()
else
{
- barGoLink bar3( result->GetRowCount() );
+ barGoLink bar( result->GetRowCount() );
do
{
Field *fields = result->Fetch();
- bar3.step();
+ bar.step();
uint32 id = fields[0].GetUInt32();
uint32 quest = fields[1].GetUInt32();
uint16 event_id = fields[2].GetUInt16();
@@ -569,10 +585,10 @@ void GameEvent::LoadFromDB()
questlist.push_back(QuestRelation(id, quest));
} while( result->NextRow() );
+ delete result;
+
sLog.outString();
sLog.outString( ">> Loaded %u quests additions in game events", count );
-
- delete result;
}
// Load quest to (event,condition) mapping
@@ -913,9 +929,64 @@ void GameEvent::LoadFromDB()
delete result;
}
+
+ ////////////////////////
+ // GameEventPool
+ ////////////////////////
+
+ mGameEventPoolIds.resize(mGameEvent.size()*2-1);
+ // 1 2
+ result = WorldDatabase.Query("SELECT pool_template.entry, game_event_pool.event "
+ "FROM pool_template JOIN game_event_pool ON pool_template.entry = game_event_pool.pool_entry");
+
+ count = 0;
+ if( !result )
+ {
+ barGoLink bar2(1);
+ bar2.step();
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u pools in game events", count );
+ }
+ else
+ {
+
+ barGoLink bar2( result->GetRowCount() );
+ do
+ {
+ Field *fields = result->Fetch();
+
+ bar2.step();
+
+ uint32 entry = fields[0].GetUInt16();
+ int16 event_id = fields[1].GetInt16();
+
+ int32 internal_event_id = mGameEvent.size() + event_id - 1;
+
+ if(internal_event_id < 0 || internal_event_id >= mGameEventPoolIds.size())
+ {
+ sLog.outErrorDb("`game_event_pool` game event id (%i) is out of range compared to max event id in `game_event`",event_id);
+ continue;
+ }
+
+ if (!poolhandler.CheckPool(entry))
+ {
+ sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", entry);
+ continue;
+ }
+
+ ++count;
+ IdList& poollist = mGameEventPoolIds[internal_event_id];
+ poollist.push_back(entry);
+
+ } while( result->NextRow() );
+ sLog.outString();
+ sLog.outString( ">> Loaded %u pools in game events", count );
+ delete result;
+ }
}
-uint32 GameEvent::GetNPCFlag(Creature * cr)
+uint32 GameEventMgr::GetNPCFlag(Creature * cr)
{
uint32 mask = 0;
uint32 guid = cr->GetDBTableGUIDLow();
@@ -932,7 +1003,7 @@ uint32 GameEvent::GetNPCFlag(Creature * cr)
return mask;
}
-uint32 GameEvent::GetNpcTextId(uint32 guid)
+uint32 GameEventMgr::GetNpcTextId(uint32 guid)
{
GuidEventNpcGossipIdMap::iterator itr = mNPCGossipIds.find(guid);
if(itr != mNPCGossipIds.end())
@@ -941,7 +1012,7 @@ uint32 GameEvent::GetNpcTextId(uint32 guid)
return 0;
}
-uint32 GameEvent::Initialize() // return the next event delay in ms
+uint32 GameEventMgr::Initialize() // return the next event delay in ms
{
m_ActiveEvents.clear();
uint32 delay = Update();
@@ -950,7 +1021,7 @@ uint32 GameEvent::Initialize() // return the next e
return delay;
}
-uint32 GameEvent::Update() // return the next event delay in ms
+uint32 GameEventMgr::Update() // return the next event delay in ms
{
time_t currenttime = time(NULL);
uint32 nextEventDelay = max_ge_check_delay; // 1 day
@@ -1017,10 +1088,10 @@ uint32 GameEvent::Update() // return the next e
for(std::set<uint16>::iterator itr = deactivate.begin(); itr != deactivate.end(); ++itr)
StopEvent(*itr);
sLog.outDetail("Next game event check in %u seconds.", nextEventDelay + 1);
- return (nextEventDelay + 1) * 1000; // Add 1 second to be sure event has started/stopped at next call
+ return (nextEventDelay + 1) * IN_MILISECONDS; // Add 1 second to be sure event has started/stopped at next call
}
-void GameEvent::UnApplyEvent(uint16 event_id)
+void GameEventMgr::UnApplyEvent(uint16 event_id)
{
sLog.outString("GameEvent %u \"%s\" removed.", event_id, mGameEvent[event_id].description.c_str());
// un-spawn positive event tagged objects
@@ -1040,7 +1111,7 @@ void GameEvent::UnApplyEvent(uint16 event_id)
UpdateBattleGroundSettings();
}
-void GameEvent::ApplyNewEvent(uint16 event_id)
+void GameEventMgr::ApplyNewEvent(uint16 event_id)
{
switch(sWorld.getConfig(CONFIG_EVENT_ANNOUNCE))
{
@@ -1070,7 +1141,7 @@ void GameEvent::ApplyNewEvent(uint16 event_id)
UpdateBattleGroundSettings();
}
-void GameEvent::UpdateEventNPCFlags(uint16 event_id)
+void GameEventMgr::UpdateEventNPCFlags(uint16 event_id)
{
// go through the creatures whose npcflags are changed in the event
for(NPCFlagList::iterator itr = mGameEventNPCFlags[event_id].begin(); itr != mGameEventNPCFlags[event_id].end(); ++itr)
@@ -1096,7 +1167,7 @@ void GameEvent::UpdateEventNPCFlags(uint16 event_id)
}
}
-void GameEvent::UpdateBattleGroundSettings()
+void GameEventMgr::UpdateBattleGroundSettings()
{
uint32 mask = 0;
for(ActiveEvents::const_iterator itr = m_ActiveEvents.begin(); itr != m_ActiveEvents.end(); ++itr )
@@ -1104,7 +1175,7 @@ void GameEvent::UpdateBattleGroundSettings()
sBattleGroundMgr.SetHolidayWeekends(mask);
}
-void GameEvent::UpdateEventNPCVendor(uint16 event_id, bool activate)
+void GameEventMgr::UpdateEventNPCVendor(uint16 event_id, bool activate)
{
for(NPCVendorList::iterator itr = mGameEventVendors[event_id].begin(); itr != mGameEventVendors[event_id].end(); ++itr)
{
@@ -1115,13 +1186,13 @@ void GameEvent::UpdateEventNPCVendor(uint16 event_id, bool activate)
}
}
-void GameEvent::GameEventSpawn(int16 event_id)
+void GameEventMgr::GameEventSpawn(int16 event_id)
{
int32 internal_event_id = mGameEvent.size() + event_id - 1;
if(internal_event_id < 0 || internal_event_id >= mGameEventCreatureGuids.size())
{
- sLog.outError("GameEvent::GameEventSpawn attempt access to out of range mGameEventCreatureGuids element %i (size: %u)",internal_event_id,mGameEventCreatureGuids.size());
+ sLog.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventCreatureGuids element %i (size: %u)",internal_event_id,mGameEventCreatureGuids.size());
return;
}
@@ -1154,7 +1225,7 @@ void GameEvent::GameEventSpawn(int16 event_id)
if(internal_event_id < 0 || internal_event_id >= mGameEventGameobjectGuids.size())
{
- sLog.outError("GameEvent::GameEventSpawn attempt access to out of range mGameEventGameobjectGuids element %i (size: %u)",internal_event_id,mGameEventGameobjectGuids.size());
+ sLog.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventGameobjectGuids element %i (size: %u)",internal_event_id,mGameEventGameobjectGuids.size());
return;
}
@@ -1185,15 +1256,26 @@ void GameEvent::GameEventSpawn(int16 event_id)
}
}
}
+
+ if(internal_event_id < 0 || internal_event_id >= mGameEventPoolIds.size())
+ {
+ sLog.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventPoolIds element %i (size: %u)",internal_event_id,mGameEventPoolIds.size());
+ return;
+ }
+
+ for (IdList::iterator itr = mGameEventPoolIds[internal_event_id].begin();itr != mGameEventPoolIds[internal_event_id].end();++itr)
+ {
+ poolhandler.SpawnPool(*itr);
+ }
}
-void GameEvent::GameEventUnspawn(int16 event_id)
+void GameEventMgr::GameEventUnspawn(int16 event_id)
{
int32 internal_event_id = mGameEvent.size() + event_id - 1;
if(internal_event_id < 0 || internal_event_id >= mGameEventCreatureGuids.size())
{
- sLog.outError("GameEvent::GameEventUnspawn attempt access to out of range mGameEventCreatureGuids element %i (size: %u)",internal_event_id,mGameEventCreatureGuids.size());
+ sLog.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventCreatureGuids element %i (size: %u)",internal_event_id,mGameEventCreatureGuids.size());
return;
}
@@ -1217,7 +1299,7 @@ void GameEvent::GameEventUnspawn(int16 event_id)
if(internal_event_id < 0 || internal_event_id >= mGameEventGameobjectGuids.size())
{
- sLog.outError("GameEvent::GameEventUnspawn attempt access to out of range mGameEventGameobjectGuids element %i (size: %u)",internal_event_id,mGameEventGameobjectGuids.size());
+ sLog.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventGameobjectGuids element %i (size: %u)",internal_event_id,mGameEventGameobjectGuids.size());
return;
}
@@ -1235,9 +1317,19 @@ void GameEvent::GameEventUnspawn(int16 event_id)
pGameobject->AddObjectToRemoveList();
}
}
+ if(internal_event_id < 0 || internal_event_id >= mGameEventPoolIds.size())
+ {
+ sLog.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventPoolIds element %i (size: %u)",internal_event_id,mGameEventPoolIds.size());
+ return;
+ }
+
+ for (IdList::iterator itr = mGameEventPoolIds[internal_event_id].begin();itr != mGameEventPoolIds[internal_event_id].end();++itr)
+ {
+ poolhandler.DespawnPool(*itr);
+ }
}
-void GameEvent::ChangeEquipOrModel(int16 event_id, bool activate)
+void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate)
{
for(ModelEquipList::iterator itr = mGameEventModelEquip[event_id].begin();itr != mGameEventModelEquip[event_id].end();++itr)
{
@@ -1285,17 +1377,17 @@ void GameEvent::ChangeEquipOrModel(int16 event_id, bool activate)
}
else // If not spawned
{
- CreatureData const* data = objmgr.GetCreatureData(itr->first);
- if (data && activate)
+ CreatureData const* data2 = objmgr.GetCreatureData(itr->first);
+ if (data2 && activate)
{
- CreatureInfo const *cinfo = objmgr.GetCreatureTemplate(data->id);
- uint32 display_id = objmgr.ChooseDisplayId(0,cinfo,data);
+ CreatureInfo const *cinfo = objmgr.GetCreatureTemplate(data2->id);
+ uint32 display_id = objmgr.ChooseDisplayId(0,cinfo,data2);
CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id);
if (minfo)
display_id = minfo->modelid;
- if (data->equipmentId == 0)
+ if (data2->equipmentId == 0)
itr->second.equipement_id_prev = cinfo->equipmentId;
- else if (data->equipmentId != -1)
+ else if (data2->equipmentId != -1)
itr->second.equipement_id_prev = data->equipmentId;
itr->second.modelid_prev = display_id;
}
@@ -1316,7 +1408,7 @@ void GameEvent::ChangeEquipOrModel(int16 event_id, bool activate)
}
}
-bool GameEvent::hasCreatureQuestActiveEventExcept(uint32 quest_id, uint16 event_id)
+bool GameEventMgr::hasCreatureQuestActiveEventExcept(uint32 quest_id, uint16 event_id)
{
for(ActiveEvents::iterator e_itr = m_ActiveEvents.begin(); e_itr != m_ActiveEvents.end(); ++e_itr)
{
@@ -1330,7 +1422,7 @@ bool GameEvent::hasCreatureQuestActiveEventExcept(uint32 quest_id, uint16 event_
return false;
}
-bool GameEvent::hasGameObjectQuestActiveEventExcept(uint32 quest_id, uint16 event_id)
+bool GameEventMgr::hasGameObjectQuestActiveEventExcept(uint32 quest_id, uint16 event_id)
{
for(ActiveEvents::iterator e_itr = m_ActiveEvents.begin(); e_itr != m_ActiveEvents.end(); ++e_itr)
{
@@ -1343,7 +1435,7 @@ bool GameEvent::hasGameObjectQuestActiveEventExcept(uint32 quest_id, uint16 even
}
return false;
}
-bool GameEvent::hasCreatureActiveEventExcept(uint32 creature_id, uint16 event_id)
+bool GameEventMgr::hasCreatureActiveEventExcept(uint32 creature_id, uint16 event_id)
{
for(ActiveEvents::iterator e_itr = m_ActiveEvents.begin(); e_itr != m_ActiveEvents.end(); ++e_itr)
{
@@ -1359,7 +1451,7 @@ bool GameEvent::hasCreatureActiveEventExcept(uint32 creature_id, uint16 event_id
}
return false;
}
-bool GameEvent::hasGameObjectActiveEventExcept(uint32 go_id, uint16 event_id)
+bool GameEventMgr::hasGameObjectActiveEventExcept(uint32 go_id, uint16 event_id)
{
for(ActiveEvents::iterator e_itr = m_ActiveEvents.begin(); e_itr != m_ActiveEvents.end(); ++e_itr)
{
@@ -1376,7 +1468,7 @@ bool GameEvent::hasGameObjectActiveEventExcept(uint32 go_id, uint16 event_id)
return false;
}
-void GameEvent::UpdateEventQuests(uint16 event_id, bool Activate)
+void GameEventMgr::UpdateEventQuests(uint16 event_id, bool Activate)
{
QuestRelList::iterator itr;
for (itr = mGameEventCreatureQuests[event_id].begin();itr != mGameEventCreatureQuests[event_id].end();++itr)
@@ -1430,12 +1522,12 @@ void GameEvent::UpdateEventQuests(uint16 event_id, bool Activate)
}
}}
-GameEvent::GameEvent()
+GameEventMgr::GameEventMgr()
{
isSystemInit = false;
}
-void GameEvent::HandleQuestComplete(uint32 quest_id)
+void GameEventMgr::HandleQuestComplete(uint32 quest_id)
{
// translate the quest to event and condition
QuestIdToEventConditionMap::iterator itr = mQuestToEventConditions.find(quest_id);
@@ -1481,7 +1573,7 @@ void GameEvent::HandleQuestComplete(uint32 quest_id)
}
}
-bool GameEvent::CheckOneGameEventConditions(uint16 event_id)
+bool GameEventMgr::CheckOneGameEventConditions(uint16 event_id)
{
for(std::map<uint32,GameEventFinishCondition>::iterator itr = mGameEvent[event_id].conditions.begin(); itr != mGameEvent[event_id].conditions.end(); ++itr)
if(itr->second.done < itr->second.reqNum)
@@ -1498,7 +1590,7 @@ bool GameEvent::CheckOneGameEventConditions(uint16 event_id)
return true;
}
-void GameEvent::SaveWorldEventStateToDB(uint16 event_id)
+void GameEventMgr::SaveWorldEventStateToDB(uint16 event_id)
{
CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM game_event_save WHERE event_id = '%u'",event_id);
@@ -1509,7 +1601,7 @@ void GameEvent::SaveWorldEventStateToDB(uint16 event_id)
CharacterDatabase.CommitTransaction();
}
-void GameEvent::HandleWorldEventGossip(Player *plr, Creature *c)
+void GameEventMgr::HandleWorldEventGossip(Player *plr, Creature *c)
{
// this function is used to send world state update before sending gossip menu
// find the npc's gossip id (if set) in an active game event
@@ -1521,7 +1613,7 @@ void GameEvent::HandleWorldEventGossip(Player *plr, Creature *c)
SendWorldStateUpdate(plr, itr->second.first);
}
-void GameEvent::SendWorldStateUpdate(Player * plr, uint16 event_id)
+void GameEventMgr::SendWorldStateUpdate(Player * plr, uint16 event_id)
{
std::map<uint32,GameEventFinishCondition>::iterator itr;
for(itr = mGameEvent[event_id].conditions.begin(); itr !=mGameEvent[event_id].conditions.end(); ++itr)
@@ -1533,3 +1625,14 @@ void GameEvent::SendWorldStateUpdate(Player * plr, uint16 event_id)
}
}
+TRINITY_DLL_SPEC bool IsHolidayActive( HolidayIds id )
+{
+ GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+ GameEventMgr::ActiveEvents const& ae = gameeventmgr.GetActiveEventList();
+
+ for(GameEventMgr::ActiveEvents::const_iterator itr = ae.begin(); itr != ae.end(); ++itr)
+ if(events[*itr].holiday_id==id)
+ return true;
+
+ return false;
+}
diff --git a/src/game/GameEvent.h b/src/game/GameEventMgr.h
index 9f69aa9e6ea..a7b52f0ab72 100644
--- a/src/game/GameEvent.h
+++ b/src/game/GameEventMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -18,12 +18,13 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef TRINITY_GAMEEVENT_H
-#define TRINITY_GAMEEVENT_H
+#ifndef TRINITY_GAMEEVENT_MGR_H
+#define TRINITY_GAMEEVENT_MGR_H
+#include "Common.h"
+#include "SharedDefines.h"
#include "Platform/Define.h"
-#include "Creature.h"
-#include "GameObject.h"
+#include "Policies/Singleton.h"
#define max_ge_check_delay 86400 // 1 day in seconds
@@ -54,11 +55,12 @@ struct GameEventQuestToEventConditionNum
struct GameEventData
{
GameEventData() : start(1),end(0),nextstart(0),occurence(0),length(0),state(GAMEEVENT_NORMAL) {}
- time_t start; // occurs after this time
- time_t end; // occurs before this time
- time_t nextstart; // after this time the follow-up events count this phase completed
- uint32 occurence; // time between end and start
- uint32 length; // length of the event (minutes) after finishing all conditions
+ time_t start; // occurs after this time
+ time_t end; // occurs before this time
+ time_t nextstart; // after this time the follow-up events count this phase completed
+ uint32 occurence; // time between end and start
+ uint32 length; // length of the event (minutes) after finishing all conditions
+ uint32 holiday_id;
GameEventState state; // state of the game event, these are saved into the game_event table on change!
std::map<uint32 /*condition id*/, GameEventFinishCondition> conditions; // conditions to finish
std::set<uint16 /*gameevent id*/> prerequisite_events; // events that must be completed before starting this event
@@ -85,11 +87,13 @@ struct NPCVendorEntry
};
class Player;
-class GameEvent
+class Creature;
+
+class GameEventMgr
{
public:
- GameEvent();
- ~GameEvent() {};
+ GameEventMgr();
+ ~GameEventMgr() {};
typedef std::set<uint16> ActiveEvents;
typedef std::vector<GameEventData> GameEventDataMap;
ActiveEvents const& GetActiveEventList() const { return m_ActiveEvents; }
@@ -127,7 +131,9 @@ class GameEvent
bool hasGameObjectActiveEventExcept(uint32 go_guid, uint16 event_id);
protected:
typedef std::list<uint32> GuidList;
+ typedef std::list<uint16> IdList;
typedef std::vector<GuidList> GameEventGuidMap;
+ typedef std::vector<IdList> GameEventIdMap;
typedef std::pair<uint32, ModelEquip> ModelEquipPair;
typedef std::list<ModelEquipPair> ModelEquipList;
typedef std::vector<ModelEquipList> GameEventModelEquipMap;
@@ -149,6 +155,7 @@ class GameEvent
GameEventModelEquipMap mGameEventModelEquip;
GameEventGuidMap mGameEventCreatureGuids;
GameEventGuidMap mGameEventGameobjectGuids;
+ GameEventIdMap mGameEventPoolIds;
GameEventDataMap mGameEvent;
GameEventBitmask mGameEventBattleGroundHolidays;
QuestIdToEventConditionMap mQuestToEventConditions;
@@ -158,6 +165,9 @@ class GameEvent
bool isSystemInit;
};
-#define gameeventmgr Trinity::Singleton<GameEvent>::Instance()
+#define gameeventmgr Trinity::Singleton<GameEventMgr>::Instance()
+
+TRINITY_DLL_SPEC bool IsHolidayActive(HolidayIds id);
+
#endif
diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp
index d1bb0362872..61e742735fb 100644
--- a/src/game/GameObject.cpp
+++ b/src/game/GameObject.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,15 +22,14 @@
#include "QuestDef.h"
#include "GameObject.h"
#include "ObjectMgr.h"
+#include "PoolHandler.h"
#include "SpellMgr.h"
#include "Spell.h"
#include "UpdateMask.h"
#include "Opcodes.h"
#include "WorldPacket.h"
-#include "WorldSession.h"
#include "World.h"
#include "Database/DatabaseEnv.h"
-#include "MapManager.h"
#include "LootMgr.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
@@ -46,7 +45,7 @@ GameObject::GameObject() : WorldObject()
m_objectType |= TYPEMASK_GAMEOBJECT;
m_objectTypeId = TYPEID_GAMEOBJECT;
// 2.3.2 - 0x58
- m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION);
+ m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);
m_valuesCount = GAMEOBJECT_END;
m_respawnTime = 0;
@@ -64,9 +63,9 @@ GameObject::GameObject() : WorldObject()
GameObject::~GameObject()
{
- if(m_uint32Values) // field array can be not exist if GameOBject not loaded
+ /*if(m_uint32Values) // field array can be not exist if GameOBject not loaded
{
- // crash possible at access to deleted GO in Unit::m_gameobj
+ // Possible crash at access to deleted GO in Unit::m_gameobj
uint64 owner_guid = GetOwnerGUID();
if(owner_guid)
{
@@ -76,7 +75,7 @@ GameObject::~GameObject()
else if(!IS_PLAYER_GUID(owner_guid))
sLog.outError("Delete GameObject (GUID: %u Entry: %u ) that have references in not found creature %u GO list. Crash possible later.",GetGUIDLow(),GetGOInfo()->id,GUID_LOPART(owner_guid));
}
- }
+ }*/
}
void GameObject::AddToWorld()
@@ -94,20 +93,30 @@ void GameObject::RemoveFromWorld()
///- Remove the gameobject from the accessor
if(IsInWorld())
{
- ObjectAccessor::Instance().RemoveObject(this);
+ // Possible crash at access to deleted GO in Unit::m_gameobj
+ if(uint64 owner_guid = GetOwnerGUID())
+ {
+ Unit* owner = ObjectAccessor::GetUnit(*this,owner_guid);
+ if(owner)
+ owner->RemoveGameObject(this,false);
+ else if(!IS_PLAYER_GUID(owner_guid))
+ sLog.outError("Delete GameObject (GUID: %u Entry: %u ) that have references in not found creature %u GO list. Crash possible later.",GetGUIDLow(),GetGOInfo()->id,GUID_LOPART(owner_guid));
+ }
WorldObject::RemoveFromWorld();
+ ObjectAccessor::Instance().RemoveObject(this);
}
}
-bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, uint32 go_state, uint32 ArtKit)
+bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 ArtKit)
{
Relocate(x,y,z,ang);
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
+ SetPhaseMask(phaseMask,false);
if(!IsPositionValid())
{
- sLog.outError("ERROR: Gameobject (GUID: %u Entry: %u ) not created. Suggested coordinates isn't valid (X: %f Y: %f)",guidlow,name_id,x,y);
+ sLog.outError("Gameobject (GUID: %u Entry: %u ) not created. Suggested coordinates isn't valid (X: %f Y: %f)",guidlow,name_id,x,y);
return false;
}
@@ -131,19 +140,18 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float
SetFloatValue(GAMEOBJECT_POS_X, x);
SetFloatValue(GAMEOBJECT_POS_Y, y);
SetFloatValue(GAMEOBJECT_POS_Z, z);
- SetFloatValue(GAMEOBJECT_FACING, ang); //this is not facing angle
- SetFloatValue (GAMEOBJECT_ROTATION, rotation0);
- SetFloatValue (GAMEOBJECT_ROTATION+1, rotation1);
- SetFloatValue (GAMEOBJECT_ROTATION+2, rotation2);
- SetFloatValue (GAMEOBJECT_ROTATION+3, rotation3);
+ SetFloatValue(GAMEOBJECT_PARENTROTATION+0, rotation0);
+ SetFloatValue(GAMEOBJECT_PARENTROTATION+1, rotation1);
+
+ UpdateRotationFields(rotation2,rotation3); // GAMEOBJECT_FACING, GAMEOBJECT_ROTATION, GAMEOBJECT_PARENTROTATION+2/3
SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size);
SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
- SetUInt32Value(OBJECT_FIELD_ENTRY, goinfo->id);
+ SetEntry(goinfo->id);
SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId);
@@ -152,7 +160,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float
SetGoAnimProgress(animprogress);
- SetUInt32Value (GAMEOBJECT_ARTKIT, ArtKit);
+ SetByteValue(GAMEOBJECT_BYTES_1, 2, ArtKit);
// Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22)
if (goinfo->type == GAMEOBJECT_TYPE_SPELLCASTER)
@@ -201,7 +209,7 @@ void GameObject::Update(uint32 /*p_time*/)
Unit* caster = GetOwner();
if(caster && caster->GetTypeId()==TYPEID_PLAYER)
{
- SetGoState(0);
+ SetGoState(GO_STATE_ACTIVE);
SetUInt32Value(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN);
UpdateData udata;
@@ -210,10 +218,7 @@ void GameObject::Update(uint32 /*p_time*/)
udata.BuildPacket(&packet);
((Player*)caster)->GetSession()->SendPacket(&packet);
- WorldPacket data(SMSG_GAMEOBJECT_CUSTOM_ANIM,8+4);
- data << GetGUID();
- data << (uint32)(0);
- ((Player*)caster)->SendMessageToSet(&data,true);
+ SendCustomAnim();
}
m_lootState = GO_READY; // can be successfully open with some chance
@@ -259,18 +264,22 @@ void GameObject::Update(uint32 /*p_time*/)
case GAMEOBJECT_TYPE_DOOR:
case GAMEOBJECT_TYPE_BUTTON:
//we need to open doors if they are closed (add there another condition if this code breaks some usage, but it need to be here for battlegrounds)
- if( !GetGoState() )
- SwitchDoorOrButton(false);
+ if (GetGoState() != GO_STATE_READY)
+ ResetDoorOrButton();
//flags in AB are type_button and we need to add them here so no break!
default:
- if(!m_spawnedByDefault) // despawn timer
+ if (!m_spawnedByDefault) // despawn timer
{
// can be despawned or destroyed
SetLootState(GO_JUST_DEACTIVATED);
return;
}
// respawn timer
- MapManager::Instance().GetMap(GetMapId(), this)->Add(this);
+ uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), TYPEID_GAMEOBJECT);
+ if (poolid)
+ poolhandler.UpdatePool(poolid, GetGUIDLow(), TYPEID_GAMEOBJECT);
+ else
+ GetMap()->Add(this);
break;
}
}
@@ -307,51 +316,32 @@ void GameObject::Update(uint32 /*p_time*/)
bool NeedDespawn = (goInfo->trap.charges != 0);
- CellPair p(Trinity::ComputeCellPair(GetPositionX(),GetPositionY()));
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
-
// Note: this hack with search required until GO casting not implemented
// search unfriendly creature
if(owner && NeedDespawn) // hunter trap
{
- Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck u_check(this, owner, radius);
- Trinity::UnitSearcher<Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck> checker(ok, u_check);
-
- CellLock<GridReadGuard> cell_lock(cell, p);
-
- TypeContainerVisitor<Trinity::UnitSearcher<Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
- cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(GetMapId(), this));
-
- // or unfriendly player/pet
- if(!ok)
- {
- TypeContainerVisitor<Trinity::UnitSearcher<Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
- cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(GetMapId(), this));
- }
+ Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck checker(this, owner, radius);
+ Trinity::UnitSearcher<Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck> searcher(this, ok, checker);
+ VisitNearbyGridObject(radius, searcher);
+ if(!ok) VisitNearbyWorldObject(radius, searcher);
}
else // environmental trap
{
// environmental damage spells already have around enemies targeting but this not help in case not existed GO casting support
-
// affect only players
- Player* p_ok = NULL;
- Trinity::AnyPlayerInObjectRangeCheck p_check(this, radius);
- Trinity::PlayerSearcher<Trinity::AnyPlayerInObjectRangeCheck> checker(p_ok, p_check);
-
- CellLock<GridReadGuard> cell_lock(cell, p);
-
- TypeContainerVisitor<Trinity::PlayerSearcher<Trinity::AnyPlayerInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
- cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(GetMapId(), this));
- ok = p_ok;
+ Player* player = NULL;
+ MaNGOS::AnyPlayerInObjectRangeCheck checker(this, radius);
+ MaNGOS::PlayerSearcher<MaNGOS::AnyPlayerInObjectRangeCheck> searcher(this, player, checker);
+ VisitNearbyWorldObject(radius, searcher);
+ ok = player;
}
if (ok)
{
//Unit *caster = owner ? owner : ok;
- //caster->CastSpell(ok, goInfo->trap.spellId, true);
CastSpell(ok, goInfo->trap.spellId);
+ //caster->CastSpell(ok, goInfo->trap.spellId, true, 0, 0, GetGUID());
m_cooldownTime = time(NULL) + 4; // 4 seconds
if(NeedDespawn)
@@ -378,11 +368,8 @@ void GameObject::Update(uint32 /*p_time*/)
{
case GAMEOBJECT_TYPE_DOOR:
case GAMEOBJECT_TYPE_BUTTON:
- if(GetAutoCloseTime() && (m_cooldownTime < time(NULL)))
- {
- SwitchDoorOrButton(false);
- SetLootState(GO_JUST_DEACTIVATED);
- }
+ if (GetAutoCloseTime() && (m_cooldownTime < time(NULL)))
+ ResetDoorOrButton();
break;
}
break;
@@ -396,12 +383,12 @@ void GameObject::Update(uint32 /*p_time*/)
if(spellId)
{
- std::set<uint32>::iterator it = m_unique_users.begin();
- std::set<uint32>::iterator end = m_unique_users.end();
+ std::set<uint32>::const_iterator it = m_unique_users.begin();
+ std::set<uint32>::const_iterator end = m_unique_users.end();
for (; it != end; it++)
{
Unit* owner = Unit::GetUnit(*this, uint64(*it));
- if (owner) owner->CastSpell(owner, spellId, false);
+ if (owner) owner->CastSpell(owner, spellId, false, 0, 0, GetGUID());
}
m_unique_users.clear();
@@ -420,7 +407,7 @@ void GameObject::Update(uint32 /*p_time*/)
//burning flags in some battlegrounds, if you find better condition, just add it
if (GetGoAnimProgress() > 0)
{
- SendObjectDeSpawnAnim(this->GetGUID());
+ SendObjectDeSpawnAnim(GetGUID());
//reset flags
SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags);
}
@@ -457,7 +444,7 @@ void GameObject::Refresh()
return;
if(isSpawned())
- MapManager::Instance().GetMap(GetMapId(), this)->Add(this);
+ GetMap()->Add(this);
}
void GameObject::AddUniqueUse(Player* player)
@@ -470,24 +457,29 @@ void GameObject::Delete()
{
SendObjectDeSpawnAnim(GetGUID());
- SetGoState(1);
+ SetGoState(GO_STATE_READY);
SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags);
- AddObjectToRemoveList();
+ uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), TYPEID_GAMEOBJECT);
+ if (poolid)
+ poolhandler.UpdatePool(poolid, GetGUIDLow(), TYPEID_GAMEOBJECT);
+ else
+ AddObjectToRemoveList();
}
-void GameObject::getFishLoot(Loot *fishloot)
+void GameObject::getFishLoot(Loot *fishloot, Player* loot_owner)
{
fishloot->clear();
- uint32 subzone = GetAreaId();
+ uint32 zone, subzone;
+ GetZoneAndAreaId(zone,subzone);
// if subzone loot exist use it
if(LootTemplates_Fishing.HaveLootFor(subzone))
- fishloot->FillLoot(subzone, LootTemplates_Fishing, NULL);
+ fishloot->FillLoot(subzone, LootTemplates_Fishing, loot_owner,true);
// else use zone loot
else
- fishloot->FillLoot(GetZoneId(), LootTemplates_Fishing, NULL);
+ fishloot->FillLoot(zone, LootTemplates_Fishing, loot_owner,true);
}
void GameObject::SaveToDB()
@@ -501,10 +493,10 @@ void GameObject::SaveToDB()
return;
}
- SaveToDB(GetMapId(), data->spawnMask);
+ SaveToDB(GetMapId(), data->spawnMask, data->phaseMask);
}
-void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask)
+void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
{
const GameObjectInfo *goI = GetGOInfo();
@@ -519,38 +511,40 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask)
// data->guid = guid don't must be update at save
data.id = GetEntry();
data.mapid = mapid;
+ data.phaseMask = phaseMask;
data.posX = GetFloatValue(GAMEOBJECT_POS_X);
data.posY = GetFloatValue(GAMEOBJECT_POS_Y);
data.posZ = GetFloatValue(GAMEOBJECT_POS_Z);
data.orientation = GetFloatValue(GAMEOBJECT_FACING);
- data.rotation0 = GetFloatValue(GAMEOBJECT_ROTATION+0);
- data.rotation1 = GetFloatValue(GAMEOBJECT_ROTATION+1);
- data.rotation2 = GetFloatValue(GAMEOBJECT_ROTATION+2);
- data.rotation3 = GetFloatValue(GAMEOBJECT_ROTATION+3);
+ data.rotation0 = GetFloatValue(GAMEOBJECT_PARENTROTATION+0);
+ data.rotation1 = GetFloatValue(GAMEOBJECT_PARENTROTATION+1);
+ data.rotation2 = GetFloatValue(GAMEOBJECT_PARENTROTATION+2);
+ data.rotation3 = GetFloatValue(GAMEOBJECT_PARENTROTATION+3);
data.spawntimesecs = m_spawnedByDefault ? m_respawnDelayTime : -(int32)m_respawnDelayTime;
data.animprogress = GetGoAnimProgress();
data.go_state = GetGoState();
data.spawnMask = spawnMask;
- data.ArtKit = GetUInt32Value (GAMEOBJECT_ARTKIT);
+ data.ArtKit = GetGoArtKit();
// updated in DB
std::ostringstream ss;
ss << "INSERT INTO gameobject VALUES ( "
<< m_DBTableGuid << ", "
- << GetUInt32Value (OBJECT_FIELD_ENTRY) << ", "
+ << GetEntry() << ", "
<< mapid << ", "
- << (uint32)spawnMask << ", "
+ << uint32(spawnMask) << "," // cast to prevent save as symbol
+ << uint16(GetPhaseMask()) << "," // prevent out of range error
<< GetFloatValue(GAMEOBJECT_POS_X) << ", "
<< GetFloatValue(GAMEOBJECT_POS_Y) << ", "
<< GetFloatValue(GAMEOBJECT_POS_Z) << ", "
<< GetFloatValue(GAMEOBJECT_FACING) << ", "
- << GetFloatValue(GAMEOBJECT_ROTATION) << ", "
- << GetFloatValue(GAMEOBJECT_ROTATION+1) << ", "
- << GetFloatValue(GAMEOBJECT_ROTATION+2) << ", "
- << GetFloatValue(GAMEOBJECT_ROTATION+3) << ", "
+ << GetFloatValue(GAMEOBJECT_PARENTROTATION) << ", "
+ << GetFloatValue(GAMEOBJECT_PARENTROTATION+1) << ", "
+ << GetFloatValue(GAMEOBJECT_PARENTROTATION+2) << ", "
+ << GetFloatValue(GAMEOBJECT_PARENTROTATION+3) << ", "
<< m_respawnDelayTime << ", "
- << GetGoAnimProgress() << ", "
- << GetGoState() << ")";
+ << uint32(GetGoAnimProgress()) << ", "
+ << uint32(GetGoState()) << ")";
WorldDatabase.BeginTransaction();
WorldDatabase.PExecuteLog("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid);
@@ -564,12 +558,13 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)
if( !data )
{
- sLog.outErrorDb("ERROR: Gameobject (GUID: %u) not found in table `gameobject`, can't load. ",guid);
+ sLog.outErrorDb("Gameobject (GUID: %u) not found in table `gameobject`, can't load. ",guid);
return false;
}
uint32 entry = data->id;
- uint32 map_id = data->mapid;
+ //uint32 map_id = data->mapid; // already used before call
+ uint32 phaseMask = data->phaseMask;
float x = data->posX;
float y = data->posY;
float z = data->posZ;
@@ -581,46 +576,43 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)
float rotation3 = data->rotation3;
uint32 animprogress = data->animprogress;
- uint32 go_state = data->go_state;
+ GOState go_state = data->go_state;
uint32 ArtKit = data->ArtKit;
m_DBTableGuid = guid;
if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
- if (!Create(guid,entry, map, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, ArtKit) )
+ if (!Create(guid,entry, map, phaseMask, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, ArtKit) )
return false;
- switch(GetGOInfo()->type)
+ if(!GetDespawnPossibility())
+ {
+ SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN);
+ m_spawnedByDefault = true;
+ m_respawnDelayTime = 0;
+ m_respawnTime = 0;
+ }
+ else
{
- case GAMEOBJECT_TYPE_DOOR:
- case GAMEOBJECT_TYPE_BUTTON:
- /* this code (in comment) isn't correct because in battlegrounds we need despawnable doors and buttons, pls remove
- SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN);
+ if(data->spawntimesecs >= 0)
+ {
m_spawnedByDefault = true;
- m_respawnDelayTime = 0;
- m_respawnTime = 0;
- break;*/
- default:
- if(data->spawntimesecs >= 0)
- {
- m_spawnedByDefault = true;
- m_respawnDelayTime = data->spawntimesecs;
- m_respawnTime = objmgr.GetGORespawnTime(m_DBTableGuid, map->GetInstanceId());
+ m_respawnDelayTime = data->spawntimesecs;
+ m_respawnTime = objmgr.GetGORespawnTime(m_DBTableGuid, map->GetInstanceId());
- // ready to respawn
- if(m_respawnTime && m_respawnTime <= time(NULL))
- {
- m_respawnTime = 0;
- objmgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),0);
- }
- }
- else
+ // ready to respawn
+ if(m_respawnTime && m_respawnTime <= time(NULL))
{
- m_spawnedByDefault = false;
- m_respawnDelayTime = -data->spawntimesecs;
m_respawnTime = 0;
+ objmgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),0);
}
- break;
+ }
+ else
+ {
+ m_spawnedByDefault = false;
+ m_respawnDelayTime = -data->spawntimesecs;
+ m_respawnTime = 0;
+ }
}
return true;
@@ -636,7 +628,7 @@ void GameObject::DeleteFromDB()
GameObject* GameObject::GetGameObject(WorldObject& object, uint64 guid)
{
- return ObjectAccessor::GetGameObject(object,guid);
+ return object.GetMap()->GetGameObject(guid);
}
GameObjectInfo const *GameObject::GetGOInfo() const
@@ -730,14 +722,10 @@ bool GameObject::isVisibleForInState(Player const* u, bool inVisibleList) const
if(owner && u->IsHostileTo(owner) && !canDetectTrap(u, GetDistance(u)))
return false;
}
-
- // Smuggled Mana Cell required 10 invisibility type detection/state
- if(GetEntry()==187039 && ((u->m_detectInvisibilityMask | u->m_invisibilityMask) & (1<<10))==0)
- return false;
}
// check distance
- return IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject() +
+ return IsWithinDistInMap(u->m_seer,World::GetMaxVisibleDistanceForObject() +
(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
}
@@ -816,7 +804,20 @@ void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target)
if(!trapSpell) // checked at load already
return;
- float range = GetSpellMaxRange(sSpellRangeStore.LookupEntry(trapSpell->rangeIndex));
+ float range;
+ SpellRangeEntry const * srentry = sSpellRangeStore.LookupEntry(trapSpell->rangeIndex);
+ //get owner to check hostility of GameObject
+ if (GetSpellMaxRangeForHostile(srentry) == GetSpellMaxRangeForHostile(srentry))
+ range = GetSpellMaxRangeForHostile(srentry);
+ else
+ {
+ Unit * owner=GetOwner();
+ if (owner)
+ range = owner->GetSpellMaxRangeForTarget(target, srentry);
+ else
+ //if no owner assume that object is hostile to target
+ range = GetSpellMaxRangeForHostile(srentry);
+ }
// search nearest linked GO
GameObject* trapGO = NULL;
@@ -826,18 +827,18 @@ void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target)
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
- Trinity::NearestGameObjectEntryInObjectRangeCheck go_check(*target,trapEntry,range);
- Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck> checker(trapGO,go_check);
+ MaNGOS::NearestGameObjectEntryInObjectRangeCheck go_check(*target,trapEntry,range);
+ MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck> checker(this, trapGO,go_check);
TypeContainerVisitor<Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(GetMapId(), this));
+ cell_lock->Visit(cell_lock, object_checker, *GetMap());
}
// found correct GO
// FIXME: when GO casting will be implemented trap must cast spell to target
if(trapGO)
- target->CastSpell(target,trapSpell,true);
+ target->CastSpell(target,trapSpell,true, 0, 0, GetGUID());
}
GameObject* GameObject::LookupFishingHoleAround(float range)
@@ -847,18 +848,28 @@ GameObject* GameObject::LookupFishingHoleAround(float range)
CellPair p(Trinity::ComputeCellPair(GetPositionX(),GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
- Trinity::NearestGameObjectFishingHole u_check(*this, range);
- Trinity::GameObjectSearcher<Trinity::NearestGameObjectFishingHole> checker(ok, u_check);
+ MaNGOS::NearestGameObjectFishingHole u_check(*this, range);
+ MaNGOS::GameObjectSearcher<MaNGOS::NearestGameObjectFishingHole> checker(this, ok, u_check);
CellLock<GridReadGuard> cell_lock(cell, p);
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::NearestGameObjectFishingHole>, GridTypeMapContainer > grid_object_checker(checker);
- cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(GetMapId(), this));
+ cell_lock->Visit(cell_lock, grid_object_checker, *GetMap());
return ok;
}
-void GameObject::UseDoorOrButton(uint32 time_to_restore)
+void GameObject::ResetDoorOrButton()
+{
+ if (m_lootState == GO_READY || m_lootState == GO_JUST_DEACTIVATED)
+ return;
+
+ SwitchDoorOrButton(false);
+ SetLootState(GO_JUST_DEACTIVATED);
+ m_cooldownTime = 0;
+}
+
+void GameObject::UseDoorOrButton(uint32 time_to_restore, bool alternative /* = false */)
{
if(m_lootState != GO_READY)
return;
@@ -866,32 +877,31 @@ void GameObject::UseDoorOrButton(uint32 time_to_restore)
if(!time_to_restore)
time_to_restore = GetAutoCloseTime();
- SwitchDoorOrButton(true);
+ SwitchDoorOrButton(true,alternative);
SetLootState(GO_ACTIVATED);
m_cooldownTime = time(NULL) + time_to_restore;
-
}
-void GameObject::SetGoArtKit(uint32 kit)
+void GameObject::SetGoArtKit(uint8 kit)
{
- SetUInt32Value(GAMEOBJECT_ARTKIT, kit);
+ SetByteValue(GAMEOBJECT_BYTES_1, 2, kit);
GameObjectData *data = const_cast<GameObjectData*>(objmgr.GetGOData(m_DBTableGuid));
if(data)
data->ArtKit = kit;
}
-void GameObject::SwitchDoorOrButton(bool activate)
+void GameObject::SwitchDoorOrButton(bool activate, bool alternative /* = false */)
{
if(activate)
SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE);
else
RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE);
- if(GetGoState()) //if closed -> open
- SetGoState(0);
+ if(GetGoState() == GO_STATE_READY) //if closed -> open
+ SetGoState(alternative ? GO_STATE_ACTIVE_ALTERNATIVE : GO_STATE_ACTIVE);
else //if open -> close
- SetGoState(1);
+ SetGoState(GO_STATE_READY);
}
void GameObject::Use(Unit* user)
@@ -899,6 +909,7 @@ void GameObject::Use(Unit* user)
// by default spell caster is user
Unit* spellCaster = user;
uint32 spellId = 0;
+ bool triggered = false;
switch(GetGoType())
{
@@ -948,7 +959,7 @@ void GameObject::Use(Unit* user)
// every slot will be on that straight line
float orthogonalOrientation = GetOrientation()+M_PI*0.5f;
// find nearest slot
- for(uint32 i=0; i<info->chair.slots; i++)
+ for(uint32 i=0; i<info->chair.slots; ++i)
{
// the distance between this slot and the center of the go - imagine a 1D space
float relativeDistance = (info->size*i)-(info->size*(info->chair.slots-1)/2.0f);
@@ -980,7 +991,7 @@ void GameObject::Use(Unit* user)
// fallback, will always work
player->TeleportTo(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET);
}
- player->SetStandState(PLAYER_STATE_SIT_LOW_CHAIR+info->chair.height);
+ player->SetStandState(UNIT_STAND_STATE_SIT_LOW_CHAIR+info->chair.height);
return;
}
//big gun, its a spell/aura
@@ -1020,12 +1031,9 @@ void GameObject::Use(Unit* user)
Player* player = (Player*)user;
- if(info->camera.cinematicId)
- {
- WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4);
- data << info->camera.cinematicId;
- player->GetSession()->SendPacket(&data);
- }
+ if (info->camera.cinematicId)
+ player->SendCinematicStart(info->camera.cinematicId);
+
return;
}
//fishing bobber
@@ -1047,11 +1055,12 @@ void GameObject::Use(Unit* user)
// 2) if skill == base_zone_skill => 5% chance
// 3) chance is linear dependence from (base_zone_skill-skill)
- uint32 subzone = GetAreaId();
+ uint32 zone, subzone;
+ GetZoneAndAreaId(zone,subzone);
int32 zone_skill = objmgr.GetFishingBaseSkillLevel( subzone );
if(!zone_skill)
- zone_skill = objmgr.GetFishingBaseSkillLevel( GetZoneId() );
+ zone_skill = objmgr.GetFishingBaseSkillLevel( zone );
//provide error, no fishable zone or area should be 0
if(!zone_skill)
@@ -1076,6 +1085,7 @@ void GameObject::Use(Unit* user)
if (ok)
{
player->SendLoot(ok->GetGUID(),LOOT_FISHINGHOLE);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT, ok->GetGOInfo()->id);
SetLootState(GO_JUST_DEACTIVATED);
}
else
@@ -1142,6 +1152,13 @@ void GameObject::Use(Unit* user)
return;
spellId = info->summoningRitual.spellId;
+ if(spellId==62330) // GO store not existed spell, replace by expected
+ {
+ // spell have reagent and mana cost but it not expected use its
+ // it triggered spell in fact casted at currently channeled GO
+ spellId = 61993;
+ triggered = true;
+ }
// finish spell
caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0);
@@ -1199,7 +1216,10 @@ void GameObject::Use(Unit* user)
if (level < info->meetingstone.minLevel || level > info->meetingstone.maxLevel)
return;
- spellId = 23598;
+ if(info->id==194097)
+ spellId = 61994; // Ritual of Summoning
+ else
+ spellId = 59782; // Summoning Stone Effect
break;
}
@@ -1211,7 +1231,7 @@ void GameObject::Use(Unit* user)
Player* player = (Player*)user;
- if( player->isAllowUseBattleGroundObject() )
+ if( player->CanUseBattleGroundObject() )
{
// in battleground check
BattleGround *bg = player->GetBattleGround();
@@ -1236,7 +1256,7 @@ void GameObject::Use(Unit* user)
Player* player = (Player*)user;
- if( player->isAllowUseBattleGroundObject() )
+ if( player->CanUseBattleGroundObject() )
{
// in battleground check
BattleGround *bg = player->GetBattleGround();
@@ -1274,6 +1294,26 @@ void GameObject::Use(Unit* user)
}
break;
}
+ case GAMEOBJECT_TYPE_BARBER_CHAIR: //32
+ {
+ GameObjectInfo const* info = GetGOInfo();
+ if(!info)
+ return;
+
+ if(user->GetTypeId()!=TYPEID_PLAYER)
+ return;
+
+ Player* player = (Player*)user;
+
+ // fallback, will always work
+ player->TeleportTo(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET);
+
+ WorldPacket data(SMSG_ENABLE_BARBER_SHOP, 0);
+ player->GetSession()->SendPacket(&data);
+
+ player->SetStandState(UNIT_STAND_STATE_SIT_LOW_CHAIR+info->barberChair.chairheight);
+ return;
+ }
default:
sLog.outDebug("Unknown Object Type %u", GetGoType());
break;
@@ -1292,7 +1332,7 @@ void GameObject::Use(Unit* user)
return;
}
- Spell *spell = new Spell(spellCaster, spellInfo, false);
+ Spell *spell = new Spell(spellCaster, spellInfo, triggered);
// spell target is user of GO
SpellCastTargets targets;
@@ -1301,8 +1341,28 @@ void GameObject::Use(Unit* user)
spell->prepare(&targets);
}
-void GameObject::CastSpell(Unit* target, uint32 spell)
+void GameObject::CastSpell(Unit* target, uint32 spellId)
{
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
+ if(!spellInfo)
+ return;
+
+ bool self = false;
+ for(int i = 0; i < 3; ++i)
+ {
+ if(spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_CASTER)
+ {
+ self = true;
+ break;
+ }
+ }
+
+ if(self)
+ {
+ target->CastSpell(target, spellInfo, true);
+ return;
+ }
+
//summon world trigger
Creature *trigger = SummonTrigger(GetPositionX(), GetPositionY(), GetPositionZ(), 0, 1);
if(!trigger) return;
@@ -1311,17 +1371,25 @@ void GameObject::CastSpell(Unit* target, uint32 spell)
if(Unit *owner = GetOwner())
{
trigger->setFaction(owner->getFaction());
- trigger->CastSpell(target, spell, true, 0, 0, owner->GetGUID());
+ trigger->CastSpell(target, spellInfo, true, 0, 0, owner->GetGUID());
}
else
{
trigger->setFaction(14);
- trigger->CastSpell(target, spell, true, 0, 0, target->GetGUID());
+ trigger->CastSpell(target, spellInfo, true, 0, 0, target->GetGUID());
}
//trigger->setDeathState(JUST_DIED);
//trigger->RemoveCorpse();
}
+void GameObject::SendCustomAnim()
+{
+ WorldPacket data(SMSG_GAMEOBJECT_CUSTOM_ANIM,8+4);
+ data << GetGUID();
+ data << (uint32)0;
+ SendMessageToSet(&data, true);
+}
+
// overwrite WorldObject function for proper name localization
const char* GameObject::GetNameForLocaleIdx(int32 loc_idx) const
{
@@ -1338,3 +1406,25 @@ const char* GameObject::GetNameForLocaleIdx(int32 loc_idx) const
return GetName();
}
+void GameObject::UpdateRotationFields(float rotation2 /*=0.0f*/, float rotation3 /*=0.0f*/)
+{
+ static double const atan_pow = atan(pow(2.0f, -20.0f));
+
+ SetFloatValue(GAMEOBJECT_FACING, GetOrientation());
+
+ double f_rot1 = sin(GetOrientation() / 2.0f);
+ double f_rot2 = cos(GetOrientation() / 2.0f);
+
+ int64 i_rot1 = int64(f_rot1 / atan_pow *(f_rot2 >= 0 ? 1.0f : -1.0f));
+ int64 rotation = (i_rot1 << 43 >> 43) & 0x00000000001FFFFF;
+ SetUInt64Value(GAMEOBJECT_ROTATION, rotation);
+
+ if(rotation2==0.0f && rotation3==0.0f)
+ {
+ rotation2 = f_rot1;
+ rotation3 = f_rot2;
+ }
+
+ SetFloatValue(GAMEOBJECT_PARENTROTATION+2, rotation2);
+ SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rotation3);
+}
diff --git a/src/game/GameObject.h b/src/game/GameObject.h
index 2eb51a6fbe4..37ccf1c6b8f 100644
--- a/src/game/GameObject.h
+++ b/src/game/GameObject.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -41,6 +41,7 @@ struct GameObjectInfo
uint32 type;
uint32 displayId;
char *name;
+ char *IconName;
char *castBarCaption;
uint32 faction;
uint32 flags;
@@ -336,12 +337,12 @@ struct GameObjectInfo
uint32 mapID; //0
uint32 difficulty; //1
} dungeonDifficulty;
- //32 GAMEOBJECT_TYPE_DO_NOT_USE_YET
+ //32 GAMEOBJECT_TYPE_BARBER_CHAIR
struct
{
- uint32 mapID; //0
- uint32 difficulty; //1
- } doNotUseYet;
+ uint32 chairheight; //0
+ uint32 heightOffset; //1
+ } barberChair;
//33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
struct
{
@@ -350,6 +351,13 @@ struct GameObjectInfo
uint32 state1Name; //2
uint32 state2Name; //3
} destructibleBuilding;
+ //34 GAMEOBJECT_TYPE_TRAPDOOR
+ struct
+ {
+ uint32 whenToPause; // 0
+ uint32 startOpen; // 1
+ uint32 autoClose; // 2
+ } trapDoor;
// not use for specific field access (only for output with loop by all filed), also this determinate max union size
struct // GAMEOBJECT_TYPE_SPELLCASTER
@@ -360,17 +368,35 @@ struct GameObjectInfo
uint32 ScriptId;
};
+// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
+#if defined( __GNUC__ )
+#pragma pack()
+#else
+#pragma pack(pop)
+#endif
+
struct GameObjectLocale
{
std::vector<std::string> Name;
std::vector<std::string> CastBarCaption;
};
+// client side GO show states
+enum GOState
+{
+ GO_STATE_ACTIVE = 0, // show in world as used and not reset (closed door open)
+ GO_STATE_READY = 1, // show in world as ready (closed door close)
+ GO_STATE_ACTIVE_ALTERNATIVE = 2 // show in world as used in alt way and not reset (closed door open by cannon fire)
+};
+
+#define MAX_GO_STATE 3
+
// from `gameobject`
struct GameObjectData
{
uint32 id; // entry in gamobject_template
- uint32 mapid;
+ uint16 mapid;
+ uint16 phaseMask;
float posX;
float posY;
float posZ;
@@ -381,18 +407,11 @@ struct GameObjectData
float rotation3;
int32 spawntimesecs;
uint32 animprogress;
- uint32 go_state;
+ GOState go_state;
uint8 spawnMask;
uint32 ArtKit;
};
-// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
-#if defined( __GNUC__ )
-#pragma pack()
-#else
-#pragma pack(pop)
-#endif
-
// For containers: [GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY -> ...
// For bobber: GO_NOT_READY ->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED-><deleted>
// For door(closed):[GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY(close) -> ...
@@ -419,7 +438,7 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
void AddToWorld();
void RemoveFromWorld();
- bool Create(uint32 guidlow, uint32 name_id, Map *map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, uint32 go_state, uint32 ArtKit = 0);
+ bool Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 ArtKit = 0);
void Update(uint32 p_time);
static GameObject* GetGameObject(WorldObject& object, uint64 guid);
GameObjectInfo const* GetGOInfo() const;
@@ -436,23 +455,21 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
uint32 GetDBTableGUIDLow() const { return m_DBTableGuid; }
- void Say(const char* text, uint32 language, uint64 TargetGuid) { MonsterSay(text,language,TargetGuid); }
- void Yell(const char* text, uint32 language, uint64 TargetGuid) { MonsterYell(text,language,TargetGuid); }
- void TextEmote(const char* text, uint64 TargetGuid) { MonsterTextEmote(text,TargetGuid); }
- void Whisper(const char* text,uint64 receiver) { MonsterWhisper(text,receiver); }
+ void UpdateRotationFields(float rotation2 = 0.0f, float rotation3 = 0.0f);
+
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
void TextEmote(int32 textId, uint64 TargetGuid) { MonsterTextEmote(textId,TargetGuid); }
void Whisper(int32 textId, uint64 receiver) { MonsterWhisper(textId,receiver); }
+ void YellToZone(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYellToZone(textId,language,TargetGuid); }
// overwrite WorldObject function for proper name localization
const char* GetNameForLocaleIdx(int32 locale_idx) const;
void SaveToDB();
- void SaveToDB(uint32 mapid, uint8 spawnMask);
+ void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);
bool LoadFromDB(uint32 guid, Map *map);
void DeleteFromDB();
- void SetLootState(LootState s) { m_lootState = s; }
static uint32 GetLootId(GameObjectInfo const* info);
uint32 GetLootId() const { return GetLootId(GetGOInfo()); }
uint32 GetLockId() const
@@ -474,6 +491,20 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
}
}
+ bool GetDespawnPossibility() const
+ {
+ switch(GetGoType())
+ {
+ case GAMEOBJECT_TYPE_DOOR: return GetGOInfo()->door.noDamageImmune;
+ case GAMEOBJECT_TYPE_BUTTON: return GetGOInfo()->button.noDamageImmune;
+ case GAMEOBJECT_TYPE_QUESTGIVER: return GetGOInfo()->questgiver.noDamageImmune;
+ case GAMEOBJECT_TYPE_GOOBER: return GetGOInfo()->goober.noDamageImmune;
+ case GAMEOBJECT_TYPE_FLAGSTAND: return GetGOInfo()->flagstand.noDamageImmune;
+ case GAMEOBJECT_TYPE_FLAGDROP: return GetGOInfo()->flagdrop.noDamageImmune;
+ default: return true;
+ }
+ }
+
time_t GetRespawnTime() const { return m_respawnTime; }
time_t GetRespawnTimeEx() const
{
@@ -503,19 +534,20 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
void Delete();
void SetSpellId(uint32 id) { m_spellId = id;}
uint32 GetSpellId() const { return m_spellId;}
- void getFishLoot(Loot *loot);
- GameobjectTypes GetGoType() const { return GameobjectTypes(GetUInt32Value(GAMEOBJECT_TYPE_ID)); }
- void SetGoType(GameobjectTypes type) { SetUInt32Value(GAMEOBJECT_TYPE_ID, type); }
- uint32 GetGoState() const { return GetUInt32Value(GAMEOBJECT_STATE); }
- void SetGoState(uint32 state) { SetUInt32Value(GAMEOBJECT_STATE, state); }
- uint32 GetGoArtKit() const { return GetUInt32Value(GAMEOBJECT_ARTKIT); }
- void SetGoArtKit(uint32 artkit);
- uint32 GetGoAnimProgress() const { return GetUInt32Value(GAMEOBJECT_ANIMPROGRESS); }
- void SetGoAnimProgress(uint32 animprogress) { SetUInt32Value(GAMEOBJECT_ANIMPROGRESS, animprogress); }
+ void getFishLoot(Loot *loot, Player* loot_owner);
+ GameobjectTypes GetGoType() const { return GameobjectTypes(GetByteValue(GAMEOBJECT_BYTES_1, 1)); }
+ void SetGoType(GameobjectTypes type) { SetByteValue(GAMEOBJECT_BYTES_1, 1, type); }
+ GOState GetGoState() const { return GOState(GetByteValue(GAMEOBJECT_BYTES_1, 0)); }
+ void SetGoState(GOState state) { SetByteValue(GAMEOBJECT_BYTES_1, 0, state); }
+ uint8 GetGoArtKit() const { return GetByteValue(GAMEOBJECT_BYTES_1, 2); }
+ void SetGoArtKit(uint8 artkit);
+ uint8 GetGoAnimProgress() const { return GetByteValue(GAMEOBJECT_BYTES_1, 3); }
+ void SetGoAnimProgress(uint8 animprogress) { SetByteValue(GAMEOBJECT_BYTES_1, 3, animprogress); }
void Use(Unit* user);
LootState getLootState() const { return m_lootState; }
+ void SetLootState(LootState s) { m_lootState = s; }
void AddToSkillupList(uint32 PlayerGuidLow) { m_SkillupList.push_back(PlayerGuidLow); }
bool IsInSkillupList(uint32 PlayerGuidLow) const
@@ -539,7 +571,10 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
bool hasQuest(uint32 quest_id) const;
bool hasInvolvedQuest(uint32 quest_id) const;
bool ActivateToQuest(Player *pTarget) const;
- void UseDoorOrButton(uint32 time_to_restore = 0); // 0 = use `gameobject`.`spawntimesecs`
+ void UseDoorOrButton(uint32 time_to_restore = 0, bool alternative = false);
+ // 0 = use `gameobject`.`spawntimesecs`
+ void ResetDoorOrButton();
+ // 0 = use `gameobject`.`spawntimesecs`
uint32 GetLinkedGameObjectEntry() const
{
@@ -578,6 +613,7 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
GridReference<GameObject> &GetGridRef() { return m_gridRef; }
void CastSpell(Unit *target, uint32 spell);
+ void SendCustomAnim();
protected:
uint32 m_charges; // Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22)
uint32 m_spellId;
@@ -595,7 +631,7 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
uint32 m_DBTableGuid; ///< For new or temporary gameobjects is 0 for saved it is lowguid
GameObjectInfo const* m_goInfo;
private:
- void SwitchDoorOrButton(bool activate);
+ void SwitchDoorOrButton(bool activate, bool alternative = false);
GridReference<GameObject> m_gridRef;
};
diff --git a/src/game/GlobalEvents.cpp b/src/game/GlobalEvents.cpp
index a2dd89d34c0..a544113f5c8 100644
--- a/src/game/GlobalEvents.cpp
+++ b/src/game/GlobalEvents.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -55,7 +55,7 @@ static void CorpsesEraseCallBack(QueryResult *result, bool bones)
{
if(!ObjectAccessor::Instance().ConvertCorpseForPlayer(player_guid))
{
- sLog.outDebug("Corpse %u not found in world. Delete from DB.",guidlow);
+ sLog.outDebug("Corpse %u not found in world or bones creating forbidden. Delete from DB.",guidlow);
CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%u'",guidlow);
}
}
diff --git a/src/game/GlobalEvents.h b/src/game/GlobalEvents.h
index 6ec6e6b60b1..aa99c47985e 100644
--- a/src/game/GlobalEvents.h
+++ b/src/game/GlobalEvents.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/GossipDef.cpp b/src/game/GossipDef.cpp
index b0f717eea9e..42c4c66ef01 100644
--- a/src/game/GossipDef.cpp
+++ b/src/game/GossipDef.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -127,12 +127,12 @@ bool PlayerMenu::GossipOptionCoded( unsigned int Selection )
void PlayerMenu::SendGossipMenu( uint32 TitleTextId, uint64 npcGUID )
{
WorldPacket data( SMSG_GOSSIP_MESSAGE, (100) ); // guess size
- data << npcGUID;
+ data << uint64(npcGUID);
data << uint32(0); // new 2.4.0
data << uint32( TitleTextId );
data << uint32( mGossipMenu.MenuItemCount() ); // max count 0x0F
- for ( unsigned int iI = 0; iI < mGossipMenu.MenuItemCount(); iI++ )
+ for (uint32 iI = 0; iI < mGossipMenu.MenuItemCount(); ++iI )
{
GossipMenuItem const& gItem = mGossipMenu.GetItem(iI);
data << uint32( iI );
@@ -145,7 +145,7 @@ void PlayerMenu::SendGossipMenu( uint32 TitleTextId, uint64 npcGUID )
data << uint32( mQuestMenu.MenuItemCount() ); // max count 0x20
- for ( uint16 iI = 0; iI < mQuestMenu.MenuItemCount(); iI++ )
+ for (uint32 iI = 0; iI < mQuestMenu.MenuItemCount(); ++iI )
{
QuestMenuItem const& qItem = mQuestMenu.GetItem(iI);
uint32 questID = qItem.m_qId;
@@ -153,7 +153,7 @@ void PlayerMenu::SendGossipMenu( uint32 TitleTextId, uint64 npcGUID )
data << uint32(questID);
data << uint32( qItem.m_qIcon );
- data << uint32( pQuest ? pQuest->GetQuestLevel() : 0 );
+ data << uint32(pSession->GetPlayer()->GetQuestLevel(pQuest));
std::string Title = pQuest->GetTitle();
int loc_idx = pSession->GetSessionDbLocaleIndex();
@@ -181,6 +181,7 @@ void PlayerMenu::CloseGossip()
//sLog.outDebug( "WORLD: Sent SMSG_GOSSIP_COMPLETE" );
}
+// Outdated
void PlayerMenu::SendPointOfInterest( float X, float Y, uint32 Icon, uint32 Flags, uint32 Data, char const * locName )
{
WorldPacket data( SMSG_GOSSIP_POI, (4+4+4+4+4+10) ); // guess size
@@ -194,12 +195,43 @@ void PlayerMenu::SendPointOfInterest( float X, float Y, uint32 Icon, uint32 Flag
//sLog.outDebug("WORLD: Sent SMSG_GOSSIP_POI");
}
-void PlayerMenu::SendTalking( uint32 textID )
+void PlayerMenu::SendPointOfInterest( uint32 poi_id )
{
- GossipText *pGossip;
- std::string GossipStr;
+ PointOfInterest const* poi = objmgr.GetPointOfInterest(poi_id);
+ if(!poi)
+ {
+ sLog.outErrorDb("Requested send not existed POI (Id: %u), ignore.",poi_id);
+ return;
+ }
+
+ std::string icon_name = poi->icon_name;
+
+ int loc_idx = pSession->GetSessionDbLocaleIndex();
+ if (loc_idx >= 0)
+ {
+ PointOfInterestLocale const *pl = objmgr.GetPointOfInterestLocale(poi_id);
+ if (pl)
+ {
+ if (pl->IconName.size() > size_t(loc_idx) && !pl->IconName[loc_idx].empty())
+ icon_name = pl->IconName[loc_idx];
+ }
+ }
+
+ WorldPacket data( SMSG_GOSSIP_POI, (4+4+4+4+4+10) ); // guess size
+ data << uint32(poi->flags);
+ data << float(poi->x);
+ data << float(poi->y);
+ data << uint32(poi->icon);
+ data << uint32(poi->data);
+ data << icon_name;
+
+ pSession->SendPacket( &data );
+ //sLog.outDebug("WORLD: Sent SMSG_GOSSIP_POI");
+}
- pGossip = objmgr.GetGossipText(textID);
+void PlayerMenu::SendTalking( uint32 textID )
+{
+ GossipText const* pGossip = objmgr.GetGossipText(textID);
WorldPacket data( SMSG_NPC_TEXT_UPDATE, 100 ); // guess size
data << textID; // can be < 0
@@ -223,7 +255,7 @@ void PlayerMenu::SendTalking( uint32 textID )
else
{
std::string Text_0[8],Text_1[8];
- for (int i=0;i<8;i++)
+ for (int i=0;i<8;++i)
{
Text_0[i]=pGossip->Options[i].Text_0;
Text_1[i]=pGossip->Options[i].Text_1;
@@ -234,7 +266,7 @@ void PlayerMenu::SendTalking( uint32 textID )
NpcTextLocale const *nl = objmgr.GetNpcTextLocale(textID);
if (nl)
{
- for (int i=0;i<8;i++)
+ for (int i=0;i<8;++i)
{
if (nl->Text_0[i].size() > loc_idx && !nl->Text_0[i][loc_idx].empty())
Text_0[i]=nl->Text_0[i][loc_idx];
@@ -243,7 +275,7 @@ void PlayerMenu::SendTalking( uint32 textID )
}
}
}
- for (int i=0; i<8; i++)
+ for (int i=0; i<8; ++i)
{
data << pGossip->Options[i].Probability;
@@ -259,14 +291,11 @@ void PlayerMenu::SendTalking( uint32 textID )
data << pGossip->Options[i].Language;
- data << pGossip->Options[i].Emotes[0]._Delay;
- data << pGossip->Options[i].Emotes[0]._Emote;
-
- data << pGossip->Options[i].Emotes[1]._Delay;
- data << pGossip->Options[i].Emotes[1]._Emote;
-
- data << pGossip->Options[i].Emotes[2]._Delay;
- data << pGossip->Options[i].Emotes[2]._Emote;
+ for(int j = 0; j < 3; ++j)
+ {
+ data << pGossip->Options[i].Emotes[j]._Delay;
+ data << pGossip->Options[i].Emotes[j]._Emote;
+ }
}
}
pSession->SendPacket( &data );
@@ -328,7 +357,7 @@ void QuestMenu::AddMenuItem( uint32 QuestId, uint8 Icon)
bool QuestMenu::HasItem( uint32 questid )
{
- for (QuestMenuItemList::iterator i = m_qItems.begin(); i != m_qItems.end(); ++i)
+ for (QuestMenuItemList::const_iterator i = m_qItems.begin(); i != m_qItems.end(); ++i)
{
if(i->m_qId==questid)
{
@@ -352,7 +381,7 @@ void PlayerMenu::SendQuestGiverQuestList( QEmote eEmote, const std::string& Titl
data << uint32(eEmote._Emote ); // NPC emote
data << uint8 ( mQuestMenu.MenuItemCount() );
- for ( uint16 iI = 0; iI < mQuestMenu.MenuItemCount(); iI++ )
+ for (uint32 iI = 0; iI < mQuestMenu.MenuItemCount(); ++iI )
{
QuestMenuItem const& qmi = mQuestMenu.GetItem(iI);
@@ -373,7 +402,7 @@ void PlayerMenu::SendQuestGiverQuestList( QEmote eEmote, const std::string& Titl
data << uint32(questID);
data << uint32(qmi.m_qIcon);
- data << uint32(pQuest ? pQuest->GetQuestLevel() : 0);
+ data << uint32(pSession->GetPlayer()->GetQuestLevel(pQuest));
data << title;
}
pSession->SendPacket( &data );
@@ -417,10 +446,14 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID
}
data << uint64(npcGUID);
+ data << uint64(0); // wotlk, something todo with quest sharing?
data << uint32(pQuest->GetQuestId());
- data << Title << Details << Objectives;
+ data << Title;
+ data << Details;
+ data << Objectives;
data << uint32(ActivateAccept);
data << uint32(pQuest->GetSuggestedPlayers());
+ data << uint8(0); // new wotlk
if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
{
@@ -433,7 +466,7 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID
ItemPrototype const* IProto;
data << uint32(pQuest->GetRewChoiceItemsCount());
- for (uint32 i=0; i < QUEST_REWARD_CHOICES_COUNT; i++)
+ for (uint32 i=0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
{
if ( !pQuest->RewChoiceItemId[i] ) continue;
data << uint32(pQuest->RewChoiceItemId[i]);
@@ -446,7 +479,7 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID
}
data << uint32(pQuest->GetRewItemsCount());
- for (uint32 i=0; i < QUEST_REWARDS_COUNT; i++)
+ for (uint32 i=0; i < QUEST_REWARDS_COUNT; ++i)
{
if ( !pQuest->RewItemId[i] ) continue;
data << uint32(pQuest->RewItemId[i]);
@@ -466,9 +499,10 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID
data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
data << uint32(pQuest->GetRewSpellCast()); // casted spell
data << uint32(pQuest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
+ data << uint32(pQuest->GetBonusTalents()); // bonus talents
data << uint32(QUEST_EMOTE_COUNT);
- for (uint32 i=0; i < QUEST_EMOTE_COUNT; i++)
+ for (uint32 i=0; i < QUEST_EMOTE_COUNT; ++i)
{
data << uint32(pQuest->DetailsEmote[i]);
data << uint32(0); // DetailsEmoteDelay
@@ -486,7 +520,7 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
Details = pQuest->GetDetails();
Objectives = pQuest->GetObjectives();
EndText = pQuest->GetEndText();
- for (int i=0;i<QUEST_OBJECTIVES_COUNT;i++)
+ for (int i=0;i<QUEST_OBJECTIVES_COUNT;++i)
ObjectiveText[i]=pQuest->ObjectiveText[i];
int loc_idx = pSession->GetSessionDbLocaleIndex();
@@ -504,7 +538,7 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
if (ql->EndText.size() > loc_idx && !ql->EndText[loc_idx].empty())
EndText=ql->EndText[loc_idx];
- for (int i=0;i<QUEST_OBJECTIVES_COUNT;i++)
+ for (int i=0;i<QUEST_OBJECTIVES_COUNT;++i)
if (ql->ObjectiveText[i].size() > loc_idx && !ql->ObjectiveText[i][loc_idx].empty())
ObjectiveText[i]=ql->ObjectiveText[i][loc_idx];
}
@@ -514,7 +548,7 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
data << uint32(pQuest->GetQuestId());
data << uint32(pQuest->GetQuestMethod()); // Accepted values: 0, 1 or 2. 0==IsAutoComplete() (skip objectives/details)
- data << uint32(pQuest->GetQuestLevel()); // may be 0
+ data << uint32(pQuest->GetQuestLevel()); // may be 0, static data, in other cases must be used dynamic level: Player::GetQuestLevel
data << uint32(pQuest->GetZoneOrSort()); // zone or sort to display in quest log
data << uint32(pQuest->GetType());
@@ -542,24 +576,26 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
data << uint32(pQuest->GetSrcItemId());
data << uint32(pQuest->GetFlags() & 0xFFFF);
data << uint32(pQuest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
+ data << uint32(pQuest->GetPlayersSlain()); // players slain
+ data << uint32(pQuest->GetBonusTalents()); // bonus talents
int iI;
if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
{
- for (iI = 0; iI < QUEST_REWARDS_COUNT; iI++)
+ for (iI = 0; iI < QUEST_REWARDS_COUNT; ++iI)
data << uint32(0) << uint32(0);
- for (iI = 0; iI < QUEST_REWARD_CHOICES_COUNT; iI++)
+ for (iI = 0; iI < QUEST_REWARD_CHOICES_COUNT; ++iI)
data << uint32(0) << uint32(0);
}
else
{
- for (iI = 0; iI < QUEST_REWARDS_COUNT; iI++)
+ for (iI = 0; iI < QUEST_REWARDS_COUNT; ++iI)
{
data << uint32(pQuest->RewItemId[iI]);
data << uint32(pQuest->RewItemCount[iI]);
}
- for (iI = 0; iI < QUEST_REWARD_CHOICES_COUNT; iI++)
+ for (iI = 0; iI < QUEST_REWARD_CHOICES_COUNT; ++iI)
{
data << uint32(pQuest->RewChoiceItemId[iI]);
data << uint32(pQuest->RewChoiceItemCount[iI]);
@@ -576,7 +612,7 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
data << Details;
data << EndText;
- for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; iI++)
+ for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; ++iI)
{
if (pQuest->ReqCreatureOrGOId[iI] < 0)
{
@@ -588,15 +624,23 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
data << uint32(pQuest->ReqCreatureOrGOId[iI]);
}
data << uint32(pQuest->ReqCreatureOrGOCount[iI]);
+ data << uint32(pQuest->ReqSourceId[iI]);
+ }
+
+ for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; ++iI)
+ {
data << uint32(pQuest->ReqItemId[iI]);
data << uint32(pQuest->ReqItemCount[iI]);
}
- for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; iI++)
+ data << uint32(0); // TODO: 5 item objective
+ data << uint32(0);
+
+ for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; ++iI)
data << ObjectiveText[iI];
pSession->SendPacket( &data );
- sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u",pQuest->GetQuestId() );
+ sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u", pQuest->GetQuestId() );
}
void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID, bool EnbleNext )
@@ -628,7 +672,7 @@ void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID,
data << uint32(0); // unk
uint32 EmoteCount = 0;
- for (uint32 i = 0; i < QUEST_EMOTE_COUNT; i++)
+ for (uint32 i = 0; i < QUEST_EMOTE_COUNT; ++i)
{
if(pQuest->OfferRewardEmote[i] <= 0)
break;
@@ -636,7 +680,7 @@ void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID,
}
data << EmoteCount; // Emote Count
- for (uint32 i = 0; i < EmoteCount; i++)
+ for (uint32 i = 0; i < EmoteCount; ++i)
{
data << uint32(0); // Delay Emote
data << pQuest->OfferRewardEmote[i];
@@ -645,7 +689,7 @@ void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID,
ItemPrototype const *pItem;
data << uint32(pQuest->GetRewChoiceItemsCount());
- for (uint32 i=0; i < pQuest->GetRewChoiceItemsCount(); i++)
+ for (uint32 i=0; i < pQuest->GetRewChoiceItemsCount(); ++i)
{
pItem = objmgr.GetItemPrototype( pQuest->RewChoiceItemId[i] );
@@ -659,7 +703,7 @@ void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID,
}
data << uint32(pQuest->GetRewItemsCount());
- for (uint16 i=0; i < pQuest->GetRewItemsCount(); i++)
+ for (uint16 i=0; i < pQuest->GetRewItemsCount(); ++i)
{
pItem = objmgr.GetItemPrototype(pQuest->RewItemId[i]);
data << uint32(pQuest->RewItemId[i]);
@@ -678,9 +722,10 @@ void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID,
data << uint32(0x08); // unused by client?
data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
data << uint32(pQuest->GetRewSpellCast()); // casted spell
- data << uint32(0x00); // unk, NOT honor
+ data << uint32(0); // unknown
+ data << uint32(pQuest->GetBonusTalents()); // bonus talents
pSession->SendPacket( &data );
- sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId() );
+ sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), pQuest->GetQuestId() );
}
void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID, bool Completable, bool CloseOnCancel )
@@ -688,16 +733,8 @@ void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID
// We can always call to RequestItems, but this packet only goes out if there are actually
// items. Otherwise, we'll skip straight to the OfferReward
- // We may wish a better check, perhaps checking the real quest requirements
- if (pQuest->GetRequestItemsText().empty())
- {
- SendQuestGiverOfferReward(pQuest, npcGUID, true);
- return;
- }
-
- std::string Title,RequestItemsText;
- Title = pQuest->GetTitle();
- RequestItemsText = pQuest->GetRequestItemsText();
+ std::string Title = pQuest->GetTitle();
+ std::string RequestItemsText = pQuest->GetRequestItemsText();
int loc_idx = pSession->GetSessionDbLocaleIndex();
if (loc_idx >= 0)
@@ -712,6 +749,13 @@ void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID
}
}
+ // We may wish a better check, perhaps checking the real quest requirements
+ if (RequestItemsText.empty())
+ {
+ SendQuestGiverOfferReward(pQuest, npcGUID, true);
+ return;
+ }
+
WorldPacket data( SMSG_QUESTGIVER_REQUEST_ITEMS, 50 ); // guess size
data << npcGUID;
data << pQuest->GetQuestId();
@@ -738,7 +782,7 @@ void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID
data << uint32( pQuest->GetReqItemsCount() );
ItemPrototype const *pItem;
- for (int i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
+ for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
{
if ( !pQuest->ReqItemId[i] ) continue;
pItem = objmgr.GetItemPrototype(pQuest->ReqItemId[i]);
diff --git a/src/game/GossipDef.h b/src/game/GossipDef.h
index e2279550528..102a34b5913 100644
--- a/src/game/GossipDef.h
+++ b/src/game/GossipDef.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -30,27 +30,27 @@ class WorldSession;
#define GOSSIP_MAX_MENU_ITEMS 64 // client supported items unknown, but provided number must be enough
#define DEFAULT_GOSSIP_MESSAGE 0xffffff
-//POI defines
+//POI icons. Many more exist, list not complete.
enum Poi_Icon
{
- ICON_POI_0 = 0, // Grey ?
- ICON_POI_1 = 1, // Red ?
- ICON_POI_2 = 2, // Blue ?
- ICON_POI_BWTOMB = 3, // Blue and White Tomb Stone
- ICON_POI_HOUSE = 4, // House
- ICON_POI_TOWER = 5, // Tower
- ICON_POI_REDFLAG = 6, // Red Flag with Yellow !
- ICON_POI_TOMB = 7, // Tomb Stone
- ICON_POI_BWTOWER = 8, // Blue and White Tower
- ICON_POI_REDTOWER = 9, // Red Tower
- ICON_POI_BLUETOWER = 10, // Blue Tower
- ICON_POI_RWTOWER = 11, // Red and White Tower
- ICON_POI_REDTOMB = 12, // Red Tomb Stone
- ICON_POI_RWTOMB = 13, // Red and White Tomb Stone
- ICON_POI_BLUETOMB = 14, // Blue Tomb Stone
- ICON_POI_NOTHING = 15, // NOTHING
- ICON_POI_16 = 16, // Red ?
- ICON_POI_17 = 17, // Grey ?
+ ICON_POI_BLANK = 0, // Blank (not visible)
+ ICON_POI_GREY_AV_MINE = 1, // Grey mine lorry
+ ICON_POI_RED_AV_MINE = 2, // Red mine lorry
+ ICON_POI_BLUE_AV_MINE = 3, // Blue mine lorry
+ ICON_POI_BWTOMB = 4, // Blue and White Tomb Stone
+ ICON_POI_SMALL_HOUSE = 5, // Small house
+ ICON_POI_GREYTOWER = 6, // Grey Tower
+ ICON_POI_REDFLAG = 7, // Red Flag w/Yellow !
+ ICON_POI_TOMBSTONE = 8, // Normal tomb stone (brown)
+ ICON_POI_BWTOWER = 9, // Blue and White Tower
+ ICON_POI_REDTOWER = 10, // Red Tower
+ ICON_POI_BLUETOWER = 11, // Blue Tower
+ ICON_POI_RWTOWER = 12, // Red and White Tower
+ ICON_POI_REDTOMB = 13, // Red Tomb Stone
+ ICON_POI_RWTOMB = 14, // Red and White Tomb Stone
+ ICON_POI_BLUETOMB = 15, // Blue Tomb Stone
+ ICON_POI_16 = 16, // Grey ?
+ ICON_POI_17 = 17, // Blue/White ?
ICON_POI_18 = 18, // Blue ?
ICON_POI_19 = 19, // Red and White ?
ICON_POI_20 = 20, // Red ?
@@ -189,6 +189,7 @@ class TRINITY_DLL_SPEC PlayerMenu
void SendGossipMenu( uint32 TitleTextId, uint64 npcGUID );
void CloseGossip();
void SendPointOfInterest( float X, float Y, uint32 Icon, uint32 Flags, uint32 Data, const char * locName );
+ void SendPointOfInterest( uint32 poi_id );
void SendTalking( uint32 textID );
void SendTalking( char const * title, char const * text );
diff --git a/src/game/GridDefines.h b/src/game/GridDefines.h
index cb67897329f..a3fe011f402 100644
--- a/src/game/GridDefines.h
+++ b/src/game/GridDefines.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -48,7 +48,7 @@ class Player;
#define CENTER_GRID_OFFSET (SIZE_OF_GRIDS/2)
-#define MIN_GRID_DELAY MINUTE*1000
+#define MIN_GRID_DELAY (MINUTE*IN_MILISECONDS)
#define MIN_MAP_UPDATE_DELAY 50
#define SIZE_OF_GRID_CELL (SIZE_OF_GRIDS/MAX_NUMBER_OF_CELLS)
@@ -57,7 +57,7 @@ class Player;
#define TOTAL_NUMBER_OF_CELLS_PER_MAP (MAX_NUMBER_OF_GRIDS*MAX_NUMBER_OF_CELLS)
-#define MAP_RESOLUTION 256
+#define MAP_RESOLUTION 128
#define MAP_SIZE (SIZE_OF_GRIDS*MAX_NUMBER_OF_GRIDS)
#define MAP_HALFSIZE (MAP_SIZE/2)
diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp
index e27abeccd0c..fe18dc35840 100644
--- a/src/game/GridNotifiers.cpp
+++ b/src/game/GridNotifiers.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -24,7 +24,6 @@
#include "UpdateData.h"
#include "Item.h"
#include "Map.h"
-#include "MapManager.h"
#include "Transports.h"
#include "ObjectAccessor.h"
@@ -94,9 +93,9 @@ PlayerVisibilityNotifier::Notify()
// Now do operations that required done at object visibility change to visible
- // target aura duration for caster show only if target exist at caster client
// send data at target visibility change (adding to client)
for(std::set<WorldObject*>::const_iterator vItr = i_visibleNow.begin(); vItr != i_visibleNow.end(); ++vItr)
+ // target aura duration for caster show only if target exist at caster client
if((*vItr)!=&i_player && (*vItr)->isType(TYPEMASK_UNIT))
i_player.SendInitialVisiblePackets((Unit*)(*vItr));
@@ -109,14 +108,20 @@ Deliverer::Visit(PlayerMapType &m)
{
for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
- if (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist)
+ //if (!i_source.InSamePhase(iter->getSource()))
+ // continue;
+ if(!iter->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
+ if (!i_dist || iter->getSource()->GetDistance(&i_source) < i_dist)
{
// Send packet to all who are sharing the player's vision
if (!iter->getSource()->GetSharedVisionList().empty())
{
- SharedVisionList::const_iterator it = iter->getSource()->GetSharedVisionList().begin();
- for ( ; it != iter->getSource()->GetSharedVisionList().end(); ++it)
- SendPacket(*it);
+ SharedVisionList::const_iterator i = iter->getSource()->GetSharedVisionList().begin();
+ for ( ; i != iter->getSource()->GetSharedVisionList().end(); ++i)
+ if((*i)->m_seer == iter->getSource())
+ SendPacket(*i);
}
VisitObject(iter->getSource());
@@ -129,14 +134,18 @@ Deliverer::Visit(CreatureMapType &m)
{
for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
- if (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist)
+ if(!iter->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
+ if (!i_dist || iter->getSource()->GetDistance(&i_source) < i_dist)
{
// Send packet to all who are sharing the creature's vision
if (!iter->getSource()->GetSharedVisionList().empty())
{
- SharedVisionList::const_iterator it = iter->getSource()->GetSharedVisionList().begin();
- for ( ; it != iter->getSource()->GetSharedVisionList().end(); ++it)
- SendPacket(*it);
+ SharedVisionList::const_iterator i = iter->getSource()->GetSharedVisionList().begin();
+ for ( ; i != iter->getSource()->GetSharedVisionList().end(); ++i)
+ if((*i)->m_seer == iter->getSource())
+ SendPacket(*i);
}
}
}
@@ -147,13 +156,18 @@ Deliverer::Visit(DynamicObjectMapType &m)
{
for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
- if (IS_PLAYER_GUID(iter->getSource()->GetCasterGUID()))
+ if(!iter->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
+ if (!i_dist || iter->getSource()->GetDistance(&i_source) < i_dist)
{
- // Send packet back to the caster if the caster has vision of dynamic object
- Player* caster = (Player*)iter->getSource()->GetCaster();
- if (caster && caster->GetUInt64Value(PLAYER_FARSIGHT) == iter->getSource()->GetGUID() &&
- (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist))
- SendPacket(caster);
+ if (IS_PLAYER_GUID(iter->getSource()->GetCasterGUID()))
+ {
+ // Send packet back to the caster if the caster has vision of dynamic object
+ Player* caster = (Player*)iter->getSource()->GetCaster();
+ if (caster && caster->m_seer == iter->getSource())
+ SendPacket(caster);
+ }
}
}
}
@@ -204,9 +218,6 @@ ObjectUpdater::Visit(GridRefManager<T> &m)
}
}
-template void ObjectUpdater::Visit<GameObject>(GameObjectMapType &);
-template void ObjectUpdater::Visit<DynamicObject>(DynamicObjectMapType &);
-
bool CannibalizeObjectCheck::operator()(Corpse* u)
{
// ignore bones
@@ -224,3 +235,5 @@ bool CannibalizeObjectCheck::operator()(Corpse* u)
return false;
}
+template void ObjectUpdater::Visit<GameObject>(GameObjectMapType &);
+template void ObjectUpdater::Visit<DynamicObject>(DynamicObjectMapType &);
diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h
index b34eee36e7b..03d8ea11b16 100644
--- a/src/game/GridNotifiers.h
+++ b/src/game/GridNotifiers.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -108,8 +108,10 @@ namespace Trinity
std::set<uint64> plr_list;
bool i_toPossessor;
bool i_toSelf;
+ uint32 i_phaseMask;
float i_dist;
- Deliverer(WorldObject &src, WorldPacket *msg, bool to_possessor, bool to_self, float dist = 0.0f) : i_source(src), i_message(msg), i_toPossessor(to_possessor), i_toSelf(to_self), i_dist(dist) {}
+ Deliverer(WorldObject &src, WorldPacket *msg, bool to_possessor, bool to_self, float dist = 0.0f)
+ : i_source(src), i_message(msg), i_toPossessor(to_possessor), i_toSelf(to_self), i_dist(dist), i_phaseMask(src.GetPhaseMask()) {}
void Visit(PlayerMapType &m);
void Visit(CreatureMapType &m);
void Visit(DynamicObjectMapType &m);
@@ -208,10 +210,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL WorldObjectSearcher
{
+ uint32 i_phaseMask;
WorldObject* &i_object;
Check &i_check;
- WorldObjectSearcher(WorldObject* & result, Check& check) : i_object(result),i_check(check) {}
+ WorldObjectSearcher(WorldObject const* searcher, WorldObject* & result, Check& check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
void Visit(GameObjectMapType &m);
void Visit(PlayerMapType &m);
@@ -225,10 +229,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL WorldObjectListSearcher
{
+ uint32 i_phaseMask;
std::list<WorldObject*> &i_objects;
Check& i_check;
- WorldObjectListSearcher(std::list<WorldObject*> &objects, Check & check) : i_objects(objects),i_check(check) {}
+ WorldObjectListSearcher(WorldObject const* searcher, std::list<WorldObject*> &objects, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects),i_check(check) {}
void Visit(PlayerMapType &m);
void Visit(CreatureMapType &m);
@@ -242,37 +248,44 @@ namespace Trinity
template<class Do>
struct TRINITY_DLL_DECL WorldObjectWorker
{
+ uint32 i_phaseMask;
Do const& i_do;
- explicit WorldObjectWorker(Do const& _do) : i_do(_do) {}
+ WorldObjectWorker(WorldObject const* searcher, Do const& _do)
+ : i_phaseMask(searcher->GetPhaseMask()), i_do(_do) {}
void Visit(GameObjectMapType &m)
{
for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- i_do(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ i_do(itr->getSource());
}
void Visit(PlayerMapType &m)
{
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- i_do(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ i_do(itr->getSource());
}
void Visit(CreatureMapType &m)
{
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- i_do(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ i_do(itr->getSource());
}
void Visit(CorpseMapType &m)
{
for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- i_do(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ i_do(itr->getSource());
}
void Visit(DynamicObjectMapType &m)
{
for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- i_do(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ i_do(itr->getSource());
}
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
@@ -283,10 +296,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL GameObjectSearcher
{
+ uint32 i_phaseMask;
GameObject* &i_object;
Check &i_check;
- GameObjectSearcher(GameObject* & result, Check& check) : i_object(result),i_check(check) {}
+ GameObjectSearcher(WorldObject const* searcher, GameObject* & result, Check& check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
void Visit(GameObjectMapType &m);
@@ -297,10 +312,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL GameObjectLastSearcher
{
+ uint32 i_phaseMask;
GameObject* &i_object;
Check& i_check;
- GameObjectLastSearcher(GameObject* & result, Check& check) : i_object(result),i_check(check) {}
+ GameObjectLastSearcher(WorldObject const* searcher, GameObject* & result, Check& check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) {}
void Visit(GameObjectMapType &m);
@@ -310,10 +327,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL GameObjectListSearcher
{
+ uint32 i_phaseMask;
std::list<GameObject*> &i_objects;
Check& i_check;
- GameObjectListSearcher(std::list<GameObject*> &objects, Check & check) : i_objects(objects),i_check(check) {}
+ GameObjectListSearcher(WorldObject const* searcher, std::list<GameObject*> &objects, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) {}
void Visit(GameObjectMapType &m);
@@ -326,10 +345,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL UnitSearcher
{
+ uint32 i_phaseMask;
Unit* &i_object;
Check & i_check;
- UnitSearcher(Unit* & result, Check & check) : i_object(result),i_check(check) {}
+ UnitSearcher(WorldObject const* searcher, Unit* & result, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
void Visit(CreatureMapType &m);
void Visit(PlayerMapType &m);
@@ -341,10 +362,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL UnitLastSearcher
{
+ uint32 i_phaseMask;
Unit* &i_object;
Check & i_check;
- UnitLastSearcher(Unit* & result, Check & check) : i_object(result),i_check(check) {}
+ UnitLastSearcher(WorldObject const* searcher, Unit* & result, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
void Visit(CreatureMapType &m);
void Visit(PlayerMapType &m);
@@ -356,10 +379,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL UnitListSearcher
{
+ uint32 i_phaseMask;
std::list<Unit*> &i_objects;
Check& i_check;
- UnitListSearcher(std::list<Unit*> &objects, Check & check) : i_objects(objects),i_check(check) {}
+ UnitListSearcher(WorldObject const* searcher, std::list<Unit*> &objects, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects),i_check(check) {}
void Visit(PlayerMapType &m);
void Visit(CreatureMapType &m);
@@ -372,10 +397,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL CreatureSearcher
{
+ uint32 i_phaseMask;
Creature* &i_object;
Check & i_check;
- CreatureSearcher(Creature* & result, Check & check) : i_object(result),i_check(check) {}
+ CreatureSearcher(WorldObject const* searcher, Creature* & result, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
void Visit(CreatureMapType &m);
@@ -386,10 +413,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL CreatureLastSearcher
{
+ uint32 i_phaseMask;
Creature* &i_object;
Check & i_check;
- CreatureLastSearcher(Creature* & result, Check & check) : i_object(result),i_check(check) {}
+ CreatureLastSearcher(WorldObject const* searcher, Creature* & result, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
void Visit(CreatureMapType &m);
@@ -399,10 +428,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL CreatureListSearcher
{
+ uint32 i_phaseMask;
std::list<Creature*> &i_objects;
Check& i_check;
- CreatureListSearcher(std::list<Creature*> &objects, Check & check) : i_objects(objects),i_check(check) {}
+ CreatureListSearcher(WorldObject const* searcher, std::list<Creature*> &objects, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects),i_check(check) {}
void Visit(CreatureMapType &m);
@@ -414,10 +445,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL PlayerSearcher
{
+ uint32 i_phaseMask;
Player* &i_object;
Check & i_check;
- PlayerSearcher(Player* & result, Check & check) : i_object(result),i_check(check) {}
+ PlayerSearcher(WorldObject const* searcher, Player* & result, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
void Visit(PlayerMapType &m);
@@ -427,14 +460,37 @@ namespace Trinity
template<class Do>
struct TRINITY_DLL_DECL PlayerWorker
{
+ uint32 i_phaseMask;
Do& i_do;
- explicit PlayerWorker(Do& _do) : i_do(_do) {}
+ PlayerWorker(WorldObject const* searcher, Do& _do)
+ : i_phaseMask(searcher->GetPhaseMask()), i_do(_do) {}
void Visit(PlayerMapType &m)
{
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- i_do(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ i_do(itr->getSource());
+ }
+
+ template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
+ };
+
+ template<class Do>
+ struct TRINITY_DLL_DECL PlayerDistWorker
+ {
+ WorldObject const* i_searcher;
+ float i_dist;
+ Do& i_do;
+
+ PlayerDistWorker(WorldObject const* searcher, float _dist, Do& _do)
+ : i_searcher(searcher), i_dist(_dist), i_do(_do) {}
+
+ void Visit(PlayerMapType &m)
+ {
+ for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
+ if(itr->getSource()->InSamePhase(i_searcher) && itr->getSource()->GetDistance(i_searcher) <= i_dist)
+ i_do(itr->getSource());
}
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
@@ -572,6 +628,62 @@ namespace Trinity
// Unit checks
+ class MostHPMissingInRange
+ {
+ public:
+ MostHPMissingInRange(Unit const* obj, float range, uint32 hp) : i_obj(obj), i_range(range), i_hp(hp) {}
+ bool operator()(Unit* u)
+ {
+ if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) && u->GetMaxHealth() - u->GetHealth() > i_hp)
+ {
+ i_hp = u->GetMaxHealth() - u->GetHealth();
+ return true;
+ }
+ return false;
+ }
+ private:
+ Unit const* i_obj;
+ float i_range;
+ uint32 i_hp;
+ };
+
+ class FriendlyCCedInRange
+ {
+ public:
+ FriendlyCCedInRange(Unit const* obj, float range) : i_obj(obj), i_range(range) {}
+ bool operator()(Unit* u)
+ {
+ if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
+ (u->isFeared() || u->isCharmed() || u->isFrozen() || u->hasUnitState(UNIT_STAT_STUNNED) || u->hasUnitState(UNIT_STAT_CONFUSED)))
+ {
+ return true;
+ }
+ return false;
+ }
+ private:
+ Unit const* i_obj;
+ float i_range;
+ };
+
+ class FriendlyMissingBuffInRange
+ {
+ public:
+ FriendlyMissingBuffInRange(Unit const* obj, float range, uint32 spellid) : i_obj(obj), i_range(range), i_spell(spellid) {}
+ bool operator()(Unit* u)
+ {
+ if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
+ !(u->HasAura(i_spell)))
+ {
+ return true;
+ }
+ return false;
+ }
+ private:
+ Unit const* i_obj;
+ float i_range;
+ uint32 i_spell;
+ };
+
class AnyUnfriendlyUnitInObjectRangeCheck
{
public:
@@ -859,63 +971,6 @@ namespace Trinity
float i_range;
};
- // Searchers used by ScriptedAI
- class MostHPMissingInRange
- {
- public:
- MostHPMissingInRange(Unit const* obj, float range, uint32 hp) : i_obj(obj), i_range(range), i_hp(hp) {}
- bool operator()(Unit* u)
- {
- if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) && u->GetMaxHealth() - u->GetHealth() > i_hp)
- {
- i_hp = u->GetMaxHealth() - u->GetHealth();
- return true;
- }
- return false;
- }
- private:
- Unit const* i_obj;
- float i_range;
- uint32 i_hp;
- };
-
- class FriendlyCCedInRange
- {
- public:
- FriendlyCCedInRange(Unit const* obj, float range) : i_obj(obj), i_range(range) {}
- bool operator()(Unit* u)
- {
- if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
- (u->isFeared() || u->isCharmed() || u->isFrozen() || u->hasUnitState(UNIT_STAT_STUNNED) || u->hasUnitState(UNIT_STAT_CONFUSED)))
- {
- return true;
- }
- return false;
- }
- private:
- Unit const* i_obj;
- float i_range;
- };
-
- class FriendlyMissingBuffInRange
- {
- public:
- FriendlyMissingBuffInRange(Unit const* obj, float range, uint32 spellid) : i_obj(obj), i_range(range), i_spell(spellid) {}
- bool operator()(Unit* u)
- {
- if(u->isAlive() && u->isInCombat() && /*!i_obj->IsHostileTo(u)*/ i_obj->IsFriendlyTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
- !(u->HasAura(i_spell, 0) || u->HasAura(i_spell, 1) || u->HasAura(i_spell, 2)))
- {
- return true;
- }
- return false;
- }
- private:
- Unit const* i_obj;
- float i_range;
- uint32 i_spell;
- };
-
class AllFriendlyCreaturesInGrid
{
public:
@@ -963,6 +1018,49 @@ namespace Trinity
float range;
};
+ // Player checks and do
+
+ // Prepare using Builder localized packets with caching and send to player
+ template<class Builder>
+ class LocalizedPacketDo
+ {
+ public:
+ explicit LocalizedPacketDo(Builder& builder) : i_builder(builder) {}
+
+ ~LocalizedPacketDo()
+ {
+ for(size_t i = 0; i < i_data_cache.size(); ++i)
+ delete i_data_cache[i];
+ }
+ void operator()( Player* p );
+
+ private:
+ Builder& i_builder;
+ std::vector<WorldPacket*> i_data_cache; // 0 = default, i => i-1 locale index
+ };
+
+ // Prepare using Builder localized packets with caching and send to player
+ template<class Builder>
+ class LocalizedPacketListDo
+ {
+ public:
+ typedef std::vector<WorldPacket*> WorldPacketList;
+ explicit LocalizedPacketListDo(Builder& builder) : i_builder(builder) {}
+
+ ~LocalizedPacketListDo()
+ {
+ for(size_t i = 0; i < i_data_cache.size(); ++i)
+ for(int j = 0; j < i_data_cache[i].size(); ++j)
+ delete i_data_cache[i][j];
+ }
+ void operator()( Player* p );
+
+ private:
+ Builder& i_builder;
+ std::vector<WorldPacketList> i_data_cache;
+ // 0 = default, i => i-1 locale index
+ };
+
#ifndef WIN32
template<> inline void PlayerRelocationNotifier::Visit<Creature>(CreatureMapType &);
template<> inline void PlayerRelocationNotifier::Visit<Player>(PlayerMapType &);
diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h
index a43a97cd898..7fc6c147f5b 100644
--- a/src/game/GridNotifiersImpl.h
+++ b/src/game/GridNotifiersImpl.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -128,7 +128,7 @@ Trinity::CreatureRelocationNotifier::Visit(PlayerMapType &m)
continue;
iter->getSource()->UpdateVisibilityOf(&i_creature);
-
+
PlayerCreatureRelocationWorker(iter->getSource(), &i_creature);
}
}
@@ -144,7 +144,7 @@ Trinity::CreatureRelocationNotifier::Visit(CreatureMapType &m)
{
if(iter->getSource()->m_Notified)
continue;
-
+
if(!iter->getSource()->isAlive())
continue;
@@ -202,11 +202,10 @@ inline void Trinity::DynamicObjectUpdater::VisitHelper(Unit* target)
}
// Check target immune to spell or aura
- if (target->IsImmunedToSpell(spellInfo) || target->IsImmunedToSpellEffect(spellInfo->Effect[eff_index], spellInfo->EffectMechanic[eff_index]))
+ if (target->IsImmunedToSpell(spellInfo) || target->IsImmunedToSpellEffect(spellInfo, eff_index))
return;
// Apply PersistentAreaAura on target
- PersistentAreaAura* Aur = new PersistentAreaAura(spellInfo, eff_index, NULL, target, i_dynobject.GetCaster());
- target->AddAura(Aur);
+ target->AddAuraEffect(spellInfo->Id, eff_index, i_dynobject.GetCaster());
i_dynobject.AddAffected(target);
}
@@ -239,7 +238,10 @@ void Trinity::WorldObjectSearcher<Check>::Visit(GameObjectMapType &m)
for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
- if(i_check(itr->getSource()))
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
+ if (i_check(itr->getSource()))
{
i_object = itr->getSource();
return;
@@ -256,6 +258,9 @@ void Trinity::WorldObjectSearcher<Check>::Visit(PlayerMapType &m)
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -273,6 +278,9 @@ void Trinity::WorldObjectSearcher<Check>::Visit(CreatureMapType &m)
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -290,6 +298,9 @@ void Trinity::WorldObjectSearcher<Check>::Visit(CorpseMapType &m)
for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -307,6 +318,9 @@ void Trinity::WorldObjectSearcher<Check>::Visit(DynamicObjectMapType &m)
for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -319,40 +333,45 @@ template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(PlayerMapType &m)
{
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if(i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(CreatureMapType &m)
{
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if(i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(CorpseMapType &m)
{
for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if(i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(GameObjectMapType &m)
{
for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if(i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(DynamicObjectMapType &m)
{
for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if(i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
// Gameobject searchers
@@ -366,6 +385,9 @@ void Trinity::GameObjectSearcher<Check>::Visit(GameObjectMapType &m)
for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -379,6 +401,9 @@ void Trinity::GameObjectLastSearcher<Check>::Visit(GameObjectMapType &m)
{
for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
i_object = itr->getSource();
}
@@ -388,8 +413,9 @@ template<class Check>
void Trinity::GameObjectListSearcher<Check>::Visit(GameObjectMapType &m)
{
for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if(i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
// Unit searchers
@@ -403,6 +429,9 @@ void Trinity::UnitSearcher<Check>::Visit(CreatureMapType &m)
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -420,6 +449,9 @@ void Trinity::UnitSearcher<Check>::Visit(PlayerMapType &m)
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -433,6 +465,9 @@ void Trinity::UnitLastSearcher<Check>::Visit(CreatureMapType &m)
{
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
i_object = itr->getSource();
}
@@ -443,6 +478,9 @@ void Trinity::UnitLastSearcher<Check>::Visit(PlayerMapType &m)
{
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
i_object = itr->getSource();
}
@@ -452,16 +490,18 @@ template<class Check>
void Trinity::UnitListSearcher<Check>::Visit(PlayerMapType &m)
{
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if(i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
template<class Check>
void Trinity::UnitListSearcher<Check>::Visit(CreatureMapType &m)
{
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if(i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
// Creature searchers
@@ -475,6 +515,9 @@ void Trinity::CreatureSearcher<Check>::Visit(CreatureMapType &m)
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -488,6 +531,9 @@ void Trinity::CreatureLastSearcher<Check>::Visit(CreatureMapType &m)
{
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
i_object = itr->getSource();
}
@@ -497,8 +543,9 @@ template<class Check>
void Trinity::CreatureListSearcher<Check>::Visit(CreatureMapType &m)
{
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if( i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
template<class Check>
@@ -510,6 +557,9 @@ void Trinity::PlayerSearcher<Check>::Visit(PlayerMapType &m)
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -518,5 +568,53 @@ void Trinity::PlayerSearcher<Check>::Visit(PlayerMapType &m)
}
}
-#endif // TRINITY_GRIDNOTIFIERSIMPL_H
+template<class Builder>
+void MaNGOS::LocalizedPacketDo<Builder>::operator()( Player* p )
+{
+ uint32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex();
+ uint32 cache_idx = loc_idx+1;
+ WorldPacket* data;
+
+ // create if not cached yet
+ if(i_data_cache.size() < cache_idx+1 || !i_data_cache[cache_idx])
+ {
+ if(i_data_cache.size() < cache_idx+1)
+ i_data_cache.resize(cache_idx+1);
+
+ data = new WorldPacket(SMSG_MESSAGECHAT, 200);
+
+ i_builder(*data,loc_idx);
+
+ i_data_cache[cache_idx] = data;
+ }
+ else
+ data = i_data_cache[cache_idx];
+
+ p->SendDirectMessage(data);
+}
+
+template<class Builder>
+void MaNGOS::LocalizedPacketListDo<Builder>::operator()( Player* p )
+{
+ uint32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex();
+ uint32 cache_idx = loc_idx+1;
+ WorldPacketList* data_list;
+
+ // create if not cached yet
+ if(i_data_cache.size() < cache_idx+1 || i_data_cache[cache_idx].empty())
+ {
+ if(i_data_cache.size() < cache_idx+1)
+ i_data_cache.resize(cache_idx+1);
+
+ data_list = &i_data_cache[cache_idx];
+
+ i_builder(*data_list,loc_idx);
+ }
+ else
+ data_list = &i_data_cache[cache_idx];
+
+ for(size_t i = 0; i < data_list->size(); ++i)
+ p->SendDirectMessage((*data_list)[i]);
+}
+#endif // MANGOS_GRIDNOTIFIERSIMPL_H
diff --git a/src/game/GridStates.h b/src/game/GridStates.h
index 167f30b8371..12d64ad58ca 100644
--- a/src/game/GridStates.h
+++ b/src/game/GridStates.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/Group.cpp b/src/game/Group.cpp
index 535a3d4392c..601440c0466 100644
--- a/src/game/Group.cpp
+++ b/src/game/Group.cpp
@@ -46,7 +46,7 @@ Group::Group()
m_lootThreshold = ITEM_QUALITY_UNCOMMON;
m_subGroupsCounts = NULL;
- for(int i=0; i<TARGETICONCOUNT; i++)
+ for (int i=0; i<TARGETICONCOUNT; ++i)
m_targetIcons[i] = 0;
}
@@ -71,9 +71,9 @@ Group::~Group()
// it is undefined whether objectmgr (which stores the groups) or instancesavemgr
// will be unloaded first so we must be prepared for both cases
// this may unload some instance saves
- for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
- for(BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
- itr->second.save->RemoveGroup(this);
+ for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i)
+ for(BoundInstancesMap::iterator itr2 = m_boundInstances[i].begin(); itr2 != m_boundInstances[i].end(); ++itr2)
+ itr2->second.save->RemoveGroup(this);
// Sub group counters clean up
if (m_subGroupsCounts)
@@ -156,7 +156,7 @@ bool Group::LoadGroupFromDB(const uint64 &leaderGuid, QueryResult *result, bool
m_looterGuid = MAKE_NEW_GUID((*result)[3].GetUInt32(), 0, HIGHGUID_PLAYER);
m_lootThreshold = (ItemQualities)(*result)[4].GetUInt16();
- for(int i=0; i<TARGETICONCOUNT; i++)
+ for(int i=0; i<TARGETICONCOUNT; ++i)
m_targetIcons[i] = (*result)[5+i].GetUInt64();
if(!external) delete result;
@@ -203,13 +203,24 @@ void Group::ConvertToRaid()
_initRaidSubGroupsCounter();
- if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE groups SET isRaid = 1 WHERE leaderGuid='%u'", GUID_LOPART(m_leaderGuid));
+ if(!isBGGroup())
+ CharacterDatabase.PExecute("UPDATE groups SET isRaid = 1 WHERE leaderGuid='%u'", GUID_LOPART(m_leaderGuid));
SendUpdate();
+
+ // update quest related GO states (quest activity dependent from raid membership)
+ for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
+ if(Player* player = objmgr.GetPlayer(citr->guid))
+ player->UpdateForQuestsGO();
}
bool Group::AddInvite(Player *player)
{
- if(!player || player->GetGroupInvite() || player->GetGroup())
+ if( !player || player->GetGroupInvite() )
+ return false;
+ Group* group = player->GetGroup();
+ if( group && group->isBGGroup() )
+ group = player->GetOriginalGroup();
+ if( group )
return false;
RemoveInvite(player);
@@ -290,6 +301,10 @@ bool Group::AddMember(const uint64 &guid, const char* name)
}
player->SetGroupUpdateFlag(GROUP_UPDATE_FULL);
UpdatePlayerOutOfRange(player);
+
+ // quest related GO state dependent from raid memebership
+ if(isRaidGroup())
+ player->UpdateForQuestsGO();
}
return true;
@@ -306,6 +321,10 @@ uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method)
if(Player *player = objmgr.GetPlayer( guid ))
{
+ // quest related GO state dependent from raid membership
+ if(isRaidGroup())
+ player->UpdateForQuestsGO();
+
WorldPacket data;
if(method == 1)
@@ -314,9 +333,17 @@ uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method)
player->GetSession()->SendPacket( &data );
}
- data.Initialize(SMSG_GROUP_LIST, 24);
- data << uint64(0) << uint64(0) << uint64(0);
- player->GetSession()->SendPacket(&data);
+ //we already removed player from group and in player->GetGroup() is his original group!
+ if( Group* group = player->GetGroup() )
+ {
+ group->SendUpdate();
+ }
+ else
+ {
+ data.Initialize(SMSG_GROUP_LIST, 24);
+ data << uint64(0) << uint64(0) << uint64(0);
+ player->GetSession()->SendPacket(&data);
+ }
_homebindIfInstance(player);
}
@@ -325,7 +352,7 @@ uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method)
{
WorldPacket data(SMSG_GROUP_SET_LEADER, (m_memberSlots.front().name.size()+1));
data << m_memberSlots.front().name;
- BroadcastPacket(&data);
+ BroadcastPacket(&data, true);
}
SendUpdate();
@@ -348,7 +375,7 @@ void Group::ChangeLeader(const uint64 &guid)
WorldPacket data(SMSG_GROUP_SET_LEADER, slot->name.size()+1);
data << slot->name;
- BroadcastPacket(&data);
+ BroadcastPacket(&data, true);
SendUpdate();
}
@@ -362,7 +389,22 @@ void Group::Disband(bool hideDestroy)
if(!player)
continue;
- player->SetGroup(NULL);
+ //we cannot call _removeMember because it would invalidate member iterator
+ //if we are removing player from battleground raid
+ if( isBGGroup() )
+ player->RemoveFromBattleGroundRaid();
+ else
+ {
+ //we can remove player who is in battleground from his original group
+ if( player->GetOriginalGroup() == this )
+ player->SetOriginalGroup(NULL);
+ else
+ player->SetGroup(NULL);
+ }
+
+ // quest related GO state dependent from raid membership
+ if(isRaidGroup())
+ player->UpdateForQuestsGO();
if(!player->GetSession())
continue;
@@ -374,9 +416,17 @@ void Group::Disband(bool hideDestroy)
player->GetSession()->SendPacket(&data);
}
- data.Initialize(SMSG_GROUP_LIST, 24);
- data << uint64(0) << uint64(0) << uint64(0);
- player->GetSession()->SendPacket(&data);
+ //we already removed player from group and in player->GetGroup() is his original group, send update
+ if( Group* group = player->GetGroup() )
+ {
+ group->SendUpdate();
+ }
+ else
+ {
+ data.Initialize(SMSG_GROUP_LIST, 24);
+ data << uint64(0) << uint64(0) << uint64(0);
+ player->GetSession()->SendPacket(&data);
+ }
_homebindIfInstance(player);
}
@@ -730,6 +780,8 @@ void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers)
if(player && player->GetSession())
{
+ player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT, roll->itemid, maxresul);
+
ItemPosCountVec dest;
LootItem *item = &(roll->getLoot()->items[roll->itemSlot]);
uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count );
@@ -775,6 +827,8 @@ void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers)
if(player && player->GetSession())
{
+ player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT, roll->itemid, maxresul);
+
ItemPosCountVec dest;
LootItem *item = &(roll->getLoot()->items[roll->itemSlot]);
uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count );
@@ -810,7 +864,7 @@ void Group::SetTargetIcon(uint8 id, uint64 guid)
// clean other icons
if( guid != 0 )
- for(int i=0; i<TARGETICONCOUNT; i++)
+ for(int i=0; i<TARGETICONCOUNT; ++i)
if( m_targetIcons[i] == guid )
SetTargetIcon(i, 0);
@@ -820,7 +874,7 @@ void Group::SetTargetIcon(uint8 id, uint64 guid)
data << (uint8)0;
data << id;
data << guid;
- BroadcastPacket(&data);
+ BroadcastPacket(&data, true);
}
void Group::GetDataForXPAtKill(Unit const* victim, uint32& count,uint32& sum_level, Player* & member_with_max_level, Player* & not_gray_member_with_max_level)
@@ -836,13 +890,10 @@ void Group::GetDataForXPAtKill(Unit const* victim, uint32& count,uint32& sum_lev
++count;
sum_level += member->getLevel();
- // store maximum member level
if(!member_with_max_level || member_with_max_level->getLevel() < member->getLevel())
member_with_max_level = member;
- uint32 gray_level = Trinity::XP::GetGrayLevel(member->getLevel());
- // if the victim is higher level than the gray level of the currently examined group member,
- // then set not_gray_member_with_max_level if needed.
+ uint32 gray_level = MaNGOS::XP::GetGrayLevel(member->getLevel());
if( victim->getLevel() > gray_level && (!not_gray_member_with_max_level
|| not_gray_member_with_max_level->getLevel() < member->getLevel()))
not_gray_member_with_max_level = member;
@@ -857,7 +908,7 @@ void Group::SendTargetIconList(WorldSession *session)
WorldPacket data(MSG_RAID_TARGET_UPDATE, (1+TARGETICONCOUNT*9));
data << (uint8)1;
- for(int i=0; i<TARGETICONCOUNT; i++)
+ for(int i=0; i<TARGETICONCOUNT; ++i)
{
if(m_targetIcons[i] == 0)
continue;
@@ -876,7 +927,7 @@ void Group::SendUpdate()
for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
{
player = objmgr.GetPlayer(citr->guid);
- if(!player || !player->GetSession())
+ if(!player || !player->GetSession() || player->GetGroup() != this )
continue;
// guess size
WorldPacket data(SMSG_GROUP_LIST, (1+1+1+1+8+4+GetMembersCount()*20));
@@ -890,11 +941,14 @@ void Group::SendUpdate()
{
if(citr->guid == citr2->guid)
continue;
+ Player* member = objmgr.GetPlayer(citr2->guid);
+ uint8 onlineState = (member) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE;
+ onlineState = onlineState | ((isBGGroup()) ? MEMBER_STATUS_PVP : 0);
data << citr2->name;
data << (uint64)citr2->guid;
// online-state
- data << (uint8)(objmgr.GetPlayer(citr2->guid) ? 1 : 0);
+ data << (uint8)(onlineState);
data << (uint8)(citr2->group); // groupid
data << (uint8)(citr2->assistant?0x01:0); // 0x2 main assist, 0x4 main tank
}
@@ -906,7 +960,6 @@ void Group::SendUpdate()
data << (uint64)m_looterGuid; // looter guid
data << (uint8)m_lootThreshold; // loot threshold
data << (uint8)m_difficulty; // Heroic Mod Group
-
}
player->GetSession()->SendPacket( &data );
}
@@ -929,12 +982,12 @@ void Group::UpdatePlayerOutOfRange(Player* pPlayer)
}
}
-void Group::BroadcastPacket(WorldPacket *packet, int group, uint64 ignore)
+void Group::BroadcastPacket(WorldPacket *packet, bool ignorePlayersInBGRaid, int group, uint64 ignore)
{
for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
Player *pl = itr->getSource();
- if(!pl || (ignore != 0 && pl->GetGUID() == ignore))
+ if(!pl || (ignore != 0 && pl->GetGUID() == ignore) || (ignorePlayersInBGRaid && pl->GetGroup() != this) )
continue;
if (pl->GetSession() && (group==-1 || itr->getSubGroup()==group))
@@ -985,7 +1038,7 @@ bool Group::_addMember(const uint64 &guid, const char* name, bool isAssistant)
}
// We are raid group and no one slot is free
if (!groupFound)
- return false;
+ return false;
}
return _addMember(guid, name, isAssistant, groupid);
@@ -1013,7 +1066,15 @@ bool Group::_addMember(const uint64 &guid, const char* name, bool isAssistant, u
if(player)
{
player->SetGroupInvite(NULL);
- player->SetGroup(this, group);
+ //if player is in group and he is being added to BG raid group, then call SetBattleGroundRaid()
+ if( player->GetGroup() && isBGGroup() )
+ player->SetBattleGroundRaid(this, group);
+ //if player is in bg raid and we are adding him to normal group, then call SetOriginalGroup()
+ else if ( player->GetGroup() )
+ player->SetOriginalGroup(this, group);
+ //if player is not in group, then call set group
+ else
+ player->SetGroup(this, group);
// if the same group invites the player back, cancel the homebind timer
InstanceGroupBind *bind = GetBoundInstance(player->GetMapId(), player->GetDifficulty());
if(bind && bind->save->GetInstanceId() == player->GetInstanceId())
@@ -1022,7 +1083,7 @@ bool Group::_addMember(const uint64 &guid, const char* name, bool isAssistant, u
if(!isRaidGroup()) // reset targetIcons for non-raid-groups
{
- for(int i=0; i<TARGETICONCOUNT; i++)
+ for(int i=0; i<TARGETICONCOUNT; ++i)
m_targetIcons[i] = 0;
}
@@ -1040,7 +1101,17 @@ bool Group::_removeMember(const uint64 &guid)
Player *player = objmgr.GetPlayer(guid);
if (player)
{
- player->SetGroup(NULL);
+ //if we are removing player from battleground raid
+ if( isBGGroup() )
+ player->RemoveFromBattleGroundRaid();
+ else
+ {
+ //we can remove player who is in battleground from his original group
+ if( player->GetOriginalGroup() == this )
+ player->SetOriginalGroup(NULL);
+ else
+ player->SetGroup(NULL);
+ }
}
_removeRolls(guid);
@@ -1091,7 +1162,7 @@ void Group::_setLeader(const uint64 &guid)
Player *player = objmgr.GetPlayer(slot->guid);
if(player)
{
- for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
+ for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i)
{
for(BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end();)
{
@@ -1232,12 +1303,17 @@ void Group::ChangeMembersGroup(Player *player, const uint8 &group)
return;
if(_setMembersGroup(player->GetGUID(), group))
{
- uint8 prevSubGroup;
- prevSubGroup = player->GetSubGroup();
-
+ uint8 prevSubGroup = player->GetSubGroup();
+ if( player->GetGroup() == this )
+ player->GetGroupRef().setSubGroup(group);
+ //if player is in BG raid, it is possible that he is also in normal raid - and that normal raid is stored in m_originalGroup reference
+ else
+ {
+ prevSubGroup = player->GetOriginalSubGroup();
+ player->GetOriginalGroupRef().setSubGroup(group);
+ }
SubGroupCounterDecrease(prevSubGroup);
- player->GetGroupRef().setSubGroup(group);
SendUpdate();
}
}
@@ -1315,7 +1391,7 @@ void Group::UpdateLooterGuid( Creature* creature, bool ifneed )
SendUpdate();
}
-uint32 Group::CanJoinBattleGroundQueue(uint32 bgTypeId, uint32 bgQueueType, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot)
+uint32 Group::CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, BattleGroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot)
{
// check for min / max count
uint32 memberscount = GetMembersCount();
@@ -1330,7 +1406,7 @@ uint32 Group::CanJoinBattleGroundQueue(uint32 bgTypeId, uint32 bgQueueType, uint
if(!reference)
return BG_JOIN_ERR_OFFLINE_MEMBER;
- uint32 bgQueueId = reference->GetBattleGroundQueueIdFromLevel();
+ BGQueueIdBasedOnLevel queue_id = reference->GetBattleGroundQueueIdFromLevel(bgTypeId);
uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot);
uint32 team = reference->GetTeam();
@@ -1345,13 +1421,13 @@ uint32 Group::CanJoinBattleGroundQueue(uint32 bgTypeId, uint32 bgQueueType, uint
if(member->GetTeam() != team)
return BG_JOIN_ERR_MIXED_FACTION;
// not in the same battleground level braket, don't let join
- if(member->GetBattleGroundQueueIdFromLevel() != bgQueueId)
+ if(member->GetBattleGroundQueueIdFromLevel(bgTypeId) != queue_id)
return BG_JOIN_ERR_MIXED_LEVELS;
// don't let join rated matches if the arena team id doesn't match
if(isRated && member->GetArenaTeamId(arenaSlot) != arenaTeamId)
return BG_JOIN_ERR_MIXED_ARENATEAM;
// don't let join if someone from the group is already in that bg queue
- if(member->InBattleGroundQueueForBattleGroundQueueType(bgQueueType))
+ if(member->InBattleGroundQueueForBattleGroundQueueType(bgQueueTypeId))
return BG_JOIN_ERR_GROUP_MEMBER_ALREADY_IN_QUEUE;
// check for deserter debuff in case not arena queue
if(bgTypeId != BATTLEGROUND_AA && !member->CanJoinToBattleground())
@@ -1480,7 +1556,7 @@ InstanceGroupBind* Group::BindToInstance(InstanceSave *save, bool permanent, boo
InstanceGroupBind& bind = m_boundInstances[save->GetDifficulty()][save->GetMapId()];
if(bind.save)
{
- // when a boss is killed or when copying the player's binds to the group
+ // when a boss is killed or when copying the players's binds to the group
if(permanent != bind.perm || save != bind.save)
if(!load) CharacterDatabase.PExecute("UPDATE group_instance SET instance = '%u', permanent = '%u' WHERE leaderGuid = '%u' AND instance = '%u'", save->GetInstanceId(), permanent, GUID_LOPART(GetLeaderGUID()), bind.save->GetInstanceId());
}
diff --git a/src/game/Group.h b/src/game/Group.h
index 76543dd4873..d09ef616897 100644
--- a/src/game/Group.h
+++ b/src/game/Group.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -23,6 +23,7 @@
#include "GroupReference.h"
#include "GroupRefManager.h"
+#include "BattleGround.h"
#include "LootMgr.h"
#include <map>
@@ -66,24 +67,25 @@ enum GroupUpdateFlags
{
GROUP_UPDATE_FLAG_NONE = 0x00000000, // nothing
GROUP_UPDATE_FLAG_STATUS = 0x00000001, // uint16, flags
- GROUP_UPDATE_FLAG_CUR_HP = 0x00000002, // uint16
- GROUP_UPDATE_FLAG_MAX_HP = 0x00000004, // uint16
+ GROUP_UPDATE_FLAG_CUR_HP = 0x00000002, // uint32
+ GROUP_UPDATE_FLAG_MAX_HP = 0x00000004, // uint32
GROUP_UPDATE_FLAG_POWER_TYPE = 0x00000008, // uint8
GROUP_UPDATE_FLAG_CUR_POWER = 0x00000010, // uint16
GROUP_UPDATE_FLAG_MAX_POWER = 0x00000020, // uint16
GROUP_UPDATE_FLAG_LEVEL = 0x00000040, // uint16
GROUP_UPDATE_FLAG_ZONE = 0x00000080, // uint16
GROUP_UPDATE_FLAG_POSITION = 0x00000100, // uint16, uint16
- GROUP_UPDATE_FLAG_AURAS = 0x00000200, // uint64 mask, for each bit set uint16 spellid + uint8 unk
+ GROUP_UPDATE_FLAG_AURAS = 0x00000200, // uint64 mask, for each bit set uint32 spellid + uint8 unk
GROUP_UPDATE_FLAG_PET_GUID = 0x00000400, // uint64 pet guid
GROUP_UPDATE_FLAG_PET_NAME = 0x00000800, // pet name, NULL terminated string
GROUP_UPDATE_FLAG_PET_MODEL_ID = 0x00001000, // uint16, model id
- GROUP_UPDATE_FLAG_PET_CUR_HP = 0x00002000, // uint16 pet cur health
- GROUP_UPDATE_FLAG_PET_MAX_HP = 0x00004000, // uint16 pet max health
+ GROUP_UPDATE_FLAG_PET_CUR_HP = 0x00002000, // uint32 pet cur health
+ GROUP_UPDATE_FLAG_PET_MAX_HP = 0x00004000, // uint32 pet max health
GROUP_UPDATE_FLAG_PET_POWER_TYPE = 0x00008000, // uint8 pet power type
GROUP_UPDATE_FLAG_PET_CUR_POWER = 0x00010000, // uint16 pet cur power
GROUP_UPDATE_FLAG_PET_MAX_POWER = 0x00020000, // uint16 pet max power
- GROUP_UPDATE_FLAG_PET_AURAS = 0x00040000, // uint64 mask, for each bit set uint16 spellid + uint8 unk, pet auras...
+ GROUP_UPDATE_FLAG_PET_AURAS = 0x00040000, // uint64 mask, for each bit set uint32 spellid + uint8 unk, pet auras...
+ GROUP_UPDATE_FLAG_VEHICLE_SEAT = 0x00080000, // uint32 vehicle_seat_id (index from VehicleSeat.dbc)
GROUP_UPDATE_PET = 0x0007FC00, // all pet flags
GROUP_UPDATE_FULL = 0x0007FFFF, // all known flags
};
@@ -249,7 +251,7 @@ class TRINITY_DLL_SPEC Group
void ConvertToRaid();
void SetBattlegroundGroup(BattleGround *bg) { m_bgGroup = bg; }
- uint32 CanJoinBattleGroundQueue(uint32 bgTypeId, uint32 bgQueueType, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot);
+ uint32 CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, BattleGroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot);
void ChangeMembersGroup(const uint64 &guid, const uint8 &group);
void ChangeMembersGroup(Player *player, const uint8 &group);
@@ -291,7 +293,7 @@ class TRINITY_DLL_SPEC Group
void SendUpdate();
void UpdatePlayerOutOfRange(Player* pPlayer);
// ignore: GUID of player that will be ignored
- void BroadcastPacket(WorldPacket *packet, int group=-1, uint64 ignore=0);
+ void BroadcastPacket(WorldPacket *packet, bool ignorePlayersInBGRaid, int group=-1, uint64 ignore=0);
void BroadcastReadyCheck(WorldPacket *packet);
void OfflineReadyCheck();
diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp
index f63505ae24a..b0094989e19 100644
--- a/src/game/GroupHandler.cpp
+++ b/src/game/GroupHandler.cpp
@@ -28,10 +28,11 @@
#include "ObjectMgr.h"
#include "Player.h"
#include "Group.h"
-#include "ObjectAccessor.h"
-#include "MapManager.h"
#include "SocialMgr.h"
#include "Util.h"
+#include "SpellAuras.h"
+
+class Aura;
/* differeces from off:
-you can uninvite yourself - is is useful
@@ -59,12 +60,6 @@ void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data )
std::string membername;
recv_data >> membername;
- if(_player->InBattleGround())
- {
- SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_INVITE_RESTRICTED);
- return;
- }
-
// attempt add selected player
// cheating
@@ -107,15 +102,20 @@ void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data )
return;
}
+ Group *group = GetPlayer()->GetGroup();
+ if( group && group->isBGGroup() )
+ group = GetPlayer()->GetOriginalGroup();
+
+ Group *group2 = player->GetGroup();
+ if( group2 && group2->isBGGroup() )
+ group2 = player->GetOriginalGroup();
// player already in another group or invited
- if(player->GetGroup() || player->GetGroupInvite() )
+ if( group2 || player->GetGroupInvite() )
{
SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_ALREADY_IN_GROUP);
return;
}
- Group *group = GetPlayer()->GetGroup();
-
if(group)
{
// not have permissions for invite
@@ -161,6 +161,7 @@ void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data )
// ok, we do it
WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size
+ data << uint8(1); // ok
data << GetPlayer()->GetName();
player->GetSession()->SendPacket(&data);
@@ -193,12 +194,6 @@ void WorldSession::HandleGroupAcceptOpcode( WorldPacket & /*recv_data*/ )
Player* leader = objmgr.GetPlayer(group->GetLeaderGUID());
- if(leader && leader->InBattleGround())
- {
- SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED);
- return;
- }
-
// forming a new group, create it
if(!group->IsCreated())
{
@@ -208,14 +203,10 @@ void WorldSession::HandleGroupAcceptOpcode( WorldPacket & /*recv_data*/ )
objmgr.AddGroup(group);
}
- // everything's fine, do it
+ // everything's fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
if(!group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName()))
return;
- uint8 subgroup = group->GetMemberGroup(GetPlayer()->GetGUID());
-
- GetPlayer()->SetGroup(group, subgroup);
-
group->BroadcastGroupUpdate();
}
@@ -224,26 +215,16 @@ void WorldSession::HandleGroupDeclineOpcode( WorldPacket & /*recv_data*/ )
Group *group = GetPlayer()->GetGroupInvite();
if (!group) return;
+ // remember leader if online
Player *leader = objmgr.GetPlayer(group->GetLeaderGUID());
- /** error handling **/
+ // uninvite, group can be deleted
+ GetPlayer()->UninviteFromGroup();
+
if(!leader || !leader->GetSession())
return;
- /********************/
-
- // everything's fine, do it
- if(!group->IsCreated())
- {
- // note: this means that if you invite more than one person
- // and one of them declines before the first one accepts
- // all invites will be cleared
- // fixme: is that ok ?
- group->RemoveAllInvites();
- delete group;
- }
-
- GetPlayer()->SetGroupInvite(NULL);
+ // report
WorldPacket data( SMSG_GROUP_DECLINE, 10 ); // guess size
data << GetPlayer()->GetName();
leader->GetSession()->SendPacket( &data );
@@ -445,7 +426,7 @@ void WorldSession::HandleMinimapPingOpcode(WorldPacket& recv_data)
data << GetPlayer()->GetGUID();
data << x;
data << y;
- GetPlayer()->GetGroup()->BroadcastPacket(&data, -1, GetPlayer()->GetGUID());
+ GetPlayer()->GetGroup()->BroadcastPacket(&data, true, -1, GetPlayer()->GetGUID());
}
void WorldSession::HandleRandomRollOpcode(WorldPacket& recv_data)
@@ -472,7 +453,7 @@ void WorldSession::HandleRandomRollOpcode(WorldPacket& recv_data)
data << roll;
data << GetPlayer()->GetGUID();
if(GetPlayer()->GetGroup())
- GetPlayer()->GetGroup()->BroadcastPacket(&data);
+ GetPlayer()->GetGroup()->BroadcastPacket(&data, false);
else
SendPacket(&data);
}
@@ -555,8 +536,20 @@ void WorldSession::HandleGroupChangeSubGroupOpcode( WorldPacket & recv_data )
return;
/********************/
+ Player *movedPlayer=objmgr.GetPlayer(name.c_str());
+ if(!movedPlayer)
+ return;
+
+ //Do not allow leader to change group of player in combat
+ if (movedPlayer->isInCombat())
+ {
+ WorldPacket data(SMSG_GROUP_SWAP_FAILED, (0));
+ SendPacket(&data);
+ return;
+ }
+
// everything's fine, do it
- group->ChangeMembersGroup(objmgr.GetPlayer(name.c_str()), groupNr);
+ group->ChangeMembersGroup(movedPlayer, groupNr);
}
void WorldSession::HandleGroupAssistantOpcode( WorldPacket & recv_data )
@@ -626,7 +619,7 @@ void WorldSession::HandleRaidReadyCheckOpcode( WorldPacket & recv_data )
// everything's fine, do it
WorldPacket data(MSG_RAID_READY_CHECK, 8);
data << GetPlayer()->GetGUID();
- group->BroadcastPacket(&data, -1);
+ group->BroadcastPacket(&data, false, -1);
group->OfflineReadyCheck();
}
@@ -691,10 +684,10 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
}
if (mask & GROUP_UPDATE_FLAG_CUR_HP)
- *data << (uint16) player->GetHealth();
+ *data << (uint32) player->GetHealth();
if (mask & GROUP_UPDATE_FLAG_MAX_HP)
- *data << (uint16) player->GetMaxHealth();
+ *data << (uint32) player->GetMaxHealth();
Powers powerType = player->getPowerType();
if (mask & GROUP_UPDATE_FLAG_POWER_TYPE)
@@ -717,14 +710,14 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
if (mask & GROUP_UPDATE_FLAG_AURAS)
{
- uint64 auramask = player->GetAuraUpdateMask();
+ const uint64& auramask = player->GetAuraUpdateMaskForRaid();
*data << uint64(auramask);
for(uint32 i = 0; i < MAX_AURAS; ++i)
{
if(auramask & (uint64(1) << i))
{
- uint32 updatedAura=player->GetUInt32Value(uint16(UNIT_FIELD_AURA + i));
- *data << uint16(updatedAura);
+ Aura * pAura = player->GetVisibleAura(i);
+ *data << uint32(pAura ? pAura->GetId() : 0);
*data << uint8(1);
}
}
@@ -758,17 +751,17 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP)
{
if(pet)
- *data << (uint16) pet->GetHealth();
+ *data << (uint32) pet->GetHealth();
else
- *data << (uint16) 0;
+ *data << (uint32) 0;
}
if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP)
{
if(pet)
- *data << (uint16) pet->GetMaxHealth();
+ *data << (uint32) pet->GetMaxHealth();
else
- *data << (uint16) 0;
+ *data << (uint32) 0;
}
if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE)
@@ -799,14 +792,14 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
{
if(pet)
{
- uint64 auramask = pet->GetAuraUpdateMask();
+ const uint64& auramask = pet->GetAuraUpdateMaskForRaid();
*data << uint64(auramask);
for(uint32 i = 0; i < MAX_AURAS; ++i)
{
if(auramask & (uint64(1) << i))
{
- uint32 updatedAura=pet->GetUInt32Value(uint16(UNIT_FIELD_AURA + i));
- *data << uint16(updatedAura);
+ Aura * pAura = pet->GetVisibleAura(i);
+ *data << uint32(pAura ? pAura->GetId() : 0);
*data << uint8(1);
}
}
@@ -829,6 +822,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
if(!player)
{
WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
+ data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
data.appendPackGUID(Guid);
data << (uint32) GROUP_UPDATE_FLAG_STATUS;
data << (uint16) MEMBER_STATUS_OFFLINE;
@@ -839,6 +833,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
Pet *pet = player->GetPet();
WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
+ data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
data.append(player->GetPackGUID());
uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF
@@ -848,8 +843,8 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
Powers powerType = player->getPowerType();
data << (uint32) mask1; // group update mask
data << (uint16) MEMBER_STATUS_ONLINE; // member's online status
- data << (uint16) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP
- data << (uint16) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP
+ data << (uint32) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP
+ data << (uint32) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP
data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE
data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER
data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER
@@ -863,11 +858,11 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
data << (uint64) auramask; // placeholder
for(uint8 i = 0; i < MAX_AURAS; ++i)
{
- if(uint32 aura = player->GetUInt32Value(UNIT_FIELD_AURA + i))
+ if(Aura * pAura = player->GetVisibleAura(i))
{
auramask |= (uint64(1) << i);
- data << uint16(aura);
- data << uint8(1);
+ data << (uint32) pAura->GetId();
+ data << (uint8) 1;
}
}
data.put<uint64>(maskPos,auramask); // GROUP_UPDATE_FLAG_AURAS
@@ -878,8 +873,8 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID
data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME
data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID
- data << (uint16) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP
- data << (uint16) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP
+ data << (uint32) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP
+ data << (uint32) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP
data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE
data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER
data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER
@@ -889,10 +884,10 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
data << (uint64) petauramask; // placeholder
for(uint8 i = 0; i < MAX_AURAS; ++i)
{
- if(uint32 petaura = pet->GetUInt32Value(UNIT_FIELD_AURA + i))
+ if(Aura * pAura = pet->GetVisibleAura(i))
{
petauramask |= (uint64(1) << i);
- data << (uint16) petaura;
+ data << (uint32) pAura->GetId();
data << (uint8) 1;
}
}
diff --git a/src/game/GroupRefManager.h b/src/game/GroupRefManager.h
index 94741c30279..ab3b6417611 100644
--- a/src/game/GroupRefManager.h
+++ b/src/game/GroupRefManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/GroupReference.cpp b/src/game/GroupReference.cpp
index 24646e3059a..a09fc769dad 100644
--- a/src/game/GroupReference.cpp
+++ b/src/game/GroupReference.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/GroupReference.h b/src/game/GroupReference.h
index 0b338991109..da896cf02dd 100644
--- a/src/game/GroupReference.h
+++ b/src/game/GroupReference.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/GuardAI.cpp b/src/game/GuardAI.cpp
index 07a5bd9f819..b716642ebd7 100644
--- a/src/game/GuardAI.cpp
+++ b/src/game/GuardAI.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -33,107 +33,107 @@ int GuardAI::Permissible(const Creature *creature)
return PERMIT_BASE_NO;
}
-GuardAI::GuardAI(Creature *c) : CreatureAI(c), i_creature(*c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
+GuardAI::GuardAI(Creature *c) : CreatureAI(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
{
}
void GuardAI::MoveInLineOfSight(Unit *u)
{
// Ignore Z for flying creatures
- if ( !i_creature.canFly() && i_creature.GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
+ if ( !m_creature->canFly() && m_creature->GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
return;
- if( !i_creature.getVictim() && i_creature.canAttack(u) &&
- ( u->IsHostileToPlayers() || i_creature.IsHostileTo(u) /*|| u->getVictim() && i_creature.IsFriendlyTo(u->getVictim())*/ ) &&
- u->isInAccessiblePlaceFor(&i_creature))
+ if( !m_creature->getVictim() && m_creature->canAttack(u) &&
+ ( u->IsHostileToPlayers() || m_creature->IsHostileTo(u) /*|| u->getVictim() && m_creature->IsFriendlyTo(u->getVictim())*/ ) &&
+ u->isInAccessiblePlaceFor(m_creature))
{
- float attackRadius = i_creature.GetAttackDistance(u);
- if(i_creature.IsWithinDistInMap(u,attackRadius))
+ float attackRadius = m_creature->GetAttackDistance(u);
+ if(m_creature->IsWithinDistInMap(u,attackRadius))
{
//Need add code to let guard support player
AttackStart(u);
- //u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+ //u->RemoveAurasByType(SPELL_AURA_MOD_STEALTH);
}
}
}
void GuardAI::EnterEvadeMode()
{
- if( !i_creature.isAlive() )
+ if( !m_creature->isAlive() )
{
- DEBUG_LOG("Creature stopped attacking because he's dead [guid=%u]", i_creature.GetGUIDLow());
- i_creature.GetMotionMaster()->MoveIdle();
+ DEBUG_LOG("Creature stopped attacking because he's dead [guid=%u]", m_creature->GetGUIDLow());
+ m_creature->GetMotionMaster()->MoveIdle();
i_state = STATE_NORMAL;
i_victimGuid = 0;
- i_creature.CombatStop();
- i_creature.DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->DeleteThreatList();
return;
}
- Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid );
+ Unit* victim = ObjectAccessor::GetUnit(*m_creature, i_victimGuid );
if( !victim )
{
- DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", m_creature->GetGUIDLow());
}
else if( !victim ->isAlive() )
{
- DEBUG_LOG("Creature stopped attacking because victim is dead [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking because victim is dead [guid=%u]", m_creature->GetGUIDLow());
}
else if( victim ->HasStealthAura() )
{
- DEBUG_LOG("Creature stopped attacking because victim is using stealth [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking because victim is using stealth [guid=%u]", m_creature->GetGUIDLow());
}
else if( victim ->isInFlight() )
{
- DEBUG_LOG("Creature stopped attacking because victim is flying away [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking because victim is flying away [guid=%u]", m_creature->GetGUIDLow());
}
else
{
- DEBUG_LOG("Creature stopped attacking because victim outran him [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking because victim outran him [guid=%u]", m_creature->GetGUIDLow());
}
- i_creature.RemoveAllAuras();
- i_creature.DeleteThreatList();
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
i_victimGuid = 0;
- i_creature.CombatStop();
+ m_creature->CombatStop(true);
i_state = STATE_NORMAL;
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
- if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
- i_creature.GetMotionMaster()->MoveTargetedHome();
+ if( m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
+ m_creature->GetMotionMaster()->MoveTargetedHome();
}
void GuardAI::UpdateAI(const uint32 /*diff*/)
{
- // update i_victimGuid if i_creature.getVictim() !=0 and changed
+ // update i_victimGuid if m_creature->getVictim() !=0 and changed
if(!UpdateVictim())
return;
- i_victimGuid = i_creature.getVictim()->GetGUID();
+ i_victimGuid = m_creature->getVictim()->GetGUID();
- if( i_creature.isAttackReady() )
+ if( m_creature->isAttackReady() )
{
- if( i_creature.IsWithinMeleeRange(i_creature.getVictim()))
+ if( m_creature->IsWithinMeleeRange(m_creature->getVictim()))
{
- i_creature.AttackerStateUpdate(i_creature.getVictim());
- i_creature.resetAttackTimer();
+ m_creature->AttackerStateUpdate(m_creature->getVictim());
+ m_creature->resetAttackTimer();
}
}
}
bool GuardAI::IsVisible(Unit *pl) const
{
- return i_creature.GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_GUARDER)
- && pl->isVisibleForOrDetect(&i_creature,true);
+ return m_creature->GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_GUARDER)
+ && pl->isVisibleForOrDetect(m_creature,true);
}
void GuardAI::JustDied(Unit *killer)
{
if(Player* pkiller = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
- i_creature.SendZoneUnderAttackMessage(pkiller);
+ m_creature->SendZoneUnderAttackMessage(pkiller);
}
diff --git a/src/game/GuardAI.h b/src/game/GuardAI.h
index b7b3c79607b..db1bfe0229d 100644
--- a/src/game/GuardAI.h
+++ b/src/game/GuardAI.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -36,7 +36,7 @@ class TRINITY_DLL_DECL GuardAI : public CreatureAI
public:
- GuardAI(Creature *c);
+ explicit GuardAI(Creature *c);
void MoveInLineOfSight(Unit *);
void EnterEvadeMode();
@@ -47,7 +47,6 @@ class TRINITY_DLL_DECL GuardAI : public CreatureAI
static int Permissible(const Creature *);
private:
- Creature &i_creature;
uint64 i_victimGuid;
GuardState i_state;
TimeTracker i_tracker;
diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp
index 87dbb81c5c6..fdc39d5d851 100644
--- a/src/game/Guild.cpp
+++ b/src/game/Guild.cpp
@@ -21,7 +21,6 @@
#include "Database/DatabaseEnv.h"
#include "WorldPacket.h"
#include "WorldSession.h"
-#include "MapManager.h"
#include "Player.h"
#include "Opcodes.h"
#include "ObjectMgr.h"
@@ -29,6 +28,7 @@
#include "Chat.h"
#include "SocialMgr.h"
#include "Util.h"
+#include "Language.h"
Guild::Guild()
{
@@ -52,27 +52,25 @@ Guild::~Guild()
}
-bool Guild::create(uint64 lGuid, std::string gname)
+bool Guild::create(Player* leader, std::string gname)
{
- std::string rname;
- std::string lName;
-
- if(!objmgr.GetPlayerNameByGUID(lGuid, lName))
- return false;
if(objmgr.GetGuildByName(gname))
return false;
- sLog.outDebug("GUILD: creating guild %s to leader: %u", gname.c_str(), GUID_LOPART(lGuid));
+ WorldSession* lSession = leader->GetSession();
+ if(!lSession)
+ return false;
- leaderGuid = lGuid;
+ leaderGuid = leader->GetGUID();
name = gname;
GINFO = "";
MOTD = "No message set.";
guildbank_money = 0;
purchased_tabs = 0;
-
Id = objmgr.GenerateGuildId();
+ sLog.outDebug("GUILD: creating guild %s to leader: %u", gname.c_str(), GUID_LOPART(leaderGuid));
+
// gname already assigned to Guild::name, use it to encode string for DB
CharacterDatabase.escape_string(gname);
@@ -90,18 +88,13 @@ bool Guild::create(uint64 lGuid, std::string gname)
Id, gname.c_str(), GUID_LOPART(leaderGuid), dbGINFO.c_str(), dbMOTD.c_str(), EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor, guildbank_money);
CharacterDatabase.CommitTransaction();
- rname = "Guild Master";
- CreateRank(rname,GR_RIGHT_ALL);
- rname = "Officer";
- CreateRank(rname,GR_RIGHT_ALL);
- rname = "Veteran";
- CreateRank(rname,GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
- rname = "Member";
- CreateRank(rname,GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
- rname = "Initiate";
- CreateRank(rname,GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
+ CreateRank(lSession->GetMangosString(LANG_GUILD_MASTER), GR_RIGHT_ALL);
+ CreateRank(lSession->GetMangosString(LANG_GUILD_OFFICER), GR_RIGHT_ALL);
+ CreateRank(lSession->GetMangosString(LANG_GUILD_VETERAN), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
+ CreateRank(lSession->GetMangosString(LANG_GUILD_MEMBER), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
+ CreateRank(lSession->GetMangosString(LANG_GUILD_INITIATE),GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
- return AddMember(lGuid, (uint32)GR_GUILDMASTER);
+ return AddMember(leaderGuid, (uint32)GR_GUILDMASTER);
}
bool Guild::AddMember(uint64 plGuid, uint32 plRank)
@@ -569,7 +562,7 @@ void Guild::BroadcastToOfficers(WorldSession *session, const std::string& msg, u
{
if (session && session->GetPlayer() && HasRankRight(session->GetPlayer()->GetRank(),GR_RIGHT_OFFCHATSPEAK))
{
- for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
+ for(MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
{
WorldPacket data;
ChatHandler::FillMessageData(&data, session, CHAT_MSG_OFFICER, language, NULL, 0, msg.c_str(),NULL);
@@ -584,7 +577,7 @@ void Guild::BroadcastToOfficers(WorldSession *session, const std::string& msg, u
void Guild::BroadcastPacket(WorldPacket *packet)
{
- for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
+ for(MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
{
Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));
if(player)
@@ -594,7 +587,7 @@ void Guild::BroadcastPacket(WorldPacket *packet)
void Guild::BroadcastPacketToRank(WorldPacket *packet, uint32 rankId)
{
- for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
+ for(MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
{
if (itr->second.RankId == rankId)
{
@@ -621,7 +614,7 @@ void Guild::CreateRank(std::string name_,uint32 rights)
// name now can be used for encoding to DB
CharacterDatabase.escape_string(name_);
- CharacterDatabase.PExecute( "INSERT INTO guild_rank (guildid,rid,rname,rights) VALUES ('%u', '%u', '%s', '%u')", Id, m_ranks.size(), name_.c_str(), rights );
+ CharacterDatabase.PExecute( "INSERT INTO guild_rank (guildid,rid,rname,rights) VALUES ('%u', '%u', '%s', '%u')", Id, (unsigned int)m_ranks.size(), name_.c_str(), rights );
}
void Guild::AddRank(const std::string& name_,uint32 rights, uint32 money)
@@ -681,7 +674,7 @@ void Guild::SetRankRights(uint32 rankId, uint32 rights)
int32 Guild::GetRank(uint32 LowGuid)
{
- MemberList::iterator itr = members.find(LowGuid);
+ MemberList::const_iterator itr = members.find(LowGuid);
if (itr==members.end())
return -1;
@@ -696,7 +689,7 @@ void Guild::Disband()
while (!members.empty())
{
- MemberList::iterator itr = members.begin();
+ MemberList::const_iterator itr = members.begin();
DelMember(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER), true);
}
@@ -785,6 +778,7 @@ void Guild::Query(WorldSession *session)
data << uint32(BorderStyle);
data << uint32(BorderColor);
data << uint32(BackgroundColor);
+ data << uint32(0); // something new in WotLK
session->SendPacket( &data );
sLog.outDebug( "WORLD: Sent (SMSG_GUILD_QUERY_RESPONSE)" );
@@ -1603,7 +1597,21 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId)
{
data << uint8((*itr)->LogEntry);
data << uint64(MAKE_NEW_GUID((*itr)->PlayerGuid,0,HIGHGUID_PLAYER));
- data << uint32((*itr)->ItemOrMoney);
+ if ((*itr)->LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY ||
+ (*itr)->LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY ||
+ (*itr)->LogEntry == GUILD_BANK_LOG_REPAIR_MONEY ||
+ (*itr)->LogEntry == GUILD_BANK_LOG_UNK1 ||
+ (*itr)->LogEntry == GUILD_BANK_LOG_UNK2)
+ {
+ data << uint32((*itr)->ItemOrMoney);
+ }
+ else
+ {
+ data << uint32((*itr)->ItemOrMoney);
+ data << uint32((*itr)->ItemStackCount);
+ if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2)
+ data << uint8((*itr)->DestTabId); // moved tab
+ }
data << uint32(time(NULL)-(*itr)->TimeStamp);
}
session->SendPacket(&data);
@@ -1619,10 +1627,21 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId)
{
data << uint8((*itr)->LogEntry);
data << uint64(MAKE_NEW_GUID((*itr)->PlayerGuid,0,HIGHGUID_PLAYER));
- data << uint32((*itr)->ItemOrMoney);
- data << uint8((*itr)->ItemStackCount);
- if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2)
- data << uint8((*itr)->DestTabId); // moved tab
+ if ((*itr)->LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY ||
+ (*itr)->LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY ||
+ (*itr)->LogEntry == GUILD_BANK_LOG_REPAIR_MONEY ||
+ (*itr)->LogEntry == GUILD_BANK_LOG_UNK1 ||
+ (*itr)->LogEntry == GUILD_BANK_LOG_UNK2)
+ {
+ data << uint32((*itr)->ItemOrMoney);
+ }
+ else
+ {
+ data << uint32((*itr)->ItemOrMoney);
+ data << uint32((*itr)->ItemStackCount);
+ if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2)
+ data << uint8((*itr)->DestTabId); // moved tab
+ }
data << uint32(time(NULL)-(*itr)->TimeStamp);
}
session->SendPacket(&data);
@@ -1704,7 +1723,7 @@ void Guild::AppendDisplayGuildBankSlot( WorldPacket& data, GuildBankTab const *t
// SuffixFactor +4
data << (uint32) pItem->GetItemSuffixFactor();
// +12 // ITEM_FIELD_STACK_COUNT
- data << uint8(pItem->GetCount());
+ data << uint32(pItem->GetCount());
data << uint32(0); // +16 // Unknown value
data << uint8(0); // unknown 2.4.2
if (uint32 Enchant0 = pItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT))
@@ -1961,6 +1980,9 @@ void Guild::SetGuildBankTabText(uint8 TabId, std::string text)
CharacterDatabase.escape_string(text);
CharacterDatabase.PExecute("UPDATE guild_bank_tab SET TabText='%s' WHERE guildid='%u' AND TabId='%u'", text.c_str(), Id, uint32(TabId));
+
+ // announce
+ SendGuildBankTabText(NULL,TabId);
}
void Guild::SendGuildBankTabText(WorldSession *session, uint8 TabId)
@@ -1975,7 +1997,12 @@ void Guild::SendGuildBankTabText(WorldSession *session, uint8 TabId)
WorldPacket data(MSG_QUERY_GUILD_BANK_TEXT, 1+tab->Text.size()+1);
data << uint8(TabId);
data << tab->Text;
- session->SendPacket(&data);
+
+ if(session)
+ session->SendPacket(&data);
+ else
+ BroadcastPacket(&data);
+
}
bool GuildItemPosCount::isContainedIn(GuildItemPosCountVec const &vec) const
diff --git a/src/game/Guild.h b/src/game/Guild.h
index 5dc6c00111d..12dea1feb1f 100644
--- a/src/game/Guild.h
+++ b/src/game/Guild.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -53,10 +53,11 @@ enum GuildRankRights
GR_RIGHT_VIEWOFFNOTE = 0x00004040,
GR_RIGHT_EOFFNOTE = 0x00008040,
GR_RIGHT_MODIFY_GUILD_INFO = 0x00010040,
- GR_RIGHT_REPAIR_FROM_GUILD = 0x00020000, // unused in 2.4.x?, Remove money withdraw capacity
+ GR_RIGHT_WITHDRAW_GOLD_LOCK = 0x00020000, // remove money withdraw capacity
GR_RIGHT_WITHDRAW_REPAIR = 0x00040000, // withdraw for repair
GR_RIGHT_WITHDRAW_GOLD = 0x00080000, // withdraw gold
- GR_RIGHT_ALL = 0x000FF1FF
+ GR_RIGHT_CREATE_GUILD_EVENT = 0x00100000, // wotlk
+ GR_RIGHT_ALL = 0x001DF1FF
};
enum Typecommand
@@ -156,6 +157,8 @@ enum GuildBankLogEntries
GUILD_BANK_LOG_WITHDRAW_MONEY = 5,
GUILD_BANK_LOG_REPAIR_MONEY = 6,
GUILD_BANK_LOG_MOVE_ITEM2 = 7,
+ GUILD_BANK_LOG_UNK1 = 8,
+ GUILD_BANK_LOG_UNK2 = 9,
};
enum GuildEventLogEntryTypes
@@ -217,12 +220,12 @@ struct GuildBankTab
struct GuildItemPosCount
{
- GuildItemPosCount(uint8 _slot, uint8 _count) : slot(_slot), count(_count) {}
+ GuildItemPosCount(uint8 _slot, uint32 _count) : slot(_slot), count(_count) {}
bool isContainedIn(std::vector<GuildItemPosCount> const& vec) const;
uint8 slot;
- uint8 count;
+ uint32 count;
};
typedef std::vector<GuildItemPosCount> GuildItemPosCountVec;
@@ -266,7 +269,7 @@ class Guild
Guild();
~Guild();
- bool create(uint64 lGuid, std::string gname);
+ bool create(Player* leader, std::string gname);
void Disband();
typedef std::map<uint32, MemberSlot> MemberList;
@@ -314,6 +317,15 @@ class Guild
void BroadcastPacketToRank(WorldPacket *packet, uint32 rankId);
void BroadcastPacket(WorldPacket *packet);
+ template<class Do>
+ void BroadcastWorker(Do& _do, Player* except = NULL)
+ {
+ for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
+ if(Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)))
+ if(player != except)
+ _do(player);
+ }
+
void CreateRank(std::string name,uint32 rights);
void DelRank();
std::string GetRankName(uint32 rankId);
diff --git a/src/game/GuildHandler.cpp b/src/game/GuildHandler.cpp
index 77e9af49ed3..ef59a67ceae 100644
--- a/src/game/GuildHandler.cpp
+++ b/src/game/GuildHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -26,7 +26,6 @@
#include "Log.h"
#include "Opcodes.h"
#include "Guild.h"
-#include "MapManager.h"
#include "GossipDef.h"
#include "SocialMgr.h"
@@ -65,7 +64,7 @@ void WorldSession::HandleGuildCreateOpcode(WorldPacket& recvPacket)
return;
Guild *guild = new Guild;
- if(!guild->create(GetPlayer()->GetGUID(),gname))
+ if(!guild->create(GetPlayer(),gname))
{
delete guild;
return;
@@ -375,7 +374,7 @@ void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket)
guild->ChangeRank(plGuid, (slot->RankId+1));
// Put record into guildlog
- guild->LogGuildEvent(GUILD_EVENT_LOG_DEMOTE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), (slot->RankId));
+ guild->LogGuildEvent(GUILD_EVENT_LOG_DEMOTE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), slot->RankId);
WorldPacket data(SMSG_GUILD_EVENT, (2+30)); // guess size
data << (uint8)GE_DEMOTION;
@@ -663,7 +662,7 @@ void WorldSession::HandleGuildRankOpcode(WorldPacket& recvPacket)
guild->SetRankName(rankId, rankname);
if(rankId==GR_GUILDMASTER) // prevent loss leader rights
- rights |= GR_RIGHT_ALL;
+ rights = GR_RIGHT_ALL;
guild->SetRankRights(rankId, rights);
@@ -783,7 +782,7 @@ void WorldSession::HandleGuildSaveEmblemOpcode(WorldPacket& recvPacket)
recvPacket >> vendorGuid;
- Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, vendorGuid,UNIT_NPC_FLAG_TABARDDESIGNER);
+ Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorGuid,UNIT_NPC_FLAG_TABARDDESIGNER);
if (!pCreature)
{
//"That's not an emblem vendor!"
@@ -794,7 +793,7 @@ void WorldSession::HandleGuildSaveEmblemOpcode(WorldPacket& recvPacket)
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
recvPacket >> EmblemStyle;
recvPacket >> EmblemColor;
@@ -906,7 +905,7 @@ void WorldSession::HandleGuildBankQuery( WorldPacket & recv_data )
uint8 unk;
recv_data >> GoGuid >> unk;
- if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
if (uint32 GuildId = GetPlayer()->GetGuildId())
@@ -930,7 +929,7 @@ void WorldSession::HandleGuildBankTabColon( WorldPacket & recv_data )
uint8 TabId,unk1;
recv_data >> GoGuid >> TabId >> unk1;
- if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
@@ -959,7 +958,7 @@ void WorldSession::HandleGuildBankDeposit( WorldPacket & recv_data )
if (!money)
return;
- if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
@@ -1007,7 +1006,7 @@ void WorldSession::HandleGuildBankWithdraw( WorldPacket & recv_data )
if (!money)
return;
- if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
@@ -1109,7 +1108,7 @@ void WorldSession::HandleGuildBankDepositItem( WorldPacket & recv_data )
return;
}
- if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
@@ -1195,7 +1194,7 @@ void WorldSession::HandleGuildBankDepositItem( WorldPacket & recv_data )
else // swap
{
gDest.clear();
- uint8 msg = pGuild->CanStoreItem(BankTabDst,BankTabSlotDst,gDest,pItemSrc->GetCount(),pItemSrc,true);
+ msg = pGuild->CanStoreItem(BankTabDst,BankTabSlotDst,gDest,pItemSrc->GetCount(),pItemSrc,true);
if( msg != EQUIP_ERR_OK )
{
pl->SendEquipError( msg, pItemSrc, NULL );
@@ -1564,7 +1563,7 @@ void WorldSession::HandleGuildBankBuyTab( WorldPacket & recv_data )
recv_data >> GoGuid;
recv_data >> TabId;
- if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
@@ -1621,7 +1620,7 @@ void WorldSession::HandleGuildBankModifyTab( WorldPacket & recv_data )
if(IconIndex.empty())
return;
- if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
diff --git a/src/game/HomeMovementGenerator.cpp b/src/game/HomeMovementGenerator.cpp
index ddf66ad220c..4f0ca2f8cec 100644
--- a/src/game/HomeMovementGenerator.cpp
+++ b/src/game/HomeMovementGenerator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -20,9 +20,8 @@
#include "HomeMovementGenerator.h"
#include "Creature.h"
+#include "CreatureAI.h"
#include "Traveller.h"
-#include "MapManager.h"
-#include "ObjectAccessor.h"
#include "DestinationHolderImp.h"
#include "WorldPacket.h"
@@ -70,11 +69,14 @@ HomeMovementGenerator<Creature>::Update(Creature &owner, const uint32& time_diff
// restore orientation of not moving creature at returning to home
if(owner.GetDefaultMovementType()==IDLE_MOTION_TYPE)
{
+ //sLog.outDebug("Entering HomeMovement::GetDestination(z,y,z)");
owner.SetOrientation(ori);
WorldPacket packet;
owner.BuildHeartBeatMsg(&packet);
owner.SendMessageToSet(&packet, false);
}
+
+ owner.AI()->JustReachedHome();
return false;
}
diff --git a/src/game/HomeMovementGenerator.h b/src/game/HomeMovementGenerator.h
index 12d5f150405..964b5c3e801 100644
--- a/src/game/HomeMovementGenerator.h
+++ b/src/game/HomeMovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -47,6 +47,7 @@ class TRINITY_DLL_SPEC HomeMovementGenerator<Creature>
MovementGeneratorType GetMovementGeneratorType() { return HOME_MOTION_TYPE; }
bool GetDestination(float& x, float& y, float& z) const { i_destinationHolder.GetDestination(x,y,z); return true; }
+
private:
void _setTargetLocation(Creature &);
DestinationHolder< Traveller<Creature> > i_destinationHolder;
diff --git a/src/game/HostilRefManager.cpp b/src/game/HostilRefManager.cpp
index f1cb465520e..4a51d54248d 100644
--- a/src/game/HostilRefManager.cpp
+++ b/src/game/HostilRefManager.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,7 +21,7 @@
#include "HostilRefManager.h"
#include "ThreatManager.h"
#include "Unit.h"
-#include "Database/DBCStructure.h"
+#include "DBCStructure.h"
#include "SpellMgr.h"
HostilRefManager::~HostilRefManager()
diff --git a/src/game/HostilRefManager.h b/src/game/HostilRefManager.h
index e7addd5479b..316509e3908 100644
--- a/src/game/HostilRefManager.h
+++ b/src/game/HostilRefManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/IdleMovementGenerator.cpp b/src/game/IdleMovementGenerator.cpp
index c6598409b44..67f89303e40 100644
--- a/src/game/IdleMovementGenerator.cpp
+++ b/src/game/IdleMovementGenerator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -19,7 +19,7 @@
*/
#include "IdleMovementGenerator.h"
-#include "Creature.h"
+#include "Unit.h"
IdleMovementGenerator si_idleMovement;
diff --git a/src/game/IdleMovementGenerator.h b/src/game/IdleMovementGenerator.h
index ac5a4da529c..7ada9f08f52 100644
--- a/src/game/IdleMovementGenerator.h
+++ b/src/game/IdleMovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/InstanceData.cpp b/src/game/InstanceData.cpp
index 622dc7842e7..785cea8f38c 100644
--- a/src/game/InstanceData.cpp
+++ b/src/game/InstanceData.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -30,12 +30,12 @@ void InstanceData::SaveToDB()
CharacterDatabase.PExecute("UPDATE instance SET data = '%s' WHERE id = '%d'", data.c_str(), instance->GetInstanceId());
}
-void InstanceData::HandleGameObject(uint64 GUID, bool open, GameObject *go)
-{
+void InstanceData::HandleGameObject(uint64 GUID, bool open, GameObject *go)
+{
if(!go)
- go = instance->GetGameObjectInMap(GUID);
+ go = instance->GetGameObject(GUID);
if(go)
- go->SetGoState(open ? 0 : 1);
+ go->SetGoState(open ? GO_STATE_ACTIVE : GO_STATE_READY);
else
debug_log("TSCR: InstanceData: HandleGameObject failed");
}
diff --git a/src/game/InstanceData.h b/src/game/InstanceData.h
index ec36a794525..c33beccfffb 100644
--- a/src/game/InstanceData.h
+++ b/src/game/InstanceData.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -67,6 +67,10 @@ class TRINITY_DLL_SPEC InstanceData
//called on creature creation
virtual void OnCreatureCreate(Creature * /*creature*/, uint32 /*creature_entry*/) {}
+ //All-purpose data storage 64 bit
+ virtual uint64 GetData64(uint32 /*Data*/) { return 0; }
+ virtual void SetData64(uint32 /*Data*/, uint64 /*Value*/) { }
+
//All-purpose data storage 32 bit
virtual uint32 GetData(uint32) { return 0; }
virtual void SetData(uint32, uint32 data) {}
diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp
index ba34f949a5f..9332f4b8f0a 100644
--- a/src/game/InstanceSaveMgr.cpp
+++ b/src/game/InstanceSaveMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -19,13 +19,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "InstanceSaveMgr.h"
#include "Common.h"
#include "Database/SQLStorage.h"
#include "Player.h"
#include "GridNotifiers.h"
-#include "WorldSession.h"
#include "Log.h"
#include "GridStates.h"
#include "CellImpl.h"
@@ -37,7 +35,6 @@
#include "GridNotifiersImpl.h"
#include "Config/ConfigEnv.h"
#include "Transports.h"
-#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "World.h"
#include "Group.h"
@@ -58,16 +55,16 @@ InstanceSaveManager::~InstanceSaveManager()
for (InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end(); ++itr)
{
InstanceSave *save = itr->second;
- for(InstanceSave::PlayerListType::iterator itr = save->m_playerList.begin(), next = itr; itr != save->m_playerList.end(); itr = next)
+ for(InstanceSave::PlayerListType::iterator itr2 = save->m_playerList.begin(), next = itr2; itr2 != save->m_playerList.end(); itr2 = next)
{
++next;
- (*itr)->UnbindInstance(save->GetMapId(), save->GetDifficulty(), true);
+ (*itr2)->UnbindInstance(save->GetMapId(), save->GetDifficulty(), true);
}
save->m_playerList.clear();
- for(InstanceSave::GroupListType::iterator itr = save->m_groupList.begin(), next = itr; itr != save->m_groupList.end(); itr = next)
+ for(InstanceSave::GroupListType::iterator itr2 = save->m_groupList.begin(), next = itr2; itr2 != save->m_groupList.end(); itr2 = next)
{
++next;
- (*itr)->UnbindInstance(save->GetMapId(), save->GetDifficulty(), true);
+ (*itr2)->UnbindInstance(save->GetMapId(), save->GetDifficulty(), true);
}
save->m_groupList.clear();
delete save;
@@ -142,9 +139,8 @@ void InstanceSaveManager::RemoveInstanceSave(uint32 InstanceId)
}
}
-InstanceSave::InstanceSave(uint16 MapId, uint32 InstanceId, uint8 difficulty,
- time_t resetTime, bool canReset)
-: m_mapid(MapId), m_instanceid(InstanceId), m_resetTime(resetTime),
+InstanceSave::InstanceSave(uint16 MapId, uint32 InstanceId, uint8 difficulty, time_t resetTime, bool canReset)
+: m_resetTime(resetTime), m_instanceid(InstanceId), m_mapid(MapId),
m_difficulty(difficulty), m_canReset(canReset)
{
}
@@ -270,7 +266,7 @@ void InstanceSaveManager::CleanupInstances()
// creature_respawn and gameobject_respawn are in another database
// first, obtain total instance set
- std::set< uint32 > InstanceSet;
+ std::set<uint32> InstanceSet;
QueryResult *result = CharacterDatabase.Query("SELECT id FROM instance");
if( result )
{
@@ -322,7 +318,7 @@ void InstanceSaveManager::PackInstances()
// TODO: this can be done a LOT more efficiently
// obtain set of all associations
- std::set< uint32 > InstanceSet;
+ std::set<uint32> InstanceSet;
// all valid ids are in the instance table
// any associations to ids not in this table are assumed to be
@@ -344,7 +340,7 @@ void InstanceSaveManager::PackInstances()
uint32 InstanceNumber = 1;
// we do assume std::set is sorted properly on integer value
- for (std::set< uint32 >::iterator i = InstanceSet.begin(); i != InstanceSet.end(); ++i)
+ for (std::set<uint32>::iterator i = InstanceSet.begin(); i != InstanceSet.end(); ++i)
{
if (*i != InstanceNumber)
{
@@ -361,8 +357,8 @@ void InstanceSaveManager::PackInstances()
bar.step();
}
- sLog.outString();
sLog.outString( ">> Instance numbers remapped, next instance id is %u", InstanceNumber );
+ sLog.outString();
}
void InstanceSaveManager::LoadResetTimes()
@@ -375,14 +371,14 @@ void InstanceSaveManager::LoadResetTimes()
// get the current reset times for normal instances (these may need to be updated)
// these are only kept in memory for InstanceSaves that are loaded later
// resettime = 0 in the DB for raid/heroic instances so those are skipped
- typedef std::map<uint32, std::pair<uint32, uint64> > ResetTimeMapType;
+ typedef std::map<uint32, std::pair<uint32, time_t> > ResetTimeMapType;
ResetTimeMapType InstResetTime;
QueryResult *result = CharacterDatabase.Query("SELECT id, map, resettime FROM instance WHERE resettime > 0");
if( result )
{
do
{
- if(uint64 resettime = (*result)[2].GetUInt64())
+ if(time_t resettime = time_t((*result)[2].GetUInt64()))
{
uint32 id = (*result)[0].GetUInt32();
uint32 mapid = (*result)[1].GetUInt32();
@@ -400,11 +396,11 @@ void InstanceSaveManager::LoadResetTimes()
{
Field *fields = result->Fetch();
uint32 instance = fields[1].GetUInt32();
- uint64 resettime = fields[0].GetUInt64() + 2 * HOUR;
+ time_t resettime = time_t(fields[0].GetUInt64() + 2 * HOUR);
ResetTimeMapType::iterator itr = InstResetTime.find(instance);
if(itr != InstResetTime.end() && itr->second.second != resettime)
{
- CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '"I64FMTD"' WHERE id = '%u'", resettime, instance);
+ CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '"I64FMTD"' WHERE id = '%u'", uint64(resettime), instance);
itr->second.second = resettime;
}
}
@@ -454,7 +450,7 @@ void InstanceSaveManager::LoadResetTimes()
// add the global reset times to the priority queue
for(uint32 i = 0; i < sInstanceTemplate.MaxEntry; i++)
{
- InstanceTemplate* temp = (InstanceTemplate*)objmgr.GetInstanceTemplate(i);
+ InstanceTemplate const* temp = objmgr.GetInstanceTemplate(i);
if(!temp) continue;
// only raid/heroic maps have a global reset time
const MapEntry* entry = sMapStore.LookupEntry(temp->map);
@@ -559,6 +555,7 @@ void InstanceSaveManager::_ResetSave(InstanceSaveHashMap::iterator &itr)
Group *group = *(gList.begin());
group->UnbindInstance(itr->second->GetMapId(), itr->second->GetDifficulty(), true);
}
+ delete itr->second;
m_instanceSaveById.erase(itr++);
lock_instLists = false;
}
@@ -583,7 +580,7 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, bool warn, uint32 timeLe
{
// global reset for all instances of the given map
// note: this isn't fast but it's meant to be executed very rarely
- Map *map = (MapInstanced*)MapManager::Instance().GetBaseMap(mapid);
+ Map const *map = MapManager::Instance().GetBaseMap(mapid);
if(!map->Instanceable())
return;
uint64 now = (uint64)time(NULL);
@@ -591,7 +588,7 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, bool warn, uint32 timeLe
if(!warn)
{
// this is called one minute before the reset time
- InstanceTemplate* temp = (InstanceTemplate*)objmgr.GetInstanceTemplate(mapid);
+ InstanceTemplate const* temp = objmgr.GetInstanceTemplate(mapid);
if(!temp || !temp->reset_delay)
{
sLog.outError("InstanceSaveManager::ResetOrWarnAll: no instance template or reset delay for map %d", mapid);
@@ -626,10 +623,10 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, bool warn, uint32 timeLe
MapInstanced::InstancedMaps::iterator mitr;
for(mitr = instMaps.begin(); mitr != instMaps.end(); ++mitr)
{
- Map *map = mitr->second;
- if(!map->IsDungeon()) continue;
- if(warn) ((InstanceMap*)map)->SendResetWarnings(timeLeft);
- else ((InstanceMap*)map)->Reset(INSTANCE_RESET_GLOBAL);
+ Map *map2 = mitr->second;
+ if(!map2->IsDungeon()) continue;
+ if(warn) ((InstanceMap*)map2)->SendResetWarnings(timeLeft);
+ else ((InstanceMap*)map2)->Reset(INSTANCE_RESET_GLOBAL);
}
// TODO: delete creature/gameobject respawn times even if the maps are not loaded
diff --git a/src/game/InstanceSaveMgr.h b/src/game/InstanceSaveMgr.h
index 58b891b3a9f..2a913e5cedf 100644
--- a/src/game/InstanceSaveMgr.h
+++ b/src/game/InstanceSaveMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/game/Item.cpp b/src/game/Item.cpp
index 766bd81d640..c44bca06246 100644
--- a/src/game/Item.cpp
+++ b/src/game/Item.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -206,6 +206,10 @@ bool ItemCanGoIntoBag(ItemPrototype const *pProto, ItemPrototype const *pBagProt
if(!(pProto->BagFamily & BAG_FAMILY_MASK_LEATHERWORKING_SUPP))
return false;
return true;
+ case ITEM_SUBCLASS_INSCRIPTION_CONTAINER:
+ if(!(pProto->BagFamily & BAG_FAMILY_MASK_INSCRIPTION_SUPP))
+ return false;
+ return true;
default:
return false;
}
@@ -261,7 +265,7 @@ bool Item::Create( uint32 guidlow, uint32 itemid, Player const* owner)
SetUInt32Value(ITEM_FIELD_MAXDURABILITY, itemProto->MaxDurability);
SetUInt32Value(ITEM_FIELD_DURABILITY, itemProto->MaxDurability);
- for(int i = 0; i < 5; ++i)
+ for(int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
SetSpellCharges(i,itemProto->Spells[i].SpellCharges);
SetUInt32Value(ITEM_FIELD_FLAGS, itemProto->Flags);
@@ -284,7 +288,7 @@ void Item::UpdateDuration(Player* owner, uint32 diff)
}
SetUInt32Value(ITEM_FIELD_DURATION, GetUInt32Value(ITEM_FIELD_DURATION) - diff);
- SetState(ITEM_CHANGED); // save new time in database
+ SetState(ITEM_CHANGED, owner); // save new time in database
}
void Item::SaveToDB()
@@ -297,7 +301,7 @@ void Item::SaveToDB()
CharacterDatabase.PExecute( "DELETE FROM item_instance WHERE guid = '%u'", guid );
std::ostringstream ss;
ss << "INSERT INTO item_instance (guid,owner_guid,data) VALUES (" << guid << "," << GUID_LOPART(GetOwnerGUID()) << ",'";
- for(uint16 i = 0; i < m_valuesCount; i++ )
+ for(uint16 i = 0; i < m_valuesCount; ++i )
ss << GetUInt32Value(i) << " ";
ss << "' )";
CharacterDatabase.Execute( ss.str().c_str() );
@@ -306,7 +310,7 @@ void Item::SaveToDB()
{
std::ostringstream ss;
ss << "UPDATE item_instance SET data = '";
- for(uint16 i = 0; i < m_valuesCount; i++ )
+ for(uint16 i = 0; i < m_valuesCount; ++i )
ss << GetUInt32Value(i) << " ";
ss << "', owner_guid = '" << GUID_LOPART(GetOwnerGUID()) << "' WHERE guid = '" << guid << "'";
@@ -346,7 +350,7 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result)
if (!result)
{
- sLog.outError("ERROR: Item (GUID: %u owner: %u) not found in table `item_instance`, can't load. ",guid,GUID_LOPART(owner_guid));
+ sLog.outError("Item (GUID: %u owner: %u) not found in table `item_instance`, can't load. ",guid,GUID_LOPART(owner_guid));
return false;
}
@@ -354,7 +358,7 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result)
if(!LoadValues(fields[0].GetString()))
{
- sLog.outError("ERROR: Item #%d have broken data in `data` field. Can't be loaded.",guid);
+ sLog.outError("Item #%d have broken data in `data` field. Can't be loaded.",guid);
if (delete_result) delete result;
return false;
}
@@ -407,7 +411,7 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result)
{
std::ostringstream ss;
ss << "UPDATE item_instance SET data = '";
- for(uint16 i = 0; i < m_valuesCount; i++ )
+ for(uint16 i = 0; i < m_valuesCount; ++i )
ss << GetUInt32Value(i) << " ";
ss << "', owner_guid = '" << GUID_LOPART(GetOwnerGUID()) << "' WHERE guid = '" << guid << "'";
@@ -450,7 +454,7 @@ uint32 Item::GetSkill()
const static uint32 item_armor_skills[MAX_ITEM_SUBCLASS_ARMOR] =
{
- 0,SKILL_CLOTH,SKILL_LEATHER,SKILL_MAIL,SKILL_PLATE_MAIL,0,SKILL_SHIELD,0,0,0
+ 0,SKILL_CLOTH,SKILL_LEATHER,SKILL_MAIL,SKILL_PLATE_MAIL,0,SKILL_SHIELD,0,0,0,0
};
ItemPrototype const* proto = GetProto();
@@ -752,7 +756,12 @@ bool Item::IsFitToSpellRequirements(SpellEntry const* spellInfo) const
if(spellInfo->EquippedItemInventoryTypeMask != 0) // 0 == any inventory type
{
- if((spellInfo->EquippedItemInventoryTypeMask & (1 << proto->InventoryType)) == 0)
+ // Special case - accept weapon type for main and offhand requirements
+ if(proto->InventoryType == INVTYPE_WEAPON &&
+ (spellInfo->EquippedItemInventoryTypeMask & (1 << INVTYPE_WEAPONMAINHAND) ||
+ spellInfo->EquippedItemInventoryTypeMask & (1 << INVTYPE_WEAPONOFFHAND)))
+ return true;
+ else if ((spellInfo->EquippedItemInventoryTypeMask & (1 << proto->InventoryType)) == 0)
return false; // inventory type not present in mask
}
@@ -765,9 +774,9 @@ void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint
if((GetEnchantmentId(slot) == id) && (GetEnchantmentDuration(slot) == duration) && (GetEnchantmentCharges(slot) == charges))
return;
- SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET,id);
- SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration);
- SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges);
+ SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET,id);
+ SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration);
+ SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges);
SetState(ITEM_CHANGED);
}
@@ -776,7 +785,7 @@ void Item::SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration)
if(GetEnchantmentDuration(slot) == duration)
return;
- SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration);
+ SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration);
SetState(ITEM_CHANGED);
}
@@ -785,7 +794,7 @@ void Item::SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges)
if(GetEnchantmentCharges(slot) == charges)
return;
- SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges);
+ SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges);
SetState(ITEM_CHANGED);
}
@@ -795,14 +804,14 @@ void Item::ClearEnchantment(EnchantmentSlot slot)
return;
for(uint8 x = 0; x < 3; ++x)
- SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + x, 0);
+ SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + x, 0);
SetState(ITEM_CHANGED);
}
bool Item::GemsFitSockets() const
{
bool fits = true;
- for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)
+ for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
{
uint8 SocketColor = GetProto()->Socket[enchant_slot-SOCK_ENCHANTMENT_SLOT].Color;
@@ -842,7 +851,7 @@ bool Item::GemsFitSockets() const
uint8 Item::GetGemCountWithID(uint32 GemID) const
{
uint8 count = 0;
- for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)
+ for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
{
uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot));
if(!enchant_id)
@@ -858,6 +867,29 @@ uint8 Item::GetGemCountWithID(uint32 GemID) const
return count;
}
+uint8 Item::GetGemCountWithLimitCategory(uint32 limitCategory) const
+{
+ uint8 count = 0;
+ for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
+ {
+ uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot));
+ if(!enchant_id)
+ continue;
+
+ SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
+ if(!enchantEntry)
+ continue;
+
+ ItemPrototype const* gemProto = ObjectMgr::GetItemPrototype(enchantEntry->GemID);
+ if(!gemProto)
+ continue;
+
+ if(gemProto->ItemLimitCategory==limitCategory)
+ ++count;
+ }
+ return count;
+}
+
bool Item::IsLimitedToAnotherMapOrZone( uint32 cur_mapId, uint32 cur_zoneId) const
{
ItemPrototype const* proto = GetProto();
@@ -886,8 +918,8 @@ Item* Item::CreateItem( uint32 item, uint32 count, Player const* player )
ItemPrototype const *pProto = objmgr.GetItemPrototype( item );
if( pProto )
{
- if ( count > pProto->Stackable )
- count = pProto->Stackable;
+ if ( count > pProto->GetMaxStackSize())
+ count = pProto->GetMaxStackSize();
assert(count !=0 && "pProto->Stackable==0 but checked at loading already");
diff --git a/src/game/Item.h b/src/game/Item.h
index 3417f2fcc6d..824375cea8d 100644
--- a/src/game/Item.h
+++ b/src/game/Item.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -148,29 +148,32 @@ enum SellFailure
// -1 from client enchantment slot number
enum EnchantmentSlot
{
- PERM_ENCHANTMENT_SLOT = 0,
- TEMP_ENCHANTMENT_SLOT = 1,
- SOCK_ENCHANTMENT_SLOT = 2,
- SOCK_ENCHANTMENT_SLOT_2 = 3,
- SOCK_ENCHANTMENT_SLOT_3 = 4,
- BONUS_ENCHANTMENT_SLOT = 5,
- MAX_INSPECTED_ENCHANTMENT_SLOT = 6,
-
- PROP_ENCHANTMENT_SLOT_0 = 6, // used with RandomSuffix
- PROP_ENCHANTMENT_SLOT_1 = 7, // used with RandomSuffix
- PROP_ENCHANTMENT_SLOT_2 = 8, // used with RandomSuffix and RandomProperty
- PROP_ENCHANTMENT_SLOT_3 = 9, // used with RandomProperty
- PROP_ENCHANTMENT_SLOT_4 = 10, // used with RandomProperty
- MAX_ENCHANTMENT_SLOT = 11
+ PERM_ENCHANTMENT_SLOT = 0,
+ TEMP_ENCHANTMENT_SLOT = 1,
+ SOCK_ENCHANTMENT_SLOT = 2,
+ SOCK_ENCHANTMENT_SLOT_2 = 3,
+ SOCK_ENCHANTMENT_SLOT_3 = 4,
+ BONUS_ENCHANTMENT_SLOT = 5,
+ PRISMATIC_ENCHANTMENT_SLOT = 6, // added at apply special permanent enchantment
+ MAX_INSPECTED_ENCHANTMENT_SLOT = 7,
+
+ PROP_ENCHANTMENT_SLOT_0 = 7, // used with RandomSuffix
+ PROP_ENCHANTMENT_SLOT_1 = 8, // used with RandomSuffix
+ PROP_ENCHANTMENT_SLOT_2 = 9, // used with RandomSuffix and RandomProperty
+ PROP_ENCHANTMENT_SLOT_3 = 10, // used with RandomProperty
+ PROP_ENCHANTMENT_SLOT_4 = 11, // used with RandomProperty
+ MAX_ENCHANTMENT_SLOT = 12
};
-#define MAX_VISIBLE_ITEM_OFFSET 16 // 16 fields per visible item (creator(2) + enchantments(12) + properties(1) + pad(1))
+#define MAX_VISIBLE_ITEM_OFFSET 18 // 18 fields per visible item (creator(2) + enchantments(13) + properties(1) + seed(1) + pad(1))
+
+#define MAX_GEM_SOCKETS MAX_ITEM_PROTO_SOCKETS// (BONUS_ENCHANTMENT_SLOT-SOCK_ENCHANTMENT_SLOT) and item proto size, equal value expected
enum EnchantmentOffset
{
ENCHANTMENT_ID_OFFSET = 0,
ENCHANTMENT_DURATION_OFFSET = 1,
- ENCHANTMENT_CHARGES_OFFSET = 2
+ ENCHANTMENT_CHARGES_OFFSET = 2 // now here not only charges, but something new in wotlk
};
#define MAX_ENCHANTMENT_OFFSET 3
@@ -211,6 +214,7 @@ class TRINITY_DLL_SPEC Item : public Object
void SetBinding(bool val) { ApplyModFlag(ITEM_FIELD_FLAGS,ITEM_FLAGS_BINDED,val); }
bool IsSoulBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BINDED); }
+ bool IsAccountBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BOA); }
bool IsBindedNotWith(uint64 guid) const { return IsSoulBound() && GetOwnerGUID()!= guid; }
bool IsBoundByEnchant() const;
virtual void SaveToDB();
@@ -230,8 +234,9 @@ class TRINITY_DLL_SPEC Item : public Object
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; }
+ uint32 GetMaxStackCount() const { return GetProto()->GetMaxStackSize(); }
uint8 GetGemCountWithID(uint32 GemID) const;
+ uint8 GetGemCountWithLimitCategory(uint32 limitCategory) const;
uint8 GetSlot() const {return m_slot;}
Bag *GetContainer() { return m_container; }
@@ -256,9 +261,9 @@ class TRINITY_DLL_SPEC Item : public Object
void SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration);
void SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges);
void ClearEnchantment(EnchantmentSlot slot);
- uint32 GetEnchantmentId(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET);}
- uint32 GetEnchantmentDuration(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET);}
- uint32 GetEnchantmentCharges(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET);}
+ uint32 GetEnchantmentId(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET);}
+ uint32 GetEnchantmentDuration(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET);}
+ uint32 GetEnchantmentCharges(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET);}
void SendTimeUpdate(Player* owner);
void UpdateDuration(Player* owner, uint32 diff);
@@ -282,13 +287,10 @@ class TRINITY_DLL_SPEC Item : public Object
uState = state;
}
- bool hasQuest(uint32 quest_id) const
- {
- ItemPrototype const *itemProto = GetProto();
- return itemProto && itemProto->StartQuest == quest_id;
- }
+ bool hasQuest(uint32 quest_id) const { return GetProto()->StartQuest == quest_id; }
bool hasInvolvedQuest(uint32 /*quest_id*/) const { return false; }
-
+ bool IsPotion() const { return GetProto()->IsPotion(); }
+ bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); }
private:
uint8 m_slot;
Bag *m_container;
diff --git a/src/game/ItemEnchantmentMgr.cpp b/src/game/ItemEnchantmentMgr.cpp
index 3326fb56e96..b40a398a782 100644
--- a/src/game/ItemEnchantmentMgr.cpp
+++ b/src/game/ItemEnchantmentMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -50,7 +50,7 @@ void LoadRandomEnchantmentsTable()
{
RandomItemEnch.clear(); // for reload case
- EnchantmentStore::iterator tab;
+ EnchantmentStore::const_iterator tab;
uint32 entry, ench;
float chance;
uint32 count = 0;
@@ -92,7 +92,7 @@ uint32 GetItemEnchantMod(uint32 entry)
{
if (!entry) return 0;
- EnchantmentStore::iterator tab = RandomItemEnch.find(entry);
+ EnchantmentStore::const_iterator tab = RandomItemEnch.find(entry);
if (tab == RandomItemEnch.end())
{
@@ -103,7 +103,7 @@ uint32 GetItemEnchantMod(uint32 entry)
double dRoll = rand_chance();
float fCount = 0;
- for(EnchStoreList::iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter)
+ for(EnchStoreList::const_iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter)
{
fCount += ench_iter->chance;
@@ -114,7 +114,7 @@ uint32 GetItemEnchantMod(uint32 entry)
dRoll = (irand(0, (int)floor(fCount * 100) + 1)) / 100;
fCount = 0;
- for(EnchStoreList::iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter)
+ for(EnchStoreList::const_iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter)
{
fCount += ench_iter->chance;
diff --git a/src/game/ItemEnchantmentMgr.h b/src/game/ItemEnchantmentMgr.h
index 17cf634860e..ce627515aee 100644
--- a/src/game/ItemEnchantmentMgr.h
+++ b/src/game/ItemEnchantmentMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp
index 0e46115de08..774a6eb8287 100644
--- a/src/game/ItemHandler.cpp
+++ b/src/game/ItemHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,7 +21,6 @@
#include "Common.h"
#include "WorldPacket.h"
#include "WorldSession.h"
-#include "World.h"
#include "Opcodes.h"
#include "Log.h"
#include "ObjectMgr.h"
@@ -202,7 +201,7 @@ void WorldSession::HandleAutoEquipItemOpcode( WorldPacket & recv_data )
// check dest->src move possibility
ItemPosCountVec sSrc;
- uint16 eSrc;
+ uint16 eSrc = 0;
if( _player->IsInventoryPos( src ) )
{
msg = _player->CanStoreItem( srcbag, srcslot, sSrc, pDstItem, true );
@@ -324,7 +323,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
data << pProto->ItemId;
data << pProto->Class;
data << pProto->SubClass;
- data << uint32(-1); // new 2.0.3, not exist in wdb cache?
+ data << int32(pProto->Unk0); // new 2.0.3, not exist in wdb cache?
data << Name;
data << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name...
data << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00);
@@ -346,15 +345,18 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
data << pProto->RequiredCityRank;
data << pProto->RequiredReputationFaction;
data << pProto->RequiredReputationRank;
- data << pProto->MaxCount;
- data << pProto->Stackable;
+ data << int32(pProto->MaxCount);
+ data << int32(pProto->Stackable);
data << pProto->ContainerSlots;
- for(int i = 0; i < 10; i++)
+ data << pProto->StatsCount; // item stats count
+ for(uint32 i = 0; i < pProto->StatsCount; ++i)
{
data << pProto->ItemStat[i].ItemStatType;
data << pProto->ItemStat[i].ItemStatValue;
}
- for(int i = 0; i < 5; i++)
+ data << pProto->ScalingStatDistribution; // scaling stats distribution
+ data << pProto->ScalingStatValue; // some kind of flags used to determine stat values column
+ for(int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
{
data << pProto->Damage[i].DamageMin;
data << pProto->Damage[i].DamageMax;
@@ -374,7 +376,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
data << pProto->AmmoType;
data << pProto->RangedModRange;
- for(int s = 0; s < 5; s++)
+ for(int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
{
// send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown
// use `item_template` or if not set then only use spell cooldowns
@@ -417,7 +419,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
data << pProto->PageMaterial;
data << pProto->StartQuest;
data << pProto->LockID;
- data << pProto->Material;
+ data << int32(pProto->Material);
data << pProto->Sheath;
data << pProto->RandomProperty;
data << pProto->RandomSuffix;
@@ -428,7 +430,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
data << pProto->Map; // Added in 1.12.x & 2.0.1 client branch
data << pProto->BagFamily;
data << pProto->TotemCategory;
- for(int s = 0; s < 3; s++)
+ for(int s = 0; s < MAX_ITEM_PROTO_SOCKETS; ++s)
{
data << pProto->Socket[s].Color;
data << pProto->Socket[s].Content;
@@ -437,7 +439,8 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
data << pProto->GemProperties;
data << pProto->RequiredDisenchantSkill;
data << pProto->ArmorDamageModifier;
- data << uint32(0); // added in 2.4.2.8209, duration (seconds)
+ data << pProto->Duration; // added in 2.4.2.8209, duration (seconds)
+ data << pProto->ItemLimitCategory; // WotLK, ItemLimitCategory
SendPacket( &data );
}
else
@@ -515,7 +518,7 @@ void WorldSession::HandleSellItemOpcode( WorldPacket & recv_data )
if(!itemguid)
return;
- Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, vendorguid,UNIT_NPC_FLAG_VENDOR);
+ Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid,UNIT_NPC_FLAG_VENDOR);
if (!pCreature)
{
sLog.outDebug( "WORLD: HandleSellItemOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(vendorguid)) );
@@ -525,7 +528,7 @@ void WorldSession::HandleSellItemOpcode( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
Item *pItem = _player->GetItemByGuid( itemguid );
if( pItem )
@@ -620,7 +623,7 @@ void WorldSession::HandleBuybackItem(WorldPacket & recv_data)
recv_data >> vendorguid >> slot;
- Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, vendorguid,UNIT_NPC_FLAG_VENDOR);
+ Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid,UNIT_NPC_FLAG_VENDOR);
if (!pCreature)
{
sLog.outDebug( "WORLD: HandleBuybackItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(vendorguid)) );
@@ -630,7 +633,7 @@ void WorldSession::HandleBuybackItem(WorldPacket & recv_data)
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
Item *pItem = _player->GetItemFromBuyBackSlot( slot );
if( pItem )
@@ -707,7 +710,7 @@ void WorldSession::SendListInventory( uint64 vendorguid )
{
sLog.outDebug( "WORLD: Sent SMSG_LIST_INVENTORY" );
- Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, vendorguid,UNIT_NPC_FLAG_VENDOR);
+ Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid,UNIT_NPC_FLAG_VENDOR);
if (!pCreature)
{
sLog.outDebug( "WORLD: SendListInventory - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(vendorguid)) );
@@ -717,7 +720,7 @@ void WorldSession::SendListInventory( uint64 vendorguid )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
// Stop the npc if moving
pCreature->StopMoving();
@@ -738,7 +741,7 @@ void WorldSession::SendListInventory( uint64 vendorguid )
float discountMod = _player->GetReputationPriceDiscount(pCreature);
- for(int i = 0; i < numitems; i++ )
+ for(int i = 0; i < numitems; ++i )
{
if(VendorItem const* crItem = vItems->GetItem(i))
{
@@ -824,10 +827,23 @@ void WorldSession::HandleAutoStoreBagItemOpcode( WorldPacket & recv_data )
_player->StoreItem( dest, pItem, true );
}
-void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& /*recvPacket*/)
+void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& recvPacket)
{
+ CHECK_PACKET_SIZE(recvPacket, 8);
+
sLog.outDebug("WORLD: CMSG_BUY_BANK_SLOT");
+ uint64 guid;
+ recvPacket >> guid;
+
+ // cheating protection
+ Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_BANKER);
+ if(!pCreature)
+ {
+ sLog.outDebug( "WORLD: HandleBuyBankSlotOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
+ return;
+ }
+
uint32 slot = _player->GetByteValue(PLAYER_BYTES_2, 2);
// next slot
@@ -845,6 +861,7 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& /*recvPacket*/)
if (_player->GetMoney() < price)
return;
+ _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT, slot);
_player->SetByteValue(PLAYER_BYTES_2, 2, slot);
_player->ModifyMoney(-int32(price));
}
@@ -1106,120 +1123,193 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data)
{
sLog.outDebug("WORLD: CMSG_SOCKET_GEMS");
- CHECK_PACKET_SIZE(recv_data,8*4);
-
- uint64 guids[4];
- uint32 GemEnchants[3], OldEnchants[3];
- Item *Gems[3];
- bool SocketBonusActivated, SocketBonusToBeActivated;
+ CHECK_PACKET_SIZE(recv_data,8+8*MAX_GEM_SOCKETS);
- for(int i = 0; i < 4; i++)
- recv_data >> guids[i];
+ uint64 item_guid;
+ uint64 gem_guids[MAX_GEM_SOCKETS];
- if(!guids[0])
+ recv_data >> item_guid;
+ if(!item_guid)
return;
+ for(int i = 0; i < MAX_GEM_SOCKETS; ++i)
+ recv_data >> gem_guids[i];
+
//cheat -> tried to socket same gem multiple times
- if((guids[1] && (guids[1] == guids[2] || guids[1] == guids[3])) || (guids[2] && (guids[2] == guids[3])))
+ if ((gem_guids[0] && (gem_guids[0] == gem_guids[1] || gem_guids[0] == gem_guids[2])) ||
+ (gem_guids[1] && (gem_guids[1] == gem_guids[2])))
return;
- Item *itemTarget = _player->GetItemByGuid(guids[0]);
+ Item *itemTarget = _player->GetItemByGuid(item_guid);
if(!itemTarget) //missing item to socket
return;
+ ItemPrototype const* itemProto = itemTarget->GetProto();
+ if(!itemProto)
+ return;
+
//this slot is excepted when applying / removing meta gem bonus
- uint8 slot = itemTarget->IsEquipped() ? itemTarget->GetSlot() : NULL_SLOT;
+ uint8 slot = itemTarget->IsEquipped() ? itemTarget->GetSlot() : uint8(NULL_SLOT);
- for(int i = 0; i < 3; i++)
- Gems[i] = guids[i + 1] ? _player->GetItemByGuid(guids[i + 1]) : NULL;
+ Item *Gems[MAX_GEM_SOCKETS];
+ for(int i = 0; i < MAX_GEM_SOCKETS; ++i)
+ Gems[i] = gem_guids[i] ? _player->GetItemByGuid(gem_guids[i]) : NULL;
- GemPropertiesEntry const *GemProps[3];
- for(int i = 0; i < 3; ++i) //get geminfo from dbc storage
- {
+ GemPropertiesEntry const *GemProps[MAX_GEM_SOCKETS];
+ for(int i = 0; i < MAX_GEM_SOCKETS; ++i) //get geminfo from dbc storage
GemProps[i] = (Gems[i]) ? sGemPropertiesStore.LookupEntry(Gems[i]->GetProto()->GemProperties) : NULL;
- }
- for(int i = 0; i < 3; ++i) //check for hack maybe
+ for(int i = 0; i < MAX_GEM_SOCKETS; ++i) //check for hack maybe
{
- // tried to put gem in socket where no socket exists / tried to put normal gem in meta socket
+ if (!GemProps[i])
+ continue;
+
+ // tried to put gem in socket where no socket exists (take care about prismatic sockets)
+ if (!itemProto->Socket[i].Color)
+ {
+ // no prismatic socket
+ if(!itemTarget->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
+ return;
+
+ // not first not-colored (not normaly used) socket
+ if(i!=0 && !itemProto->Socket[i-1].Color && (i+1 >= MAX_GEM_SOCKETS || itemProto->Socket[i+1].Color))
+ return;
+
+ // ok, this is first not colored socket for item with prismatic socket
+ }
+
+ // tried to put normal gem in meta socket
+ if (itemProto->Socket[i].Color == SOCKET_COLOR_META && GemProps[i]->color != SOCKET_COLOR_META)
+ return;
+
// tried to put meta gem in normal socket
- if( GemProps[i] && ( !itemTarget->GetProto()->Socket[i].Color ||
- itemTarget->GetProto()->Socket[i].Color == SOCKET_COLOR_META && GemProps[i]->color != SOCKET_COLOR_META ||
- itemTarget->GetProto()->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META ) )
+ if (itemProto->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META)
return;
}
- for(int i = 0; i < 3; ++i) //get new and old enchantments
+ uint32 GemEnchants[MAX_GEM_SOCKETS];
+ uint32 OldEnchants[MAX_GEM_SOCKETS];
+ for(int i = 0; i < MAX_GEM_SOCKETS; ++i) //get new and old enchantments
{
GemEnchants[i] = (GemProps[i]) ? GemProps[i]->spellitemenchantement : 0;
OldEnchants[i] = itemTarget->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i));
}
// check unique-equipped conditions
- for(int i = 0; i < 3; ++i)
+ for(int i = 0; i < MAX_GEM_SOCKETS; ++i)
{
- if (Gems[i] && (Gems[i]->GetProto()->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED))
+ if(!Gems[i])
+ continue;
+
+ // continue check for case when attempt add 2 similar unique equipped gems in one item.
+ ItemPrototype const* iGemProto = Gems[i]->GetProto();
+
+ // unique item (for new and already placed bit removed enchantments
+ if (iGemProto->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED)
{
- // for equipped item check all equipment for duplicate equipped gems
- if(itemTarget->IsEquipped())
+ for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
{
- if(GetPlayer()->GetItemOrItemWithGemEquipped(Gems[i]->GetEntry()))
+ if(i==j) // skip self
+ continue;
+
+ if (Gems[j])
{
- _player->SendEquipError( EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE, itemTarget, NULL );
- return;
+ if (iGemProto->ItemId == Gems[j]->GetEntry())
+ {
+ _player->SendEquipError( EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL );
+ return;
+ }
+ }
+ else if(OldEnchants[j])
+ {
+ if(SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
+ {
+ if (iGemProto->ItemId == enchantEntry->GemID)
+ {
+ _player->SendEquipError( EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL );
+ return;
+ }
+ }
}
+
}
+ }
- // continue check for case when attempt add 2 similar unique equipped gems in one item.
- for (int j = 0; j < 3; ++j)
+ // unique limit type item
+ int32 limit_newcount = 0;
+ if (iGemProto->ItemLimitCategory)
+ {
+ if(ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(iGemProto->ItemLimitCategory))
{
- if ((i != j) && (Gems[j]) && (Gems[i]->GetProto()->ItemId == Gems[j]->GetProto()->ItemId))
+ for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
+ {
+ if (Gems[j])
+ {
+ // destroyed gem
+ if (OldEnchants[j])
+ {
+ if(SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
+ if(ItemPrototype const* jProto = ObjectMgr::GetItemPrototype(enchantEntry->GemID))
+ if (iGemProto->ItemLimitCategory == jProto->ItemLimitCategory)
+ --limit_newcount;
+ }
+
+ // new gem
+ if (iGemProto->ItemLimitCategory == Gems[j]->GetProto()->ItemLimitCategory)
+ ++limit_newcount;
+ }
+ // existed gem
+ else if(OldEnchants[j])
+ {
+ if(SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
+ if(ItemPrototype const* jProto = ObjectMgr::GetItemPrototype(enchantEntry->GemID))
+ if (iGemProto->ItemLimitCategory == jProto->ItemLimitCategory)
+ ++limit_newcount;
+ }
+ }
+
+ if(limit_newcount > 0 && uint32(limit_newcount) > limitEntry->maxCount)
{
_player->SendEquipError( EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL );
return;
}
}
- for (int j = 0; j < 3; ++j)
- {
- if (OldEnchants[j])
- {
- SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]);
- if(!enchantEntry)
- continue;
+ }
- if ((enchantEntry->GemID == Gems[i]->GetProto()->ItemId) && (i != j))
- {
- _player->SendEquipError( EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL );
- return;
- }
- }
+ // for equipped item check all equipment for duplicate equipped gems
+ if(itemTarget->IsEquipped())
+ {
+ if(uint8 res = _player->CanEquipUniqueItem(Gems[i],slot,limit_newcount >= 0 ? limit_newcount : 0))
+ {
+ _player->SendEquipError( res, itemTarget, NULL );
+ return;
}
}
}
- SocketBonusActivated = itemTarget->GemsFitSockets(); //save state of socketbonus
+ bool SocketBonusActivated = itemTarget->GemsFitSockets(); //save state of socketbonus
_player->ToggleMetaGemsActive(slot, false); //turn off all metagems (except for the target item)
//if a meta gem is being equipped, all information has to be written to the item before testing if the conditions for the gem are met
//remove ALL enchants
- for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)
+ for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
_player->ApplyEnchantment(itemTarget,EnchantmentSlot(enchant_slot),false);
- for(int i = 0; i < 3; ++i)
+ for(int i = 0; i < MAX_GEM_SOCKETS; ++i)
{
if(GemEnchants[i])
{
itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i), GemEnchants[i],0,0);
- if(Item* guidItem = _player->GetItemByGuid(guids[i + 1]))
+ if(Item* guidItem = _player->GetItemByGuid(gem_guids[i]))
_player->DestroyItem(guidItem->GetBagSlot(), guidItem->GetSlot(), true );
}
}
- for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)
+ for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
_player->ApplyEnchantment(itemTarget,EnchantmentSlot(enchant_slot),true);
- SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state
+ bool SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state
if(SocketBonusActivated ^ SocketBonusToBeActivated) //if there was a change...
{
_player->ApplyEnchantment(itemTarget,BONUS_ENCHANTMENT_SLOT,false);
diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h
index 15b01faf5a2..3967b37622b 100644
--- a/src/game/ItemPrototype.h
+++ b/src/game/ItemPrototype.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -57,10 +57,18 @@ enum ItemModType
ITEM_MOD_CRIT_TAKEN_RATING = 34,
ITEM_MOD_RESILIENCE_RATING = 35,
ITEM_MOD_HASTE_RATING = 36,
- ITEM_MOD_EXPERTISE_RATING = 37
+ ITEM_MOD_EXPERTISE_RATING = 37,
+ ITEM_MOD_ATTACK_POWER = 38,
+ ITEM_MOD_RANGED_ATTACK_POWER = 39,
+ ITEM_MOD_FERAL_ATTACK_POWER = 40,
+ ITEM_MOD_SPELL_HEALING_DONE = 41,
+ ITEM_MOD_SPELL_DAMAGE_DONE = 42,
+ ITEM_MOD_MANA_REGENERATION = 43,
+ ITEM_MOD_ARMOR_PENETRATION_RATING = 44,
+ ITEM_MOD_SPELL_POWER = 45
};
-#define MAX_ITEM_MOD 38
+#define MAX_ITEM_MOD 46
enum ItemSpelltriggerType
{
@@ -68,6 +76,12 @@ enum ItemSpelltriggerType
ITEM_SPELLTRIGGER_ON_EQUIP = 1,
ITEM_SPELLTRIGGER_CHANCE_ON_HIT = 2,
ITEM_SPELLTRIGGER_SOULSTONE = 4,
+ /*
+ * ItemSpelltriggerType 5 might have changed on 2.4.3/3.0.3: Such auras
+ * will be applied on item pickup and removed on item loss - maybe on the
+ * other hand the item is destroyed if the aura is removed ("removed on
+ * death" of spell 57348 makes me think so)
+ */
ITEM_SPELLTRIGGER_ON_NO_DELAY_USE = 5, // no equip cooldown
ITEM_SPELLTRIGGER_LEARN_SPELL_ID = 6 // used in item_template.spell_2 with spell_id with SPELL_GENERIC_LEARN in spell_1
};
@@ -93,9 +107,11 @@ enum ITEM_FLAGS
ITEM_FLAGS_CONJURED = 0x00000002,
ITEM_FLAGS_OPENABLE = 0x00000004,
ITEM_FLAGS_WRAPPED = 0x00000008,
+ ITEM_FLAGS_BROKEN = 0x00000010, // appears red icon (like when item durability==0)
ITEM_FLAGS_WRAPPER = 0x00000200, // used or not used wrapper
ITEM_FLAGS_PARTY_LOOT = 0x00000800, // determines if item is party loot or not
ITEM_FLAGS_CHARTER = 0x00002000, // arena/guild charter
+ ITEM_FLAGS_PROSPECTABLE = 0x00040000,
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
@@ -185,10 +201,11 @@ enum ItemClass
ITEM_CLASS_QUEST = 12,
ITEM_CLASS_KEY = 13,
ITEM_CLASS_PERMANENT = 14,
- ITEM_CLASS_JUNK = 15
+ ITEM_CLASS_MISC = 15,
+ ITEM_CLASS_GLYPH = 16
};
-#define MAX_ITEM_CLASS 16
+#define MAX_ITEM_CLASS 17
enum ItemSubclassConsumable
{
@@ -214,10 +231,11 @@ enum ItemSubclassContainer
ITEM_SUBCLASS_ENGINEERING_CONTAINER = 4,
ITEM_SUBCLASS_GEM_CONTAINER = 5,
ITEM_SUBCLASS_MINING_CONTAINER = 6,
- ITEM_SUBCLASS_LEATHERWORKING_CONTAINER = 7
+ ITEM_SUBCLASS_LEATHERWORKING_CONTAINER = 7,
+ ITEM_SUBCLASS_INSCRIPTION_CONTAINER = 8
};
-#define MAX_ITEM_SUBCLASS_CONTAINER 8
+#define MAX_ITEM_SUBCLASS_CONTAINER 9
enum ItemSubclassWeapon
{
@@ -272,10 +290,11 @@ enum ItemSubclassArmor
ITEM_SUBCLASS_ARMOR_SHIELD = 6,
ITEM_SUBCLASS_ARMOR_LIBRAM = 7,
ITEM_SUBCLASS_ARMOR_IDOL = 8,
- ITEM_SUBCLASS_ARMOR_TOTEM = 9
+ ITEM_SUBCLASS_ARMOR_TOTEM = 9,
+ ITEM_SUBCLASS_ARMOR_SIGIL = 10
};
-#define MAX_ITEM_SUBCLASS_ARMOR 10
+#define MAX_ITEM_SUBCLASS_ARMOR 11
enum ItemSubclassReagent
{
@@ -310,10 +329,12 @@ enum ItemSubclassTradeGoods
ITEM_SUBCLASS_ELEMENTAL = 10,
ITEM_SUBCLASS_TRADE_GOODS_OTHER = 11,
ITEM_SUBCLASS_ENCHANTING = 12,
- ITEM_SUBCLASS_MATERIAL = 13 // Added in 2.4.2
+ ITEM_SUBCLASS_MATERIAL = 13,
+ ITEM_SUBCLASS_ARMOR_ENCHANTMENT = 14,
+ ITEM_SUBCLASS_WEAPON_ENCHANTMENT = 15
};
-#define MAX_ITEM_SUBCLASS_TRADE_GOODS 14
+#define MAX_ITEM_SUBCLASS_TRADE_GOODS 16
enum ItemSubclassGeneric
{
@@ -423,7 +444,8 @@ const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] =
MAX_ITEM_SUBCLASS_QUEST,
MAX_ITEM_SUBCLASS_KEY,
MAX_ITEM_SUBCLASS_PERMANENT,
- MAX_ITEM_SUBCLASS_JUNK
+ MAX_ITEM_SUBCLASS_JUNK,
+ MAX_ITEM_SUBCLASS_GLYPH
};
inline uint8 ItemSubClassToDurabilityMultiplierId(uint32 ItemClass, uint32 ItemSubClass)
@@ -472,12 +494,17 @@ struct _Socket
uint32 Content;
};
+#define MAX_ITEM_PROTO_DAMAGES 5
+#define MAX_ITEM_PROTO_SOCKETS 3
+#define MAX_ITEM_PROTO_SPELLS 5
+#define MAX_ITEM_PROTO_STATS 10
+
struct ItemPrototype
{
uint32 ItemId;
uint32 Class; // id from ItemClass.dbc
uint32 SubClass; // id from ItemSubClass.dbc
- uint32 Unk0;
+ int32 Unk0;
char* Name1;
uint32 DisplayInfoID; // id from ItemDisplayInfo.dbc
uint32 Quality;
@@ -497,11 +524,14 @@ struct ItemPrototype
uint32 RequiredCityRank;
uint32 RequiredReputationFaction; // id from Faction.dbc
uint32 RequiredReputationRank;
- uint32 MaxCount;
- uint32 Stackable;
+ int32 MaxCount; // <=0: no limit
+ int32 Stackable; // 0: not allowed, -1: put in player coin info tab and don't limit stacking (so 1 slot)
uint32 ContainerSlots;
- _ItemStat ItemStat[10];
- _Damage Damage[5];
+ uint32 StatsCount;
+ _ItemStat ItemStat[MAX_ITEM_PROTO_STATS];
+ uint32 ScalingStatDistribution; // id from ScalingStatDistribution.dbc
+ uint32 ScalingStatValue; // mask for selecting column in ScalingStatValues.dbc
+ _Damage Damage[MAX_ITEM_PROTO_DAMAGES];
uint32 Armor;
uint32 HolyRes;
uint32 FireRes;
@@ -512,7 +542,7 @@ struct ItemPrototype
uint32 Delay;
uint32 AmmoType;
float RangedModRange;
- _Spell Spells[5];
+ _Spell Spells[MAX_ITEM_PROTO_SPELLS];
uint32 Bonding;
char* Description;
uint32 PageText;
@@ -520,7 +550,7 @@ struct ItemPrototype
uint32 PageMaterial;
uint32 StartQuest; // id from QuestCache.wdb
uint32 LockID;
- uint32 Material; // id from Material.dbc
+ int32 Material; // id from Material.dbc
uint32 Sheath;
uint32 RandomProperty; // id from ItemRandomProperties.dbc
uint32 RandomSuffix; // id from ItemRandomSuffix.dbc
@@ -529,19 +559,20 @@ struct ItemPrototype
uint32 MaxDurability;
uint32 Area; // id from AreaTable.dbc
uint32 Map; // id from Map.dbc
- uint32 BagFamily; // id from ItemBagFamily.dbc
+ uint32 BagFamily; // bit string (1 << id from ItemBagFamily.dbc)
uint32 TotemCategory; // id from TotemCategory.dbc
- _Socket Socket[3];
+ _Socket Socket[MAX_ITEM_PROTO_SOCKETS];
uint32 socketBonus; // id from SpellItemEnchantment.dbc
uint32 GemProperties; // id from GemProperties.dbc
uint32 RequiredDisenchantSkill;
float ArmorDamageModifier;
+ int32 Duration; // negative = realtime, positive = ingame time
+ uint32 ItemLimitCategory; // id from ItemLimitCategory.dbc
uint32 ScriptId;
uint32 DisenchantID;
uint32 FoodType;
uint32 MinMoneyLoot;
uint32 MaxMoneyLoot;
- int32 Duration; // negative = realtime, positive = ingame time
// helpers
bool CanChangeEquipStateInCombat() const
@@ -563,6 +594,74 @@ struct ItemPrototype
return false;
}
+
+ uint32 GetScalingStatValuesColumn() const
+ {
+ if(ScalingStatValue & 0x00000001) // stat mod
+ return 0;
+ if(ScalingStatValue & 0x00000002) // stat mod
+ return 1;
+ if(ScalingStatValue & 0x00000004) // stat mod
+ return 2;
+ if(ScalingStatValue & 0x00000008) // stat mod
+ return 3;
+ if(ScalingStatValue & 0x00000010) // stat mod
+ return 4;
+ if(ScalingStatValue & 0x00000020) // armor mod
+ return 5;
+ if(ScalingStatValue & 0x00000040) // armor mod
+ return 6;
+ if(ScalingStatValue & 0x00000080) // armor mod
+ return 7;
+ if(ScalingStatValue & 0x00000100) // armor mod
+ return 8;
+ if(ScalingStatValue & 0x00000200) // damage mod
+ return 9;
+ if(ScalingStatValue & 0x00000400) // damage mod
+ return 10;
+ if(ScalingStatValue & 0x00000800) // damage mod
+ return 11;
+ if(ScalingStatValue & 0x00001000) // damage mod
+ return 12;
+ if(ScalingStatValue & 0x00002000) // damage mod
+ return 13;
+ if(ScalingStatValue & 0x00004000) // damage mod
+ return 14;
+ if(ScalingStatValue & 0x00008000) // spell power
+ return 15;
+ if(ScalingStatValue & 0x00020000) // feral AP
+ return 16;
+
+ return 0;
+ }
+
+ uint32 GetMaxStackSize() const { return Stackable > 0 ? uint32(Stackable) : uint32(0x7FFFFFFF-1); }
+
+ float getDPS() const
+ {
+ if (Delay == 0)
+ return 0;
+ float temp = 0;
+ for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
+ temp+=Damage[i].DamageMin + Damage[i].DamageMax;
+ return temp*500/Delay;
+ }
+
+ int32 getFeralBonus() const
+ {
+ // 0x02A5F3 - is mask for Melee weapon from ItemSubClassMask.dbc
+ if (Class == ITEM_CLASS_WEAPON && (1<<SubClass)&0x02A5F3)
+ {
+ int32 bonus = int32(getDPS()*14.0f) - 767;
+ if (bonus < 0)
+ return 0;
+ return bonus;
+ }
+ return 0;
+ }
+
+ bool IsPotion() const { return Class==ITEM_CLASS_CONSUMABLE && SubClass==ITEM_SUBCLASS_POTION; }
+ bool IsConjuredConsumable() const { return Class == ITEM_CLASS_CONSUMABLE && (Flags & ITEM_FLAGS_CONJURED); }
};
struct ItemLocale
diff --git a/src/game/LFGHandler.cpp b/src/game/LFGHandler.cpp
index 667b65327d5..85c196a9346 100644
--- a/src/game/LFGHandler.cpp
+++ b/src/game/LFGHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/Language.h b/src/game/Language.h
index 03c485a4b02..69bfbf00159 100644
--- a/src/game/Language.h
+++ b/src/game/Language.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -84,7 +84,8 @@ enum TrinityStrings
LANG_MOTD_CURRENT = 56,
LANG_USING_WORLD_DB = 57,
LANG_USING_SCRIPT_LIB = 58,
- // Room for more level 0 59-99 not used
+ LANG_USING_EVENT_AI = 59,
+ // Room for more level 0 60-99 not used
// level 1 chat
LANG_GLOBAL_NOTIFY = 100,
@@ -170,7 +171,10 @@ enum TrinityStrings
LANG_SOUND_NOT_EXIST = 170,
LANG_TELEPORTED_TO_BY_CONSOLE = 171,
LANG_CONSOLE_COMMAND = 172,
- // Room for more level 1 173-199 not used
+ LANG_YOU_CHANGE_RUNIC_POWER = 173,
+ LANG_YOURS_RUNIC_POWER_CHANGED = 174,
+ LANG_LIQUID_STATUS = 175,
+ // Room for more level 1 176-199 not used
// level 2 chat
LANG_NO_SELECTION = 200,
@@ -269,9 +273,9 @@ enum TrinityStrings
LANG_COMMAND_WHISPERON = 285,
LANG_COMMAND_WHISPEROFF = 286,
LANG_COMMAND_CREATGUIDNOTFOUND = 287,
- // TICKET STRINGS NEED REWRITE // 288-296 FREE
+ // TICKET STRINGS NEED REWRITE // 288-296 FREE
- // END
+ // END
LANG_COMMAND_SPAWNDIST = 297,
LANG_COMMAND_SPAWNTIME = 298,
LANG_COMMAND_MODIFY_HONOR = 299,
@@ -322,6 +326,8 @@ enum TrinityStrings
LANG_CREATURE_NOT_FOLLOW_YOU_NOW = 342,
LANG_CREATURE_NON_TAMEABLE = 343,
LANG_YOU_ALREADY_HAVE_PET = 344,
+ LANG_CUSTOMIZE_PLAYER = 345,
+ LANG_CUSTOMIZE_PLAYER_GUID = 346,
// Room for more level 2 345-399 not used
// level 3 chat
@@ -529,9 +535,9 @@ enum TrinityStrings
LANG_CHANGE_32BIT = 575, //log
LANG_CHANGE_32BIT_FIELD = 576,
- LANG_INVISIBLE_INVISIBLE = 577,
- LANG_INVISIBLE_VISIBLE = 578,
- LANG_SELECTED_TARGET_NOT_HAVE_VICTIM = 579,
+ LANG_INVISIBLE_INVISIBLE = 577,
+ LANG_INVISIBLE_VISIBLE = 578,
+ LANG_SELECTED_TARGET_NOT_HAVE_VICTIM = 579,
LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST = 580,
LANG_COMMAND_NEAROBJMESSAGE = 581,
@@ -561,9 +567,11 @@ enum TrinityStrings
// Battleground
LANG_BG_A_WINS = 600,
LANG_BG_H_WINS = 601,
- LANG_BG_WS_ONE_MINUTE = 602,
- LANG_BG_WS_HALF_MINUTE = 603,
- LANG_BG_WS_BEGIN = 604,
+
+ LANG_BG_WS_START_TWO_MINUTES = 753,
+ LANG_BG_WS_START_ONE_MINUTE = 602,
+ LANG_BG_WS_START_HALF_MINUTE = 603,
+ LANG_BG_WS_HAS_BEGUN = 604,
LANG_BG_WS_CAPTURED_HF = 605,
LANG_BG_WS_CAPTURED_AF = 606,
@@ -577,9 +585,10 @@ enum TrinityStrings
LANG_BG_WS_ALLIANCE_FLAG_RESPAWNED = 614,
LANG_BG_WS_HORDE_FLAG_RESPAWNED = 615,
- LANG_BG_EY_ONE_MINUTE = 636,
- LANG_BG_EY_HALF_MINUTE = 637,
- LANG_BG_EY_BEGIN = 638,
+ LANG_BG_EY_START_TWO_MINUTES = 755,
+ LANG_BG_EY_START_ONE_MINUTE = 636,
+ LANG_BG_EY_START_HALF_MINUTE = 637,
+ LANG_BG_EY_HAS_BEGUN = 638,
LANG_BG_AB_ALLY = 650,
LANG_BG_AB_HORDE = 651,
@@ -592,9 +601,11 @@ enum TrinityStrings
LANG_BG_AB_NODE_DEFENDED = 658,
LANG_BG_AB_NODE_ASSAULTED = 659,
LANG_BG_AB_NODE_CLAIMED = 660,
- LANG_BG_AB_ONEMINTOSTART = 661,
- LANG_BG_AB_HALFMINTOSTART = 662,
- LANG_BG_AB_STARTED = 663,
+
+ LANG_BG_AB_START_TWO_MINUTES = 754,
+ LANG_BG_AB_START_ONE_MINUTE = 661,
+ LANG_BG_AB_START_HALF_MINUTE = 662,
+ LANG_BG_AB_HAS_BEGUN = 663,
LANG_BG_AB_A_NEAR_VICTORY = 664,
LANG_BG_AB_H_NEAR_VICTORY = 665,
LANG_BG_MARK_BY_MAIL = 666,
@@ -625,7 +636,7 @@ enum TrinityStrings
LANG_ARENA_ONE_MINUTE = 701,
LANG_ARENA_THIRTY_SECONDS = 702,
LANG_ARENA_FIFTEEN_SECONDS = 703,
- LANG_ARENA_BEGUN = 704,
+ LANG_ARENA_HAS_BEGUN = 704,
LANG_WAIT_BEFORE_SPEAKING = 705,
LANG_NOT_EQUIPPED_ITEM = 706,
@@ -636,77 +647,58 @@ enum TrinityStrings
LANG_BG_QUEUE_ANNOUNCE_SELF = 711,
LANG_BG_QUEUE_ANNOUNCE_WORLD = 712,
-
-
LANG_YOUR_ARENA_LEVEL_REQ_ERROR = 713,
-// LANG_HIS_ARENA_LEVEL_REQ_ERROR = 714, an opcode exists for this
+// = 714, not used
LANG_YOUR_BG_LEVEL_REQ_ERROR = 715,
-// LANG_YOUR_ARENA_TEAM_FULL = 716, an opcode exists for this
-
- LANG_BG_AV_ALLY = 717,
- LANG_BG_AV_HORDE = 718,
- LANG_BG_AV_TOWER_TAKEN = 719,
- LANG_BG_AV_TOWER_ASSAULTED = 720,
- LANG_BG_AV_TOWER_DEFENDED = 721,
- LANG_BG_AV_GRAVE_TAKEN = 722,
- LANG_BG_AV_GRAVE_DEFENDED = 723,
- LANG_BG_AV_GRAVE_ASSAULTED = 724,
-
- LANG_BG_AV_MINE_TAKEN = 725,
- LANG_BG_AV_MINE_NORTH = 726,
- LANG_BG_AV_MINE_SOUTH = 727,
-
- LANG_BG_AV_NODE_GRAVE_STORM_AID = 728,
- LANG_BG_AV_NODE_TOWER_DUN_S = 729,
- LANG_BG_AV_NODE_TOWER_DUN_N = 730,
- LANG_BG_AV_NODE_GRAVE_STORMPIKE = 731,
- LANG_BG_AV_NODE_TOWER_ICEWING = 732,
- LANG_BG_AV_NODE_GRAVE_STONE = 733,
- LANG_BG_AV_NODE_TOWER_STONE = 734,
- LANG_BG_AV_NODE_GRAVE_SNOW = 735,
- LANG_BG_AV_NODE_TOWER_ICE = 736,
- LANG_BG_AV_NODE_GRAVE_ICE = 737,
- LANG_BG_AV_NODE_TOWER_POINT = 738,
- LANG_BG_AV_NODE_GRAVE_FROST = 739,
- LANG_BG_AV_NODE_TOWER_FROST_E = 740,
- LANG_BG_AV_NODE_TOWER_FROST_W = 741,
- LANG_BG_AV_NODE_GRAVE_FROST_HUT = 742,
-
- LANG_BG_AV_ONEMINTOSTART = 743,
- LANG_BG_AV_HALFMINTOSTART = 744,
- LANG_BG_AV_STARTED = 745,
- LANG_BG_AV_A_NEAR_LOSE = 746,
- LANG_BG_AV_H_NEAR_LOSE = 747,
- LANG_BG_AV_H_CAPTAIN_DEAD = 748,
- LANG_BG_AV_A_CAPTAIN_DEAD = 749,
- LANG_NPCINFO_LINKGUID = 750,
+// = 716, not used
+ LANG_BG_STARTED_ANNOUNCE_WORLD = 717,
+ LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN= 718,
+ LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT= 719,
+
+ LANG_BG_GROUP_TOO_LARGE = 720, // "Your group is too large for this battleground. Please regroup to join."
+ LANG_ARENA_GROUP_TOO_LARGE = 721, // "Your group is too large for this arena. Please regroup to join."
+ LANG_ARENA_YOUR_TEAM_ONLY = 722, // "Your group has members not in your arena team. Please regroup to join."
+ LANG_ARENA_NOT_ENOUGH_PLAYERS = 723, // "Your group does not have enough players to join this match."
+ LANG_ARENA_GOLD_WINS = 724, // "The Gold Team wins!"
+ LANG_ARENA_GREEN_WINS = 725, // "The Green Team wins!"
+// = 726, not used
+ LANG_BG_GROUP_OFFLINE_MEMBER = 727, // "Your group has an offline member. Please remove him before joining."
+ LANG_BG_GROUP_MIXED_FACTION = 728, // "Your group has players from the opposing faction. You can't join the battleground as a group."
+ LANG_BG_GROUP_MIXED_LEVELS = 729, // "Your group has players from different battleground brakets. You can't join as group."
+ LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE = 730, // "Someone in your party is already in this battleground queue. (S)he must leave it before joining as group."
+ LANG_BG_GROUP_MEMBER_DESERTER = 731, // "Someone in your party is Deserter. You can't join as group."
+ LANG_BG_GROUP_MEMBER_NO_FREE_QUEUE_SLOTS = 732, // "Someone in your party is already in three battleground queues. You cannot join as group."
+
+ LANG_CANNOT_TELE_TO_BG = 733, // "You cannot teleport to a battleground or arena map."
+ LANG_CANNOT_SUMMON_TO_BG = 734, // "You cannot summon players to a battleground or arena map."
+ LANG_CANNOT_GO_TO_BG_GM = 735, // "You must be in GM mode to teleport to a player in a battleground."
+ LANG_CANNOT_GO_TO_BG_FROM_BG = 736, // "You cannot teleport to a battleground from another battleground. Please leave the current battleground first."
+ LANG_DEBUG_ARENA_ON = 737,
+ LANG_DEBUG_ARENA_OFF = 738,
+ LANG_DEBUG_BG_ON = 739,
+ LANG_DEBUG_BG_OFF = 740,
+ LANG_DIST_ARENA_POINTS_START = 741,
+ LANG_DIST_ARENA_POINTS_ONLINE_START = 742,
+ LANG_DIST_ARENA_POINTS_ONLINE_END = 743,
+ LANG_DIST_ARENA_POINTS_TEAM_START = 744,
+ LANG_DIST_ARENA_POINTS_TEAM_END = 745,
+ LANG_DIST_ARENA_POINTS_END = 746,
+// = 747, not used
+// = 748, not used
+// = 749, not used
+ LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 750, // "Not enough players. This game will close in %u mins."
+ LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING_SECS = 751, // "Not enough players. This game will close in %u seconds."
+// = 752, not used
+// LANG_BG_WS_START_TWO_MINUTES = 753, - defined above
+// LANG_BG_AB_START_TWO_MINUTES = 754, - defined above
+// LANG_BG_EY_START_TWO_MINUTES = 755, - defined above
+ // Room for batleground/arena strings 756-799 not used
// Room for BG/ARENA 751-769 not used
-
LANG_ARENA_TESTING = 785,
-
LANG_AUTO_ANN = 786,
LANG_ANNOUNCE_COLOR = 787,
- LANG_BG_GROUP_TOO_LARGE = 1122, // "Your group is too large for this battleground. Please regroup to join."
- LANG_ARENA_GROUP_TOO_LARGE = 1123, // "Your group is too large for this arena. Please regroup to join."
- LANG_ARENA_YOUR_TEAM_ONLY = 1124, // "Your group has members not in your arena team. Please regroup to join."
- LANG_ARENA_NOT_ENOUGH_PLAYERS = 1125, // "Your group does not have enough players to join this match."
- LANG_ARENA_GOLD_WINS = 1126, // "The Gold Team wins!"
- LANG_ARENA_GREEN_WINS = 1127, // "The Green Team wins!"
- LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 1128, // The battleground will end soon, because there aren't enough players. Get more ppl or win already!
- LANG_BG_GROUP_OFFLINE_MEMBER = 1129, // "Your group has an offline member. Please remove him before joining."
- LANG_BG_GROUP_MIXED_FACTION = 1130, // "Your group has players from the opposing faction. You can't join the battleground as a group."
- LANG_BG_GROUP_MIXED_LEVELS = 1131, // "Your group has players from different battleground brakets. You can't join as group."
- LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE = 1132, // "Someone in your party is already in this battleground queue. (S)he must leave it before joining as group."
- LANG_BG_GROUP_MEMBER_DESERTER = 1133, // "Someone in your party is Deserter. You can't join as group."
- LANG_BG_GROUP_MEMBER_NO_FREE_QUEUE_SLOTS = 1134, // "Someone in your party is already in three battleground queues. You cannot join as group."
-
- LANG_CANNOT_TELE_TO_BG = 1135, // "You cannot teleport to a battleground or arena map."
- LANG_CANNOT_SUMMON_TO_BG = 1136, // "You cannot summon players to a battleground or arena map."
- LANG_CANNOT_GO_TO_BG_GM = 1137, // "You must be in GM mode to teleport to a player in a battleground."
- LANG_CANNOT_GO_TO_BG_FROM_BG = 1138, // "You cannot teleport to a battleground from another battleground. Please leave the current battleground first."
-
// in game strings
LANG_PET_INVALID_NAME = 800,
LANG_NOT_ENOUGH_GOLD = 801,
@@ -718,7 +710,13 @@ enum TrinityStrings
LANG_NEED_CHARACTER_NAME = 807,
LANG_PLAYER_NOT_EXIST_OR_OFFLINE = 808,
LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND = 809,
- // Room for in-game strings 810-999 not used
+ LANG_ACHIEVEMENT_EARNED = 810,
+ LANG_GUILD_MASTER = 811,
+ LANG_GUILD_OFFICER = 812,
+ LANG_GUILD_VETERAN = 813,
+ LANG_GUILD_MEMBER = 814,
+ LANG_GUILD_INITIATE = 815,
+ // Room for in-game strings 816-999 not used
// Level 4 (CLI only commands)
LANG_COMMAND_EXIT = 1000,
@@ -733,7 +731,10 @@ enum TrinityStrings
LANG_CHARACTER_DELETED = 1009,
LANG_ACCOUNT_LIST_HEADER = 1010,
LANG_ACCOUNT_LIST_ERROR = 1011,
- // Room for more level 4 1012-1099 not used
+ LANG_ACCOUNT_LIST_BAR = 1012,
+ LANG_ACCOUNT_LIST_LINE = 1013,
+ LANG_ACCOUNT_LIST_EMPTY = 1014,
+ // Room for more level 4 1015-1099 not used
// Level 3 (continue)
LANG_ACCOUNT_SETADDON = 1100,
@@ -758,6 +759,59 @@ enum TrinityStrings
LANG_MUST_MALE_OR_FEMALE = 1119,
LANG_YOU_CHANGE_GENDER = 1120,
LANG_YOUR_GENDER_CHANGED = 1121,
+ LANG_SKILL_VALUES = 1122,
+ LANG_NO_PET_FOUND = 1123,
+ LANG_WRONG_PET_TYPE = 1124,
+ LANG_COMMAND_LEARN_PET_TALENTS = 1125,
+ LANG_RESET_PET_TALENTS = 1126,
+ LANG_RESET_PET_TALENTS_ONLINE = 1127,
+ // Room for more level 3 1128-1199 not used
+
+ // Debug commands
+ LANG_CINEMATIC_NOT_EXIST = 1200,
+ LANG_MOVIE_NOT_EXIST = 1201,
+ // Room for more debug 1202-1299 not used
+
+ // FREE IDS 1300-9999
+
+ // AV
+ LANG_BG_AV_ALLY = 1300,
+ LANG_BG_AV_HORDE = 1301,
+ LANG_BG_AV_TOWER_TAKEN = 1302,
+ LANG_BG_AV_TOWER_ASSAULTED = 1303,
+ LANG_BG_AV_TOWER_DEFENDED = 1304,
+ LANG_BG_AV_GRAVE_TAKEN = 1305,
+ LANG_BG_AV_GRAVE_DEFENDED = 1306,
+ LANG_BG_AV_GRAVE_ASSAULTED = 1307,
+
+ LANG_BG_AV_MINE_TAKEN = 1308,
+ LANG_BG_AV_MINE_NORTH = 1309,
+ LANG_BG_AV_MINE_SOUTH = 1310,
+
+ LANG_BG_AV_NODE_GRAVE_STORM_AID = 1311,
+ LANG_BG_AV_NODE_TOWER_DUN_S = 1312,
+ LANG_BG_AV_NODE_TOWER_DUN_N = 1313,
+ LANG_BG_AV_NODE_GRAVE_STORMPIKE = 1314,
+ LANG_BG_AV_NODE_TOWER_ICEWING = 1315,
+ LANG_BG_AV_NODE_GRAVE_STONE = 1316,
+ LANG_BG_AV_NODE_TOWER_STONE = 1317,
+ LANG_BG_AV_NODE_GRAVE_SNOW = 1318,
+ LANG_BG_AV_NODE_TOWER_ICE = 1319,
+ LANG_BG_AV_NODE_GRAVE_ICE = 1320,
+ LANG_BG_AV_NODE_TOWER_POINT = 1321,
+ LANG_BG_AV_NODE_GRAVE_FROST = 1322,
+ LANG_BG_AV_NODE_TOWER_FROST_E = 1323,
+ LANG_BG_AV_NODE_TOWER_FROST_W = 1324,
+ LANG_BG_AV_NODE_GRAVE_FROST_HUT = 1325,
+
+ LANG_BG_AV_ONEMINTOSTART = 1326,
+ LANG_BG_AV_HALFMINTOSTART = 1327,
+ LANG_BG_AV_STARTED = 1328,
+ LANG_BG_AV_A_NEAR_LOSE = 1329,
+ LANG_BG_AV_H_NEAR_LOSE = 1330,
+ LANG_BG_AV_H_CAPTAIN_DEAD = 1331,
+ LANG_BG_AV_A_CAPTAIN_DEAD = 1332,
+ // FREE IDS 1333-1999
// Ticket Strings 2000-2029
LANG_COMMAND_TICKETNEW = 2000,
@@ -787,7 +841,7 @@ enum TrinityStrings
LANG_COMMAND_TICKETLISTADDCOMMENT = 2024,
LANG_COMMAND_TICKETLISTAGECREATE = 2025,
- // Trinity strings 5000-9999
+ // Trinity strings 5000-9999
LANG_COMMAND_FREEZE = 5000,
LANG_COMMAND_FREEZE_ERROR = 5001,
LANG_COMMAND_FREEZE_WRONG = 5002,
@@ -795,14 +849,20 @@ enum TrinityStrings
LANG_COMMAND_NO_FROZEN_PLAYERS = 5004,
LANG_COMMAND_LIST_FREEZE = 5005,
LANG_COMMAND_FROZEN_PLAYERS = 5006,
- LANG_INSTANCE_MUST_RAID_GRP = 5007,
- LANG_INSTANCE_NOT_AS_GHOST = 5008,
+ LANG_INSTANCE_RAID_GROUP_ONLY = 5007,
+ //LANG_INSTANCE_NOT_AS_GHOST = 5008,
LANG_COMMAND_PLAYED_TO_ALL = 5009,
- // Room for more Trinity strings 5010-9999
+ LANG_NPCINFO_LINKGUID = 5010,
+ // Room for more Trinity strings 5011-9999
// Used for GM Announcements
LANG_GM_BROADCAST = 6613,
LANG_GM_NOTIFY = 6614,
LANG_GM_ANNOUNCE_COLOR = 6615,
+ LANG_RESETALL_PET_SPELLS = 6616,
+
+ LANG_WORLD_CLOSED = 7523,
+ LANG_WORLD_OPENED = 7524,
+
// Use for not-in-offcial-sources patches
// 10000-10999
@@ -868,9 +928,7 @@ enum TrinityStrings
LANG_OPVP_EP_FLIGHT_CGT = 10053,
LANG_OPVP_ZM_GOSSIP_ALLIANCE = 10054,
LANG_OPVP_ZM_GOSSIP_HORDE = 10055,
- LANG_NO_ENTER_HALL_OF_LEGENDS = 10056,
- LANG_NO_ENTER_CHAMPIONS_HALL = 10057,
-
+
// Use for custom patches 11000-11999
// NOT RESERVED IDS 12000-1999999999
diff --git a/src/game/Level0.cpp b/src/game/Level0.cpp
index 62aa5d41709..c4f6935bced 100644
--- a/src/game/Level0.cpp
+++ b/src/game/Level0.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -20,13 +20,10 @@
#include "Common.h"
#include "Database/DatabaseEnv.h"
-#include "WorldPacket.h"
-#include "WorldSession.h"
#include "World.h"
#include "Player.h"
#include "Opcodes.h"
#include "Chat.h"
-#include "MapManager.h"
#include "ObjectAccessor.h"
#include "Language.h"
#include "AccountMgr.h"
@@ -59,8 +56,8 @@ bool ChatHandler::HandleCommandsCommand(const char* args)
bool ChatHandler::HandleAccountCommand(const char* /*args*/)
{
- uint32 gmlevel = m_session->GetSecurity();
- PSendSysMessage(LANG_ACCOUNT_LEVEL, gmlevel);
+ AccountTypes gmlevel = m_session->GetSecurity();
+ PSendSysMessage(LANG_ACCOUNT_LEVEL, uint32(gmlevel));
return true;
}
@@ -105,6 +102,7 @@ bool ChatHandler::HandleServerInfoCommand(const char* /*args*/)
//SendSysMessage(full);
//PSendSysMessage(LANG_USING_SCRIPT_LIB,sWorld.GetScriptsVersion());
//PSendSysMessage(LANG_USING_WORLD_DB,sWorld.GetDBVersion());
+ //PSendSysMessage(LANG_USING_EVENT_AI,sWorld.GetCreatureEventAIVersion());
PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum);
PSendSysMessage(LANG_UPTIME, str.c_str());
PSendSysMessage("Update time diff: %u.", updateTime);
@@ -130,7 +128,7 @@ bool ChatHandler::HandleDismountCommand(const char* /*args*/)
}
m_session->GetPlayer()->Unmount();
- m_session->GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+ m_session->GetPlayer()->RemoveAurasByType(SPELL_AURA_MOUNTED);
return true;
}
@@ -139,7 +137,7 @@ bool ChatHandler::HandleSaveCommand(const char* /*args*/)
Player *player=m_session->GetPlayer();
// save GM account without delay and output message (testing, etc)
- if(m_session->GetSecurity())
+ if(m_session->GetSecurity() > SEC_PLAYER)
{
player->SaveToDB();
SendSysMessage(LANG_PLAYER_SAVED);
@@ -148,7 +146,7 @@ bool ChatHandler::HandleSaveCommand(const char* /*args*/)
// save or plan save after 20 sec (logout delay) if current next save time more this value and _not_ output any messages to prevent cheat planning
uint32 save_interval = sWorld.getConfig(CONFIG_INTERVAL_SAVE);
- if(save_interval==0 || save_interval > 20*1000 && player->GetSaveTimer() <= save_interval - 20*1000)
+ if(save_interval==0 || save_interval > 20*IN_MILISECONDS && player->GetSaveTimer() <= save_interval - 20*IN_MILISECONDS)
player->SaveToDB();
return true;
@@ -159,10 +157,10 @@ bool ChatHandler::HandleGMListIngameCommand(const char* /*args*/)
bool first = true;
HashMapHolder<Player>::MapType &m = HashMapHolder<Player>::GetContainer();
- HashMapHolder<Player>::MapType::iterator itr = m.begin();
+ HashMapHolder<Player>::MapType::const_iterator itr = m.begin();
for(; itr != m.end(); ++itr)
{
- if (itr->second->GetSession()->GetSecurity() &&
+ if (itr->second->GetSession()->GetSecurity() > SEC_PLAYER &&
(itr->second->isGameMaster() || sWorld.getConfig(CONFIG_GM_IN_GM_LIST)) &&
(!m_session || itr->second->IsVisibleGloballyFor(m_session->GetPlayer())) )
{
@@ -172,7 +170,7 @@ bool ChatHandler::HandleGMListIngameCommand(const char* /*args*/)
first = false;
}
- SendSysMessage(itr->second->GetName());
+ SendSysMessage(GetNameLink(itr->second).c_str());
}
}
@@ -182,7 +180,7 @@ bool ChatHandler::HandleGMListIngameCommand(const char* /*args*/)
return true;
}
-bool ChatHandler::HandlePasswordCommand(const char* args)
+bool ChatHandler::HandleAccountPasswordCommand(const char* args)
{
if(!*args)
return false;
@@ -233,7 +231,7 @@ bool ChatHandler::HandlePasswordCommand(const char* args)
return true;
}
-bool ChatHandler::HandleLockAccountCommand(const char* args)
+bool ChatHandler::HandleAccountLockCommand(const char* args)
{
if (!*args)
{
diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp
index 1966bf6aa51..963e79f8829 100644
--- a/src/game/Level1.cpp
+++ b/src/game/Level1.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -40,6 +40,7 @@
#include "VMapFactory.h"
#endif
+//-----------------------Npc Commands-----------------------
bool ChatHandler::HandleNpcSayCommand(const char* args)
{
if(!*args)
@@ -53,7 +54,7 @@ bool ChatHandler::HandleNpcSayCommand(const char* args)
return false;
}
- pCreature->Say(args, LANG_UNIVERSAL, 0);
+ pCreature->MonsterSay(args, LANG_UNIVERSAL, 0);
return true;
}
@@ -71,7 +72,7 @@ bool ChatHandler::HandleNpcYellCommand(const char* args)
return false;
}
- pCreature->Yell(args, LANG_UNIVERSAL, 0);
+ pCreature->MonsterYell(args, LANG_UNIVERSAL, 0);
return true;
}
@@ -91,7 +92,7 @@ bool ChatHandler::HandleNpcTextEmoteCommand(const char* args)
return false;
}
- pCreature->TextEmote(args, 0);
+ pCreature->MonsterTextEmote(args, 0);
return true;
}
@@ -106,7 +107,7 @@ bool ChatHandler::HandleNpcWhisperCommand(const char* args)
char* text = strtok(NULL, "");
uint64 guid = m_session->GetPlayer()->GetSelection();
- Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
+ Creature* pCreature = m_session->GetPlayer()->GetMap()->GetCreature(guid);
if(!pCreature || !receiver_str || !text)
{
@@ -115,18 +116,22 @@ bool ChatHandler::HandleNpcWhisperCommand(const char* args)
uint64 receiver_guid= atol(receiver_str);
- pCreature->Whisper(text,receiver_guid);
+ // check online security
+ if (HasLowerSecurity(objmgr.GetPlayer(receiver_guid), 0))
+ return false;
+
+ pCreature->MonsterWhisper(text,receiver_guid);
return true;
}
+//----------------------------------------------------------
bool ChatHandler::HandleNameAnnounceCommand(const char* args)
{
WorldPacket data;
if(!*args)
return false;
- //char str[1024];
- //sprintf(str, GetTrinityString(LANG_ANNOUNCE_COLOR), m_session->GetPlayer()->GetName(), args);
+
sWorld.SendWorldText(LANG_ANNOUNCE_COLOR, m_session->GetPlayer()->GetName(), args);
return true;
}
@@ -194,7 +199,7 @@ bool ChatHandler::HandleGMNotifyCommand(const char* args)
}
//Enable\Dissable GM Mode
-bool ChatHandler::HandleGMmodeCommand(const char* args)
+bool ChatHandler::HandleGMCommand(const char* args)
{
if(!*args)
{
@@ -627,7 +632,7 @@ bool ChatHandler::HandleGMTicketReloadCommand(const char*)
}
//Enable\Dissable Invisible mode
-bool ChatHandler::HandleVisibleCommand(const char* args)
+bool ChatHandler::HandleGMVisibleCommand(const char* args)
{
if (!*args)
{
@@ -656,14 +661,16 @@ bool ChatHandler::HandleVisibleCommand(const char* args)
return false;
}
+
+
bool ChatHandler::HandleGPSCommand(const char* args)
{
WorldObject *obj = NULL;
if (*args)
{
- std::string name = args;
- if(normalizePlayerName(name))
- obj = objmgr.GetPlayer(name.c_str());
+ uint64 guid = extractGuidFromLink((char*)args);
+ if(guid)
+ obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
if(!obj)
{
@@ -686,8 +693,8 @@ bool ChatHandler::HandleGPSCommand(const char* args)
CellPair cell_val = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
Cell cell(cell_val);
- uint32 zone_id = obj->GetZoneId();
- uint32 area_id = obj->GetAreaId();
+ uint32 zone_id, area_id;
+ obj->GetZoneAndAreaId(zone_id,area_id);
MapEntry const* mapEntry = sMapStore.LookupEntry(obj->GetMapId());
AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zone_id);
@@ -714,22 +721,30 @@ bool ChatHandler::HandleGPSCommand(const char* args)
obj->GetMapId(), (mapEntry ? mapEntry->name[m_session->GetSessionDbcLocale()] : "<unknown>" ),
zone_id, (zoneEntry ? zoneEntry->area_name[m_session->GetSessionDbcLocale()] : "<unknown>" ),
area_id, (areaEntry ? areaEntry->area_name[m_session->GetSessionDbcLocale()] : "<unknown>" ),
+ obj->GetPhaseMask(),
obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation(),
cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), obj->GetInstanceId(),
zone_x, zone_y, ground_z, floor_z, have_map, have_vmap );
sLog.outDebug("Player %s GPS call for %s '%s' (%s: %u):",
- GetName(),
+ m_session ? GetNameLink().c_str() : GetMangosString(LANG_CONSOLE_COMMAND),
(obj->GetTypeId() == TYPEID_PLAYER ? "player" : "creature"), obj->GetName(),
(obj->GetTypeId() == TYPEID_PLAYER ? "GUID" : "Entry"), (obj->GetTypeId() == TYPEID_PLAYER ? obj->GetGUIDLow(): obj->GetEntry()) );
sLog.outDebug(GetTrinityString(LANG_MAP_POSITION),
obj->GetMapId(), (mapEntry ? mapEntry->name[sWorld.GetDefaultDbcLocale()] : "<unknown>" ),
zone_id, (zoneEntry ? zoneEntry->area_name[sWorld.GetDefaultDbcLocale()] : "<unknown>" ),
area_id, (areaEntry ? areaEntry->area_name[sWorld.GetDefaultDbcLocale()] : "<unknown>" ),
+ obj->GetPhaseMask(),
obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation(),
cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), obj->GetInstanceId(),
zone_x, zone_y, ground_z, floor_z, have_map, have_vmap );
+ LiquidData liquid_status;
+ ZLiquidStatus res = map->getLiquidStatus(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), MAP_ALL_LIQUIDS, &liquid_status);
+ if (res)
+ {
+ PSendSysMessage(LANG_LIQUID_STATUS, liquid_status.level, liquid_status.depth_level, liquid_status.type, res);
+ }
return true;
}
@@ -739,9 +754,8 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
if(!*args)
return false;
- std::string name = args;
-
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -751,9 +765,14 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
Player *chr = objmgr.GetPlayer(name.c_str());
if (chr)
{
- if(chr->IsBeingTeleported()==true)
+ std::string nameLink = playerLink(name);
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ if(chr->IsBeingTeleported())
{
- PSendSysMessage(LANG_IS_TELEPORTED, chr->GetName());
+ PSendSysMessage(LANG_IS_TELEPORTED, nameLink.c_str());
SetSentErrorMessage(true);
return false;
}
@@ -762,10 +781,25 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
if(pMap->IsBattleGroundOrArena())
{
- // cannot summon to bg
- PSendSysMessage(LANG_CANNOT_SUMMON_TO_BG,chr->GetName());
- SetSentErrorMessage(true);
- return false;
+ // only allow if gm mode is on
+ if (!chr->isGameMaster())
+ {
+ PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM, nameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+ // if both players are in different bgs
+ else if (chr->GetBattleGroundId() && m_session->GetPlayer()->GetBattleGroundId() != chr->GetBattleGroundId())
+ {
+ PSendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG, nameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+ // all's well, set bg id
+ // when porting out from the bg, it will be reset to 0
+ chr->SetBattleGroundId(m_session->GetPlayer()->GetBattleGroundId(), m_session->GetPlayer()->GetBattleGroundTypeId());
+ // remember current position as entry point for return at bg end teleportation
+ chr->SetBattleGroundEntryPoint(chr->GetMapId(),chr->GetPositionX(),chr->GetPositionY(),chr->GetPositionZ(),chr->GetOrientation());
}
else if(pMap->IsDungeon())
{
@@ -773,7 +807,7 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
if( cMap->Instanceable() && cMap->GetInstanceId() != pMap->GetInstanceId() )
{
// cannot summon from instance to instance
- PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,chr->GetName());
+ PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,nameLink.c_str());
SetSentErrorMessage(true);
return false;
}
@@ -784,15 +818,15 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
(m_session->GetPlayer()->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) )
// the last check is a bit excessive, but let it be, just in case
{
- PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,chr->GetName());
+ PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,nameLink.c_str());
SetSentErrorMessage(true);
return false;
}
}
- PSendSysMessage(LANG_SUMMONING, chr->GetName(),"");
+ PSendSysMessage(LANG_SUMMONING, nameLink.c_str(),"");
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_SUMMONED_BY, GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_SUMMONED_BY, GetNameLink().c_str());
// stop flight if need
if(chr->isInFlight())
@@ -811,7 +845,13 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
}
else if (uint64 guid = objmgr.GetPlayerGUIDByName(name))
{
- PSendSysMessage(LANG_SUMMONING, name.c_str(),GetTrinityString(LANG_OFFLINE));
+ // check offline security
+ if (HasLowerSecurity(NULL, guid))
+ return false;
+
+ std::string nameLink = playerLink(name);
+
+ PSendSysMessage(LANG_SUMMONING, nameLink.c_str(),GetTrinityString(LANG_OFFLINE));
// in point where GM stay
Player::SavePositionInDB(m_session->GetPlayer()->GetMapId(),
@@ -839,9 +879,8 @@ bool ChatHandler::HandleGonameCommand(const char* args)
Player* _player = m_session->GetPlayer();
- std::string name = args;
-
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -851,26 +890,34 @@ bool ChatHandler::HandleGonameCommand(const char* args)
Player *chr = objmgr.GetPlayer(name.c_str());
if (chr)
{
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ std::string chrNameLink = playerLink(name);
+
Map* cMap = chr->GetMap();
if(cMap->IsBattleGroundOrArena())
{
// only allow if gm mode is on
if (!_player->isGameMaster())
{
- PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM,chr->GetName());
+ PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM,chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
- // if already in a bg, don't let port to other
- else if (_player->GetBattleGroundId())
+ // if both players are in different bgs
+ else if (_player->GetBattleGroundId() && _player->GetBattleGroundId() != chr->GetBattleGroundId())
{
- PSendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG,chr->GetName());
+ PSendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG,chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
// all's well, set bg id
// when porting out from the bg, it will be reset to 0
- _player->SetBattleGroundId(chr->GetBattleGroundId());
+ _player->SetBattleGroundId(chr->GetBattleGroundId(), chr->GetBattleGroundTypeId());
+ // remember current position as entry point for return at bg end teleportation
+ _player->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());
}
else if(cMap->IsDungeon())
{
@@ -884,7 +931,7 @@ bool ChatHandler::HandleGonameCommand(const char* args)
// we are in group, we can go only if we are in the player group
if (_player->GetGroup() != chr->GetGroup())
{
- PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY,chr->GetName());
+ PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY,chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
@@ -894,7 +941,7 @@ bool ChatHandler::HandleGonameCommand(const char* args)
// we are not in group, let's verify our GM mode
if (!_player->isGameMaster())
{
- PSendSysMessage(LANG_CANNOT_GO_TO_INST_GM,chr->GetName());
+ PSendSysMessage(LANG_CANNOT_GO_TO_INST_GM,chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
@@ -918,10 +965,9 @@ bool ChatHandler::HandleGonameCommand(const char* args)
_player->SetDifficulty(chr->GetDifficulty());
}
- PSendSysMessage(LANG_APPEARING_AT, chr->GetName());
-
+ PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str());
if (_player->IsVisibleGloballyFor(chr))
- ChatHandler(chr).PSendSysMessage(LANG_APPEARING_TO, _player->GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_APPEARING_TO, GetNameLink().c_str());
// stop flight if need
if(_player->isInFlight())
@@ -944,7 +990,13 @@ bool ChatHandler::HandleGonameCommand(const char* args)
if (uint64 guid = objmgr.GetPlayerGUIDByName(name))
{
- PSendSysMessage(LANG_APPEARING_AT, name.c_str());
+ // check offline security
+ if (HasLowerSecurity(NULL, guid))
+ return false;
+
+ std::string nameLink = playerLink(name);
+
+ PSendSysMessage(LANG_APPEARING_AT, nameLink.c_str());
// to point where player stay (if loaded)
float x,y,z,o;
@@ -983,12 +1035,15 @@ bool ChatHandler::HandleRecallCommand(const char* args)
chr = getSelectedPlayer();
if(!chr)
chr = m_session->GetPlayer();
+
+ // check online security
+ else if (HasLowerSecurity(chr, 0))
+ return false;
}
else
{
- std::string name = args;
-
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -1003,11 +1058,15 @@ bool ChatHandler::HandleRecallCommand(const char* args)
SetSentErrorMessage(true);
return false;
}
+
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
}
if(chr->IsBeingTeleported())
{
- PSendSysMessage(LANG_IS_TELEPORTED, chr->GetName());
+ PSendSysMessage(LANG_IS_TELEPORTED, GetNameLink(chr).c_str());
SetSentErrorMessage(true);
return false;
}
@@ -1041,6 +1100,10 @@ bool ChatHandler::HandleModifyKnownTitlesCommand(const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
uint64 titles2 = titles;
for(int i=1; i < sCharTitlesStore.GetNumRows(); ++i)
@@ -1090,9 +1153,13 @@ bool ChatHandler::HandleModifyHPCommand(const char* args)
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_HP, chr->GetName(), hp, hpm);
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_HP, GetNameLink(chr).c_str(), hp, hpm);
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_HP_CHANGED, GetName(), hp, hpm);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_HP_CHANGED, GetNameLink().c_str(), hp, hpm);
chr->SetMaxHealth( hpm );
chr->SetHealth( hp );
@@ -1134,9 +1201,13 @@ bool ChatHandler::HandleModifyManaCommand(const char* args)
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_MANA, chr->GetName(), mana, manam);
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_MANA, GetNameLink(chr).c_str(), mana, manam);
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_MANA_CHANGED, GetName(), mana, manam);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_MANA_CHANGED, GetNameLink().c_str(), mana, manam);
chr->SetMaxPower(POWER_MANA,manam );
chr->SetPower(POWER_MANA, mana );
@@ -1179,9 +1250,13 @@ bool ChatHandler::HandleModifyEnergyCommand(const char* args)
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_ENERGY, chr->GetName(), energy/10, energym/10);
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_ENERGY, GetNameLink(chr).c_str(), energy/10, energym/10);
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_ENERGY_CHANGED, GetName(), energy/10, energym/10);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_ENERGY_CHANGED, GetNameLink().c_str(), energy/10, energym/10);
chr->SetMaxPower(POWER_ENERGY,energym );
chr->SetPower(POWER_ENERGY, energy );
@@ -1226,9 +1301,13 @@ bool ChatHandler::HandleModifyRageCommand(const char* args)
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_RAGE, chr->GetName(), rage/10, ragem/10);
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_RAGE, GetNameLink(chr).c_str(), rage/10, ragem/10);
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_RAGE_CHANGED, GetName(), rage/10, ragem/10);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_RAGE_CHANGED, GetNameLink().c_str(), rage/10, ragem/10);
chr->SetMaxPower(POWER_RAGE,ragem );
chr->SetPower(POWER_RAGE, rage );
@@ -1236,6 +1315,40 @@ bool ChatHandler::HandleModifyRageCommand(const char* args)
return true;
}
+// Edit Player Runic Power
+bool ChatHandler::HandleModifyRunicPowerCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ int32 rune = atoi((char*)args)*10;
+ int32 runem = atoi((char*)args)*10;
+
+ if (rune <= 0 || runem <= 0 || runem < rune)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PSendSysMessage(LANG_YOU_CHANGE_RUNIC_POWER, GetNameLink(chr).c_str(), rune/10, runem/10);
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_RUNIC_POWER_CHANGED, GetNameLink().c_str(), rune/10, runem/10);
+
+ chr->SetMaxPower(POWER_RUNIC_POWER,runem );
+ chr->SetPower(POWER_RUNIC_POWER, rune );
+
+ return true;
+}
+
//Edit Player Faction
bool ChatHandler::HandleModifyFactionCommand(const char* args)
{
@@ -1350,9 +1463,13 @@ bool ChatHandler::HandleModifySpellCommand(const char* args)
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_SPELLFLATID, spellflatid, val, mark, chr->GetName());
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_SPELLFLATID, spellflatid, val, mark, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_SPELLFLATID_CHANGED, GetName(), spellflatid, val, mark);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_SPELLFLATID_CHANGED, GetNameLink().c_str(), spellflatid, val, mark);
WorldPacket data(SMSG_SET_FLAT_SPELL_MODIFIER, (1+1+2+2));
data << uint8(spellflatid);
@@ -1380,6 +1497,11 @@ bool ChatHandler::HandleModifyTalentCommand (const char* args)
SetSentErrorMessage(true);
return false;
}
+
+ // check online security
+ if (HasLowerSecurity(player, 0))
+ return false;
+
player->SetFreeTalentPoints(tp);
return true;
}
@@ -1404,21 +1526,25 @@ bool ChatHandler::HandleTaxiCheatCommand(const char* args)
chr=m_session->GetPlayer();
}
+ // check online security
+ else if (HasLowerSecurity(chr, 0))
+ return false;
+
if (argstr == "on")
{
chr->SetTaxiCheater(true);
- PSendSysMessage(LANG_YOU_GIVE_TAXIS, chr->GetName());
+ PSendSysMessage(LANG_YOU_GIVE_TAXIS, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, GetNameLink().c_str());
return true;
}
if (argstr == "off")
{
chr->SetTaxiCheater(false);
- PSendSysMessage(LANG_YOU_REMOVE_TAXIS, chr->GetName());
+ PSendSysMessage(LANG_YOU_REMOVE_TAXIS, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_REMOVED, GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_REMOVED, GetNameLink().c_str());
return true;
}
@@ -1451,16 +1577,22 @@ bool ChatHandler::HandleModifyASpeedCommand(const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ std::string chrNameLink = GetNameLink(chr);
+
if(chr->isInFlight())
{
- PSendSysMessage(LANG_CHAR_IN_FLIGHT,chr->GetName());
+ PSendSysMessage(LANG_CHAR_IN_FLIGHT,chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_ASPEED, ASpeed, chr->GetName());
+ PSendSysMessage(LANG_YOU_CHANGE_ASPEED, ASpeed, chrNameLink.c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_ASPEED_CHANGED, GetName(), ASpeed);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_ASPEED_CHANGED, GetNameLink().c_str(), ASpeed);
chr->SetSpeed(MOVE_WALK, ASpeed,true);
chr->SetSpeed(MOVE_RUN, ASpeed,true);
@@ -1493,16 +1625,22 @@ bool ChatHandler::HandleModifySpeedCommand(const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ std::string chrNameLink = GetNameLink(chr);
+
if(chr->isInFlight())
{
- PSendSysMessage(LANG_CHAR_IN_FLIGHT,chr->GetName());
+ PSendSysMessage(LANG_CHAR_IN_FLIGHT,chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_SPEED, Speed, chr->GetName());
+ PSendSysMessage(LANG_YOU_CHANGE_SPEED, Speed, chrNameLink.c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_SPEED_CHANGED, GetName(), Speed);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_SPEED_CHANGED, GetNameLink().c_str(), Speed);
chr->SetSpeed(MOVE_RUN,Speed,true);
@@ -1532,16 +1670,22 @@ bool ChatHandler::HandleModifySwimCommand(const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ std::string chrNameLink = GetNameLink(chr);
+
if(chr->isInFlight())
{
- PSendSysMessage(LANG_CHAR_IN_FLIGHT,chr->GetName());
+ PSendSysMessage(LANG_CHAR_IN_FLIGHT,chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_SWIM_SPEED, Swim, chr->GetName());
+ PSendSysMessage(LANG_YOU_CHANGE_SWIM_SPEED, Swim, chrNameLink.c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_SWIM_SPEED_CHANGED, GetName(), Swim);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_SWIM_SPEED_CHANGED, GetNameLink().c_str(), Swim);
chr->SetSpeed(MOVE_SWIM,Swim,true);
@@ -1571,16 +1715,22 @@ bool ChatHandler::HandleModifyBWalkCommand(const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ std::string chrNameLink = GetNameLink(chr);
+
if(chr->isInFlight())
{
- PSendSysMessage(LANG_CHAR_IN_FLIGHT,chr->GetName());
+ PSendSysMessage(LANG_CHAR_IN_FLIGHT,chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_BACK_SPEED, BSpeed, chr->GetName());
+ PSendSysMessage(LANG_YOU_CHANGE_BACK_SPEED, BSpeed, chrNameLink.c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_BACK_SPEED_CHANGED, GetName(), BSpeed);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_BACK_SPEED_CHANGED, GetNameLink().c_str(), BSpeed);
chr->SetSpeed(MOVE_RUN_BACK,BSpeed,true);
@@ -1610,9 +1760,13 @@ bool ChatHandler::HandleModifyFlyCommand(const char* args)
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_FLY_SPEED, FSpeed, chr->GetName());
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_FLY_SPEED, FSpeed, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_FLY_SPEED_CHANGED, GetName(), FSpeed);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_FLY_SPEED_CHANGED, GetNameLink().c_str(), FSpeed);
chr->SetSpeed(MOVE_FLIGHT,FSpeed,true);
@@ -1641,9 +1795,13 @@ bool ChatHandler::HandleModifyScaleCommand(const char* args)
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_SIZE, Scale, chr->GetName());
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_SIZE, Scale, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_SIZE_CHANGED, GetName(), Scale);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_SIZE_CHANGED, GetNameLink().c_str(), Scale);
chr->SetFloatValue(OBJECT_FIELD_SCALE_X, Scale);
@@ -1884,9 +2042,13 @@ bool ChatHandler::HandleModifyMountCommand(const char* args)
return false;
}
- PSendSysMessage(LANG_YOU_GIVE_MOUNT, chr->GetName());
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_GIVE_MOUNT, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_MOUNT_GIVED, GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_MOUNT_GIVED, GetNameLink().c_str());
chr->SetUInt32Value( UNIT_FIELD_FLAGS , 0x001000 );
chr->Mount(mId);
@@ -1921,6 +2083,10 @@ bool ChatHandler::HandleModifyMoneyCommand(const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
int32 addmoney = atoi((char*)args);
uint32 moneyuser = chr->GetMoney();
@@ -1932,25 +2098,25 @@ bool ChatHandler::HandleModifyMoneyCommand(const char* args)
sLog.outDetail(GetTrinityString(LANG_CURRENT_MONEY), moneyuser, addmoney, newmoney);
if(newmoney <= 0 )
{
- PSendSysMessage(LANG_YOU_TAKE_ALL_MONEY, chr->GetName());
+ PSendSysMessage(LANG_YOU_TAKE_ALL_MONEY, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_ALL_MONEY_GONE, GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_ALL_MONEY_GONE, GetNameLink().c_str());
chr->SetMoney(0);
}
else
{
- PSendSysMessage(LANG_YOU_TAKE_MONEY, abs(addmoney), chr->GetName());
+ PSendSysMessage(LANG_YOU_TAKE_MONEY, abs(addmoney), GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_MONEY_TAKEN, GetName(), abs(addmoney));
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_MONEY_TAKEN, GetNameLink().c_str(), abs(addmoney));
chr->SetMoney( newmoney );
}
}
else
{
- PSendSysMessage(LANG_YOU_GIVE_MONEY, addmoney, chr->GetName());
+ PSendSysMessage(LANG_YOU_GIVE_MONEY, addmoney, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, GetName(), addmoney);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, GetNameLink().c_str(), addmoney);
chr->ModifyMoney( addmoney );
}
@@ -1959,20 +2125,24 @@ bool ChatHandler::HandleModifyMoneyCommand(const char* args)
return true;
}
-//Edit Player field
+//Edit Unit field
bool ChatHandler::HandleModifyBitCommand(const char* args)
{
if( !*args )
return false;
- Player *chr = getSelectedPlayer();
- if (chr == NULL)
+ Unit *unit = getSelectedUnit();
+ if (!unit)
{
SendSysMessage(LANG_NO_CHAR_SELECTED);
SetSentErrorMessage(true);
return false;
}
+ // check online security
+ if (unit->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player *)unit, 0))
+ return false;
+
char* pField = strtok((char*)args, " ");
if (!pField)
return false;
@@ -1984,13 +2154,12 @@ bool ChatHandler::HandleModifyBitCommand(const char* args)
uint16 field = atoi(pField);
uint32 bit = atoi(pBit);
- if (field < 1 || field >= PLAYER_END)
+ if (field < OBJECT_END || field >= unit->GetValuesCount())
{
SendSysMessage(LANG_BAD_VALUE);
SetSentErrorMessage(true);
return false;
}
-
if (bit < 1 || bit > 32)
{
SendSysMessage(LANG_BAD_VALUE);
@@ -1998,17 +2167,16 @@ bool ChatHandler::HandleModifyBitCommand(const char* args)
return false;
}
- if ( chr->HasFlag( field, (1<<(bit-1)) ) )
+ if ( unit->HasFlag( field, (1<<(bit-1)) ) )
{
- chr->RemoveFlag( field, (1<<(bit-1)) );
+ unit->RemoveFlag( field, (1<<(bit-1)) );
PSendSysMessage(LANG_REMOVE_BIT, bit, field);
}
else
{
- chr->SetFlag( field, (1<<(bit-1)) );
+ unit->SetFlag( field, (1<<(bit-1)) );
PSendSysMessage(LANG_SET_BIT, bit, field);
}
-
return true;
}
@@ -2025,11 +2193,15 @@ bool ChatHandler::HandleModifyHonorCommand (const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
int32 amount = (uint32)atoi(args);
target->ModifyHonorPoints(amount);
- PSendSysMessage(LANG_COMMAND_MODIFY_HONOR, target->GetName(), target->GetHonorPoints());
+ PSendSysMessage(LANG_COMMAND_MODIFY_HONOR, GetNameLink(target).c_str(), target->GetHonorPoints());
return true;
}
@@ -2132,8 +2304,10 @@ bool ChatHandler::HandleLookupAreaCommand(const char* args)
}
}
}
+
if (counter == 0) // if counter == 0 then we found nth
SendSysMessage (LANG_COMMAND_NOAREAFOUND);
+
return true;
}
@@ -2215,35 +2389,6 @@ bool ChatHandler::HandleWhispersCommand(const char* args)
return false;
}
-//Play sound
-bool ChatHandler::HandlePlaySoundCommand(const char* args)
-{
- // USAGE: .debug playsound #soundid
- // #soundid - ID decimal number from SoundEntries.dbc (1st column)
- // this file have about 5000 sounds.
- // In this realization only caller can hear this sound.
- if( *args )
- {
- uint32 dwSoundId = atoi((char*)args);
-
- if( !sSoundEntriesStore.LookupEntry(dwSoundId) )
- {
- PSendSysMessage(LANG_SOUND_NOT_EXIST, dwSoundId);
- SetSentErrorMessage(true);
- return false;
- }
-
- WorldPacket data(SMSG_PLAY_OBJECT_SOUND,4+8);
- data << uint32(dwSoundId) << m_session->GetPlayer()->GetGUID();
- m_session->SendPacket(&data);
-
- PSendSysMessage(LANG_YOU_HEAR_SOUND, dwSoundId);
- return true;
- }
-
- return false;
-}
-
//Save all players in the world
bool ChatHandler::HandleSaveAllCommand(const char* /*args*/)
{
@@ -2260,9 +2405,13 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
// format: name "subject text" "mail text"
- char* pName = strtok((char*)args, " ");
- if(!pName)
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
+ }
char* tail1 = strtok(NULL, "");
if(!tail1)
@@ -2300,18 +2449,10 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
if (!msgText)
return false;
- // pName, msgSubject, msgText isn't NUL after prev. check
- std::string name = pName;
+ // msgSubject, msgText isn't NUL after prev. check
std::string subject = msgSubject;
std::string text = msgText;
- if(!normalizePlayerName(name))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
if(!receiver_guid)
{
@@ -2320,7 +2461,6 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
return false;
}
- uint32 mailId = objmgr.GenerateMailID();
// from console show not existed sender
uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
@@ -2332,24 +2472,19 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_NONE);
- PSendSysMessage(LANG_MAIL_SENT, name.c_str());
+ std::string nameLink = playerLink(name);
+ PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
return true;
}
// teleport player to given game_tele.entry
-bool ChatHandler::HandleNameTeleCommand(const char * args)
+bool ChatHandler::HandleTeleNameCommand(const char * args)
{
if(!*args)
return false;
- char* pName = strtok((char*)args, " ");
-
- if(!pName)
- return false;
-
- std::string name = pName;
-
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -2380,17 +2515,22 @@ bool ChatHandler::HandleNameTeleCommand(const char * args)
Player *chr = objmgr.GetPlayer(name.c_str());
if (chr)
{
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ std::string chrNameLink = playerLink(name);
if(chr->IsBeingTeleported()==true)
{
- PSendSysMessage(LANG_IS_TELEPORTED, chr->GetName());
+ PSendSysMessage(LANG_IS_TELEPORTED, chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
- PSendSysMessage(LANG_TELEPORTING_TO, chr->GetName(),"", tele->name.c_str());
+ PSendSysMessage(LANG_TELEPORTING_TO, chrNameLink.c_str(),"", tele->name.c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_TELEPORTED_TO_BY, GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_TELEPORTED_TO_BY, GetNameLink().c_str());
// stop flight if need
if(chr->isInFlight())
@@ -2404,10 +2544,17 @@ bool ChatHandler::HandleNameTeleCommand(const char * args)
chr->TeleportTo(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation);
}
- else if (uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str()))
+ else if (uint64 guid = objmgr.GetPlayerGUIDByName(name))
{
- PSendSysMessage(LANG_TELEPORTING_TO, name.c_str(), GetTrinityString(LANG_OFFLINE), tele->name.c_str());
- Player::SavePositionInDB(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation,MapManager::Instance().GetZoneId(tele->mapId,tele->position_x,tele->position_y),guid);
+ // check offline security
+ if (HasLowerSecurity(NULL, guid))
+ return false;
+
+ std::string nameLink = playerLink(name);
+
+ PSendSysMessage(LANG_TELEPORTING_TO, nameLink.c_str(), GetMangosString(LANG_OFFLINE), tele->name.c_str());
+ Player::SavePositionInDB(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation,
+ MapManager::Instance().GetZoneId(tele->mapId,tele->position_x,tele->position_y,tele->position_z),guid);
}
else
PSendSysMessage(LANG_NO_PLAYER, name.c_str());
@@ -2416,7 +2563,7 @@ bool ChatHandler::HandleNameTeleCommand(const char * args)
}
//Teleport group to given game_tele.entry
-bool ChatHandler::HandleGroupTeleCommand(const char * args)
+bool ChatHandler::HandleTeleGroupCommand(const char * args)
{
if(!*args)
return false;
@@ -2429,6 +2576,10 @@ bool ChatHandler::HandleGroupTeleCommand(const char * args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(player, 0))
+ return false;
+
// id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
GameTele const* tele = extractGameTeleFromLink((char*)args);
if(!tele)
@@ -2445,10 +2596,13 @@ bool ChatHandler::HandleGroupTeleCommand(const char * args)
SetSentErrorMessage(true);
return false;
}
+
+ std::string nameLink = GetNameLink(player);
+
Group *grp = player->GetGroup();
if(!grp)
{
- PSendSysMessage(LANG_NOT_IN_GROUP,player->GetName());
+ PSendSysMessage(LANG_NOT_IN_GROUP,nameLink.c_str());
SetSentErrorMessage(true);
return false;
}
@@ -2460,15 +2614,21 @@ bool ChatHandler::HandleGroupTeleCommand(const char * args)
if(!pl || !pl->GetSession() )
continue;
+ // check online security
+ if (HasLowerSecurity(pl, 0))
+ return false;
+
+ std::string plNameLink = GetNameLink(pl);
+
if(pl->IsBeingTeleported())
{
- PSendSysMessage(LANG_IS_TELEPORTED, pl->GetName());
+ PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str());
continue;
}
- PSendSysMessage(LANG_TELEPORTING_TO, pl->GetName(),"", tele->name.c_str());
+ PSendSysMessage(LANG_TELEPORTING_TO, plNameLink.c_str(),"", tele->name.c_str());
if (needReportToTarget(pl))
- ChatHandler(pl).PSendSysMessage(LANG_TELEPORTED_TO_BY, GetName());
+ ChatHandler(pl).PSendSysMessage(LANG_TELEPORTED_TO_BY, nameLink.c_str());
// stop flight if need
if(pl->isInFlight())
@@ -2492,9 +2652,8 @@ bool ChatHandler::HandleGroupgoCommand(const char* args)
if(!*args)
return false;
- std::string name = args;
-
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -2509,16 +2668,22 @@ bool ChatHandler::HandleGroupgoCommand(const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(player, 0))
+ return false;
+
Group *grp = player->GetGroup();
+ std::string nameLink = playerLink(name);
+
if(!grp)
{
- PSendSysMessage(LANG_NOT_IN_GROUP,player->GetName());
+ PSendSysMessage(LANG_NOT_IN_GROUP,nameLink.c_str());
SetSentErrorMessage(true);
return false;
}
- Map* gmMap = MapManager::Instance().GetMap(m_session->GetPlayer()->GetMapId(),m_session->GetPlayer());
+ Map* gmMap = m_session->GetPlayer()->GetMap();
bool to_instance = gmMap->Instanceable();
// we are in instance, and can summon only player in our group with us as lead
@@ -2539,29 +2704,35 @@ bool ChatHandler::HandleGroupgoCommand(const char* args)
if(!pl || pl==m_session->GetPlayer() || !pl->GetSession() )
continue;
+ // check online security
+ if (HasLowerSecurity(pl, 0))
+ return false;
+
+ std::string plNameLink = playerLink(pl->GetName());
+
if(pl->IsBeingTeleported()==true)
{
- PSendSysMessage(LANG_IS_TELEPORTED, pl->GetName());
+ PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
if (to_instance)
{
- Map* plMap = MapManager::Instance().GetMap(pl->GetMapId(),pl);
+ Map* plMap = pl->GetMap();
if ( plMap->Instanceable() && plMap->GetInstanceId() != gmMap->GetInstanceId() )
{
// cannot summon from instance to instance
- PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,pl->GetName());
+ PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,plNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
}
- PSendSysMessage(LANG_SUMMONING, pl->GetName(),"");
+ PSendSysMessage(LANG_SUMMONING, plNameLink.c_str(),"");
if (needReportToTarget(pl))
- ChatHandler(pl).PSendSysMessage(LANG_SUMMONED_BY, GetName());
+ ChatHandler(pl).PSendSysMessage(LANG_SUMMONED_BY, GetNameLink().c_str());
// stop flight if need
if(pl->isInFlight())
@@ -2695,6 +2866,11 @@ bool ChatHandler::HandleGoZoneXYCommand(const char* args)
float x = (float)atof(px);
float y = (float)atof(py);
+
+ // prevent accept wrong numeric args
+ if (x==0.0f && *px!='0' || y==0.0f && *py!='0')
+ return false;
+
uint32 areaid = cAreaId ? (uint32)atoi(cAreaId) : _player->GetZoneId();
AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaid);
@@ -2791,7 +2967,7 @@ bool ChatHandler::HandleGoGridCommand(const char* args)
return true;
}
-bool ChatHandler::HandleDrunkCommand(const char* args)
+bool ChatHandler::HandleModifyDrunkCommand(const char* args)
{
if(!*args) return false;
diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp
index 4937d230142..136156d44dd 100644
--- a/src/game/Level2.cpp
+++ b/src/game/Level2.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -10,19 +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 "Common.h"
#include "Database/DatabaseEnv.h"
-#include "WorldPacket.h"
-#include "WorldSession.h"
-#include "World.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "Item.h"
@@ -33,9 +30,11 @@
#include "MapManager.h"
#include "Language.h"
#include "World.h"
-#include "GameEvent.h"
+#include "GameEventMgr.h"
#include "SpellMgr.h"
+#include "PoolHandler.h"
#include "AccountMgr.h"
+#include "TicketMgr.h"
#include "WaypointManager.h"
#include "Util.h"
#include <cctype>
@@ -46,6 +45,7 @@
#include "TicketMgr.h"
#include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
+#include "CreatureGroups.h"
static uint32 ReputationRankStrIndex[MAX_REPUTATION_RANK] =
{
@@ -59,11 +59,13 @@ bool ChatHandler::HandleMuteCommand(const char* args)
if (!*args)
return false;
- char *charname = strtok((char*)args, " ");
- if (!charname)
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
-
- std::string cname = charname;
+ }
char *timetonotspeak = strtok(NULL, " ");
if(!timetonotspeak)
@@ -71,14 +73,7 @@ bool ChatHandler::HandleMuteCommand(const char* args)
uint32 notspeaktime = (uint32) atoi(timetonotspeak);
- if(!normalizePlayerName(cname))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str());
+ uint64 guid = objmgr.GetPlayerGUIDByName(name);
if(!guid)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
@@ -88,27 +83,11 @@ bool ChatHandler::HandleMuteCommand(const char* args)
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);
+ // must have strong lesser security level
+ if(HasLowerSecurity (chr,guid,true))
return false;
- }
+
+ uint32 account_id = chr ? chr->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(guid);
time_t mutetime = time(NULL) + notspeaktime*60;
@@ -120,7 +99,9 @@ bool ChatHandler::HandleMuteCommand(const char* args)
if(chr)
ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime);
- PSendSysMessage(LANG_YOU_DISABLE_CHAT, cname.c_str(), notspeaktime);
+ std::string nameLink = playerLink(name);
+
+ PSendSysMessage(LANG_YOU_DISABLE_CHAT, nameLink.c_str(), notspeaktime);
return true;
}
@@ -131,20 +112,15 @@ 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))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
- uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str());
+ uint64 guid = objmgr.GetPlayerGUIDByName(name);
if(!guid)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
@@ -154,27 +130,11 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)
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);
+ // must have strong lesser security level
+ if(HasLowerSecurity (chr,guid,true))
return false;
- }
+
+ uint32 account_id = chr ? chr->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(guid);
if (chr)
{
@@ -193,161 +153,15 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)
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();
+ std::string nameLink = playerLink(name);
- _player->TeleportTo(mapid, x, y, z, ort);
+ PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str());
return true;
}
bool ChatHandler::HandleGoTicketCommand(const char * args)
{
- if(!*args)
+ if(!*args)
return false;
char *cstrticket_id = strtok((char*)args, " ");
@@ -478,15 +292,15 @@ bool ChatHandler::HandleGoGraveyardCommand(const char* args)
}
/** \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.
- */
+*
+* .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)
{
@@ -584,434 +398,180 @@ bool ChatHandler::HandleGoCreatureCommand(const char* args)
return true;
}
-bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
+//teleport to gameobject
+bool ChatHandler::HandleGoObjectCommand(const char* args)
{
- uint64 guid = m_session->GetPlayer()->GetSelection();
-
- if (guid == 0)
- {
- SendSysMessage(LANG_NO_SELECTION);
- SetSentErrorMessage(true);
+ if(!*args)
return false;
- }
- PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid));
- return true;
-}
+ Player* _player = m_session->GetPlayer();
-bool ChatHandler::HandleLookupFactionCommand(const char* args)
-{
- if (!*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;
- // Can be NULL at console call
- Player *target = getSelectedPlayer ();
-
- std::string namepart = args;
- std::wstring wnamepart;
-
- if (!Utf8toWStr (namepart,wnamepart))
+ int32 guid = atoi(cId);
+ if(!guid)
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.
+ float x, y, z, ort;
+ int mapid;
- for (uint32 id = 0; id < sFactionStore.GetNumRows(); ++id)
+ // by DB guid
+ if (GameObjectData const* go_data = objmgr.GetGOData(guid))
{
- 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++;
- }
- }
+ x = go_data->posX;
+ y = go_data->posY;
+ z = go_data->posZ;
+ ort = go_data->orientation;
+ mapid = go_data->mapid;
}
-
- 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)
+ else
{
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);
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)
+ if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
{
- PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN, factionId);
+ PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
SetSentErrorMessage(true);
return false;
}
- if (factionEntry->reputationListID < 0)
+ // stop flight if need
+ if(_player->isInFlight())
{
- PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[m_session->GetSessionDbcLocale()], factionId);
- SetSentErrorMessage(true);
- return false;
+ _player->GetMotionMaster()->MovementExpired();
+ _player->m_taxi.ClearTaxiDestinations();
}
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
- target->SetFactionReputation(factionEntry,amount);
- PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId, target->GetName(), target->GetReputation(factionId));
+ _player->TeleportTo(mapid, x, y, z, ort);
return true;
}
-bool ChatHandler::HandleNameCommand(const char* args)
+bool ChatHandler::HandleGameObjectTargetCommand(const char* args)
{
- /* Temp. disabled
- if(!*args)
+ Player* pl = m_session->GetPlayer();
+ QueryResult *result;
+ GameEventMgr::ActiveEvents const& activeEventsList = gameeventmgr.GetActiveEventList();
+ if(*args)
+ {
+ // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
+ if(!cId)
return false;
- if(strlen((char*)args)>75)
+ uint32 id = atol(cId);
+
+ 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
{
- PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
- return true;
+ std::string name = cId;
+ 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 (uint8 i = 0; i < strlen(args); i++)
+ for (GameEventMgr::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr)
{
- if(!isalpha(args[i]) && args[i]!=' ')
+ if (initString)
{
- SendSysMessage(LANG_CHARS_ONLY);
- return false;
+ eventFilter << "OR event IN (" <<*itr;
+ initString =false;
}
+ else
+ eventFilter << "," << *itr;
}
- 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)
- {
+ if (!initString)
+ eventFilter << "))";
+ else
+ eventFilter << ")";
- PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
- return true;
+ 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 10",
+ m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY(), m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetMapId(),eventFilter.str().c_str());
}
- 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)
+ if (!result)
{
- SendSysMessage(LANG_NO_SELECTION);
+ SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND);
return true;
}
- Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
+ bool found = false;
+ float x, y, z, o;
+ uint32 lowguid, id;
+ uint16 mapid, pool_id;
- if(!pCreature)
+ do
{
- 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);
+ Field *fields = result->Fetch();
+ lowguid = fields[0].GetUInt32();
+ id = fields[1].GetUInt32();
+ x = fields[2].GetFloat();
+ y = fields[3].GetFloat();
+ z = fields[4].GetFloat();
+ o = fields[5].GetFloat();
+ mapid = fields[6].GetUInt16();
+ pool_id = poolhandler.IsPartOfAPool(lowguid, TYPEID_GAMEOBJECT);
+ if (!pool_id || (pool_id && poolhandler.IsSpawnedObject(pool_id, lowguid, TYPEID_GAMEOBJECT)))
+ found = true;
+ } while( result->NextRow() && (!found) );
- 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();
+ delete result;
- Creature* pCreature = new Creature;
- if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, (uint32)teamval))
+ if (!found)
{
- delete pCreature;
+ PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
return false;
}
- pCreature->Relocate(x,y,z,o);
+ GameObjectInfo const* goI = objmgr.GetGameObjectInfo(id);
- if(!pCreature->IsPositionValid())
+ if (!goI)
{
- 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;
+ PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
return false;
}
- pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
-
- uint32 db_guid = pCreature->GetDBTableGUIDLow();
-
- // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
- pCreature->LoadFromDB(db_guid, map);
+ GameObject* target = m_session->GetPlayer()->GetMap()->GetGameObject(MAKE_NEW_GUID(lowguid,id,HIGHGUID_GAMEOBJECT));
- map->Add(pCreature);
- objmgr.AddCreatureToGrid(db_guid, objmgr.GetCreatureData(db_guid));
- return true;
-}
-
-bool ChatHandler::HandleNpcDeleteCommand(const char* args)
-{
- Creature* unit = NULL;
+ PSendSysMessage(LANG_GAMEOBJECT_DETAIL, lowguid, goI->name, lowguid, id, x, y, z, mapid, o);
- if(*args)
+ if(target)
{
- // 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;
+ int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
+ if(curRespawnDelay < 0)
+ curRespawnDelay = 0;
- 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();
+ std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
+ std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
- if(!unit || unit->isPet() || unit->isTotem())
- {
- SendSysMessage(LANG_SELECT_CREATURE);
- SetSentErrorMessage(true);
- return false;
+ PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
}
-
- // 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)
+bool ChatHandler::HandleGameObjectDeleteCommand(const char* args)
{
// number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
char* cId = extractKeyFromLink((char*)args,"Hgameobject");
@@ -1039,7 +599,7 @@ bool ChatHandler::HandleDelObjectCommand(const char* args)
if(owner_guid)
{
Unit* owner = ObjectAccessor::GetUnit(*m_session->GetPlayer(),owner_guid);
- if(!owner && !IS_PLAYER_GUID(owner_guid))
+ if(!owner || !IS_PLAYER_GUID(owner_guid))
{
PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, GUID_LOPART(owner_guid), obj->GetGUIDLow());
SetSentErrorMessage(true);
@@ -1059,7 +619,7 @@ bool ChatHandler::HandleDelObjectCommand(const char* args)
}
//turn selected object
-bool ChatHandler::HandleTurnObjectCommand(const char* args)
+bool ChatHandler::HandleGameObjectTurnCommand(const char* args)
{
// number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
char* cId = extractKeyFromLink((char*)args,"Hgameobject");
@@ -1096,109 +656,24 @@ bool ChatHandler::HandleTurnObjectCommand(const char* args)
o = chr->GetOrientation();
}
- float rot2 = sin(o/2);
- float rot3 = cos(o/2);
-
- Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
+ Map* map = obj->GetMap();
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);
+ obj->UpdateRotationFields();
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();
+ PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), obj->GetGOInfo()->name, obj->GetGUIDLow(), o);
- 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)
+bool ChatHandler::HandleGameObjectMoveCommand(const char* args)
{
// number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
char* cId = extractKeyFromLink((char*)args,"Hgameobject");
@@ -1230,7 +705,7 @@ bool ChatHandler::HandleMoveObjectCommand(const char* args)
{
Player *chr = m_session->GetPlayer();
- Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
+ Map* map = obj->GetMap();
map->Remove(obj,false);
obj->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), obj->GetOrientation());
@@ -1256,7 +731,7 @@ bool ChatHandler::HandleMoveObjectCommand(const char* args)
return false;
}
- Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
+ Map* map = obj->GetMap();
map->Remove(obj,false);
obj->Relocate(x, y, z, obj->GetOrientation());
@@ -1270,25 +745,422 @@ bool ChatHandler::HandleMoveObjectCommand(const char* args)
obj->SaveToDB();
obj->Refresh();
- PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, obj->GetGUIDLow());
+ PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, obj->GetGUIDLow(), obj->GetGOInfo()->name, obj->GetGUIDLow());
return true;
}
-//demorph player or unit
-bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
+//spawn go
+bool ChatHandler::HandleGameObjectAddCommand(const char* args)
{
- Unit *target = getSelectedUnit();
+ if (!*args)
+ return false;
+
+ // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
+ if(!cId)
+ return false;
+
+ uint32 id = atol(cId);
+ 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();
+
+ GameObject* pGameObj = new GameObject;
+ uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
+
+ if(!pGameObj->Create(db_lowGUID, goI->id, map, chr->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))
+ {
+ 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()),chr->GetPhaseMaskForSpawn());
+
+ // 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(GetMangosString(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;
+}
+
+//set pahsemask for selected object
+bool ChatHandler::HandleGameObjectPhaseCommand(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* phaseStr = strtok (NULL, " ");
+ uint32 phasemask = phaseStr? atoi(phaseStr) : 0;
+ if ( phasemask == 0 )
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ obj->SetPhaseMask(phasemask,true);
+ obj->SaveToDB();
+ return true;
+}
+
+bool ChatHandler::HandleGameObjectNearCommand(const char* args)
+{
+ float distance = (!*args) ? 10 : atol(args);
+ uint32 count = 0;
+
+ Player* pl = m_session->GetPlayer();
+ QueryResult *result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
+ "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
+ "FROM gameobject WHERE map='%u' AND (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) <= '%f' ORDER BY order_",
+ pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),
+ pl->GetMapId(),pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),distance*distance);
+
+ if (result)
+ {
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 guid = fields[0].GetUInt32();
+ uint32 entry = fields[1].GetUInt32();
+ float x = fields[2].GetFloat();
+ float y = fields[3].GetFloat();
+ float z = fields[4].GetFloat();
+ int mapid = fields[5].GetUInt16();
+
+ GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(entry);
+
+ if(!gInfo)
+ continue;
+
+ PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
+
+ ++count;
+ } while (result->NextRow());
+
+ delete result;
+ }
+
+ PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE,distance,count);
+ 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 = target ? target->GetReputationMgr().GetState(factionEntry) : NULL;
+
+ 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->GetReputationMgr().GetRank(factionEntry);
+ std::string rankName = GetMangosString(ReputationRankStrIndex[rank]);
+
+ ss << " " << rankName << "|h|r (" << target->GetReputationMgr().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)
- target = m_session->GetPlayer();
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
- target->DeMorph();
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ 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 > ReputationMgr::PointsInRank[r] -1))
+ {
+ PSendSysMessage(LANG_COMMAND_FACTION_DELTA, (ReputationMgr::PointsInRank[r]-1));
+ SetSentErrorMessage(true);
+ return false;
+ }
+ amount += delta;
+ }
+ break;
+ }
+ amount += ReputationMgr::PointsInRank[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->GetReputationMgr().SetReputation(factionEntry,amount);
+ PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId,
+ GetNameLink(target).c_str(), target->GetReputationMgr().GetReputation(factionEntry));
+ return true;
+}
+
+//-----------------------Npc Commands-----------------------
+//add spawn of creature
+bool ChatHandler::HandleNpcAddCommand(const char* args)
+{
+ if(!*args)
+ return false;
+ char* charID = extractKeyFromLink((char*)args,"Hcreature_entry");
+ 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, chr->GetPhaseMaskForSpawn(), id, (uint32)teamval))
+ {
+ delete pCreature;
+ return false;
+ }
+
+ pCreature->Relocate(x,y,z,o);
+
+ if(!pCreature->IsPositionValid())
+ {
+ sLog.outError("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()), chr->GetPhaseMaskForSpawn());
+
+ 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;
}
//add item in vendorlist
-bool ChatHandler::HandleAddVendorItemCommand(const char* args)
+bool ChatHandler::HandleNpcAddVendorItemCommand(const char* args)
{
if (!*args)
return false;
@@ -1335,7 +1207,7 @@ bool ChatHandler::HandleAddVendorItemCommand(const char* args)
}
//del item from vendor list
-bool ChatHandler::HandleDelVendorItemCommand(const char* args)
+bool ChatHandler::HandleNpcDelVendorItemCommand(const char* args)
{
if (!*args)
return false;
@@ -1357,7 +1229,6 @@ bool ChatHandler::HandleDelVendorItemCommand(const char* args)
}
uint32 itemId = atol(pitem);
-
if(!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId))
{
PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId);
@@ -1413,6 +1284,8 @@ bool ChatHandler::HandleNpcAddMoveCommand(const char* args)
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->GetWaypointPath())
@@ -1427,10 +1300,193 @@ bool ChatHandler::HandleNpcAddMoveCommand(const char* args)
pCreature->SaveToDB();
}
+ SendSysMessage(LANG_WAYPOINT_ADDED);
+
return true;
}
-/**
+//change level of creature or pet
+bool ChatHandler::HandleNpcChangeLevelCommand(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;
+}
+
+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 = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT));
+ }
+ else
+ unit = getSelectedCreature();
+
+ if(!unit || unit->isPet() || unit->isTotem() || unit->isVehicle())
+ {
+ 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;
+}
+
+//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;
+
+ 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;
+ }
+ pCreature->GetMap()->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;
+}
+
+/**HandleNpcSetMoveTypeCommand
* Set the movement type for an NPC.<br/>
* <br/>
* Valid movement types are:
@@ -1545,6 +1601,10 @@ bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args)
else
return false;
+ // update movement type
+ //if(doNotDelete == false)
+ // WaypointMgr.DeletePath(lowguid);
+
if(pCreature)
{
// update movement type
@@ -1570,23 +1630,49 @@ bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args)
}
return true;
-} // HandleNpcSetMoveTypeCommand
+}
-//change level of creature or pet
-bool ChatHandler::HandleChangeLevelCommand(const char* args)
+//set model of creature
+bool ChatHandler::HandleNpcSetModelCommand(const char* args)
{
if (!*args)
return false;
- uint8 lvl = (uint8) atoi((char*)args);
- if ( lvl < 1 || lvl > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) + 3)
+ uint32 displayId = (uint32) atoi((char*)args);
+
+ Creature *pCreature = getSelectedCreature();
+
+ if(!pCreature || pCreature->isPet())
{
- SendSysMessage(LANG_BAD_VALUE);
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pCreature->SetDisplayId(displayId);
+ pCreature->SetNativeDisplayId(displayId);
+
+ pCreature->SaveToDB();
+
+ 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);
@@ -1594,126 +1680,441 @@ bool ChatHandler::HandleChangeLevelCommand(const char* args)
return false;
}
- if(pCreature->isPet())
+ pCreature->setFaction(factionId);
+
+ // faction is set in creature_template - not inside creature
+
+ // update in memory
+ if(CreatureInfo const *cinfo = pCreature->GetCreatureInfo())
{
- ((Pet*)pCreature)->GivePetLevel(lvl);
+ 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;
+}
+//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->SetMaxHealth( 100 + 30*lvl);
- pCreature->SetHealth( 100 + 30*lvl);
- pCreature->SetLevel( lvl);
- pCreature->SaveToDB();
+ 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;
}
-
-//set npcflag of creature
-bool ChatHandler::HandleNpcFlagCommand(const char* args)
+//spawn time handling
+bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args)
{
- if (!*args)
+ if(!*args)
return false;
- uint32 npcFlags = (uint32) atoi((char*)args);
+ char* stime = strtok((char*)args, " ");
- Creature* pCreature = getSelectedCreature();
+ if (!stime)
+ return false;
- if(!pCreature)
+ int i_stime = atoi((char*)stime);
+
+ if (i_stime < 0)
{
- SendSysMessage(LANG_SELECT_CREATURE);
+ SendSysMessage(LANG_BAD_VALUE);
SetSentErrorMessage(true);
return false;
}
- pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags);
+ Creature *pCreature = getSelectedCreature();
+ uint32 u_guidlow = 0;
- WorldDatabase.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry());
+ if (pCreature)
+ u_guidlow = pCreature->GetDBTableGUIDLow();
+ else
+ return false;
- SendSysMessage(LANG_VALUE_SAVED_REJOIN);
+ 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;
}
-
-//set model of creature
-bool ChatHandler::HandleNpcSetModelCommand(const char* args)
+//npc follow handling
+bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
{
- if (!*args)
+ Player *player = m_session->GetPlayer();
+ Creature *creature = getSelectedCreature();
+
+ if(!creature)
+ {
+ PSendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
return false;
+ }
- uint32 displayId = (uint32) atoi((char*)args);
+ // Follow player - Using pet's default dist and angle
+ creature->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
- Creature *pCreature = getSelectedCreature();
+ PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW, creature->GetName());
+ return true;
+}
+//npc unfollow handling
+bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
+{
+ Player *player = m_session->GetPlayer();
+ Creature *creature = getSelectedCreature();
- if(!pCreature || pCreature->isPet())
+ if(!creature)
{
- SendSysMessage(LANG_SELECT_CREATURE);
+ PSendSysMessage(LANG_SELECT_CREATURE);
SetSentErrorMessage(true);
return false;
}
- pCreature->SetDisplayId(displayId);
- pCreature->SetNativeDisplayId(displayId);
+ if (/*creature->GetMotionMaster()->empty() ||*/
+ creature->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE)
+ {
+ PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
+ SetSentErrorMessage(true);
+ return false;
+ }
- pCreature->SaveToDB();
+ 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;
}
+//npc tame handling
+bool ChatHandler::HandleNpcTameCommand(const char* /*args*/)
+{
+ Creature *creatureTarget = getSelectedCreature ();
+ if (!creatureTarget || creatureTarget->isPet ())
+ {
+ PSendSysMessage (LANG_SELECT_CREATURE);
+ SetSentErrorMessage (true);
+ return false;
+ }
-//morph creature or player
-bool ChatHandler::HandleMorphCommand(const char* args)
+ Player *player = m_session->GetPlayer ();
+
+ if(player->GetPetGUID ())
+ {
+ SendSysMessage (LANG_YOU_ALREADY_HAVE_PET);
+ SetSentErrorMessage (true);
+ return false;
+ }
+
+ CreatureInfo const* cInfo = creatureTarget->GetCreatureInfo();
+
+ if (!cInfo->isTameable ())
+ {
+ PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry);
+ SetSentErrorMessage (true);
+ return false;
+ }
+
+ // Everything looks OK, create new pet
+ Pet* pet = player->CreateTamedPetFrom (creatureTarget);
+ if (!pet)
+ {
+ PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry);
+ SetSentErrorMessage (true);
+ return false;
+ }
+
+ // place pet before player
+ float x,y,z;
+ player->GetClosePoint (x,y,z,creatureTarget->GetObjectSize (),CONTACT_DISTANCE);
+ pet->Relocate (x,y,z,M_PI-player->GetOrientation ());
+
+ // set pet to defensive mode by default (some classes can't control controlled pets in fact).
+ pet->SetReactState(REACT_DEFENSIVE);
+
+ // calculate proper level
+ uint32 level = (creatureTarget->getLevel() < (player->getLevel() - 5)) ? (player->getLevel() - 5) : creatureTarget->getLevel();
+
+ // prepare visual effect for levelup
+ pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
+
+ // add to world
+ pet->GetMap()->Add((Creature*)pet);
+
+ // visual effect for levelup
+ pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
+
+ // caster have pet now
+ player->SetGuardian(pet, true);
+
+ pet->SavePetToDB(PET_SAVE_AS_CURRENT);
+ player->PetSpellInitialize();
+
+ return true;
+}
+//npc phasemask handling
+//change phasemask of creature or pet
+bool ChatHandler::HandleNpcSetPhaseCommand(const char* args)
{
if (!*args)
return false;
- uint16 display_id = (uint16)atoi((char*)args);
+ uint32 phasemask = (uint32) atoi((char*)args);
+ if ( phasemask == 0 )
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
- Unit *target = getSelectedUnit();
- if(!target)
- target = m_session->GetPlayer();
+ Creature* pCreature = getSelectedCreature();
+ if(!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
- target->SetDisplayId(display_id);
+ pCreature->SetPhaseMask(phasemask,true);
+
+ if(!pCreature->isPet())
+ pCreature->SaveToDB();
return true;
}
-
-//set faction of creature
-bool ChatHandler::HandleNpcFactionIdCommand(const char* args)
+//npc deathstate handling
+bool ChatHandler::HandleNpcSetDeathStateCommand(const char* args)
{
if (!*args)
return false;
- uint32 factionId = (uint32) atoi((char*)args);
+ Creature* pCreature = getSelectedCreature();
+ if(!pCreature || pCreature->isPet())
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
- if (!sFactionTemplateStore.LookupEntry(factionId))
+ if (strncmp(args, "on", 3) == 0)
+ pCreature->SetDeadByDefault(true);
+ else if (strncmp(args, "off", 4) == 0)
+ pCreature->SetDeadByDefault(false);
+ else
{
- PSendSysMessage(LANG_WRONG_FACTION, factionId);
+ SendSysMessage(LANG_USE_BOL);
SetSentErrorMessage(true);
return false;
}
- Creature* pCreature = getSelectedCreature();
+ pCreature->SaveToDB();
+ pCreature->Respawn();
+
+ return true;
+}
+
+//TODO: NpcCommands that need to be fixed :
+
+bool ChatHandler::HandleNpcNameCommand(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);
- SetSentErrorMessage(true);
- return false;
+ return true;
}
- pCreature->setFaction(factionId);
+ pCreature->SetName(args);
+ uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
+ pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
- // faction is set in creature_template - not inside creature
+ pCreature->SaveToDB();
+ */
- // update in memory
- if(CreatureInfo const *cinfo = pCreature->GetCreatureInfo())
+ return true;
+}
+
+bool ChatHandler::HandleNpcSubNameCommand(const char* /*args*/)
+{
+ /* Temp. disabled
+
+ if(!*args)
+ args = "";
+
+ if(strlen((char*)args)>75)
{
- const_cast<CreatureInfo*>(cinfo)->faction_A = factionId;
- const_cast<CreatureInfo*>(cinfo)->faction_H = factionId;
+
+ PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
+ return true;
}
- // and DB
- WorldDatabase.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId, factionId, pCreature->GetEntry());
+ 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;
+}
+
+//demorph player or unit
+bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
+{
+ Unit *target = getSelectedUnit();
+ if(!target)
+ target = m_session->GetPlayer();
+
+
+ // check online security
+ else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
+ return false;
+
+ target->DeMorph();
+
+ return true;
+}
+
+//morph creature or player
+bool ChatHandler::HandleModifyMorphCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint16 display_id = (uint16)atoi((char*)args);
+
+ Unit *target = getSelectedUnit();
+ if(!target)
+ target = m_session->GetPlayer();
+
+ // check online security
+ else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
+ return false;
+
+ target->SetDisplayId(display_id);
return true;
}
@@ -1731,7 +2132,7 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args)
kicker = m_session->GetPlayer()->GetName();
if(!kickName)
- {
+ {
Player* player = getSelectedPlayer();
if(!player)
{
@@ -1747,14 +2148,16 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(player, 0))
+ return false;
+
if(sWorld.getConfig(CONFIG_SHOW_KICK_IN_WORLD) == 1)
{
-
sWorld.SendWorldText(LANG_COMMAND_KICKMESSAGE, player->GetName(), kicker.c_str(), reason.c_str());
}
else
{
-
PSendSysMessage(LANG_COMMAND_KICKMESSAGE, player->GetName(), kicker.c_str(), reason.c_str());
}
@@ -1762,8 +2165,8 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args)
}
else
{
- std::string name = kickName;
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)kickName);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -1785,34 +2188,56 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args)
return false;
}
- if(m_session && player->GetSession()->GetSecurity() > m_session->GetSecurity())
+ if(HasLowerSecurity(player, 0))
{
SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); //maybe replacement string for this later on
SetSentErrorMessage(true);
return false;
}
- if(sWorld.KickPlayer(name.c_str()))
+ std::string nameLink = playerLink(name);
+
+ if(sWorld.KickPlayer(name))
{
if(sWorld.getConfig(CONFIG_SHOW_KICK_IN_WORLD) == 1)
{
-
- sWorld.SendWorldText(LANG_COMMAND_KICKMESSAGE, name.c_str(), kicker.c_str(), reason.c_str());
+ sWorld.SendWorldText(LANG_COMMAND_KICKMESSAGE, nameLink.c_str(), kicker.c_str(), reason.c_str());
}
else
{
- PSendSysMessage(LANG_COMMAND_KICKMESSAGE, name.c_str(), kicker.c_str(), reason.c_str());
+ PSendSysMessage(LANG_COMMAND_KICKMESSAGE,nameLink.c_str());
}
}
else
{
- PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER, name.c_str());
+ PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER,nameLink.c_str());
return false;
}
}
return true;
}
+//set temporary phase mask for player
+bool ChatHandler::HandleModifyPhaseCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 phasemask = (uint32)atoi((char*)args);
+
+ Unit *target = getSelectedUnit();
+ if(!target)
+ target = m_session->GetPlayer();
+
+ // check online security
+ else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
+ return false;
+
+ target->SetPhaseMask(phasemask,true);
+
+ return true;
+}
+
//show info of player
bool ChatHandler::HandlePInfoCommand(const char* args)
{
@@ -1826,12 +2251,8 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
if (px)
{
- name = px;
-
+ name = extractPlayerNameFromLink(px);
if(name.empty())
- return false;
-
- if(!normalizePlayerName(name))
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -1872,6 +2293,10 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
// get additional information from Player object
if(target)
{
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
targetGUID = target->GetGUID();
name = target->GetName(); // re-read for case getSelectedPlayer() target
accId = target->GetSession()->GetAccountId();
@@ -1883,6 +2308,11 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
// get additional information from DB
else
{
+ // check offline security
+ if (HasLowerSecurity(NULL, targetGUID))
+ return false;
+
+ // 0
QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(targetGUID));
if (!result)
{
@@ -1933,7 +2363,9 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
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 nameLink = playerLink(name);
+
+ PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetMangosString(LANG_OFFLINE)), nameLink.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;
@@ -1951,18 +2383,16 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
return false;
}
- char* FactionName;
- for(FactionStateList::const_iterator itr = target->m_factions.begin(); itr != target->m_factions.end(); ++itr)
+ FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList();
+ for(FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.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]);
+ char const* factionName = factionEntry ? factionEntry->name[m_session->GetSessionDbcLocale()] : "#Not found#";
+ ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry);
+ std::string rankName = GetMangosString(ReputationRankStrIndex[rank]);
std::ostringstream ss;
- ss << itr->second.ID << ": |cffffffff|Hfaction:" << itr->second.ID << "|h[" << FactionName << "]|h|r " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")";
+ ss << itr->second.ID << ": |cffffffff|Hfaction:" << itr->second.ID << "|h[" << factionName << "]|h|r " << rankName << "|h|r ("
+ << target->GetReputationMgr().GetReputation(factionEntry) << ")";
if(itr->second.Flags & FACTION_FLAG_VISIBLE)
ss << GetTrinityString(LANG_FACTION_VISIBLE);
@@ -1983,81 +2413,215 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
return true;
}
-//set spawn dist of creature
-bool ChatHandler::HandleNpcSpawnDistCommand(const char* args)
+/*//show tickets
+void ChatHandler::ShowTicket(uint64 guid, char const* text, char const* time)
{
- if(!*args)
- return false;
+ std::string name;
+ if(!objmgr.GetPlayerNameByGUID(guid,name))
+ name = GetTrinityString(LANG_UNKNOWN);
- float option = atof((char*)args);
- if (option < 0.0f)
+ std::string nameLink = playerLink(name);
+
+ PSendSysMessage(LANG_COMMAND_TICKETVIEW, nameLink.c_str(),time,text);
+}
+
+//ticket commands
+bool ChatHandler::HandleTicketCommand(const char* args)
+{
+ char* px = strtok((char*)args, " ");
+
+ // ticket<end>
+ if (!px)
{
- SendSysMessage(LANG_BAD_VALUE);
- return false;
+ 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;
}
- MovementGeneratorType mtype = IDLE_MOTION_TYPE;
- if (option >0.0f)
- mtype = RANDOM_MOTION_TYPE;
+ // ticket on
+ if(strncmp(px,"on",3) == 0)
+ {
+ if(!m_session)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
- Creature *pCreature = getSelectedCreature();
- uint32 u_guidlow = 0;
+ m_session->GetPlayer()->SetAcceptTicket(true);
+ SendSysMessage(LANG_COMMAND_TICKETON);
+ return true;
+ }
- if (pCreature)
- u_guidlow = pCreature->GetDBTableGUIDLow();
- else
- return false;
+ // ticket off
+ if(strncmp(px,"off",4) == 0)
+ {
+ if(!m_session)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
- pCreature->SetRespawnRadius((float)option);
- pCreature->SetDefaultMovementType(mtype);
- pCreature->GetMotionMaster()->Initialize();
- if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
+ m_session->GetPlayer()->SetAcceptTicket(false);
+ SendSysMessage(LANG_COMMAND_TICKETOFF);
+ return true;
+ }
+
+ // ticket #num
+ int num = atoi(px);
+ if(num > 0)
{
- pCreature->setDeathState(JUST_DIED);
- pCreature->Respawn();
+ 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;
}
- WorldDatabase.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow);
- PSendSysMessage(LANG_COMMAND_SPAWNDIST,option);
+ std::string name = extractPlayerNameFromLink(px);
+ if(name.empty())
+ {
+ 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;
}
-bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args)
+//dell all tickets
+bool ChatHandler::HandleDelTicketCommand(const char *args)
{
- if(!*args)
+ char* px = strtok((char*)args, " ");
+ if (!px)
return false;
- char* stime = strtok((char*)args, " ");
+ // delticket all
+ if(strncmp(px,"all",4) == 0)
+ {
+ ticketmgr.DeleteAll();
+ SendSysMessage(LANG_COMMAND_ALLTICKETDELETED);
+ return true;
+ }
- if (!stime)
- return false;
+ int num = (uint32)atoi(px);
- int i_stime = atoi((char*)stime);
+ // 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;
- if (i_stime < 0)
+ 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, GetNameLink(pl).c_str());
+ }
+ else
+ PSendSysMessage(LANG_COMMAND_TICKETDEL);
+
+ return true;
+ }
+
+ std::string name = extractPlayerNameFromLink(px);
+ if(name.empty())
{
- SendSysMessage(LANG_BAD_VALUE);
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
- Creature *pCreature = getSelectedCreature();
- uint32 u_guidlow = 0;
+ uint64 guid = objmgr.GetPlayerGUIDByName(name);
- if (pCreature)
- u_guidlow = pCreature->GetDBTableGUIDLow();
- else
+ if(!guid)
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);
+ // delticket $char_name
+ ticketmgr.Delete(GUID_LOPART(guid));
+
+ // notify players about ticket deleting
+ if(Player* sender = objmgr.GetPlayer(guid))
+ sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
+ std::string nameLink = playerLink(name);
+
+ PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,nameLink.c_str());
return true;
-}
+}*/
+
/////WAYPOINT COMMANDS
+/**
+ * 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");
@@ -2177,7 +2741,7 @@ bool ChatHandler::HandleWpLoadPathCommand(const char *args)
target->LoadPath(pathid);
target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
target->GetMotionMaster()->Initialize();
- target->Say("Path loaded.",0,0);
+ target->MonsterSay("Path loaded.",0,0);
return true;
}
@@ -2220,7 +2784,7 @@ bool ChatHandler::HandleWpUnLoadPathCommand(const char *args)
target->SetDefaultMovementType(IDLE_MOTION_TYPE);
target->GetMotionMaster()->MoveTargetedHome();
target->GetMotionMaster()->Initialize();
- target->Say("Path unloaded.",0,0);
+ target->MonsterSay("Path unloaded.",0,0);
return true;
}
PSendSysMessage("%s%s|r", "|cffff33ff", "Target have no loaded path.");
@@ -2507,7 +3071,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
// Did the user select a visual spawnpoint?
if(wpGuid)
- wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
+ wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
// attempt check creature existence by DB data
else
{
@@ -2577,7 +3141,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
if( wpGuid != 0 )
{
- wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
+ wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
wpCreature->CombatStop();
wpCreature->DeleteFromDB();
wpCreature->AddObjectToRemoveList();
@@ -2606,13 +3170,13 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
// Respawn the owner of the waypoints
if( wpGuid != 0 )
{
- wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
+ wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
wpCreature->CombatStop();
wpCreature->DeleteFromDB();
wpCreature->AddObjectToRemoveList();
// re-create
Creature* wpCreature2 = new Creature;
- if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, VISUAL_WAYPOINT, 0))
+ if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0))
{
PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
delete wpCreature2;
@@ -2622,12 +3186,12 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
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());
+ sLog.outError("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()));
+ wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
// To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map);
map->Add(wpCreature2);
@@ -2661,7 +3225,6 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
}
PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
-
return true;
}
@@ -2718,11 +3281,8 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
pathid = atoi((char*)guid_str);
}
-
sLog.outDebug("DEBUG: HandleWpShowCommand: danach");
-
-
std::string show = show_str;
uint32 Maxpoint;
@@ -2801,7 +3361,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
{
Field *fields = result2->Fetch();
uint32 wpguid = fields[0].GetUInt32();
- Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpguid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
+ Creature* pCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpguid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
if(!pCreature)
{
@@ -2843,7 +3403,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
float o = chr->GetOrientation();
Creature* wpCreature = new Creature;
- if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
+ if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0))
{
PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
delete wpCreature;
@@ -2855,7 +3415,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
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());
+ sLog.outError("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;
@@ -2865,7 +3425,8 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
// set "wpguid" column to the visual waypoint
WorldDatabase.PExecuteLog("UPDATE waypoint_data SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), pathid, point);
- wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
+ wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
+ // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);
map->Add(wpCreature);
@@ -2906,7 +3467,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
Map *map = chr->GetMap();
Creature* pCreature = new Creature;
- if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, id, 0))
+ if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, chr->GetPhaseMaskForSpawn(), id, 0))
{
PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
delete pCreature;
@@ -2918,13 +3479,13 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
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());
+ sLog.outError("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->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
map->Add(pCreature);
@@ -2971,7 +3532,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
Map *map = chr->GetMap();
Creature* pCreature = new Creature;
- if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
+ if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0))
{
PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
delete pCreature;
@@ -2983,13 +3544,13 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
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());
+ sLog.outError("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->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
map->Add(pCreature);
@@ -3018,7 +3579,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
{
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 = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(guid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
if(!pCreature)
{
@@ -3061,7 +3622,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
//////////// WAYPOINT COMMANDS //
//rename characters
-bool ChatHandler::HandleRenameCommand(const char* args)
+bool ChatHandler::HandleCharacterRenameCommand(const char* args)
{
Player* target = NULL;
uint64 targetGUID = 0;
@@ -3071,9 +3632,8 @@ bool ChatHandler::HandleRenameCommand(const char* args)
if(px)
{
- oldname = px;
-
- if(!normalizePlayerName(oldname))
+ oldname = extractPlayerNameFromLink(px);
+ if(oldname.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -3100,104 +3660,85 @@ bool ChatHandler::HandleRenameCommand(const char* args)
if(target)
{
- PSendSysMessage(LANG_RENAME_PLAYER, target->GetName());
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ PSendSysMessage(LANG_RENAME_PLAYER, GetNameLink(target).c_str());
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));
+ // check offline security
+ if (HasLowerSecurity(NULL, targetGUID))
+ return false;
+
+ std::string oldNameLink = playerLink(oldname);
+
+ PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.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)
+// customize characters
+bool ChatHandler::HandleCharacterCustomizeCommand(const char* args)
{
- if (!*args)
- return false;
+ Player* target = NULL;
+ uint64 targetGUID = 0;
+ std::string oldname;
- char* pParam1 = strtok((char*)args, " ");
- if (!pParam1)
- return false;
+ char* px = strtok((char*)args, " ");
- uint32 id = atoi((char*)pParam1);
- if(!id)
- return false;
+ if(px)
+ {
+ oldname = extractPlayerNameFromLink(px);
+ if(oldname.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
- char* spawntimeSecs = strtok(NULL, " ");
+ target = objmgr.GetPlayer(oldname.c_str());
- const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id);
+ if (!target)
+ targetGUID = objmgr.GetPlayerGUIDByName(oldname);
+ }
- if (!goI)
+ if(!target && !targetGUID)
{
- PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
- SetSentErrorMessage(true);
- return false;
+ target = getSelectedPlayer();
}
- 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))
+ if(!target && !targetGUID)
{
- delete pGameObj;
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
}
- if( spawntimeSecs )
+ if(target)
{
- uint32 value = atoi((char*)spawntimeSecs);
- pGameObj->SetRespawnTime(value);
- //sLog.outDebug("*** spawntimeSecs: %d", value);
+ PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str());
+ target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE);
+ CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target->GetGUIDLow());
}
-
- // 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))
+ else
{
- delete pGameObj;
- return false;
- }
-
- sLog.outDebug(GetTrinityString(LANG_GAMEOBJECT_CURRENT), goI->name, db_lowGUID, x, y, z, o);
-
- map->Add(pGameObj);
+ std::string oldNameLink = playerLink(oldname);
- // 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_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGUID));
+ CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(targetGUID));
+ }
- 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)
+bool ChatHandler::HandleModifyStandStateCommand(const char* args)
{
if (!*args)
return false;
@@ -3208,7 +3749,7 @@ bool ChatHandler::HandleStandStateCommand(const char* args)
return true;
}
-bool ChatHandler::HandleAddHonorCommand(const char* args)
+bool ChatHandler::HandleHonorAddCommand(const char* args)
{
if (!*args)
return false;
@@ -3221,6 +3762,10 @@ bool ChatHandler::HandleAddHonorCommand(const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
uint32 amount = (uint32)atoi(args);
target->RewardHonor(NULL, 1, amount);
return true;
@@ -3236,11 +3781,15 @@ bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
return false;
}
+ // check online security
+ if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
+ return false;
+
m_session->GetPlayer()->RewardHonor(target, 1);
return true;
}
-bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)
+bool ChatHandler::HandleHonorUpdateCommand(const char* /*args*/)
{
Player *target = getSelectedPlayer();
if(!target)
@@ -3250,6 +3799,10 @@ bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)
return false;
}
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
target->UpdateHonorFields();
return true;
}
@@ -3270,8 +3823,8 @@ bool ChatHandler::HandleLookupEventCommand(const char* args)
uint32 counter = 0;
- GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
- GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
+ GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+ GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
for(uint32 id = 0; id < events.size(); ++id )
{
@@ -3304,12 +3857,12 @@ bool ChatHandler::HandleEventActiveListCommand(const char* args)
{
uint32 counter = 0;
- GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
- GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
+ GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+ GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
char const* active = GetTrinityString(LANG_ACTIVE);
- for(GameEvent::ActiveEvents::const_iterator itr = activeEvents.begin(); itr != activeEvents.end(); ++itr )
+ for(GameEventMgr::ActiveEvents::const_iterator itr = activeEvents.begin(); itr != activeEvents.end(); ++itr )
{
uint32 event_id = *itr;
GameEventData const& eventData = events[event_id];
@@ -3340,7 +3893,7 @@ bool ChatHandler::HandleEventInfoCommand(const char* args)
uint32 event_id = atoi(cId);
- GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+ GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
if(event_id >=events.size())
{
@@ -3357,7 +3910,7 @@ bool ChatHandler::HandleEventInfoCommand(const char* args)
return false;
}
- GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
+ GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
bool active = activeEvents.find(event_id) != activeEvents.end();
char const* activeStr = active ? GetTrinityString(LANG_ACTIVE) : "";
@@ -3389,7 +3942,7 @@ bool ChatHandler::HandleEventStartCommand(const char* args)
int32 event_id = atoi(cId);
- GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+ GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
if(event_id < 1 || event_id >=events.size())
{
@@ -3406,7 +3959,7 @@ bool ChatHandler::HandleEventStartCommand(const char* args)
return false;
}
- GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
+ GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
if(activeEvents.find(event_id) != activeEvents.end())
{
PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id);
@@ -3430,7 +3983,7 @@ bool ChatHandler::HandleEventStopCommand(const char* args)
int32 event_id = atoi(cId);
- GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+ GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
if(event_id < 1 || event_id >=events.size())
{
@@ -3447,7 +4000,7 @@ bool ChatHandler::HandleEventStopCommand(const char* args)
return false;
}
- GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
+ GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
if(activeEvents.find(event_id) == activeEvents.end())
{
@@ -3466,9 +4019,8 @@ bool ChatHandler::HandleCombatStopCommand(const char* args)
if(*args)
{
- std::string playername = args;
-
- if(!normalizePlayerName(playername))
+ std::string playername = extractPlayerNameFromLink((char*)args);
+ if(playername.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -3492,6 +4044,10 @@ bool ChatHandler::HandleCombatStopCommand(const char* args)
player = m_session->GetPlayer();
}
+ // check online security
+ if (HasLowerSecurity(player, 0))
+ return false;
+
player->CombatStop();
player->getHostilRefManager().deleteReferences();
return true;
@@ -3530,7 +4086,7 @@ bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
continue;
- m_session->GetPlayer()->learnSpell(skillLine->spellId);
+ m_session->GetPlayer()->learnSpell(skillLine->spellId,false);
}
}
}
@@ -3603,7 +4159,7 @@ bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)
continue;
if( !target->HasSpell(spellInfo->Id) )
- m_session->GetPlayer()->learnSpell(skillLine->spellId);
+ m_session->GetPlayer()->learnSpell(skillLine->spellId,false);
}
uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id);
@@ -3710,6 +4266,13 @@ bool ChatHandler::LookupPlayerSearchCommand(QueryResult* result, int32 limit)
delete result;
+ if(i==0) // empty accounts only
+ {
+ PSendSysMessage(LANG_NO_PLAYERS_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
return true;
}
@@ -3731,68 +4294,50 @@ bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/)
return false;
}
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
// Repair items
target->DurabilityRepairAll(false, 0, false);
- PSendSysMessage(LANG_YOU_REPAIR_ITEMS, target->GetName());
+ PSendSysMessage(LANG_YOU_REPAIR_ITEMS, GetNameLink(target).c_str());
if(needReportToTarget(target))
- ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, GetName());
+ ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, GetNameLink().c_str());
return true;
}
-bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
+bool ChatHandler::HandleWaterwalkCommand(const char* args)
{
- Player *player = m_session->GetPlayer();
- Creature *creature = getSelectedCreature();
-
- if(!creature)
- {
- PSendSysMessage(LANG_SELECT_CREATURE);
- SetSentErrorMessage(true);
+ if(!*args)
return false;
- }
- // Follow player - Using pet's default dist and angle
- creature->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ Player *player = getSelectedPlayer();
- 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)
+ if(!player)
{
- PSendSysMessage(LANG_SELECT_CREATURE);
+ PSendSysMessage(LANG_NO_CHAR_SELECTED);
SetSentErrorMessage(true);
return false;
}
- if (/*creature->GetMotionMaster()->empty() ||*/
- creature->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE)
- {
- PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
- SetSentErrorMessage(true);
+ // check online security
+ if (HasLowerSecurity(player, 0))
return false;
- }
- TargetedMovementGenerator<Creature> const* mgen
- = static_cast<TargetedMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top()));
-
- if(mgen->GetTarget()!=player)
+ if (strncmp(args, "on", 3) == 0)
+ player->SetMovement(MOVE_WATER_WALK); // ON
+ else if (strncmp(args, "off", 4) == 0)
+ player->SetMovement(MOVE_LAND_WALK); // OFF
+ else
{
- PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
- SetSentErrorMessage(true);
+ SendSysMessage(LANG_USE_BOL);
return false;
}
- // reset movement
- creature->GetMotionMaster()->MovementExpired(true);
-
- PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW, creature->GetName());
+ PSendSysMessage(LANG_YOU_SET_WATERWALK, args, GetNameLink(player).c_str());
+ if(needReportToTarget(player))
+ ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetNameLink().c_str());
return true;
}
@@ -3825,7 +4370,7 @@ bool ChatHandler::HandleCreatePetCommand(const char* args)
}
// Everything looks OK, create new pet
- Pet* pet = new Pet(HUNTER_PET);
+ Pet* pet = new Pet(player, HUNTER_PET);
if(!pet->CreateBaseAtCreature(creatureTarget))
{
@@ -3838,7 +4383,6 @@ bool ChatHandler::HandleCreatePetCommand(const char* args)
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());
@@ -3854,16 +4398,15 @@ bool ChatHandler::HandleCreatePetCommand(const char* args)
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);
+ pet->GetMap()->Add((Creature*)pet);
// visual effect for levelup
pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel());
- player->SetPet(pet);
+ player->SetGuardian(pet, true);
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
player->PetSpellInitialize();
@@ -3955,7 +4498,7 @@ bool ChatHandler::HandlePetTpCommand(const char *args)
uint32 tp = atol(args);
- pet->SetTP(tp);
+ //pet->SetTP(tp);
PSendSysMessage("Pet's tp changed to %u", tp);
return true;
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index 128971f0153..259bba869e2 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -36,7 +36,6 @@
#include "Guild.h"
#include "ObjectAccessor.h"
#include "MapManager.h"
-#include "SpellAuras.h"
#include "ScriptCalls.h"
#include "Language.h"
#include "GridNotifiersImpl.h"
@@ -526,19 +525,11 @@ bool ChatHandler::HandleAHBotOptionsCommand(const char* args)
}
//reload commands
-bool ChatHandler::HandleReloadCommand(const char* arg)
-{
- // this is error catcher for wrong table name in .reload commands
- PSendSysMessage("Db table with name starting from '%s' not found and can't be reloaded.",arg);
- SetSentErrorMessage(true);
- return false;
-}
-
bool ChatHandler::HandleReloadAllCommand(const char*)
{
- HandleReloadAreaTriggerTeleportCommand("");
HandleReloadSkillFishingBaseLevelCommand("");
+ HandleReloadAllAchievementCommand("");
HandleReloadAllAreaCommand("");
HandleReloadAllLootCommand("");
HandleReloadAllNpcCommand("");
@@ -554,6 +545,13 @@ bool ChatHandler::HandleReloadAllCommand(const char*)
return true;
}
+bool ChatHandler::HandleReloadAllAchievementCommand(const char*)
+{
+ HandleReloadAchievementCriteriaDataCommand("");
+ HandleReloadAchievementRewardCommand("");
+ return true;
+}
+
bool ChatHandler::HandleReloadAllAreaCommand(const char*)
{
//HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
@@ -577,6 +575,7 @@ bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/)
HandleReloadNpcOptionCommand("a");
HandleReloadNpcTrainerCommand("a");
HandleReloadNpcVendorCommand("a");
+ HandleReloadPointsOfInterestCommand("a");
return true;
}
@@ -618,10 +617,12 @@ bool ChatHandler::HandleReloadAllSpellCommand(const char*)
HandleReloadSkillExtraItemTemplateCommand("a");
HandleReloadSpellAffectCommand("a");
HandleReloadSpellRequiredCommand("a");
+ HandleReloadSpellAreaCommand("a");
HandleReloadSpellElixirCommand("a");
HandleReloadSpellLearnSpellCommand("a");
HandleReloadSpellLinkedSpellCommand("a");
HandleReloadSpellProcEventCommand("a");
+ HandleReloadSpellBonusesCommand("a");
HandleReloadSpellScriptTargetCommand("a");
HandleReloadSpellTargetPositionCommand("a");
HandleReloadSpellThreatsCommand("a");
@@ -639,11 +640,13 @@ bool ChatHandler::HandleReloadAllItemCommand(const char*)
bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
{
+ HandleReloadLocalesAchievementRewardCommand("a");
HandleReloadLocalesCreatureCommand("a");
HandleReloadLocalesGameobjectCommand("a");
HandleReloadLocalesItemCommand("a");
HandleReloadLocalesNpcTextCommand("a");
HandleReloadLocalesPageTextCommand("a");
+ HandleReloadLocalesPointsOfInterestCommand("a");
HandleReloadLocalesQuestCommand("a");
return true;
}
@@ -656,6 +659,22 @@ bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
return true;
}
+bool ChatHandler::HandleReloadAchievementCriteriaDataCommand(const char*)
+{
+ sLog.outString( "Re-Loading Additional Achievement Criteria Data..." );
+ achievementmgr.LoadAchievementCriteriaData();
+ SendGlobalSysMessage("DB table `achievement_criteria_data` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAchievementRewardCommand(const char*)
+{
+ sLog.outString( "Re-Loading Achievement Reward Data..." );
+ achievementmgr.LoadRewards();
+ SendGlobalSysMessage("DB table `achievement_reward` reloaded.");
+ return true;
+}
+
bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
{
sLog.outString( "Re-Loading Tavern Area Triggers..." );
@@ -740,6 +759,11 @@ bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
sLog.outString( "Re-Loading Quest Templates..." );
objmgr.LoadQuests();
SendGlobalGMSysMessage("DB table `quest_template` (quest definitions) reloaded.");
+
+ /// dependent also from `gameobject` but this table not reloaded anyway
+ sLog.outString( "Re-Loading GameObjects for quests..." );
+ objmgr.LoadGameObjectForQuests();
+ SendGlobalGMSysMessage("Data GameObjects for quests reloaded.");
return true;
}
@@ -788,6 +812,15 @@ bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
return true;
}
+bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*)
+{
+ sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" );
+ LoadLootTemplates_Milling();
+ LootTemplates_Milling.CheckLootRefs();
+ SendGlobalSysMessage("DB table `milling_loot_template` reloaded.");
+ return true;
+}
+
bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
{
sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
@@ -832,6 +865,15 @@ bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
return true;
}
+bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*)
+{
+ sLog.outString( "Re-Loading Loot Tables... (`spell_loot_template`)" );
+ LoadLootTemplates_Spell();
+ LootTemplates_Spell.CheckLootRefs();
+ SendGlobalSysMessage("DB table `spell_loot_template` reloaded.");
+ return true;
+}
+
bool ChatHandler::HandleReloadTrinityStringCommand(const char*)
{
sLog.outString( "Re-Loading trinity_string Table!" );
@@ -872,6 +914,14 @@ bool ChatHandler::HandleReloadNpcVendorCommand(const char*)
return true;
}
+bool ChatHandler::HandleReloadPointsOfInterestCommand(const char*)
+{
+ sLog.outString( "Re-Loading `points_of_interest` Table!" );
+ objmgr.LoadPointsOfInterest();
+ SendGlobalSysMessage("DB table `points_of_interest` reloaded.");
+ return true;
+}
+
bool ChatHandler::HandleReloadReservedNameCommand(const char*)
{
sLog.outString( "Loading ReservedNames... (`reserved_name`)" );
@@ -912,6 +962,14 @@ bool ChatHandler::HandleReloadSpellAffectCommand(const char*)
return true;
}
+bool ChatHandler::HandleReloadSpellAreaCommand(const char*)
+{
+ sLog.outString( "Re-Loading SpellArea Data..." );
+ spellmgr.LoadSpellAreas();
+ SendGlobalSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded.");
+ return true;
+}
+
bool ChatHandler::HandleReloadSpellRequiredCommand(const char*)
{
sLog.outString( "Re-Loading Spell Required Data... " );
@@ -952,6 +1010,14 @@ bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
return true;
}
+bool ChatHandler::HandleReloadSpellBonusesCommand(const char*)
+{
+ sLog.outString( "Re-Loading Spell Bonus Data..." );
+ spellmgr.LoadSpellBonusess();
+ SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
+ return true;
+}
+
bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
{
sLog.outString( "Re-Loading SpellsScriptTarget..." );
@@ -1161,6 +1227,14 @@ bool ChatHandler::HandleReloadSpellDisabledCommand(const char* /*arg*/)
return true;
}
+bool ChatHandler::HandleReloadLocalesAchievementRewardCommand(const char*)
+{
+ sLog.outString( "Re-Loading Locales Achievement Reward Data..." );
+ achievementmgr.LoadRewardLocales();
+ SendGlobalSysMessage("DB table `locales_achievement_reward` reloaded.");
+ return true;
+}
+
bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
{
sLog.outString( "Re-Loading Locales Creature ...");
@@ -1201,6 +1275,14 @@ bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/)
return true;
}
+bool ChatHandler::HandleReloadLocalesPointsOfInterestCommand(const char* /*arg*/)
+{
+ sLog.outString( "Re-Loading Locales Points Of Interest ... ");
+ objmgr.LoadPointOfInterestLocales();
+ SendGlobalSysMessage("DB table `locales_points_of_interest` reloaded.");
+ return true;
+}
+
bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
{
sLog.outString( "Re-Loading Locales Quest ... ");
@@ -1347,19 +1429,10 @@ bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
return false;
}
- uint32 targetSecurity = accmgr.GetSecurity(targetAccountId);
-
- /// m_session==NULL only for console
- uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
-
/// can set password only for target with less security
/// This is also reject self apply in fact
- if (targetSecurity >= plSecurity)
- {
- SendSysMessage (LANG_YOURS_SECURITY_IS_LOW);
- SetSentErrorMessage (true);
+ if(HasLowerSecurityAccount (NULL,targetAccountId,true))
return false;
- }
if (strcmp(szPassword1,szPassword2))
{
@@ -1392,21 +1465,6 @@ bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
return true;
}
-bool ChatHandler::HandleAllowMovementCommand(const char* /*args*/)
-{
- if(sWorld.getAllowMovement())
- {
- sWorld.SetAllowMovement(false);
- SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
- }
- else
- {
- sWorld.SetAllowMovement(true);
- SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
- }
- return true;
-}
-
bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
{
Player* SelectedPlayer = getSelectedPlayer();
@@ -1437,7 +1495,6 @@ bool ChatHandler::HandleSetSkillCommand(const char* args)
char *max_p = strtok (NULL, " ");
int32 skill = atoi(skill_p);
-
if (skill <= 0)
{
PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
@@ -1463,9 +1520,11 @@ bool ChatHandler::HandleSetSkillCommand(const char* args)
return false;
}
+ std::string tNameLink = GetNameLink(target);
+
if(!target->GetSkillValue(skill))
{
- PSendSysMessage(LANG_SET_SKILL_ERROR, target->GetName(), skill, sl->name[0]);
+ PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, sl->name[0]);
SetSentErrorMessage(true);
return false;
}
@@ -1476,7 +1535,7 @@ bool ChatHandler::HandleSetSkillCommand(const char* args)
return false;
target->SetSkill(skill, level, max);
- PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], target->GetName(), level, max);
+ PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], tNameLink.c_str(), level, max);
return true;
}
@@ -1487,27 +1546,12 @@ bool ChatHandler::HandleUnLearnCommand(const char* args)
return false;
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
- uint32 min_id = extractSpellIdFromLink((char*)args);
- if(!min_id)
+ uint32 spell_id = extractSpellIdFromLink((char*)args);
+ if(!spell_id)
return false;
- // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
- char* tail = strtok(NULL,"");
-
- uint32 max_id = extractSpellIdFromLink(tail);
-
- if (!max_id)
- {
- // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
- max_id = min_id+1;
- }
- else
- {
- if (max_id < min_id)
- std::swap(min_id,max_id);
-
- max_id=max_id+1;
- }
+ char const* allStr = strtok(NULL," ");
+ bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
Player* target = getSelectedPlayer();
if(!target)
@@ -1517,13 +1561,13 @@ bool ChatHandler::HandleUnLearnCommand(const char* args)
return false;
}
- for(uint32 spell=min_id;spell<max_id;spell++)
- {
- if (target->HasSpell(spell))
- target->removeSpell(spell);
- else
- SendSysMessage(LANG_FORGET_SPELL);
- }
+ if(allRanks)
+ spell_id = spellmgr.GetFirstSpellInChain (spell_id);
+
+ if (target->HasSpell(spell_id))
+ target->removeSpell(spell_id,false,!allRanks);
+ else
+ SendSysMessage(LANG_FORGET_SPELL);
return true;
}
@@ -1538,10 +1582,12 @@ bool ChatHandler::HandleCooldownCommand(const char* args)
return false;
}
+ std::string tNameLink = GetNameLink(target);
+
if (!*args)
{
target->RemoveAllSpellCooldown();
- PSendSysMessage(LANG_REMOVEALL_COOLDOWN, target->GetName());
+ PSendSysMessage(LANG_REMOVEALL_COOLDOWN, tNameLink.c_str());
}
else
{
@@ -1552,7 +1598,7 @@ bool ChatHandler::HandleCooldownCommand(const char* args)
if(!sSpellStore.LookupEntry(spell_id))
{
- PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetTrinityString(LANG_YOU) : target->GetName());
+ PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
@@ -1562,8 +1608,8 @@ bool ChatHandler::HandleCooldownCommand(const char* args)
data << uint64(target->GetGUID());
target->GetSession()->SendPacket(&data);
target->RemoveSpellCooldown(spell_id);
- PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetTrinityString(LANG_YOU) : target->GetName());
- }
+ PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
+ }
return true;
}
@@ -2188,7 +2234,7 @@ bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
continue;
}
- m_session->GetPlayer()->learnSpell(spell);
+ m_session->GetPlayer()->learnSpell(spell,false);
}
SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
@@ -2228,7 +2274,7 @@ bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
continue;
}
- m_session->GetPlayer()->learnSpell(spell);
+ m_session->GetPlayer()->learnSpell(spell,false);
}
SendSysMessage(LANG_LEARNING_GM_SKILLS);
@@ -2249,12 +2295,16 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
return true;
uint32 family = clsEntry->spellfamily;
- for (uint32 i = 0; i < sSpellStore.GetNumRows(); i++)
+ for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
if(!spellInfo)
continue;
+ // skip server-side/triggered spells
+ if(spellInfo->spellLevel==0)
+ continue;
+
// skip wrong class/race skills
if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
continue;
@@ -2263,8 +2313,6 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
if( spellInfo->SpellFamilyName != family)
continue;
- //TODO: skip triggered spells
-
// skip spells with first rank learned as talent (and all talents then also)
uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);
if(GetTalentSpellCost(first_rank) > 0 )
@@ -2274,33 +2322,94 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
continue;
- m_session->GetPlayer()->learnSpell(i);
+ m_session->GetPlayer()->learnSpell(i,false);
}
SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
return true;
}
-static void learnAllHighRanks(Player* player, uint32 spellid)
+bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
{
- SpellChainNode const* node;
- do
+ Player* player = m_session->GetPlayer();
+ uint32 classMask = player->getClassMask();
+
+ for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
{
- node = spellmgr.GetSpellChainNode(spellid);
- player->learnSpell(spellid);
- if (!node)
- break;
- spellid=node->next;
+ TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
+ if(!talentInfo)
+ continue;
+
+ TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
+ if(!talentTabInfo)
+ continue;
+
+ if( (classMask & talentTabInfo->ClassMask) == 0 )
+ continue;
+
+ // search highest talent rank
+ uint32 spellid = 0;
+
+ for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
+ {
+ if(talentInfo->RankID[rank]!=0)
+ {
+ spellid = talentInfo->RankID[rank];
+ break;
+ }
+ }
+
+ if(!spellid) // ??? none spells in talent
+ continue;
+
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
+ if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
+ continue;
+
+ // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
+ player->learnSpellHighRank(spellid);
}
- while (node->next);
+
+ SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
+ return true;
}
-bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
+bool ChatHandler::HandleLearnAllMyPetTalentsCommand(const char* /*args*/)
{
Player* player = m_session->GetPlayer();
- uint32 classMask = player->getClassMask();
- for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++)
+ Pet* pet = player->GetPet();
+ if(!pet)
+ {
+ SendSysMessage(LANG_NO_PET_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ CreatureInfo const *ci = pet->GetCreatureInfo();
+ if(!ci)
+ {
+ SendSysMessage(LANG_WRONG_PET_TYPE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
+ if(!pet_family)
+ {
+ SendSysMessage(LANG_WRONG_PET_TYPE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if(pet_family->petTalentType < 0) // not hunter pet
+ {
+ SendSysMessage(LANG_WRONG_PET_TYPE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
{
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
if(!talentInfo)
@@ -2310,13 +2419,14 @@ bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
if(!talentTabInfo)
continue;
- if( (classMask & talentTabInfo->ClassMask) == 0 )
+ // prevent learn talent for different family (cheating)
+ if(((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask)==0)
continue;
// search highest talent rank
uint32 spellid = 0;
- int rank = 4;
- for(; rank >= 0; --rank)
+
+ for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
{
if(talentInfo->RankID[rank]!=0)
{
@@ -2332,14 +2442,11 @@ bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
continue;
- // learn highest rank of talent
- player->learnSpell(spellid);
-
- // and learn all non-talent spell ranks (recursive by tree)
- learnAllHighRanks(player,spellid);
+ // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
+ pet->learnSpellHighRank(spellid);
}
- SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
+ SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS);
return true;
}
@@ -2347,7 +2454,7 @@ bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
{
// skipping UNIVERSAL language (0)
for(int i = 1; i < LANGUAGES_COUNT; ++i)
- m_session->GetPlayer()->learnSpell(lang_description[i].spell_id);
+ m_session->GetPlayer()->learnSpell(lang_description[i].spell_id,false);
SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
return true;
@@ -2355,13 +2462,11 @@ bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
{
- char* pName = strtok((char*)args, "");
Player *player = NULL;
- if (pName)
+ if (*args)
{
- std::string name = pName;
-
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -2383,7 +2488,7 @@ bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
player->learnDefaultSpells();
player->learnQuestRewardedSpells();
- PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,player->GetName());
+ PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,GetNameLink(player).c_str());
return true;
}
@@ -2403,25 +2508,31 @@ bool ChatHandler::HandleLearnCommand(const char* args)
if(!spell || !sSpellStore.LookupEntry(spell))
return false;
- if (targetPlayer->HasSpell(spell))
+ char const* allStr = strtok(NULL," ");
+ bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
+
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
+ if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
{
- if(targetPlayer == m_session->GetPlayer())
- SendSysMessage(LANG_YOU_KNOWN_SPELL);
- else
- PSendSysMessage(LANG_TARGET_KNOWN_SPELL,targetPlayer->GetName());
+ PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
SetSentErrorMessage(true);
return false;
}
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
- if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
+ if (!allRanks && targetPlayer->HasSpell(spell))
{
- PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
+ if(targetPlayer == m_session->GetPlayer())
+ SendSysMessage(LANG_YOU_KNOWN_SPELL);
+ else
+ PSendSysMessage(LANG_TARGET_KNOWN_SPELL,GetNameLink(targetPlayer).c_str());
SetSentErrorMessage(true);
return false;
}
- targetPlayer->learnSpell(spell);
+ if(allRanks)
+ targetPlayer->learnSpellHighRank(spell);
+ else
+ targetPlayer->learnSpell(spell,false);
return true;
}
@@ -2491,7 +2602,7 @@ bool ChatHandler::HandleAddItemCommand(const char* args)
if (count < 0)
{
plTarget->DestroyItemCount(itemId, -count, true, false);
- PSendSysMessage(LANG_REMOVEITEM, itemId, -count, plTarget->GetName());
+ PSendSysMessage(LANG_REMOVEITEM, itemId, -count, GetNameLink(plTarget).c_str());
return true;
}
@@ -2901,48 +3012,7 @@ bool ChatHandler::HandleListObjectCommand(const char* args)
return true;
}
-bool ChatHandler::HandleNearObjectCommand(const char* args)
-{
- float distance = (!*args) ? 10 : atol(args);
- uint32 count = 0;
-
- Player* pl = m_session->GetPlayer();
- QueryResult *result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
- "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
- "FROM gameobject WHERE map='%u' AND (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) <= '%f' ORDER BY order_",
- pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),
- pl->GetMapId(),pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),distance*distance);
-
- if (result)
- {
- do
- {
- Field *fields = result->Fetch();
- uint32 guid = fields[0].GetUInt32();
- uint32 entry = fields[1].GetUInt32();
- float x = fields[2].GetFloat();
- float y = fields[3].GetFloat();
- float z = fields[4].GetFloat();
- int mapid = fields[5].GetUInt16();
-
- GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(entry);
-
- if(!gInfo)
- continue;
-
- PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
-
- ++count;
- } while (result->NextRow());
-
- delete result;
- }
-
- PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE,distance,count);
- return true;
-}
-
-bool ChatHandler::HandleObjectStateCommand(const char* args)
+bool ChatHandler::HandleGameObjectStateCommand(const char* args)
{
// number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
char* cId = extractKeyFromLink((char*)args, "Hgameobject");
@@ -2965,17 +3035,40 @@ bool ChatHandler::HandleObjectStateCommand(const char* args)
return false;
}
+ char* ctype = strtok(NULL, " ");
+ if(!ctype)
+ return false;
+
+ int32 type = atoi(ctype);
+ if(type < 0)
+ {
+ if(type == -1)
+ gobj->SendObjectDeSpawnAnim(gobj->GetGUID());
+ else if(type == -2)
+ {
+ WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8);
+ data << gobj->GetGUID();
+ gobj->SendMessageToSet(&data,true);
+ }
+ return true;
+ }
+
char* cstate = strtok(NULL, " ");
if(!cstate)
return false;
int32 state = atoi(cstate);
- if(state < 0)
- gobj->SendObjectDeSpawnAnim(gobj->GetGUID());
- else
- gobj->SetGoState(state);
- return true;
+ if(type < 4)
+ gobj->SetByteValue(GAMEOBJECT_BYTES_1, type, state);
+ else if(type == 4)
+ {
+ WorldPacket data(SMSG_GAMEOBJECT_CUSTOM_ANIM,8+4);
+ data << gobj->GetGUID();
+ data << (uint32)(state);
+ gobj->SendMessageToSet(&data, true);
+ }
+ PSendSysMessage("Set gobject type %d state %d", type, state);
return true;
}
@@ -3231,15 +3324,25 @@ bool ChatHandler::HandleLookupSkillCommand(const char* args)
if(loc < MAX_LOCALE)
{
+ char valStr[50] = "";
char const* knownStr = "";
if(target && target->HasSkill(id))
+ {
knownStr = GetTrinityString(LANG_KNOWN);
+ uint32 curValue = target->GetPureSkillValue(id);
+ uint32 maxValue = target->GetPureMaxSkillValue(id);
+ uint32 permValue = target->GetSkillPermBonusValue(id);
+ uint32 tempValue = target->GetSkillTempBonusValue(id);
+
+ char const* valFormat = GetTrinityString(LANG_SKILL_VALUES);
+ snprintf(valStr,50,valFormat,curValue,maxValue,permValue,tempValue);
+ }
// send skill in "id - [namedlink locale]" format
if (m_session)
- PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr);
+ PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr,valStr);
else
- PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr);
+ PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr,valStr);
++counter;
}
@@ -3306,7 +3409,7 @@ bool ChatHandler::HandleLookupSpellCommand(const char* args)
bool talent = (talentCost > 0);
bool passive = IsPassiveSpell(id);
- bool active = target && (target->HasAura(id,0) || target->HasAura(id,1) || target->HasAura(id,2));
+ bool active = target && target->HasAura(id);
// unit32 used to prevent interpreting uint8 as char at output
// find rank of learned spell for learning spell, or talent rank
@@ -3626,7 +3729,7 @@ bool ChatHandler::HandleGuildCreateCommand(const char* args)
}
Guild *guild = new Guild;
- if (!guild->create (player->GetGUID (),guildname))
+ if (!guild->create (player,guildname))
{
delete guild;
SendSysMessage (LANG_GUILD_NOT_CREATED);
@@ -3653,11 +3756,11 @@ bool ChatHandler::HandleGuildInviteCommand(const char *args)
if (!targetGuild)
return false;
- std::string plName = par1;
- if (!normalizePlayerName (plName))
+ std::string plName = extractPlayerNameFromLink(par1);
+ if(plName.empty())
{
- SendSysMessage (LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage (true);
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
}
@@ -3665,10 +3768,10 @@ bool ChatHandler::HandleGuildInviteCommand(const char *args)
if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
plGuid = targetPlayer->GetGUID ();
else
- plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
+ plGuid = objmgr.GetPlayerGUIDByName (plName);
if (!plGuid)
- false;
+ return false;
// player's guild membership checked in AddMember before add
if (!targetGuild->AddMember (plGuid,targetGuild->GetLowestRank ()))
@@ -3686,11 +3789,11 @@ bool ChatHandler::HandleGuildUninviteCommand(const char *args)
if(!par1)
return false;
- std::string plName = par1;
- if (!normalizePlayerName (plName))
+ std::string plName = extractPlayerNameFromLink(par1);
+ if(plName.empty())
{
- SendSysMessage (LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage (true);
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
}
@@ -3703,7 +3806,7 @@ bool ChatHandler::HandleGuildUninviteCommand(const char *args)
}
else
{
- plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
+ plGuid = objmgr.GetPlayerGUIDByName (plName);
glId = Player::GetGuildIdFromDB (plGuid);
}
@@ -3728,14 +3831,16 @@ bool ChatHandler::HandleGuildRankCommand(const char *args)
char* par2 = strtok (NULL, " ");
if (!par1 || !par2)
return false;
- std::string plName = par1;
- if (!normalizePlayerName (plName))
+
+ std::string plName = extractPlayerNameFromLink(par1);
+ if(plName.empty())
{
- SendSysMessage (LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage (true);
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
}
+
uint64 plGuid = 0;
uint32 glId = 0;
if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
@@ -3745,7 +3850,7 @@ bool ChatHandler::HandleGuildRankCommand(const char *args)
}
else
{
- plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
+ plGuid = objmgr.GetPlayerGUIDByName (plName);
glId = Player::GetGuildIdFromDB (plGuid);
}
@@ -3785,90 +3890,37 @@ bool ChatHandler::HandleGuildDeleteCommand(const char* args)
return true;
}
-bool ChatHandler::HandleGetDistanceCommand(const char* /*args*/)
-{
- Unit* pUnit = getSelectedUnit();
-
- if(!pUnit)
- {
- SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
-
- PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(pUnit),m_session->GetPlayer()->GetDistance2d(pUnit));
-
- return true;
-}
-
-// FIX-ME!!!
-
-bool ChatHandler::HandleAddWeaponCommand(const char* /*args*/)
+bool ChatHandler::HandleGetDistanceCommand(const char* args)
{
- /*if (!*args)
- return false;
-
- uint64 guid = m_session->GetPlayer()->GetSelection();
- if (guid == 0)
- {
- SendSysMessage(LANG_NO_SELECTION);
- return true;
- }
-
- Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
+ WorldObject* obj = NULL;
- if(!pCreature)
+ if (*args)
{
- SendSysMessage(LANG_SELECT_CREATURE);
- return true;
- }
+ uint64 guid = extractGuidFromLink((char*)args);
+ if(guid)
+ obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
- char* pSlotID = strtok((char*)args, " ");
- if (!pSlotID)
- return false;
-
- char* pItemID = strtok(NULL, " ");
- if (!pItemID)
- return false;
-
- uint32 ItemID = atoi(pItemID);
- uint32 SlotID = atoi(pSlotID);
-
- ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
-
- bool added = false;
- if(tmpItem)
- {
- switch(SlotID)
+ if(!obj)
{
- case 1:
- pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
- added = true;
- break;
- case 2:
- pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
- added = true;
- break;
- case 3:
- pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
- added = true;
- break;
- default:
- PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
- added = false;
- break;
- }
- if(added)
- {
- PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
}
}
else
{
- PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
- return true;
+ obj = getSelectedUnit();
+
+ if(!obj)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
}
- */
+
+ PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(obj),m_session->GetPlayer()->GetDistance2d(obj));
+
return true;
}
@@ -3883,6 +3935,12 @@ bool ChatHandler::HandleDieCommand(const char* /*args*/)
return false;
}
+ if(target->GetTypeId()==TYPEID_PLAYER)
+ {
+ if(HasLowerSecurity((Player*)target,0,false))
+ return false;
+ }
+
if( target->isAlive() )
{
//m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
@@ -3934,7 +3992,7 @@ bool ChatHandler::HandleDamageCommand(const char * args)
SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
- damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
+ damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage, NULL, BASE_ATTACK);
char* spellStr = strtok((char*)NULL, " ");
@@ -3984,49 +4042,56 @@ bool ChatHandler::HandleModifyArenaCommand(const char * args)
target->ModifyArenaPoints(amount);
- PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, target->GetName(), target->GetArenaPoints());
+ PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, GetNameLink(target).c_str(), target->GetArenaPoints());
return true;
}
bool ChatHandler::HandleReviveCommand(const char* args)
{
- Player* SelectedPlayer = NULL;
+ Player* player = NULL;
+ uint64 player_guid = 0;
if (*args)
{
- std::string name = args;
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if (name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
- SelectedPlayer = objmgr.GetPlayer(name.c_str());
+ player = objmgr.GetPlayer(name.c_str());
+ if (!player)
+ player_guid = objmgr.GetPlayerGUIDByName(name);
}
else
- SelectedPlayer = getSelectedPlayer();
+ player = getSelectedPlayer();
- if(!SelectedPlayer)
+ if (player)
+ {
+ player->ResurrectPlayer(0.5f);
+ player->SpawnCorpseBones();
+ player->SaveToDB();
+ }
+ else if (player_guid)
+ {
+ // will resurrected at login without corpse
+ ObjectAccessor::Instance().ConvertCorpseForPlayer(player_guid);
+ }
+ else
{
SendSysMessage(LANG_NO_CHAR_SELECTED);
SetSentErrorMessage(true);
return false;
}
- SelectedPlayer->ResurrectPlayer(0.5f);
- SelectedPlayer->SpawnCorpseBones();
- SelectedPlayer->SaveToDB();
return true;
}
bool ChatHandler::HandleAuraCommand(const char* args)
{
- char* px = strtok((char*)args, " ");
- if (!px)
- return false;
-
Unit *target = getSelectedUnit();
if(!target)
{
@@ -4035,11 +4100,14 @@ bool ChatHandler::HandleAuraCommand(const char* args)
return false;
}
- uint32 spellID = (uint32)atoi(px);
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spellID = extractSpellIdFromLink((char*)args);
+
SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
+ uint8 eff_mask=0;
if(spellInfo)
{
- for(uint32 i = 0;i<3;i++)
+ for(uint32 i = 0;i<3;++i)
{
uint8 eff = spellInfo->Effect[i];
if (eff>=TOTAL_SPELL_EFFECTS)
@@ -4048,10 +4116,11 @@ bool ChatHandler::HandleAuraCommand(const char* args)
eff == SPELL_EFFECT_APPLY_AURA ||
eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
{
- Aura *Aur = CreateAura(spellInfo, i, NULL, target);
- target->AddAura(Aur);
+ eff_mask|=1<<i;
}
}
+ Aura *Aur = new Aura(spellInfo, eff_mask, NULL, target);
+ target->AddAura(Aur);
}
return true;
@@ -4059,10 +4128,6 @@ bool ChatHandler::HandleAuraCommand(const char* args)
bool ChatHandler::HandleUnAuraCommand(const char* args)
{
- char* px = strtok((char*)args, " ");
- if (!px)
- return false;
-
Unit *target = getSelectedUnit();
if(!target)
{
@@ -4078,7 +4143,11 @@ bool ChatHandler::HandleUnAuraCommand(const char* args)
return true;
}
- uint32 spellID = (uint32)atoi(px);
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spellID = extractSpellIdFromLink((char*)args);
+ if(!spellID)
+ return false;
+
target->RemoveAurasDueToSpell(spellID);
return true;
@@ -4129,7 +4198,7 @@ bool ChatHandler::HandleLinkGraveCommand(const char* args)
return false;
}
- if(objmgr.AddGraveYardLink(g_id,player->GetZoneId(),g_team))
+ if(objmgr.AddGraveYardLink(g_id,zoneId,g_team))
PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
else
PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
@@ -4153,6 +4222,7 @@ bool ChatHandler::HandleNearGraveCommand(const char* args)
return false;
Player* player = m_session->GetPlayer();
+ uint32 zone_id = player->GetZoneId();
WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
@@ -4161,7 +4231,7 @@ bool ChatHandler::HandleNearGraveCommand(const char* args)
{
uint32 g_id = graveyard->ID;
- GraveYardData const* data = objmgr.FindGraveYardData(g_id,player->GetZoneId());
+ GraveYardData const* data = objmgr.FindGraveYardData(g_id,zone_id);
if (!data)
{
PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
@@ -4180,7 +4250,7 @@ bool ChatHandler::HandleNearGraveCommand(const char* args)
else if(g_team == ALLIANCE)
team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
- PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),player->GetZoneId());
+ PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),zone_id);
}
else
{
@@ -4194,29 +4264,51 @@ bool ChatHandler::HandleNearGraveCommand(const char* args)
team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
if(g_team == ~uint32(0))
- PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, player->GetZoneId());
+ PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id);
else
- PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, player->GetZoneId(),team_name.c_str());
+ PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id,team_name.c_str());
}
return true;
}
-//play npc emote
-bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
+//-----------------------Npc Commands-----------------------
+bool ChatHandler::HandleNpcAllowMovementCommand(const char* /*args*/)
{
- uint32 emote = atoi((char*)args);
+ if(sWorld.getAllowMovement())
+ {
+ sWorld.SetAllowMovement(false);
+ SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
+ }
+ else
+ {
+ sWorld.SetAllowMovement(true);
+ SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
+ }
+ return true;
+}
- Creature* target = getSelectedCreature();
- if(!target)
+bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ uint32 newEntryNum = atoi(args);
+ if(!newEntryNum)
+ return false;
+
+ Unit* unit = getSelectedUnit();
+ if(!unit || unit->GetTypeId() != TYPEID_UNIT)
{
SendSysMessage(LANG_SELECT_CREATURE);
SetSentErrorMessage(true);
return false;
}
-
- target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
-
+ Creature* creature = (Creature*)unit;
+ if(creature->UpdateEntry(newEntryNum))
+ SendSysMessage(LANG_DONE);
+ else
+ SendSysMessage(LANG_ERROR);
return true;
}
@@ -4268,6 +4360,95 @@ bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
return true;
}
+//play npc emote
+bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
+{
+ uint32 emote = atoi((char*)args);
+
+ Creature* target = getSelectedCreature();
+ if(!target)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
+
+ return true;
+}
+
+//TODO: NpcCommands that needs to be fixed :
+
+bool ChatHandler::HandleNpcAddWeaponCommand(const char* /*args*/)
+{
+ /*if (!*args)
+ return false;
+
+ uint64 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;
+ }
+
+ char* pSlotID = strtok((char*)args, " ");
+ if (!pSlotID)
+ return false;
+
+ char* pItemID = strtok(NULL, " ");
+ if (!pItemID)
+ return false;
+
+ uint32 ItemID = atoi(pItemID);
+ uint32 SlotID = atoi(pSlotID);
+
+ ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
+
+ bool added = false;
+ if(tmpItem)
+ {
+ switch(SlotID)
+ {
+ case 1:
+ pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
+ added = true;
+ break;
+ case 2:
+ pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
+ added = true;
+ break;
+ case 3:
+ pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
+ added = true;
+ break;
+ default:
+ PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
+ added = false;
+ break;
+ }
+
+ if(added)
+ PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
+ }
+ else
+ {
+ PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
+ return true;
+ }
+ */
+ return true;
+}
+//----------------------------------------------------------
+
bool ChatHandler::HandleExploreCheatCommand(const char* args)
{
if (!*args)
@@ -4285,18 +4466,18 @@ bool ChatHandler::HandleExploreCheatCommand(const char* args)
if (flag != 0)
{
- PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, chr->GetName());
+ PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetNameLink().c_str());
}
else
{
- PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, chr->GetName());
+ PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetNameLink().c_str());
}
- for (uint8 i=0; i<128; i++)
+ for (uint8 i=0; i<128; ++i)
{
if (flag != 0)
{
@@ -4330,34 +4511,122 @@ bool ChatHandler::HandleHoverCommand(const char* args)
return true;
}
-bool ChatHandler::HandleWaterwalkCommand(const char* args)
+void ChatHandler::HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel)
{
- if(!args)
- return false;
+ if(player)
+ {
+ player->GiveLevel(newlevel);
+ player->InitTalentForLevel();
+ player->SetUInt32Value(PLAYER_XP,0);
- Player *player = getSelectedPlayer();
- if(!player)
+ if(needReportToTarget(player))
+ {
+ if(oldlevel == newlevel)
+ ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET,GetNameLink().c_str());
+ else if(oldlevel < newlevel)
+ ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_UP,GetNameLink().c_str(),newlevel);
+ else // if(oldlevel > newlevel)
+ ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,GetNameLink().c_str(),newlevel);
+ }
+ }
+ else
{
- PSendSysMessage(LANG_NO_CHAR_SELECTED);
- SetSentErrorMessage(true);
- return false;
+ // update level and XP at level, all other will be updated at loading
+ Tokens values;
+ Player::LoadValuesArrayFromDB(values,player_guid);
+ Player::SetUInt32ValueInArray(values,UNIT_FIELD_LEVEL,newlevel);
+ Player::SetUInt32ValueInArray(values,PLAYER_XP,0);
+ Player::SaveValuesArrayInDB(values,player_guid);
}
+}
- if (strncmp(args, "on", 3) == 0)
- player->SetMovement(MOVE_WATER_WALK); // ON
- else if (strncmp(args, "off", 4) == 0)
- player->SetMovement(MOVE_LAND_WALK); // OFF
- else
+bool ChatHandler::HandleCharacterLevelCommand(const char* args)
+{
+ char* px = strtok((char*)args, " ");
+ char* py = strtok((char*)NULL, " ");
+
+ // command format parsing
+ char* pname = (char*)NULL;
+ int32 newlevel = 0;
+
+ if(px && py) // .character level $name #level
{
- SendSysMessage(LANG_USE_BOL);
- return false;
+ newlevel = atoi(py);
+ pname = px;
+ }
+ else if(px && !py) // .character level $name OR .character level #level
+ {
+ if(isalpha(px[0])) // .character level $name
+ pname = px;
+ else // .character level #level
+ newlevel = atoi(px);
}
+ // // .character level - progress reset
- PSendSysMessage(LANG_YOU_SET_WATERWALK, args, player->GetName());
- if(needReportToTarget(player))
- ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetName());
- return true;
+ if(newlevel < 1)
+ return false; // invalid level
+
+ if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
+ newlevel = STRONG_MAX_LEVEL;
+ // player
+ Player *chr = NULL;
+ uint64 chr_guid = 0;
+
+ std::string name;
+
+ if(pname) // player by name
+ {
+ name = extractPlayerNameFromLink(pname);
+ if(name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ chr = objmgr.GetPlayer(name.c_str());
+ if(!chr) // not in game
+ {
+ chr_guid = objmgr.GetPlayerGUIDByName(name);
+ if (chr_guid == 0)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ }
+ else // player by selection
+ {
+ chr = getSelectedPlayer();
+
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ name = chr->GetName();
+ }
+
+ assert(chr || chr_guid);
+
+ int32 oldlevel = chr ? chr->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,chr_guid);
+
+ if(!px && !py) // .character level - progress reset
+ newlevel = oldlevel;
+
+ HandleCharacterLevel(chr,chr_guid,oldlevel,newlevel);
+
+ if(m_session && m_session->GetPlayer() != chr) // including player==NULL
+ {
+ std::string nameLink = playerLink(name);
+ PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
+ }
+
+ return true;
}
bool ChatHandler::HandleLevelUpCommand(const char* args)
@@ -4391,8 +4660,8 @@ bool ChatHandler::HandleLevelUpCommand(const char* args)
if(pname) // player by name
{
- name = pname;
- if(!normalizePlayerName(name))
+ name = extractPlayerNameFromLink(pname);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -4434,33 +4703,14 @@ bool ChatHandler::HandleLevelUpCommand(const char* args)
if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
newlevel = STRONG_MAX_LEVEL;
- if(chr)
- {
- chr->GiveLevel(newlevel);
- chr->InitTalentForLevel();
- chr->SetUInt32Value(PLAYER_XP,0);
+ HandleCharacterLevel(chr,chr_guid,oldlevel,newlevel);
- if(oldlevel == newlevel)
- ChatHandler(chr).SendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET);
- else
- if(oldlevel < newlevel)
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_UP,newlevel-oldlevel);
- else
- if(oldlevel > newlevel)
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,newlevel-oldlevel);
- }
- else
+ if(m_session && m_session->GetPlayer() != chr) // including chr==NULL
{
- // update level and XP at level, all other will be updated at loading
- Tokens values;
- Player::LoadValuesArrayFromDB(values,chr_guid);
- Player::SetUInt32ValueInArray(values,UNIT_FIELD_LEVEL,newlevel);
- Player::SetUInt32ValueInArray(values,PLAYER_XP,0);
- Player::SaveValuesArrayInDB(values,chr_guid);
+ std::string nameLink = playerLink(name);
+ PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
}
- if(m_session->GetPlayer() != chr) // including chr==NULL
- PSendSysMessage(LANG_YOU_CHANGE_LVL,name.c_str(),newlevel);
return true;
}
@@ -4469,8 +4719,6 @@ bool ChatHandler::HandleShowAreaCommand(const char* args)
if (!*args)
return false;
- int area = atoi((char*)args);
-
Player *chr = getSelectedPlayer();
if (chr == NULL)
{
@@ -4479,10 +4727,11 @@ bool ChatHandler::HandleShowAreaCommand(const char* args)
return false;
}
+ int area = GetAreaFlagByAreaID(atoi((char*)args));
int offset = area / 32;
uint32 val = (uint32)(1 << (area % 32));
- if(offset >= 128)
+ if(area<0 || offset >= 128)
{
SendSysMessage(LANG_BAD_VALUE);
SetSentErrorMessage(true);
@@ -4501,8 +4750,6 @@ bool ChatHandler::HandleHideAreaCommand(const char* args)
if (!*args)
return false;
- int area = atoi((char*)args);
-
Player *chr = getSelectedPlayer();
if (chr == NULL)
{
@@ -4511,10 +4758,11 @@ bool ChatHandler::HandleHideAreaCommand(const char* args)
return false;
}
+ int area = GetAreaFlagByAreaID(atoi((char*)args));
int offset = area / 32;
uint32 val = (uint32)(1 << (area % 32));
- if(offset >= 128)
+ if(area<0 || offset >= 128)
{
SendSysMessage(LANG_BAD_VALUE);
SetSentErrorMessage(true);
@@ -4528,7 +4776,7 @@ bool ChatHandler::HandleHideAreaCommand(const char* args)
return true;
}
-bool ChatHandler::HandleUpdate(const char* args)
+bool ChatHandler::HandleDebugUpdate(const char* args)
{
if(!*args)
return false;
@@ -4628,7 +4876,7 @@ bool ChatHandler::HandleChangeWeather(const char* args)
return true;
}
-bool ChatHandler::HandleSetValue(const char* args)
+bool ChatHandler::HandleDebugSetValue(const char* args)
{
if(!*args)
return false;
@@ -4679,7 +4927,7 @@ bool ChatHandler::HandleSetValue(const char* args)
return true;
}
-bool ChatHandler::HandleGetValue(const char* args)
+bool ChatHandler::HandleDebugGetValue(const char* args)
{
if(!*args)
return false;
@@ -4728,11 +4976,19 @@ bool ChatHandler::HandleGetValue(const char* args)
return true;
}
-bool ChatHandler::HandleSet32Bit(const char* args)
+bool ChatHandler::HandleDebugSet32Bit(const char* args)
{
if(!*args)
return false;
+ Unit* target = getSelectedUnit();
+ if(!target)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
char* px = strtok((char*)args, " ");
char* py = strtok(NULL, " ");
@@ -4746,13 +5002,14 @@ bool ChatHandler::HandleSet32Bit(const char* args)
sLog.outDebug(GetTrinityString(LANG_SET_32BIT), Opcode, Value);
- m_session->GetPlayer( )->SetUInt32Value( Opcode , 2^Value );
+ uint32 iValue = Value ? 1 << (Value - 1) : 0;
+ target->SetUInt32Value( Opcode , iValue);
- PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode,1);
+ PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode, iValue);
return true;
}
-bool ChatHandler::HandleMod32Value(const char* args)
+bool ChatHandler::HandleDebugMod32Value(const char* args)
{
if(!*args)
return false;
@@ -4784,7 +5041,7 @@ bool ChatHandler::HandleMod32Value(const char* args)
return true;
}
-bool ChatHandler::HandleAddTeleCommand(const char * args)
+bool ChatHandler::HandleTeleAddCommand(const char * args)
{
if(!*args)
return false;
@@ -4824,7 +5081,7 @@ bool ChatHandler::HandleAddTeleCommand(const char * args)
return true;
}
-bool ChatHandler::HandleDelTeleCommand(const char * args)
+bool ChatHandler::HandleTeleDelCommand(const char * args)
{
if(!*args)
return false;
@@ -4860,43 +5117,104 @@ bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
{
bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
- PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
- itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
- itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],
- (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
- IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
+
+ char const* name = itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()];
+
+ if (m_session)
+ {
+ std::ostringstream ss_name;
+ ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r";
+
+ PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffectMask(),
+ itr->second->GetAuraCharges(), itr->second->GetStackAmount(),itr->second->GetAuraSlot(),
+ itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
+ ss_name.str().c_str(),
+ (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
+ IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
+ }
+ else
+ {
+ PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffectMask(),
+ itr->second->GetAuraCharges(), itr->second->GetStackAmount(),itr->second->GetAuraSlot(),
+ itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
+ name,
+ (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
+ IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
+ }
}
- for (int i = 0; i < TOTAL_AURAS; i++)
+ for (int i = 0; i < TOTAL_AURAS; ++i)
{
- Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i));
+ Unit::AuraEffectList const& uAuraList = unit->GetAurasByType(AuraType(i));
if (uAuraList.empty()) continue;
PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
- for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
+ for (Unit::AuraEffectList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
{
- bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
+ char const* name = (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()];
+
+ std::ostringstream ss_name;
+ ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r";
+
PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
- (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
- IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
+ (*itr)->GetAmount());
}
}
return true;
}
+bool ChatHandler::HandleResetAchievementsCommand (const char * args)
+{
+ char* pName = strtok((char*)args, "");
+ Player *player = NULL;
+ uint64 guid = 0;
+ if (pName)
+ {
+ std::string name = extractPlayerNameFromLink(pName);
+ if(name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ guid = objmgr.GetPlayerGUIDByName(name);
+ player = objmgr.GetPlayer(guid);
+ }
+ else
+ {
+ player = getSelectedPlayer();
+ if(player)
+ guid = player->GetGUID();
+ }
+
+ if(!player && !guid)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ return true;
+ }
+
+ if(player)
+ player->GetAchievementMgr().Reset();
+ else if(guid)
+ AchievementMgr::DeleteFromDB(GUID_LOPART(guid));
+
+ return true;
+}
+
bool ChatHandler::HandleResetHonorCommand (const char * args)
{
char* pName = strtok((char*)args, "");
Player *player = NULL;
if (pName)
{
- std::string name = pName;
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink(pName);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
- uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
+ uint64 guid = objmgr.GetPlayerGUIDByName(name);
player = objmgr.GetPlayer(guid);
}
else
@@ -4914,6 +5232,8 @@ bool ChatHandler::HandleResetHonorCommand (const char * args)
player->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
player->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
+
return true;
}
@@ -4931,19 +5251,6 @@ static bool HandleResetStatsOrLevelHelper(Player* player)
uint8 powertype = cEntry->powerType;
- uint32 unitfield;
- if(powertype == POWER_RAGE)
- unitfield = 0x1100EE00;
- else if(powertype == POWER_ENERGY)
- unitfield = 0x00000000;
- else if(powertype == POWER_MANA)
- unitfield = 0x0000EE00;
- else
- {
- sLog.outError("Invalid default powertype %u for player (class %u)",powertype,player->getClass());
- return false;
- }
-
// reset m_form if no aura
if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
player->m_form = FORM_NONE;
@@ -4973,9 +5280,7 @@ static bool HandleResetStatsOrLevelHelper(Player* player)
}
}
- // set UNIT_FIELD_BYTES_1 to init state but preserve m_form value
- player->SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield);
- player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY | UNIT_BYTE2_FLAG_UNK5 );
+ player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP );
player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
@@ -4993,15 +5298,15 @@ bool ChatHandler::HandleResetLevelCommand(const char * args)
Player *player = NULL;
if (pName)
{
- std::string name = pName;
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink(pName);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
- uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
+ uint64 guid = objmgr.GetPlayerGUIDByName(name);
player = objmgr.GetPlayer(guid);
}
else
@@ -5017,17 +5322,27 @@ bool ChatHandler::HandleResetLevelCommand(const char * args)
if(!HandleResetStatsOrLevelHelper(player))
return false;
- player->SetLevel(1);
+ // set starting level
+ uint32 start_level = player->getClass() != CLASS_DEATH_KNIGHT
+ ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL)
+ : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
+
+ player->SetLevel(start_level);
+ player->InitRunes();
player->InitStatsForLevel(true);
player->InitTaxiNodesForLevel();
+ player->InitGlyphsForLevel();
player->InitTalentForLevel();
player->SetUInt32Value(PLAYER_XP,0);
// reset level to summoned pet
- Pet* pet = player->GetPet();
- if(pet && pet->getPetType()==SUMMON_PET)
+ Guardian* pet = player->GetGuardianPet();
+ if(pet)
+ {
pet->InitStatsForLevel(1);
-
+ if(pet->isPet())
+ ((Pet*)pet)->InitTalentForLevel();
+ }
return true;
}
@@ -5037,15 +5352,15 @@ bool ChatHandler::HandleResetStatsCommand(const char * args)
Player *player = NULL;
if (pName)
{
- std::string name = pName;
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink(pName);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
- uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
+ uint64 guid = objmgr.GetPlayerGUIDByName(name);
player = objmgr.GetPlayer(guid);
}
else
@@ -5061,8 +5376,10 @@ bool ChatHandler::HandleResetStatsCommand(const char * args)
if(!HandleResetStatsOrLevelHelper(player))
return false;
+ player->InitRunes();
player->InitStatsForLevel(true);
player->InitTaxiNodesForLevel();
+ player->InitGlyphsForLevel();
player->InitTalentForLevel();
return true;
@@ -5075,9 +5392,8 @@ bool ChatHandler::HandleResetSpellsCommand(const char * args)
uint64 playerGUID = 0;
if (pName)
{
- std::string name = pName;
-
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink(pName);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -5086,7 +5402,7 @@ bool ChatHandler::HandleResetSpellsCommand(const char * args)
player = objmgr.GetPlayer(name.c_str());
if(!player)
- playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
+ playerGUID = objmgr.GetPlayerGUIDByName(name);
}
else
player = getSelectedPlayer();
@@ -5103,9 +5419,8 @@ bool ChatHandler::HandleResetSpellsCommand(const char * args)
player->resetSpells();
ChatHandler(player).SendSysMessage(LANG_RESET_SPELLS);
-
if(m_session->GetPlayer()!=player)
- PSendSysMessage(LANG_RESET_SPELLS_ONLINE,player->GetName());
+ PSendSysMessage(LANG_RESET_SPELLS_ONLINE,GetNameLink(player).c_str());
}
else
{
@@ -5123,8 +5438,8 @@ bool ChatHandler::HandleResetTalentsCommand(const char * args)
uint64 playerGUID = 0;
if (pName)
{
- std::string name = pName;
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink(pName);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -5133,34 +5448,47 @@ bool ChatHandler::HandleResetTalentsCommand(const char * args)
player = objmgr.GetPlayer(name.c_str());
if(!player)
- playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
+ playerGUID = objmgr.GetPlayerGUIDByName(name);
}
else
player = getSelectedPlayer();
- if(!player && !playerGUID)
- {
- SendSysMessage(LANG_NO_CHAR_SELECTED);
- SetSentErrorMessage(true);
- return false;
- }
-
if(player)
{
player->resetTalents(true);
ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS);
-
if(m_session->GetPlayer()!=player)
- PSendSysMessage(LANG_RESET_TALENTS_ONLINE,player->GetName());
+ PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(player).c_str());
+
+ return true;
}
- else
+ else if (playerGUID)
{
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(playerGUID) );
- PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,pName);
+ std::string nameLink = playerLink(pName);
+ PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,nameLink.c_str());
+ return true;
+ }
+ // Try reset talenents as Hunter Pet
+ Creature* creature = getSelectedCreature();
+ if (creature && creature->isPet() && ((Pet *)creature)->getPetType() == HUNTER_PET)
+ {
+ ((Pet *)creature)->resetTalents(true);
+ Unit *owner = creature->GetOwner();
+ if (owner && owner->GetTypeId() == TYPEID_PLAYER)
+ {
+ player = (Player *)owner;
+ ChatHandler(player).SendSysMessage(LANG_RESET_PET_TALENTS);
+ if(m_session->GetPlayer()!=player)
+ PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE,GetNameLink(player).c_str());
+ }
+ return true;
}
- return true;
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
}
bool ChatHandler::HandleResetAllCommand(const char * args)
@@ -5183,6 +5511,16 @@ bool ChatHandler::HandleResetAllCommand(const char * args)
atLogin = AT_LOGIN_RESET_TALENTS;
sWorld.SendWorldText(LANG_RESETALL_TALENTS);
}
+ else if(casename=="pet_spells")
+ {
+ CharacterDatabase.PExecute("UPDATE character_pet SET load_flags = load_flags | '%u' WHERE (load_flags & '%u') = '0'",uint32(AT_LOAD_RESET_SPELLS),uint32(AT_LOAD_RESET_SPELLS));
+ HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
+ for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
+ if (itr->second->GetPet())
+ itr->second->SetPetAtLoginFlag(AT_LOAD_RESET_SPELLS);
+ sWorld.SendWorldText(LANG_RESETALL_PET_SPELLS);
+ return true;
+ }
else
{
PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
@@ -5344,7 +5682,7 @@ bool ChatHandler::HandleServerIdleShutDownCommand(const char* args)
return true;
}
-bool ChatHandler::HandleAddQuest(const char* args)
+bool ChatHandler::HandleQuestAdd(const char* args)
{
Player* player = getSelectedPlayer();
if(!player)
@@ -5398,7 +5736,7 @@ bool ChatHandler::HandleAddQuest(const char* args)
return true;
}
-bool ChatHandler::HandleRemoveQuest(const char* args)
+bool ChatHandler::HandleQuestRemove(const char* args)
{
Player* player = getSelectedPlayer();
if(!player)
@@ -5448,7 +5786,7 @@ bool ChatHandler::HandleRemoveQuest(const char* args)
return true;
}
-bool ChatHandler::HandleCompleteQuest(const char* args)
+bool ChatHandler::HandleQuestComplete(const char* args)
{
Player* player = getSelectedPlayer();
if(!player)
@@ -5496,7 +5834,7 @@ bool ChatHandler::HandleCompleteQuest(const char* args)
}
// All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
- for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
+ for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
{
uint32 creature = pQuest->ReqCreatureOrGOId[i];
uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
@@ -5522,12 +5860,10 @@ bool ChatHandler::HandleCompleteQuest(const char* args)
if(uint32 repFaction = pQuest->GetRepObjectiveFaction())
{
uint32 repValue = pQuest->GetRepObjectiveValue();
- uint32 curRep = player->GetReputation(repFaction);
+ uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
if(curRep < repValue)
- {
- FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction);
- player->SetFactionReputation(factionEntry,repValue);
- }
+ if(FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction))
+ player->GetReputationMgr().SetReputation(factionEntry,repValue);
}
// If the quest requires money
@@ -5556,7 +5892,7 @@ bool ChatHandler::HandleBanIPCommand(const char* args)
bool ChatHandler::HandleBanHelper(BanMode mode, const char* args)
{
- if(!args)
+ if (!*args)
return false;
char* cnameOrIP = strtok ((char*)args, " ");
@@ -5644,7 +5980,7 @@ bool ChatHandler::HandleUnBanIPCommand(const char* args)
bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args)
{
- if(!args)
+ if (!*args)
return false;
char* cnameOrIP = strtok ((char*)args, " ");
@@ -5687,7 +6023,7 @@ bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args)
bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
{
- if(!args)
+ if (!*args)
return false;
char* cname = strtok((char*)args, "");
@@ -5714,15 +6050,11 @@ bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
{
- if(!args)
- return false;
-
- char* cname = strtok ((char*)args, "");
- if(!cname)
+ if (!*args)
return false;
- std::string name = cname;
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -5777,7 +6109,7 @@ bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
bool ChatHandler::HandleBanInfoIPCommand(const char* args)
{
- if(!args)
+ if (!*args)
return false;
char* cIP = strtok ((char*)args, "");
@@ -6034,8 +6366,8 @@ bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
- Trinity::RespawnDo u_do;
- Trinity::WorldObjectWorker<Trinity::RespawnDo> worker(u_do);
+ MaNGOS::RespawnDo u_do;
+ MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo> worker(pl,u_do);
TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -6044,14 +6376,14 @@ bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
return true;
}
-bool ChatHandler::HandleFlyModeCommand(const char* args)
+bool ChatHandler::HandleGMFlyCommand(const char* args)
{
- if(!args)
+ if (!*args)
return false;
- Unit *unit = getSelectedUnit();
- if (!unit || (unit->GetTypeId() != TYPEID_PLAYER))
- unit = m_session->GetPlayer();
+ Player *target = getSelectedPlayer();
+ if (!target)
+ target = m_session->GetPlayer();
WorldPacket data(12);
if (strncmp(args, "on", 3) == 0)
@@ -6063,16 +6395,16 @@ bool ChatHandler::HandleFlyModeCommand(const char* args)
SendSysMessage(LANG_USE_BOL);
return false;
}
- data.append(unit->GetPackGUID());
+ data.append(target->GetPackGUID());
data << uint32(0); // unknown
- unit->SendMessageToSet(&data, true);
- PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, unit->GetName(), args);
+ target->SendMessageToSet(&data, true);
+ PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, GetNameLink(target).c_str(), args);
return true;
}
-bool ChatHandler::HandleLoadPDumpCommand(const char *args)
+bool ChatHandler::HandlePDumpLoadCommand(const char *args)
{
- if(!args)
+ if (!*args)
return false;
char * file = strtok((char*)args, " ");
@@ -6181,33 +6513,9 @@ bool ChatHandler::HandleLoadPDumpCommand(const char *args)
return true;
}
-bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
+bool ChatHandler::HandlePDumpWriteCommand(const char *args)
{
- if(!args)
- return false;
-
- uint32 newEntryNum = atoi(args);
- if(!newEntryNum)
- return false;
-
- Unit* unit = getSelectedUnit();
- if(!unit || unit->GetTypeId() != TYPEID_UNIT)
- {
- SendSysMessage(LANG_SELECT_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
- Creature* creature = (Creature*)unit;
- if(creature->UpdateEntry(newEntryNum))
- SendSysMessage(LANG_DONE);
- else
- SendSysMessage(LANG_ERROR);
- return true;
-}
-
-bool ChatHandler::HandleWritePDumpCommand(const char *args)
-{
- if(!args)
+ if (!*args)
return false;
char* file = strtok((char*)args, " ");
@@ -6222,12 +6530,11 @@ bool ChatHandler::HandleWritePDumpCommand(const char *args)
guid = atoi(p2);
else
{
- std::string name = p2;
-
- if (!normalizePlayerName (name))
+ std::string name = extractPlayerNameFromLink(p2);
+ if(name.empty())
{
- SendSysMessage (LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage (true);
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
}
@@ -6337,7 +6644,7 @@ bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
return true;
}
-bool ChatHandler::HandlePLimitCommand(const char *args)
+bool ChatHandler::HandleServerPLimitCommand(const char *args)
{
if(*args)
{
@@ -6644,10 +6951,10 @@ bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
Player* player = getSelectedPlayer();
if (!player) player = m_session->GetPlayer();
uint32 counter = 0;
- for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
+ for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i)
{
Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
- for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
+ for(Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
{
InstanceSave *save = itr->second.save;
std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
@@ -6660,10 +6967,10 @@ bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
Group *group = player->GetGroup();
if(group)
{
- for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
+ for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i)
{
Group::BoundInstancesMap &binds = group->GetBoundInstances(i);
- for(Group::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
+ for(Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
{
InstanceSave *save = itr->second.save;
std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
@@ -6688,7 +6995,7 @@ bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
Player* player = getSelectedPlayer();
if (!player) player = m_session->GetPlayer();
uint32 counter = 0;
- for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
+ for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i)
{
Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
@@ -6778,6 +7085,29 @@ bool ChatHandler::HandleServerSetMotdCommand(const char* args)
return true;
}
+/// Set whether we accept new clients
+bool ChatHandler::HandleServerSetClosedCommand(const char* args)
+{
+ std::string arg = args;
+
+ if(args == "on")
+ {
+ SendSysMessage(LANG_WORLD_CLOSED);
+ sWorld.SetClosed(true);
+ return true;
+ }
+ if(args == "off")
+ {
+ SendSysMessage(LANG_WORLD_OPENED);
+ sWorld.SetClosed(false);
+ return true;
+ }
+
+ SendSysMessage(LANG_USE_BOL);
+ SetSentErrorMessage(true);
+ return false;
+}
+
/// Set/Unset the expansion level for an account
bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
{
@@ -6819,8 +7149,15 @@ bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
SetSentErrorMessage(true);
return false;
}
+
}
+ // Let set addon state only for lesser (strong) security level
+ // or to self account
+ if (m_session && m_session->GetAccountId () != account_id &&
+ HasLowerSecurityAccount (NULL,account_id,true))
+ return false;
+
int lev=atoi(szExp); //get int anyway (0 if error)
if(lev < 0)
return false;
@@ -6839,9 +7176,13 @@ bool ChatHandler::HandleSendItemsCommand(const char* args)
// format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
- char* pName = strtok((char*)args, " ");
- if(!pName)
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
+ }
char* tail1 = strtok(NULL, "");
if(!tail1)
@@ -6879,8 +7220,7 @@ bool ChatHandler::HandleSendItemsCommand(const char* args)
if (!msgText)
return false;
- // pName, msgSubject, msgText isn't NUL after prev. check
- std::string name = pName;
+ // msgSubject, msgText isn't NUL after prev. check
std::string subject = msgSubject;
std::string text = msgText;
@@ -6915,17 +7255,17 @@ bool ChatHandler::HandleSendItemsCommand(const char* args)
}
uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
- if(item_count < 1 || item_proto->MaxCount && item_count > item_proto->MaxCount)
+ if(item_count < 1 || item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount))
{
PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
SetSentErrorMessage(true);
return false;
}
- while(item_count > item_proto->Stackable)
+ while(item_count > item_proto->GetMaxStackSize())
{
- items.push_back(ItemPair(item_id,item_proto->Stackable));
- item_count -= item_proto->Stackable;
+ items.push_back(ItemPair(item_id,item_proto->GetMaxStackSize()));
+ item_count -= item_proto->GetMaxStackSize();
}
items.push_back(ItemPair(item_id,item_count));
@@ -6938,13 +7278,6 @@ bool ChatHandler::HandleSendItemsCommand(const char* args)
}
}
- if(!normalizePlayerName(name))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
if(!receiver_guid)
{
@@ -6976,7 +7309,8 @@ bool ChatHandler::HandleSendItemsCommand(const char* args)
WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
- PSendSysMessage(LANG_MAIL_SENT, name.c_str());
+ std::string nameLink = playerLink(name);
+ PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
return true;
}
@@ -6988,9 +7322,13 @@ bool ChatHandler::HandleSendMoneyCommand(const char* args)
/// format: name "subject text" "mail text" money
- char* pName = strtok((char*)args, " ");
- if (!pName)
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
+ }
char* tail1 = strtok(NULL, "");
if (!tail1)
@@ -7033,18 +7371,10 @@ bool ChatHandler::HandleSendMoneyCommand(const char* args)
if (money <= 0)
return false;
- // pName, msgSubject, msgText isn't NUL after prev. check
- std::string name = pName;
+ // msgSubject, msgText isn't NUL after prev. check
std::string subject = msgSubject;
std::string text = msgText;
- if (!normalizePlayerName(name))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
if (!receiver_guid)
{
@@ -7053,8 +7383,6 @@ bool ChatHandler::HandleSendMoneyCommand(const char* args)
return false;
}
- uint32 mailId = objmgr.GenerateMailID();
-
// from console show not existed sender
uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
@@ -7066,7 +7394,8 @@ bool ChatHandler::HandleSendMoneyCommand(const char* args)
WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE);
- PSendSysMessage(LANG_MAIL_SENT, name.c_str());
+ std::string nameLink = playerLink(name);
+ PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
return true;
}
@@ -7074,15 +7403,16 @@ bool ChatHandler::HandleSendMoneyCommand(const char* args)
bool ChatHandler::HandleSendMessageCommand(const char* args)
{
///- Get the command line arguments
- char* name_str = strtok((char*)args, " ");
- char* msg_str = strtok(NULL, "");
-
- if(!name_str || !msg_str)
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
+ }
- std::string name = name_str;
-
- if(!normalizePlayerName(name))
+ char* msg_str = strtok(NULL, "");
+ if(!msg_str)
return false;
///- Find the player and check that he is not logging out.
@@ -7107,7 +7437,8 @@ bool ChatHandler::HandleSendMessageCommand(const char* args)
rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
//Confirmation message
- PSendSysMessage(LANG_SENDMESSAGE,name.c_str(),msg_str);
+ std::string nameLink = playerLink(name);
+ PSendSysMessage(LANG_SENDMESSAGE,nameLink.c_str(),msg_str);
return true;
}
@@ -7131,30 +7462,27 @@ bool ChatHandler::HandleModifyGenderCommand(const char *args)
return false;
}
+ PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
+ if(!info)
+ return false;
+
char const* gender_str = (char*)args;
int gender_len = strlen(gender_str);
- uint32 displayId = player->GetNativeDisplayId();
- char const* gender_full = NULL;
- uint32 new_displayId = displayId;
Gender gender;
- if(!strncmp(gender_str,"male",gender_len)) // MALE
+ if(!strncmp(gender_str, "male", gender_len)) // MALE
{
if(player->getGender() == GENDER_MALE)
return true;
- gender_full = "male";
- new_displayId = player->getRace() == RACE_BLOODELF ? displayId+1 : displayId-1;
gender = GENDER_MALE;
}
- else if (!strncmp(gender_str,"female",gender_len)) // FEMALE
+ else if (!strncmp(gender_str, "female", gender_len)) // FEMALE
{
if(player->getGender() == GENDER_FEMALE)
return true;
- gender_full = "female";
- new_displayId = player->getRace() == RACE_BLOODELF ? displayId-1 : displayId+1;
gender = GENDER_FEMALE;
}
else
@@ -7169,12 +7497,16 @@ bool ChatHandler::HandleModifyGenderCommand(const char *args)
player->SetByteValue(PLAYER_BYTES_3, 0, gender);
// Change display ID
- player->SetDisplayId(new_displayId);
- player->SetNativeDisplayId(new_displayId);
+ player->SetDisplayId(gender ? info->displayId_f : info->displayId_m);
+ player->SetNativeDisplayId(gender ? info->displayId_f : info->displayId_m);
+
+ char const* gender_full = gender ? "female" : "male";
+
+ PSendSysMessage(LANG_YOU_CHANGE_GENDER, GetNameLink(player).c_str(), gender_full);
- PSendSysMessage(LANG_YOU_CHANGE_GENDER, player->GetName(),gender_full);
if (needReportToTarget(player))
- ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full,GetName());
+ ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetNameLink().c_str());
+
return true;
}
@@ -7262,26 +7594,10 @@ bool ChatHandler::HandleFreezeCommand(const char *args)
}
}
- //stop movement and disable spells
- uint32 spellID = 9454;
//m_session->GetPlayer()->CastSpell(player,spellID,false);
- SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
- if(spellInfo) //TODO: Change the duration of the aura to -1 instead of 5000000
- {
- for(uint32 i = 0;i<3;i++)
- {
- uint8 eff = spellInfo->Effect[i];
- if (eff>=TOTAL_SPELL_EFFECTS)
- continue;
- if( eff == SPELL_EFFECT_APPLY_AREA_AURA_PARTY || eff == SPELL_EFFECT_APPLY_AURA ||
- eff == SPELL_EFFECT_PERSISTENT_AREA_AURA || eff == SPELL_EFFECT_APPLY_AREA_AURA_FRIEND ||
- eff == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY)
- {
- Aura *Aur = CreateAura(spellInfo, i, NULL, player);
- player->AddAura(Aur);
- }
- }
- }
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry( 9454 );
+ Aura *Aur = new Aura(spellInfo, 1, NULL, player);
+ player->AddAura(Aur);
//save player
player->SaveToDB();
@@ -7320,8 +7636,7 @@ bool ChatHandler::HandleUnFreezeCommand(const char *args)
player->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
//allow movement and spells
- uint32 spellID = 9454;
- player->RemoveAurasDueToSpell(spellID);
+ player->RemoveAurasDueToSpell(9454);
//save player
player->SaveToDB();
@@ -7437,9 +7752,9 @@ bool ChatHandler::HandleUnPossessCommand(const char* args)
Unit* pUnit = getSelectedUnit();
if(!pUnit) pUnit = m_session->GetPlayer();
- pUnit->RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM);
- pUnit->RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS_PET);
- pUnit->RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS);
+ pUnit->RemoveAurasByType(SPELL_AURA_MOD_CHARM);
+ pUnit->RemoveAurasByType(SPELL_AURA_MOD_POSSESS_PET);
+ pUnit->RemoveAurasByType(SPELL_AURA_MOD_POSSESS);
return true;
}
diff --git a/src/game/LootHandler.cpp b/src/game/LootHandler.cpp
index 6ca7ae1c535..f8e2a6cde15 100644
--- a/src/game/LootHandler.cpp
+++ b/src/game/LootHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -46,8 +46,7 @@ void WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data )
if (IS_GAMEOBJECT_GUID(lguid))
{
- GameObject *go =
- ObjectAccessor::GetGameObject(*player, lguid);
+ GameObject *go = player->GetMap()->GetGameObject(lguid);
// not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO
if (!go || (go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player,INTERACTION_DISTANCE))
@@ -82,8 +81,7 @@ void WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data )
}
else
{
- Creature* pCreature =
- ObjectAccessor::GetCreature(*player, lguid);
+ Creature* pCreature = GetPlayer()->GetMap()->GetCreature(lguid);
bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass()==CLASS_ROGUE && pCreature->lootForPickPocketed);
@@ -154,6 +152,8 @@ void WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data )
--loot->unlootedCount;
player->SendNewItem(newitem, uint32(item->count), false, false, true);
+ player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count);
+ player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item->count);
}
else
player->SendEquipError( msg, NULL, NULL );
@@ -174,7 +174,7 @@ void WorldSession::HandleLootMoneyOpcode( WorldPacket & /*recv_data*/ )
{
case HIGHGUID_GAMEOBJECT:
{
- GameObject *pGameObject = ObjectAccessor::GetGameObject(*GetPlayer(), guid);
+ GameObject *pGameObject = GetPlayer()->GetMap()->GetGameObject(guid);
// not check distance for GO in case owned GO (fishing bobber case, for example)
if( pGameObject && (pGameObject->GetOwnerGUID()==_player->GetGUID() || pGameObject->IsWithinDistInMap(_player,INTERACTION_DISTANCE)) )
@@ -199,7 +199,7 @@ void WorldSession::HandleLootMoneyOpcode( WorldPacket & /*recv_data*/ )
}
case HIGHGUID_UNIT:
{
- Creature* pCreature = ObjectAccessor::GetCreature(*GetPlayer(), guid);
+ Creature* pCreature = GetPlayer()->GetMap()->GetCreature(guid);
bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass()==CLASS_ROGUE && pCreature->lootForPickPocketed);
@@ -230,9 +230,10 @@ void WorldSession::HandleLootMoneyOpcode( WorldPacket & /*recv_data*/ )
uint32 money_per_player = uint32((pLoot->gold)/(playersNear.size()));
- for (std::vector<Player*>::iterator i = playersNear.begin(); i != playersNear.end(); ++i)
+ for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i)
{
(*i)->ModifyMoney( money_per_player );
+ (*i)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, money_per_player);
//Offset surely incorrect, but works
WorldPacket data( SMSG_LOOT_MONEY_NOTIFY, 4 );
data << uint32(money_per_player);
@@ -240,7 +241,10 @@ void WorldSession::HandleLootMoneyOpcode( WorldPacket & /*recv_data*/ )
}
}
else
+ {
player->ModifyMoney( pLoot->gold );
+ player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, pLoot->gold);
+ }
pLoot->gold = 0;
pLoot->NotifyMoneyRemoved();
}
@@ -283,10 +287,12 @@ void WorldSession::DoLootRelease( uint64 lguid )
player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_LOOTING);
+ if(!player->IsInWorld())
+ return;
+
if (IS_GAMEOBJECT_GUID(lguid))
{
- GameObject *go =
- ObjectAccessor::GetGameObject(*player, lguid);
+ GameObject *go = GetPlayer()->GetMap()->GetGameObject(lguid);
// not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO
if (!go || (go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player,INTERACTION_DISTANCE))
@@ -326,7 +332,7 @@ void WorldSession::DoLootRelease( uint64 lguid )
int32 ReqValue = 175;
LockEntry const *lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->chest.lockId);
if(lockInfo)
- ReqValue = lockInfo->requiredminingskill;
+ ReqValue = lockInfo->Skill[0];
float skill = float(player->GetSkillValue(SKILL_MINING))/(ReqValue+25);
double chance = pow(0.8*chance_rate,4*(1/double(max_amount))*double(uses));
if(roll_chance_f(100*chance+skill))
@@ -383,14 +389,22 @@ void WorldSession::DoLootRelease( uint64 lguid )
Item *pItem = player->GetItemByGuid(lguid );
if(!pItem)
return;
- if( (pItem->GetProto()->BagFamily & BAG_FAMILY_MASK_MINING_SUPP) &&
- pItem->GetProto()->Class == ITEM_CLASS_TRADE_GOODS &&
- pItem->GetCount() >= 5)
+
+ ItemPrototype const* proto = pItem->GetProto();
+
+ // destroy only 5 items from stack in case prospecting and milling
+ if( (proto->BagFamily & (BAG_FAMILY_MASK_MINING_SUPP|BAG_FAMILY_MASK_HERBS)) &&
+ proto->Class == ITEM_CLASS_TRADE_GOODS)
{
pItem->m_lootGenerated = false;
pItem->loot.clear();
- uint32 count = 5;
+ uint32 count = pItem->GetCount();
+
+ // >=5 checked in spell code, but will work for cheating cases also with removing from another stacks.
+ if(count > 5)
+ count = 5;
+
player->DestroyItemCount(pItem, count, true);
}
else
@@ -400,7 +414,7 @@ void WorldSession::DoLootRelease( uint64 lguid )
}
else
{
- Creature* pCreature = ObjectAccessor::GetCreature(*player, lguid);
+ Creature* pCreature = GetPlayer()->GetMap()->GetCreature(lguid);
bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass()==CLASS_ROGUE && pCreature->lootForPickPocketed);
if ( !ok_loot || !pCreature->IsWithinDistInMap(_player,INTERACTION_DISTANCE) )
@@ -457,7 +471,7 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data )
if(IS_CREATURE_GUID(GetPlayer()->GetLootGUID()))
{
- Creature *pCreature = ObjectAccessor::GetCreature(*GetPlayer(), lootguid);
+ Creature *pCreature = GetPlayer()->GetMap()->GetCreature(lootguid);
if(!pCreature)
return;
@@ -465,7 +479,7 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data )
}
else if(IS_GAMEOBJECT_GUID(GetPlayer()->GetLootGUID()))
{
- GameObject *pGO = ObjectAccessor::GetGameObject(*GetPlayer(), lootguid);
+ GameObject *pGO = GetPlayer()->GetMap()->GetGameObject(lootguid);
if(!pGO)
return;
@@ -477,7 +491,7 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data )
if (slotid > pLoot->items.size())
{
- sLog.outDebug("AutoLootItem: Player %s might be using a hack! (slot %d, size %d)",GetPlayer()->GetName(), slotid, pLoot->items.size());
+ sLog.outDebug("AutoLootItem: Player %s might be using a hack! (slot %d, size %lu)",GetPlayer()->GetName(), slotid, (unsigned long)pLoot->items.size());
return;
}
@@ -495,6 +509,8 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data )
// not move item from loot to target inventory
Item * newitem = target->StoreNewItem( dest, item.itemid, true, item.randomPropertyId );
target->SendNewItem(newitem, uint32(item.count), false, false, true );
+ target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count);
+ target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, pLoot->loot_type, item.count);
// mark as looted
item.count=0;
diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp
index c8511c3deeb..267749fd5a4 100644
--- a/src/game/LootMgr.cpp
+++ b/src/game/LootMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -25,6 +25,7 @@
#include "World.h"
#include "Util.h"
#include "SharedDefines.h"
+#include "SpellMgr.h"
static Rates const qualityToRate[MAX_ITEM_QUALITY] = {
RATE_DROP_ITEM_POOR, // ITEM_QUALITY_POOR
@@ -36,16 +37,18 @@ static Rates const qualityToRate[MAX_ITEM_QUALITY] = {
RATE_DROP_ITEM_ARTIFACT, // ITEM_QUALITY_ARTIFACT
};
-LootStore LootTemplates_Creature( "creature_loot_template", "creature entry");
-LootStore LootTemplates_Disenchant( "disenchant_loot_template", "item disenchant id");
-LootStore LootTemplates_Fishing( "fishing_loot_template", "area id");
-LootStore LootTemplates_Gameobject( "gameobject_loot_template", "gameobject entry");
-LootStore LootTemplates_Item( "item_loot_template", "item entry");
-LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template","creature pickpocket lootid");
-LootStore LootTemplates_Prospecting( "prospecting_loot_template", "item entry");
-LootStore LootTemplates_QuestMail( "quest_mail_loot_template", "quest id");
-LootStore LootTemplates_Reference( "reference_loot_template", "reference id");
-LootStore LootTemplates_Skinning( "skinning_loot_template", "creature skinning id");
+LootStore LootTemplates_Creature( "creature_loot_template", "creature entry", true);
+LootStore LootTemplates_Disenchant( "disenchant_loot_template", "item disenchant id", true);
+LootStore LootTemplates_Fishing( "fishing_loot_template", "area id", true);
+LootStore LootTemplates_Gameobject( "gameobject_loot_template", "gameobject entry", true);
+LootStore LootTemplates_Item( "item_loot_template", "item entry", true);
+LootStore LootTemplates_Milling( "milling_loot_template", "item entry (herb)", true);
+LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template","creature pickpocket lootid", true);
+LootStore LootTemplates_Prospecting( "prospecting_loot_template", "item entry (ore)", true);
+LootStore LootTemplates_QuestMail( "quest_mail_loot_template", "quest id (with mail template)",false);
+LootStore LootTemplates_Reference( "reference_loot_template", "reference id", false);
+LootStore LootTemplates_Skinning( "skinning_loot_template", "creature skinning id", true);
+LootStore LootTemplates_Spell( "spell_loot_template", "spell id (explicitly discovering ability)",false);
class LootTemplate::LootGroup // A set of loot definitions for items (refs are not allowed)
@@ -89,7 +92,7 @@ void LootStore::Verify() const
// All checks of the loaded template are called from here, no error reports at loot generation required
void LootStore::LoadLootTable()
{
- LootTemplateMap::iterator tab;
+ LootTemplateMap::const_iterator tab;
uint32 count = 0;
// Clearing store (for reloading case)
@@ -114,11 +117,18 @@ void LootStore::LoadLootTable()
float chanceOrQuestChance = fields[2].GetFloat();
uint8 group = fields[3].GetUInt8();
int32 mincountOrRef = fields[4].GetInt32();
- uint8 maxcount = fields[5].GetUInt8();
+ uint32 maxcount = fields[5].GetUInt32();
ConditionType condition = (ConditionType)fields[6].GetUInt8();
uint32 cond_value1 = fields[7].GetUInt32();
uint32 cond_value2 = fields[8].GetUInt32();
+ if(maxcount > std::numeric_limits<uint8>::max())
+ {
+ sLog.outErrorDb("Table '%s' entry %d item %d: maxcount value (%u) to large. must be less %u - skipped", GetName(), entry, item, maxcount,std::numeric_limits<uint8>::max());
+ continue; // error already printed to log/console.
+ }
+
+
if(!PlayerCondition::IsValid(condition,cond_value1, cond_value2))
{
sLog.outErrorDb("... in table '%s' entry %u item %u", GetName(), entry, item);
@@ -159,7 +169,7 @@ void LootStore::LoadLootTable()
Verify(); // Checks validity of the loot store
sLog.outString();
- sLog.outString( ">> Loaded %u loot definitions (%d templates)", count, m_LootTemplates.size());
+ sLog.outString( ">> Loaded %u loot definitions (%lu templates)", count, (unsigned long)m_LootTemplates.size());
}
else
{
@@ -230,17 +240,17 @@ void LootStore::ReportNotExistedId(uint32 id) const
// Checks if the entry (quest, non-quest, reference) takes it's chance (at loot generation)
// RATE_DROP_ITEMS is no longer used for all types of entries
-bool LootStoreItem::Roll() const
+bool LootStoreItem::Roll(bool rate) const
{
if(chance>=100.f)
return true;
if(mincountOrRef < 0) // reference case
- return roll_chance_f(chance*sWorld.getRate(RATE_DROP_ITEM_REFERENCED));
+ return roll_chance_f(chance* (rate ? sWorld.getRate(RATE_DROP_ITEM_REFERENCED) : 1.0f));
ItemPrototype const *pProto = objmgr.GetItemPrototype(itemid);
- float qualityModifier = pProto ? sWorld.getRate(qualityToRate[pProto->Quality]) : 1.0f;
+ float qualityModifier = pProto && rate ? sWorld.getRate(qualityToRate[pProto->Quality]) : 1.0f;
return roll_chance_f(chance*qualityModifier);
}
@@ -248,6 +258,12 @@ bool LootStoreItem::Roll() const
// Checks correctness of values
bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const
{
+ if(group >= 1 << 7) // it stored in 7 bit field
+ {
+ sLog.outErrorDb("Table '%s' entry %d item %d: group (%u) must be less %u - skipped", store.GetName(), entry, itemid, group, 1 << 7);
+ return false;
+ }
+
if (mincountOrRef == 0)
{
sLog.outErrorDb("Table '%s' entry %d item %d: wrong mincountOrRef (%d) - skipped", store.GetName(), entry, itemid, mincountOrRef);
@@ -275,6 +291,13 @@ bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const
store.GetName(), entry, itemid, chance);
return false;
}
+
+ if( maxcount < mincountOrRef) // wrong max count
+ {
+ sLog.outErrorDb("Table '%s' entry %d item %d: max count (%u) less that min count (%i) - skipped", store.GetName(), entry, itemid, uint32(maxcount), mincountOrRef);
+ return false;
+ }
+
}
else // mincountOrRef < 0
{
@@ -366,8 +389,12 @@ void Loot::AddItem(LootStoreItem const & item)
}
// Calls processor of corresponding LootTemplate (which handles everything including references)
-void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner)
+void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner, bool personal)
{
+ // Must be provided
+ if(!loot_owner)
+ return;
+
LootTemplate const* tab = store.GetLootFor(loot_id);
if (!tab)
@@ -379,44 +406,43 @@ void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner)
items.reserve(MAX_NR_LOOT_ITEMS);
quest_items.reserve(MAX_NR_QUEST_ITEMS);
- tab->Process(*this, store); // Processing is done there, callback via Loot::AddItem()
+ tab->Process(*this, store,store.IsRatesAllowed ()); // Processing is done there, callback via Loot::AddItem()
- // Setting access rights fow group-looting case
- if(!loot_owner)
- return;
+ // Setting access rights for group loot case
Group * pGroup=loot_owner->GetGroup();
- if(!pGroup)
- return;
- for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+ if(!personal && pGroup)
{
- //fill the quest item map for every player in the recipient's group
- Player* pl = itr->getSource();
- if(!pl)
- continue;
- uint32 plguid = pl->GetGUIDLow();
- QuestItemMap::iterator qmapitr = PlayerQuestItems.find(plguid);
- if (qmapitr == PlayerQuestItems.end())
- {
- FillQuestLoot(pl);
- }
- qmapitr = PlayerFFAItems.find(plguid);
- if (qmapitr == PlayerFFAItems.end())
- {
- FillFFALoot(pl);
- }
- qmapitr = PlayerNonQuestNonFFAConditionalItems.find(plguid);
- if (qmapitr == PlayerNonQuestNonFFAConditionalItems.end())
- {
- FillNonQuestNonFFAConditionalLoot(pl);
- }
+ for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+ if(Player* pl = itr->getSource())
+ FillNotNormalLootFor(pl);
}
+ // ... for personal loot
+ else
+ FillNotNormalLootFor(loot_owner);
+}
+
+void Loot::FillNotNormalLootFor(Player* pl)
+{
+ uint32 plguid = pl->GetGUIDLow();
+
+ QuestItemMap::const_iterator qmapitr = PlayerQuestItems.find(plguid);
+ if (qmapitr == PlayerQuestItems.end())
+ FillQuestLoot(pl);
+
+ qmapitr = PlayerFFAItems.find(plguid);
+ if (qmapitr == PlayerFFAItems.end())
+ FillFFALoot(pl);
+
+ qmapitr = PlayerNonQuestNonFFAConditionalItems.find(plguid);
+ if (qmapitr == PlayerNonQuestNonFFAConditionalItems.end())
+ FillNonQuestNonFFAConditionalLoot(pl);
}
QuestItemList* Loot::FillFFALoot(Player* player)
{
QuestItemList *ql = new QuestItemList();
- for(uint8 i = 0; i < items.size(); i++)
+ for(uint8 i = 0; i < items.size(); ++i)
{
LootItem &item = items[i];
if(!item.is_looted && item.freeforall && item.AllowedForPlayer(player) )
@@ -440,7 +466,7 @@ QuestItemList* Loot::FillQuestLoot(Player* player)
if (items.size() == MAX_NR_LOOT_ITEMS) return NULL;
QuestItemList *ql = new QuestItemList();
- for(uint8 i = 0; i < quest_items.size(); i++)
+ for(uint8 i = 0; i < quest_items.size(); ++i)
{
LootItem &item = quest_items[i];
if(!item.is_looted && item.AllowedForPlayer(player) )
@@ -544,7 +570,7 @@ void Loot::NotifyQuestItemRemoved(uint8 questIndex)
++i_next;
if(Player* pl = ObjectAccessor::FindPlayer(*i))
{
- QuestItemMap::iterator pq = PlayerQuestItems.find(pl->GetGUIDLow());
+ QuestItemMap::const_iterator pq = PlayerQuestItems.find(pl->GetGUIDLow());
if (pq != PlayerQuestItems.end() && pq->second)
{
// find where/if the player has the given item in it's vector
@@ -603,7 +629,7 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem **qite
QuestItemMap::const_iterator itr = PlayerFFAItems.find(player->GetGUIDLow());
if (itr != PlayerFFAItems.end())
{
- for(QuestItemList::iterator iter=itr->second->begin(); iter!= itr->second->end(); ++iter)
+ for(QuestItemList::const_iterator iter=itr->second->begin(); iter!= itr->second->end(); ++iter)
if(iter->index==lootSlot)
{
QuestItem *ffaitem2 = (QuestItem*)&(*iter);
@@ -619,7 +645,7 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem **qite
QuestItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.find(player->GetGUIDLow());
if (itr != PlayerNonQuestNonFFAConditionalItems.end())
{
- for(QuestItemList::iterator iter=itr->second->begin(); iter!= itr->second->end(); ++iter)
+ for(QuestItemList::const_iterator iter=itr->second->begin(); iter!= itr->second->end(); ++iter)
{
if(iter->index==lootSlot)
{
@@ -640,6 +666,12 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem **qite
return item;
}
+uint32 Loot::GetMaxSlotInLootFor(Player* player) const
+{
+ QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUIDLow());
+ return items.size() + (itr != PlayerQuestItems.end() ? itr->second->size() : 0);
+}
+
ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li)
{
b << uint32(li.itemid);
@@ -653,12 +685,19 @@ ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li)
ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
{
+ if (lv.permission == NONE_PERMISSION)
+ {
+ b << uint32(0); //gold
+ b << uint8(0); // item count
+ return b; // nothing output more
+ }
+
Loot &l = lv.loot;
uint8 itemsShown = 0;
//gold
- b << uint32(lv.permission!=NONE_PERMISSION ? l.gold : 0);
+ b << uint32(l.gold);
size_t count_pos = b.wpos(); // pos of item count byte
b << uint8(0); // item count placeholder
@@ -697,19 +736,21 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
}
break;
}
- case NONE_PERMISSION:
default:
return b; // nothing output more
}
- if (lv.qlist)
+ QuestItemMap const& lootPlayerQuestItems = l.GetPlayerQuestItems();
+ QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(lv.viewer->GetGUIDLow());
+ if (q_itr != lootPlayerQuestItems.end())
{
- for (QuestItemList::iterator qi = lv.qlist->begin() ; qi != lv.qlist->end(); ++qi)
+ QuestItemList *q_list = q_itr->second;
+ for (QuestItemList::const_iterator qi = q_list->begin() ; qi != q_list->end(); ++qi)
{
LootItem &item = l.quest_items[qi->index];
if (!qi->is_looted && !item.is_looted)
{
- b << uint8(l.items.size() + (qi - lv.qlist->begin()));
+ b << uint8(l.items.size() + (qi - q_list->begin()));
b << item;
b << uint8(0); // allow loot
++itemsShown;
@@ -717,9 +758,12 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
}
}
- if (lv.ffalist)
+ QuestItemMap const& lootPlayerFFAItems = l.GetPlayerFFAItems();
+ QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(lv.viewer->GetGUIDLow());
+ if (ffa_itr != lootPlayerFFAItems.end())
{
- for (QuestItemList::iterator fi = lv.ffalist->begin() ; fi != lv.ffalist->end(); ++fi)
+ QuestItemList *ffa_list = ffa_itr->second;
+ for (QuestItemList::const_iterator fi = ffa_list->begin() ; fi != ffa_list->end(); ++fi)
{
LootItem &item = l.items[fi->index];
if (!fi->is_looted && !item.is_looted)
@@ -731,9 +775,12 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
}
}
- if (lv.conditionallist)
+ QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = l.GetPlayerNonQuestNonFFAConditionalItems();
+ QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(lv.viewer->GetGUIDLow());
+ if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end())
{
- for (QuestItemList::iterator ci = lv.conditionallist->begin() ; ci != lv.conditionallist->end(); ++ci)
+ QuestItemList *conditional_list = nn_itr->second;
+ for (QuestItemList::const_iterator ci = conditional_list->begin() ; ci != conditional_list->end(); ++ci)
{
LootItem &item = l.items[ci->index];
if (!ci->is_looted && !item.is_looted)
@@ -776,7 +823,6 @@ LootStoreItem const * LootTemplate::LootGroup::Roll() const
if(ExplicitlyChanced[i].chance>=100.f)
return &ExplicitlyChanced[i];
- ItemPrototype const *pProto = objmgr.GetItemPrototype(ExplicitlyChanced[i].itemid);
Roll -= ExplicitlyChanced[i].chance;
if (Roll < 0)
return &ExplicitlyChanced[i];
@@ -900,7 +946,7 @@ void LootTemplate::AddEntry(LootStoreItem& item)
}
// Rolls for every item in the template and adds the rolled items the the loot
-void LootTemplate::Process(Loot& loot, LootStore const& store, uint8 groupId) const
+void LootTemplate::Process(Loot& loot, LootStore const& store, bool rate, uint8 groupId) const
{
if (groupId) // Group reference uses own processing of the group
{
@@ -914,7 +960,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint8 groupId) co
// Rolling non-grouped items
for (LootStoreItemList::const_iterator i = Entries.begin() ; i != Entries.end() ; ++i )
{
- if ( !i->Roll() )
+ if (!i->Roll(rate))
continue; // Bad luck for the entry
if (i->mincountOrRef < 0) // References processing
@@ -925,7 +971,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint8 groupId) co
continue; // Error message already printed at loading stage
for (uint32 loop=0; loop < i->maxcount; ++loop )// Ref multiplicator
- Referenced->Process(loot, store, i->group); // Ref processing
+ Referenced->Process(loot, store, rate, i->group);
}
else // Plain entries (not a reference, not grouped)
loot.AddItem(*i); // Chance is already checked, just add
@@ -995,7 +1041,7 @@ bool LootTemplate::HasQuestDropForPlayer(LootTemplateMap const& store, Player co
// Now checking groups
for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i )
- if (i->HasQuestDrop())
+ if (i->HasQuestDropForPlayer(player))
return true;
return false;
@@ -1137,6 +1183,29 @@ void LoadLootTemplates_Item()
LootTemplates_Item.ReportUnusedIds(ids_set);
}
+void LoadLootTemplates_Milling()
+{
+ LootIdSet ids_set;
+ LootTemplates_Milling.LoadAndCollectLootIds(ids_set);
+
+ // remove real entries and check existence loot
+ for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i )
+ {
+ ItemPrototype const* proto = sItemStorage.LookupEntry<ItemPrototype>(i);
+ if(!proto)
+ continue;
+
+ if((proto->BagFamily & BAG_FAMILY_MASK_HERBS)==0)
+ continue;
+
+ if(ids_set.count(proto->ItemId))
+ ids_set.erase(proto->ItemId);
+ }
+
+ // output error for any still listed (not referenced from appropriate table) ids
+ LootTemplates_Milling.ReportUnusedIds(ids_set);
+}
+
void LoadLootTemplates_Pickpocketing()
{
LootIdSet ids_set, ids_setUsed;
@@ -1170,9 +1239,17 @@ void LoadLootTemplates_Prospecting()
// remove real entries and check existence loot
for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i )
- if(ItemPrototype const* proto = sItemStorage.LookupEntry<ItemPrototype>(i))
- if(ids_set.count(proto->ItemId))
- ids_set.erase(proto->ItemId);
+ {
+ ItemPrototype const* proto = sItemStorage.LookupEntry<ItemPrototype>(i);
+ if(!proto)
+ continue;
+
+ if((proto->BagFamily & BAG_FAMILY_MASK_MINING_SUPP)==0)
+ continue;
+
+ if(ids_set.count(proto->ItemId))
+ ids_set.erase(proto->ItemId);
+ }
// output error for any still listed (not referenced from appropriate table) ids
LootTemplates_Prospecting.ReportUnusedIds(ids_set);
@@ -1186,8 +1263,17 @@ void LoadLootTemplates_QuestMail()
// remove real entries and check existence loot
ObjectMgr::QuestMap const& questMap = objmgr.GetQuestTemplates();
for(ObjectMgr::QuestMap::const_iterator itr = questMap.begin(); itr != questMap.end(); ++itr )
+ {
+ if(!itr->second->GetRewMailTemplateId())
+ continue;
+
if(ids_set.count(itr->first))
ids_set.erase(itr->first);
+ /* disabled reporting: some quest mails not include items
+ else
+ LootTemplates_QuestMail.ReportNotExistedId(itr->first);
+ */
+ }
// output error for any still listed (not referenced from appropriate table) ids
LootTemplates_QuestMail.ReportUnusedIds(ids_set);
@@ -1219,6 +1305,37 @@ void LoadLootTemplates_Skinning()
LootTemplates_Skinning.ReportUnusedIds(ids_set);
}
+void LoadLootTemplates_Spell()
+{
+ LootIdSet ids_set;
+ LootTemplates_Spell.LoadAndCollectLootIds(ids_set);
+
+ // remove real entries and check existence loot
+ for(uint32 spell_id = 1; spell_id < sSpellStore.GetNumRows(); ++spell_id)
+ {
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry (spell_id);
+ if(!spellInfo)
+ continue;
+
+ // possible cases
+ if( !IsLootCraftingSpell(spellInfo))
+ continue;
+
+ if(!ids_set.count(spell_id))
+ {
+ // not report about not trainable spells (optionally supported by DB) except with SPELL_ATTR_EX2_UNK14 (clams)
+ // 61756 (Northrend Inscription Research (FAST QA VERSION) for example
+ if ((spellInfo->Attributes & SPELL_ATTR_UNK5) || (spellInfo->AttributesEx2 & SPELL_ATTR_EX2_UNK14))
+ LootTemplates_Spell.ReportNotExistedId(spell_id);
+ }
+ else
+ ids_set.erase(spell_id);
+ }
+
+ // output error for any still listed (not referenced from appropriate table) ids
+ LootTemplates_QuestMail.ReportUnusedIds(ids_set);
+}
+
void LoadLootTemplates_Reference()
{
LootIdSet ids_set;
@@ -1229,6 +1346,7 @@ void LoadLootTemplates_Reference()
LootTemplates_Fishing.CheckLootRefs(&ids_set);
LootTemplates_Gameobject.CheckLootRefs(&ids_set);
LootTemplates_Item.CheckLootRefs(&ids_set);
+ LootTemplates_Milling.CheckLootRefs(&ids_set);
LootTemplates_Pickpocketing.CheckLootRefs(&ids_set);
LootTemplates_Skinning.CheckLootRefs(&ids_set);
LootTemplates_Disenchant.CheckLootRefs(&ids_set);
diff --git a/src/game/LootMgr.h b/src/game/LootMgr.h
index 8c64531bf4a..c629977ea67 100644
--- a/src/game/LootMgr.h
+++ b/src/game/LootMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -57,6 +57,21 @@ enum PermissionTypes
NONE_PERMISSION = 3
};
+enum LootType
+{
+ LOOT_CORPSE = 1,
+ LOOT_PICKPOCKETING = 2,
+ LOOT_FISHING = 3,
+ LOOT_DISENCHANTING = 4,
+ // ignored always by client
+ LOOT_SKINNING = 6,
+ LOOT_PROSPECTING = 7,
+ LOOT_MILLING = 8,
+
+ LOOT_FISHINGHOLE = 20, // unsupported by client, sending LOOT_FISHING instead
+ LOOT_INSIGNIA = 21 // unsupported by client, sending LOOT_CORPSE instead
+};
+
class Player;
class LootStore;
@@ -65,19 +80,19 @@ struct LootStoreItem
uint32 itemid; // id of the item
float chance; // always positive, chance to drop for both quest and non-quest items, chance to be used for refs
int32 mincountOrRef; // mincount for drop items (positive) or minus referenced TemplateleId (negative)
- uint8 group :8;
+ uint8 group :7;
+ bool needs_quest :1; // quest drop (negative ChanceOrQuestChance in DB)
uint8 maxcount :8; // max drop count for the item (mincountOrRef positive) or Ref multiplicator (mincountOrRef negative)
uint16 conditionId :16; // additional loot condition Id
- bool needs_quest :1; // quest drop (negative ChanceOrQuestChance in DB)
// Constructor, converting ChanceOrQuestChance -> (chance, needs_quest)
// displayid is filled in IsValid() which must be called after
LootStoreItem(uint32 _itemid, float _chanceOrQuestChance, int8 _group, uint8 _conditionId, int32 _mincountOrRef, uint8 _maxcount)
: itemid(_itemid), chance(fabs(_chanceOrQuestChance)), mincountOrRef(_mincountOrRef),
- group(_group), maxcount(_maxcount), conditionId(_conditionId),
- needs_quest(_chanceOrQuestChance < 0) {}
+ group(_group), needs_quest(_chanceOrQuestChance < 0), maxcount(_maxcount), conditionId(_conditionId)
+ {}
- bool Roll() const; // Checks if the entry takes it's chance (at loot generation)
+ bool Roll(bool rate) const; // Checks if the entry takes it's chance (at loot generation)
bool IsValid(LootStore const& store, uint32 entry) const;
// Checks correctness of values
};
@@ -129,7 +144,8 @@ typedef std::set<uint32> LootIdSet;
class LootStore
{
public:
- explicit LootStore(char const* name, char const* entryName) : m_name(name), m_entryName(entryName) {}
+ explicit LootStore(char const* name, char const* entryName, bool ratesAllowed)
+ : m_name(name), m_entryName(entryName), m_ratesAllowed(ratesAllowed) {}
virtual ~LootStore() { Clear(); }
void Verify() const;
@@ -147,6 +163,7 @@ class LootStore
char const* GetName() const { return m_name; }
char const* GetEntryName() const { return m_entryName; }
+ bool IsRatesAllowed() const { return m_ratesAllowed; }
protected:
void LoadLootTable();
void Clear();
@@ -154,6 +171,7 @@ class LootStore
LootTemplateMap m_LootTemplates;
char const* m_name;
char const* m_entryName;
+ bool m_ratesAllowed;
};
class LootTemplate
@@ -165,7 +183,7 @@ class LootTemplate
// Adds an entry to the group (at loading stage)
void AddEntry(LootStoreItem& item);
// Rolls for every item in the template and adds the rolled items the the loot
- void Process(Loot& loot, LootStore const& store, uint8 GroupId = 0) const;
+ void Process(Loot& loot, LootStore const& store, bool rate, uint8 GroupId = 0) const;
// True if template includes at least 1 quest drop entry
bool HasQuestDrop(LootTemplateMap const& store, uint8 GroupId = 0) const;
@@ -207,23 +225,25 @@ class LootValidatorRefManager : public RefManager<Loot, LootValidatorRef>
};
//=====================================================
+struct LootView;
+
+ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li);
+ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
struct Loot
{
+ friend ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
+
QuestItemMap const& GetPlayerQuestItems() const { return PlayerQuestItems; }
QuestItemMap const& GetPlayerFFAItems() const { return PlayerFFAItems; }
QuestItemMap const& GetPlayerNonQuestNonFFAConditionalItems() const { return PlayerNonQuestNonFFAConditionalItems; }
- QuestItemList* FillFFALoot(Player* player);
- QuestItemList* FillQuestLoot(Player* player);
- QuestItemList* FillNonQuestNonFFAConditionalLoot(Player* player);
-
std::vector<LootItem> items;
- std::vector<LootItem> quest_items;
uint32 gold;
uint8 unlootedCount;
+ LootType loot_type; // required for achievement system
- Loot(uint32 _gold = 0) : gold(_gold), unlootedCount(0) {}
+ Loot(uint32 _gold = 0) : gold(_gold), unlootedCount(0), loot_type(LOOT_CORPSE) {}
~Loot() { clear(); }
// if loot becomes invalid this reference is used to inform the listener
@@ -235,18 +255,19 @@ struct Loot
// void clear();
void clear()
{
- items.clear(); gold = 0; PlayersLooting.clear();
- for (QuestItemMap::iterator itr = PlayerQuestItems.begin(); itr != PlayerQuestItems.end(); ++itr)
- delete itr->second;
- for (QuestItemMap::iterator itr = PlayerFFAItems.begin(); itr != PlayerFFAItems.end(); ++itr)
- delete itr->second;
- for (QuestItemMap::iterator itr = PlayerNonQuestNonFFAConditionalItems.begin(); itr != PlayerNonQuestNonFFAConditionalItems.end(); ++itr)
+ for (QuestItemMap::const_iterator itr = PlayerQuestItems.begin(); itr != PlayerQuestItems.end(); ++itr)
delete itr->second;
-
PlayerQuestItems.clear();
+
+ for (QuestItemMap::const_iterator itr = PlayerFFAItems.begin(); itr != PlayerFFAItems.end(); ++itr)
+ delete itr->second;
PlayerFFAItems.clear();
+
+ for (QuestItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.begin(); itr != PlayerNonQuestNonFFAConditionalItems.end(); ++itr)
+ delete itr->second;
PlayerNonQuestNonFFAConditionalItems.clear();
+ PlayersLooting.clear();
items.clear();
quest_items.clear();
gold = 0;
@@ -264,13 +285,21 @@ struct Loot
void RemoveLooter(uint64 GUID) { PlayersLooting.erase(GUID); }
void generateMoneyLoot(uint32 minAmount, uint32 maxAmount);
- void FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner);
+ void FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner, bool personal);
// Inserts the item into the loot (called by LootTemplate processors)
void AddItem(LootStoreItem const & item);
LootItem* LootItemInSlot(uint32 lootslot, Player* player, QuestItem** qitem = NULL, QuestItem** ffaitem = NULL, QuestItem** conditem = NULL);
+ uint32 GetMaxSlotInLootFor(Player* player) const;
+
private:
+ void FillNotNormalLootFor(Player* player);
+ QuestItemList* FillFFALoot(Player* player);
+ QuestItemList* FillQuestLoot(Player* player);
+ QuestItemList* FillNonQuestNonFFAConditionalLoot(Player* player);
+
+ std::vector<LootItem> quest_items;
std::set<uint64> PlayersLooting;
QuestItemMap PlayerQuestItems;
QuestItemMap PlayerFFAItems;
@@ -278,40 +307,41 @@ struct Loot
// All rolls are registered here. They need to know, when the loot is not valid anymore
LootValidatorRefManager i_LootValidatorRefManager;
-
};
struct LootView
{
Loot &loot;
- QuestItemList *qlist;
- QuestItemList *ffalist;
- QuestItemList *conditionallist;
Player *viewer;
PermissionTypes permission;
- LootView(Loot &_loot, QuestItemList *_qlist, QuestItemList *_ffalist, QuestItemList *_conditionallist, Player *_viewer,PermissionTypes _permission = ALL_PERMISSION)
- : loot(_loot), qlist(_qlist), ffalist(_ffalist), conditionallist(_conditionallist), viewer(_viewer), permission(_permission) {}
+ LootView(Loot &_loot, Player *_viewer,PermissionTypes _permission = ALL_PERMISSION)
+ : loot(_loot), viewer(_viewer), permission(_permission) {}
};
extern LootStore LootTemplates_Creature;
extern LootStore LootTemplates_Fishing;
extern LootStore LootTemplates_Gameobject;
extern LootStore LootTemplates_Item;
+extern LootStore LootTemplates_Milling;
extern LootStore LootTemplates_Pickpocketing;
extern LootStore LootTemplates_Skinning;
extern LootStore LootTemplates_Disenchant;
extern LootStore LootTemplates_Prospecting;
extern LootStore LootTemplates_QuestMail;
+extern LootStore LootTemplates_Spell;
void LoadLootTemplates_Creature();
void LoadLootTemplates_Fishing();
void LoadLootTemplates_Gameobject();
void LoadLootTemplates_Item();
+void LoadLootTemplates_Milling();
void LoadLootTemplates_Pickpocketing();
void LoadLootTemplates_Skinning();
void LoadLootTemplates_Disenchant();
void LoadLootTemplates_Prospecting();
void LoadLootTemplates_QuestMail();
+
+void LoadLootTemplates_Spell();
void LoadLootTemplates_Reference();
inline void LoadLootTables()
@@ -320,15 +350,16 @@ inline void LoadLootTables()
LoadLootTemplates_Fishing();
LoadLootTemplates_Gameobject();
LoadLootTemplates_Item();
+ LoadLootTemplates_Milling();
LoadLootTemplates_Pickpocketing();
LoadLootTemplates_Skinning();
LoadLootTemplates_Disenchant();
LoadLootTemplates_Prospecting();
LoadLootTemplates_QuestMail();
+ LoadLootTemplates_Spell();
+
LoadLootTemplates_Reference();
}
-ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li);
-ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
#endif
diff --git a/src/game/Mail.cpp b/src/game/Mail.cpp
index 5698fdf03f2..8f682a858ee 100644
--- a/src/game/Mail.cpp
+++ b/src/game/Mail.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -29,8 +29,8 @@
#include "UpdateMask.h"
#include "Unit.h"
#include "Language.h"
-#include "Database/DBCStores.h"
#include "AuctionHouseBot.h"
+#include "DBCStores.h"
void MailItem::deleteItem( bool inDB )
{
@@ -55,6 +55,9 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
recv_data >> mailbox;
recv_data >> receiver;
+ if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ return;
+
// recheck
CHECK_PACKET_SIZE(recv_data, 8+(receiver.size()+1)+1+1+4+4+1+4+4+8+1);
@@ -125,9 +128,9 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
return;
}
- uint32 reqmoney = money + 30;
- if (items_count)
- reqmoney = money + (30 * items_count);
+ uint32 cost = items_count ? 30 * items_count : 30; // price hardcoded in client
+
+ uint32 reqmoney = cost + money;
if (pl->GetMoney() < reqmoney)
{
@@ -210,6 +213,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
}
pl->ModifyMoney( -int32(reqmoney) );
+ pl->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost);
bool needItemDelay = false;
@@ -276,6 +280,10 @@ void WorldSession::HandleMarkAsRead(WorldPacket & recv_data )
uint64 mailbox;
uint32 mailId;
recv_data >> mailbox;
+
+ if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ return;
+
recv_data >> mailId;
Player *pl = _player;
Mail *m = pl->GetMail(mailId);
@@ -299,6 +307,10 @@ void WorldSession::HandleMailDelete(WorldPacket & recv_data )
uint32 mailId;
recv_data >> mailbox;
recv_data >> mailId;
+
+ if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ return;
+
Player* pl = _player;
pl->m_mailsUpdated = true;
Mail *m = pl->GetMail(mailId);
@@ -314,6 +326,10 @@ void WorldSession::HandleReturnToSender(WorldPacket & recv_data )
uint64 mailbox;
uint32 mailId;
recv_data >> mailbox;
+
+ if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ return;
+
recv_data >> mailId;
Player *pl = _player;
Mail *m = pl->GetMail(mailId);
@@ -418,6 +434,10 @@ void WorldSession::HandleTakeItem(WorldPacket & recv_data )
uint32 mailId;
uint32 itemId;
recv_data >> mailbox;
+
+ if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ return;
+
recv_data >> mailId;
recv_data >> itemId; // item guid low?
Player* pl = _player;
@@ -509,6 +529,10 @@ void WorldSession::HandleTakeMoney(WorldPacket & recv_data )
uint32 mailId;
recv_data >> mailbox;
recv_data >> mailId;
+
+ if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ return;
+
Player *pl = _player;
Mail* m = pl->GetMail(mailId);
@@ -540,9 +564,8 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data )
uint64 mailbox;
recv_data >> mailbox;
- //GameObject* obj = ObjectAccessor::GetGameObject(_player, mailbox);
- //if(!obj || !obj->IsMailBox())
- // return;
+ if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ return;
Player* pl = _player;
@@ -601,7 +624,7 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data )
data << (uint32) (*itr)->mailTemplateId; // mail template (MailTemplate.dbc)
data << (*itr)->subject; // Subject string - once 00, when mail type = 3
- data << (uint8) item_count;
+ data << (uint8) item_count; // client limit is 0x10
for(uint8 i = 0; i < item_count; ++i)
{
@@ -612,7 +635,7 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data )
data << (uint32) (item ? item->GetGUIDLow() : 0);
// entry
data << (uint32) (item ? item->GetEntry() : 0);
- for(uint8 j = 0; j < 6; ++j)
+ for(uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j)
{
// unsure
data << (uint32) (item ? item->GetEnchantmentCharges((EnchantmentSlot)j) : 0);
@@ -626,13 +649,15 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data )
// unk
data << (uint32) (item ? item->GetItemSuffixFactor() : 0);
// stack count
- data << (uint8) (item ? item->GetCount() : 0);
+ data << (uint32) (item ? item->GetCount() : 0);
// charges
data << (uint32) (item ? item->GetSpellCharges() : 0);
// durability
data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0);
// durability
data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0);
+ // unknown wotlk
+ data << (uint8) 0;
}
mails_count += 1;
@@ -676,6 +701,9 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data )
recv_data >> mailbox >> mailId;
+ if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ return;
+
Player *pl = _player;
Mail* m = pl->GetMail(mailId);
diff --git a/src/game/Mail.h b/src/game/Mail.h
index 784028e6d5d..6bac6d60735 100644
--- a/src/game/Mail.h
+++ b/src/game/Mail.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -196,11 +196,11 @@ struct Mail
}
}
- bool RemoveItem(uint32 itemId)
+ bool RemoveItem(uint32 item_guid)
{
for(std::vector<MailItemInfo>::iterator itr = items.begin(); itr != items.end(); ++itr)
{
- if(itr->item_guid == itemId)
+ if(itr->item_guid == item_guid)
{
items.erase(itr);
return true;
diff --git a/src/game/Makefile.am b/src/game/Makefile.am
new file mode 100644
index 00000000000..47c072a1188
--- /dev/null
+++ b/src/game/Makefile.am
@@ -0,0 +1,847 @@
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+#
+# Copyright (C) 2008-2009 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
+
+## Process this file with automake to produce Makefile.in
+
+## Sub-directories to parse
+
+## CPP flags for includes, defines, etc.
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../dep/include -I$(srcdir)/../framework -I$(srcdir)/../shared -I$(srcdir)/../shared/vmap -I$(srcdir)/../realmd -DSYSCONFDIR=\"$(sysconfdir)/\"
+
+## Build MaNGOS game library as convenience library.
+# All libraries will be convenience libraries. Might be changed to shared
+# later.
+noinst_LIBRARIES = libmangosgame.a
+
+# libmangossgame library will later be reused by ...
+libmangosgame_a_SOURCES = \
+<<<<<<< HEAD:src/game/Makefile.am
+<<<<<<< HEAD:src/game/Makefile.am
+ AccountMgr.cpp \
+ AccountMgr.h \
+ AchievementMgr.h \
+ AchievementMgr.cpp \
+ AddonHandler.cpp \
+ AddonHandler.h \
+ AggressorAI.cpp \
+ AggressorAI.h \
+ AnimalRandomMovementGenerator.h \
+ ArenaTeam.cpp \
+ ArenaTeam.h \
+ ArenaTeamHandler.cpp \
+ AuctionHouseBot.cpp \
+ AuctionHouseBot.h \
+ AuctionHouseHandler.cpp \
+ AuctionHouseMgr.cpp \
+ AuctionHouseMgr.h \
+ Bag.cpp \
+ Bag.h \
+ BattleGround.cpp \
+ BattleGroundAA.cpp \
+ BattleGroundAB.cpp \
+ BattleGroundAV.cpp \
+ BattleGroundBE.cpp \
+ BattleGroundDS.cpp \
+ BattleGroundEY.cpp \
+ BattleGroundNA.cpp \
+ BattleGroundRL.cpp \
+ BattleGroundRV.cpp \
+ BattleGroundSA.cpp \
+ BattleGroundWS.cpp \
+ BattleGround.h \
+ BattleGroundAA.h \
+ BattleGroundAB.h \
+ BattleGroundAV.h \
+ BattleGroundBE.h \
+ BattleGroundDS.h \
+ BattleGroundEY.h \
+ BattleGroundNA.h \
+ BattleGroundRL.h \
+ BattleGroundRV.h \
+ BattleGroundSA.h \
+ BattleGroundWS.h \
+ BattleGroundHandler.cpp \
+ BattleGroundMgr.cpp \
+ BattleGroundMgr.h \
+ Calendar.cpp \
+ Calendar.h \
+ CalendarHandler.cpp \
+ Cell.h \
+ CellImpl.h \
+ Channel.cpp \
+ Channel.h \
+ ChannelHandler.cpp \
+ ChannelMgr.h \
+ CharacterHandler.cpp \
+ Chat.cpp \
+ Chat.h \
+ ChatHandler.cpp \
+ CombatHandler.cpp \
+ ConfusedMovementGenerator.cpp \
+ ConfusedMovementGenerator.h \
+ Corpse.cpp \
+ Corpse.h \
+ CreatureAI.cpp \
+ CreatureAI.h \
+ CreatureAIImpl.h \
+ CreatureAIRegistry.cpp \
+ CreatureAIRegistry.h \
+ CreatureAISelector.cpp \
+ CreatureAISelector.h \
+ CreatureGroups.cpp \
+ CreatureGroups.h \
+ Creature.cpp \
+ Creature.h \
+ debugcmds.cpp \
+ DestinationHolder.cpp \
+ DestinationHolder.h \
+ DestinationHolderImp.h \
+ DuelHandler.cpp \
+ DynamicObject.cpp \
+ DynamicObject.h \
+ FleeingMovementGenerator.cpp \
+ FleeingMovementGenerator.h \
+ Formulas.h \
+ GameEventMgr.cpp \
+ GameEventMgr.h \
+ GameObject.cpp \
+ GameObject.h \
+ GlobalEvents.cpp \
+ GlobalEvents.h \
+ GossipDef.cpp \
+ GossipDef.h \
+ GridDefines.h \
+ GridNotifiers.cpp \
+ GridNotifiers.h \
+ GridNotifiersImpl.h \
+ GridStates.cpp \
+ GridStates.h \
+ Group.cpp \
+ Group.h \
+ GroupHandler.cpp \
+ GuardAI.cpp \
+ GuardAI.h \
+ Guild.cpp \
+ Guild.h \
+ GuildHandler.cpp \
+ HomeMovementGenerator.cpp \
+ HomeMovementGenerator.h \
+ HostilRefManager.cpp \
+ HostilRefManager.h \
+ IdleMovementGenerator.cpp \
+ IdleMovementGenerator.h \
+ InstanceData.cpp \
+ InstanceData.h \
+ InstanceSaveMgr.cpp \
+ InstanceSaveMgr.h \
+ Item.cpp \
+ Item.h \
+ ItemEnchantmentMgr.cpp \
+ ItemEnchantmentMgr.h \
+ ItemHandler.cpp \
+ ItemPrototype.h \
+ Language.h \
+ Level0.cpp \
+ Level1.cpp \
+ Level2.cpp \
+ Level3.cpp \
+ LFGHandler.cpp \
+ LootHandler.cpp \
+ LootMgr.cpp \
+ LootMgr.h \
+ Mail.cpp \
+ Mail.h \
+ Map.cpp \
+ Map.h \
+ MapInstanced.cpp \
+ MapInstanced.h \
+ MapManager.cpp \
+ MapManager.h \
+ MapReference.h \
+ MapRefManager.h \
+ MiscHandler.cpp \
+ MotionMaster.cpp \
+ MotionMaster.h \
+ MovementGenerator.cpp \
+ MovementGenerator.h \
+ MovementGeneratorImpl.h \
+ MovementHandler.cpp \
+ NPCHandler.cpp \
+ NPCHandler.h \
+ NullCreatureAI.cpp \
+ NullCreatureAI.h \
+ ObjectAccessor.cpp \
+ ObjectAccessor.h \
+ Object.cpp \
+ ObjectDefines.h \
+ ObjectGridLoader.cpp \
+ ObjectGridLoader.h \
+ Object.h \
+ ObjectMgr.cpp \
+ ObjectMgr.h \
+ ObjectPosSelector.cpp \
+ ObjectPosSelector.h \
+ Opcodes.cpp \
+ Opcodes.h \
+ OutdoorPvP.cpp \
+ OutdoorPvP.h \
+ OutdoorPvPEP.cpp \
+ OutdoorPvPEP.h \
+ OutdoorPvPHP.cpp \
+ OutdoorPvPHP.h \
+ OutdoorPvPMgr.cpp \
+ OutdoorPvPMgr.h \
+ OutdoorPvPNA.cpp \
+ OutdoorPvPNA.h \
+ OutdoorPvPObjectiveAI.cpp \
+ OutdoorPvPObjectiveAI.h \
+ OutdoorPvPSI.cpp \
+ OutdoorPvPSI.h \
+ OutdoorPvPTF.cpp \
+ OutdoorPvPTF.h \
+ OutdoorPvPZM.cpp \
+ OutdoorPvPZM.h \
+ Path.h \
+ PetAI.cpp \
+ PetAI.h \
+ Pet.cpp \
+ Pet.h \
+ PetHandler.cpp \
+ PetitionsHandler.cpp \
+ Player.cpp \
+ Player.h \
+ PlayerDump.cpp \
+ PlayerDump.h \
+ PossessedAI.cpp \
+ PossessedAI.h \
+ PointMovementGenerator.cpp \
+ PointMovementGenerator.h \
+ PoolHandler.cpp \
+ PoolHandler.h \
+ QueryHandler.cpp \
+ QuestDef.cpp \
+ QuestDef.h \
+ QuestHandler.cpp \
+ RandomMovementGenerator.cpp \
+ RandomMovementGenerator.h \
+ ReactorAI.cpp \
+ ReactorAI.h \
+ ScriptCalls.cpp \
+ ScriptCalls.h \
+ SharedDefines.h \
+ SkillHandler.cpp \
+ SpellAuraDefines.h \
+ SpellAuras.cpp \
+ SpellAuras.h \
+ Spell.cpp \
+ SpellEffects.cpp \
+ Spell.h \
+ SkillDiscovery.cpp \
+ SkillDiscovery.h \
+ SkillExtraItems.cpp \
+ SkillExtraItems.h \
+ SpellHandler.cpp \
+ SocialMgr.cpp \
+ SocialMgr.h \
+ SpellMgr.cpp \
+ SpellMgr.h \
+ StatSystem.cpp \
+ TargetedMovementGenerator.cpp \
+ TargetedMovementGenerator.h \
+ TaxiHandler.cpp \
+ TemporarySummon.cpp \
+ TemporarySummon.h \
+ TotemAI.cpp \
+ TotemAI.h \
+ Totem.cpp \
+ Totem.h \
+ TradeHandler.cpp \
+ Transports.cpp \
+ Transports.h \
+ ThreatManager.cpp \
+ ThreatManager.h \
+ TicketHandler.cpp \
+ TicketMgr.cpp \
+ TicketMgr.h \
+ Traveller.h \
+ Unit.cpp \
+ Unit.h \
+ UnitEvents.h \
+ UpdateData.cpp \
+ UpdateData.h \
+ UpdateFields.h \
+ UpdateMask.h \
+ Vehicle.cpp \
+ Vehicle.h \
+ VoiceChatHandler.cpp \
+ WaypointManager.cpp \
+ WaypointManager.h \
+ WaypointMovementGenerator.cpp \
+ WaypointMovementGenerator.h \
+ Weather.cpp \
+ Weather.h \
+ World.cpp \
+ World.h \
+ WorldLog.cpp \
+ WorldLog.h \
+ WorldSession.cpp \
+ WorldSession.h \
+ WorldSocket.cpp \
+ WorldSocket.h \
+ WorldSocketMgr.cpp \
+ WorldSocketMgr.h \
+ FollowerReference.cpp \
+ FollowerReference.h \
+ FollowerRefManager.h \
+ GroupReference.cpp \
+ GroupReference.h \
+ GroupRefManager.h
+=======
+ AccountMgr.cpp \
+ AccountMgr.h \
+ AchievementMgr.h \
+ AchievementMgr.cpp \
+ AggressorAI.cpp \
+ AggressorAI.h \
+ AnimalRandomMovementGenerator.h \
+ ArenaTeam.cpp \
+ ArenaTeam.h \
+ ArenaTeamHandler.cpp \
+ AuctionHouseHandler.cpp \
+ AuctionHouseMgr.cpp \
+ AuctionHouseMgr.h \
+ Bag.cpp \
+ Bag.h \
+ BattleGround.cpp \
+ BattleGroundAA.cpp \
+ BattleGroundAB.cpp \
+ BattleGroundAV.cpp \
+ BattleGroundBE.cpp \
+ BattleGroundDS.cpp \
+ BattleGroundEY.cpp \
+ BattleGroundNA.cpp \
+ BattleGroundRL.cpp \
+ BattleGroundRV.cpp \
+ BattleGroundSA.cpp \
+ BattleGroundWS.cpp \
+ BattleGround.h \
+ BattleGroundAA.h \
+ BattleGroundAB.h \
+ BattleGroundAV.h \
+ BattleGroundBE.h \
+ BattleGroundDS.h \
+ BattleGroundEY.h \
+ BattleGroundNA.h \
+ BattleGroundRL.h \
+ BattleGroundRV.h \
+ BattleGroundSA.h \
+ BattleGroundWS.h \
+ BattleGroundHandler.cpp \
+ BattleGroundMgr.cpp \
+ BattleGroundMgr.h \
+ Calendar.cpp \
+ Calendar.h \
+ CalendarHandler.cpp \
+ Cell.h \
+ CellImpl.h \
+ Channel.cpp \
+ Channel.h \
+ ChannelHandler.cpp \
+ ChannelMgr.h \
+ CharacterHandler.cpp \
+ Chat.cpp \
+ Chat.h \
+ ChatHandler.cpp \
+ CombatHandler.cpp \
+ ConfusedMovementGenerator.cpp \
+ ConfusedMovementGenerator.h \
+ Corpse.cpp \
+ Corpse.h \
+ CreatureAI.cpp \
+ CreatureAI.h \
+ CreatureAIImpl.h \
+ CreatureAIRegistry.cpp \
+ CreatureAIRegistry.h \
+ CreatureAISelector.cpp \
+ CreatureAISelector.h \
+ Creature.cpp \
+ Creature.h \
+ DBCEnums.h \
+ DBCfmt.h \
+ DBCStores.cpp \
+ DBCStores.h \
+ DBCStructure.h \
+ debugcmds.cpp \
+ DestinationHolder.cpp \
+ DestinationHolder.h \
+ DestinationHolderImp.h \
+ DuelHandler.cpp \
+ DynamicObject.cpp \
+ DynamicObject.h \
+ FleeingMovementGenerator.cpp \
+ FleeingMovementGenerator.h \
+ Formulas.h \
+ GameEventMgr.cpp \
+ GameEventMgr.h \
+ GameObject.cpp \
+ GameObject.h \
+ GlobalEvents.cpp \
+ GlobalEvents.h \
+ GMTicketHandler.cpp \
+ GMTicketMgr.cpp \
+ GMTicketMgr.h \
+ GossipDef.cpp \
+ GossipDef.h \
+ GridDefines.h \
+ GridNotifiers.cpp \
+ GridNotifiers.h \
+ GridNotifiersImpl.h \
+ GridStates.cpp \
+ GridStates.h \
+ Group.cpp \
+ Group.h \
+ GroupHandler.cpp \
+ GuardAI.cpp \
+ GuardAI.h \
+ Guild.cpp \
+ Guild.h \
+ GuildHandler.cpp \
+ HomeMovementGenerator.cpp \
+ HomeMovementGenerator.h \
+ HostilRefManager.cpp \
+ HostilRefManager.h \
+ IdleMovementGenerator.cpp \
+ IdleMovementGenerator.h \
+ InstanceData.cpp \
+ InstanceData.h \
+ InstanceSaveMgr.cpp \
+ InstanceSaveMgr.h \
+ Item.cpp \
+ Item.h \
+ ItemEnchantmentMgr.cpp \
+ ItemEnchantmentMgr.h \
+ ItemHandler.cpp \
+ ItemPrototype.h \
+ Language.h \
+ Level0.cpp \
+ Level1.cpp \
+ Level2.cpp \
+ Level3.cpp \
+ LFGHandler.cpp \
+ LootHandler.cpp \
+ LootMgr.cpp \
+ LootMgr.h \
+ Mail.cpp \
+ Mail.h \
+ Map.cpp \
+ Map.h \
+ MapInstanced.cpp \
+ MapInstanced.h \
+ MapManager.cpp \
+ MapManager.h \
+ MapReference.h \
+ MapRefManager.h \
+ MiscHandler.cpp \
+ MotionMaster.cpp \
+ MotionMaster.h \
+ MovementGenerator.cpp \
+ MovementGenerator.h \
+ MovementGeneratorImpl.h \
+ MovementHandler.cpp \
+ NPCHandler.cpp \
+ NPCHandler.h \
+ NullCreatureAI.cpp \
+ NullCreatureAI.h \
+ ObjectAccessor.cpp \
+ ObjectAccessor.h \
+ Object.cpp \
+ ObjectDefines.h \
+ ObjectGridLoader.cpp \
+ ObjectGridLoader.h \
+ Object.h \
+ ObjectMgr.cpp \
+ ObjectMgr.h \
+ ObjectPosSelector.cpp \
+ ObjectPosSelector.h \
+ Opcodes.cpp \
+ Opcodes.h \
+ Path.h \
+ PetAI.cpp \
+ PetAI.h \
+ Pet.cpp \
+ Pet.h \
+ PetHandler.cpp \
+ PetitionsHandler.cpp \
+ Player.cpp \
+ Player.h \
+ PlayerDump.cpp \
+ PlayerDump.h \
+ PointMovementGenerator.cpp \
+ PointMovementGenerator.h \
+ PoolHandler.cpp \
+ PoolHandler.h \
+ QueryHandler.cpp \
+ QuestDef.cpp \
+ QuestDef.h \
+ QuestHandler.cpp \
+ RandomMovementGenerator.cpp \
+ RandomMovementGenerator.h \
+ ReactorAI.cpp \
+ ReactorAI.h \
+ ReputationMgr.cpp \
+ ReputationMgr.h \
+ ScriptCalls.cpp \
+ ScriptCalls.h \
+ SharedDefines.h \
+ SkillHandler.cpp \
+ SpellAuraDefines.h \
+ SpellAuras.cpp \
+ SpellAuras.h \
+ Spell.cpp \
+ SpellEffects.cpp \
+ Spell.h \
+ SkillDiscovery.cpp \
+ SkillDiscovery.h \
+ SkillExtraItems.cpp \
+ SkillExtraItems.h \
+ SpellHandler.cpp \
+ SocialMgr.cpp \
+ SocialMgr.h \
+ SpellMgr.cpp \
+ SpellMgr.h \
+ StatSystem.cpp \
+ TargetedMovementGenerator.cpp \
+ TargetedMovementGenerator.h \
+ TaxiHandler.cpp \
+ TemporarySummon.cpp \
+ TemporarySummon.h \
+ TotemAI.cpp \
+ TotemAI.h \
+ Totem.cpp \
+ Totem.h \
+ TradeHandler.cpp \
+ Transports.cpp \
+ Transports.h \
+ ThreatManager.cpp \
+ ThreatManager.h \
+ Traveller.h \
+ Unit.cpp \
+ Unit.h \
+ UnitEvents.h \
+ UpdateData.cpp \
+ UpdateData.h \
+ UpdateFields.h \
+ UpdateMask.h \
+ Vehicle.cpp \
+ Vehicle.h \
+ VoiceChatHandler.cpp \
+ WaypointManager.cpp \
+ WaypointManager.h \
+ WaypointMovementGenerator.cpp \
+ WaypointMovementGenerator.h \
+ Weather.cpp \
+ Weather.h \
+ World.cpp \
+ World.h \
+ WorldLog.cpp \
+ WorldLog.h \
+ WorldSession.cpp \
+ WorldSession.h \
+ WorldSocket.cpp \
+ WorldSocket.h \
+ WorldSocketMgr.cpp \
+ WorldSocketMgr.h \
+ FollowerReference.cpp \
+ FollowerReference.h \
+ FollowerRefManager.h \
+ GroupReference.cpp \
+ GroupReference.h \
+ GroupRefManager.h
+>>>>>>> 2429aaf2276d689e101ed88285f18449dbe4280d:src/game/Makefile.am
+=======
+ AccountMgr.cpp \
+ AccountMgr.h \
+ AchievementMgr.h \
+ AchievementMgr.cpp \
+ AggressorAI.cpp \
+ AggressorAI.h \
+ AnimalRandomMovementGenerator.h \
+ ArenaTeam.cpp \
+ ArenaTeam.h \
+ ArenaTeamHandler.cpp \
+ AuctionHouseHandler.cpp \
+ AuctionHouseMgr.cpp \
+ AuctionHouseMgr.h \
+ Bag.cpp \
+ Bag.h \
+ BattleGround.cpp \
+ BattleGroundAA.cpp \
+ BattleGroundAB.cpp \
+ BattleGroundAV.cpp \
+ BattleGroundBE.cpp \
+ BattleGroundDS.cpp \
+ BattleGroundEY.cpp \
+ BattleGroundNA.cpp \
+ BattleGroundRL.cpp \
+ BattleGroundRV.cpp \
+ BattleGroundSA.cpp \
+ BattleGroundWS.cpp \
+ BattleGround.h \
+ BattleGroundAA.h \
+ BattleGroundAB.h \
+ BattleGroundAV.h \
+ BattleGroundBE.h \
+ BattleGroundDS.h \
+ BattleGroundEY.h \
+ BattleGroundNA.h \
+ BattleGroundRL.h \
+ BattleGroundRV.h \
+ BattleGroundSA.h \
+ BattleGroundWS.h \
+ BattleGroundHandler.cpp \
+ BattleGroundMgr.cpp \
+ BattleGroundMgr.h \
+ Calendar.cpp \
+ Calendar.h \
+ CalendarHandler.cpp \
+ Cell.h \
+ CellImpl.h \
+ Channel.cpp \
+ Channel.h \
+ ChannelHandler.cpp \
+ ChannelMgr.h \
+ CharacterHandler.cpp \
+ Chat.cpp \
+ Chat.h \
+ ChatHandler.cpp \
+ CombatHandler.cpp \
+ ConfusedMovementGenerator.cpp \
+ ConfusedMovementGenerator.h \
+ Corpse.cpp \
+ Corpse.h \
+ CreatureAI.cpp \
+ CreatureAI.h \
+ CreatureAIImpl.h \
+ CreatureAIRegistry.cpp \
+ CreatureAIRegistry.h \
+ CreatureAISelector.cpp \
+ CreatureAISelector.h \
+ CreatureEventAI.cpp \
+ CreatureEventAI.h \
+ CreatureEventAIMgr.cpp \
+ CreatureEventAIMgr.h \
+ Creature.cpp \
+ Creature.h \
+ DBCEnums.h \
+ DBCfmt.h \
+ DBCStores.cpp \
+ DBCStores.h \
+ DBCStructure.h \
+ debugcmds.cpp \
+ DestinationHolder.cpp \
+ DestinationHolder.h \
+ DestinationHolderImp.h \
+ DuelHandler.cpp \
+ DynamicObject.cpp \
+ DynamicObject.h \
+ FleeingMovementGenerator.cpp \
+ FleeingMovementGenerator.h \
+ Formulas.h \
+ GameEventMgr.cpp \
+ GameEventMgr.h \
+ GameObject.cpp \
+ GameObject.h \
+ GlobalEvents.cpp \
+ GlobalEvents.h \
+ GMTicketHandler.cpp \
+ GMTicketMgr.cpp \
+ GMTicketMgr.h \
+ GossipDef.cpp \
+ GossipDef.h \
+ GridDefines.h \
+ GridNotifiers.cpp \
+ GridNotifiers.h \
+ GridNotifiersImpl.h \
+ GridStates.cpp \
+ GridStates.h \
+ Group.cpp \
+ Group.h \
+ GroupHandler.cpp \
+ GuardAI.cpp \
+ GuardAI.h \
+ Guild.cpp \
+ Guild.h \
+ GuildHandler.cpp \
+ HomeMovementGenerator.cpp \
+ HomeMovementGenerator.h \
+ HostilRefManager.cpp \
+ HostilRefManager.h \
+ IdleMovementGenerator.cpp \
+ IdleMovementGenerator.h \
+ InstanceData.cpp \
+ InstanceData.h \
+ InstanceSaveMgr.cpp \
+ InstanceSaveMgr.h \
+ Item.cpp \
+ Item.h \
+ ItemEnchantmentMgr.cpp \
+ ItemEnchantmentMgr.h \
+ ItemHandler.cpp \
+ ItemPrototype.h \
+ Language.h \
+ Level0.cpp \
+ Level1.cpp \
+ Level2.cpp \
+ Level3.cpp \
+ LFGHandler.cpp \
+ LootHandler.cpp \
+ LootMgr.cpp \
+ LootMgr.h \
+ Mail.cpp \
+ Mail.h \
+ Map.cpp \
+ Map.h \
+ MapInstanced.cpp \
+ MapInstanced.h \
+ MapManager.cpp \
+ MapManager.h \
+ MapReference.h \
+ MapRefManager.h \
+ MiscHandler.cpp \
+ MotionMaster.cpp \
+ MotionMaster.h \
+ MovementGenerator.cpp \
+ MovementGenerator.h \
+ MovementGeneratorImpl.h \
+ MovementHandler.cpp \
+ NPCHandler.cpp \
+ NPCHandler.h \
+ NullCreatureAI.cpp \
+ NullCreatureAI.h \
+ ObjectAccessor.cpp \
+ ObjectAccessor.h \
+ Object.cpp \
+ ObjectDefines.h \
+ ObjectGridLoader.cpp \
+ ObjectGridLoader.h \
+ Object.h \
+ ObjectMgr.cpp \
+ ObjectMgr.h \
+ ObjectPosSelector.cpp \
+ ObjectPosSelector.h \
+ Opcodes.cpp \
+ Opcodes.h \
+ Path.h \
+ PetAI.cpp \
+ PetAI.h \
+ Pet.cpp \
+ Pet.h \
+ PetHandler.cpp \
+ PetitionsHandler.cpp \
+ Player.cpp \
+ Player.h \
+ PlayerDump.cpp \
+ PlayerDump.h \
+ PointMovementGenerator.cpp \
+ PointMovementGenerator.h \
+ PoolHandler.cpp \
+ PoolHandler.h \
+ QueryHandler.cpp \
+ QuestDef.cpp \
+ QuestDef.h \
+ QuestHandler.cpp \
+ RandomMovementGenerator.cpp \
+ RandomMovementGenerator.h \
+ ReactorAI.cpp \
+ ReactorAI.h \
+ ReputationMgr.cpp \
+ ReputationMgr.h \
+ ScriptCalls.cpp \
+ ScriptCalls.h \
+ SharedDefines.h \
+ SkillHandler.cpp \
+ SpellAuraDefines.h \
+ SpellAuras.cpp \
+ SpellAuras.h \
+ Spell.cpp \
+ SpellEffects.cpp \
+ Spell.h \
+ SkillDiscovery.cpp \
+ SkillDiscovery.h \
+ SkillExtraItems.cpp \
+ SkillExtraItems.h \
+ SpellHandler.cpp \
+ SocialMgr.cpp \
+ SocialMgr.h \
+ SpellMgr.cpp \
+ SpellMgr.h \
+ StatSystem.cpp \
+ TargetedMovementGenerator.cpp \
+ TargetedMovementGenerator.h \
+ TaxiHandler.cpp \
+ TemporarySummon.cpp \
+ TemporarySummon.h \
+ TotemAI.cpp \
+ TotemAI.h \
+ Totem.cpp \
+ Totem.h \
+ TradeHandler.cpp \
+ Transports.cpp \
+ Transports.h \
+ ThreatManager.cpp \
+ ThreatManager.h \
+ Traveller.h \
+ Unit.cpp \
+ Unit.h \
+ UnitEvents.h \
+ UpdateData.cpp \
+ UpdateData.h \
+ UpdateFields.h \
+ UpdateMask.h \
+ Vehicle.cpp \
+ Vehicle.h \
+ VoiceChatHandler.cpp \
+ WaypointManager.cpp \
+ WaypointManager.h \
+ WaypointMovementGenerator.cpp \
+ WaypointMovementGenerator.h \
+ Weather.cpp \
+ Weather.h \
+ World.cpp \
+ World.h \
+ WorldLog.cpp \
+ WorldLog.h \
+ WorldSession.cpp \
+ WorldSession.h \
+ WorldSocket.cpp \
+ WorldSocket.h \
+ WorldSocketMgr.cpp \
+ WorldSocketMgr.h \
+ FollowerReference.cpp \
+ FollowerReference.h \
+ FollowerRefManager.h \
+ GroupReference.cpp \
+ GroupReference.h \
+ GroupRefManager.h
+>>>>>>> 5a6594330caefc0dc00a5fe792dcb0e344b457cb:src/game/Makefile.am
+
+## Link against shared library
+libmangosgame_a_LIBADD = ../shared/libmangosshared.a ../shared/Auth/libmangosauth.a ../shared/Config/libmangosconfig.a ../shared/Database/libmangosdatabase.a ../shared/vmap/libmangosvmaps.a
+
+## Additional files to include when running 'make dist'
+# Nothing yet.
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index 65c30f1781e..20590eb071b 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -21,7 +21,6 @@
#include "MapManager.h"
#include "Player.h"
#include "GridNotifiers.h"
-#include "WorldSession.h"
#include "Log.h"
#include "GridStates.h"
#include "CellImpl.h"
@@ -36,6 +35,7 @@
#include "ScriptCalls.h"
#include "Group.h"
#include "MapRefManager.h"
+#include "Vehicle.h"
#include "MapInstanced.h"
#include "InstanceSaveMgr.h"
@@ -44,9 +44,6 @@
#define DEFAULT_GRID_EXPIRY 300
#define MAX_GRID_LOAD_TIME 50
-// magic *.map header
-const char MAP_MAGIC[] = "MAP_2.50";
-
GridState* si_GridStates[MAX_GRID_STATE];
Map::~Map()
@@ -54,11 +51,11 @@ Map::~Map()
UnloadAll();
}
-bool Map::ExistMap(uint32 mapid,int x,int y)
+bool Map::ExistMap(uint32 mapid,int gx,int gy)
{
int len = sWorld.GetDataPath().length()+strlen("maps/%03u%02u%02u.map")+1;
char* tmp = new char[len];
- snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),mapid,x,y);
+ snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),mapid,gx,gy);
FILE *pf=fopen(tmp,"rb");
@@ -69,9 +66,10 @@ bool Map::ExistMap(uint32 mapid,int x,int y)
return false;
}
- char magic[8];
- fread(magic,1,8,pf);
- if(strncmp(MAP_MAGIC,magic,8))
+ map_fileheader header;
+ fread(&header, sizeof(header), 1, pf);
+ if (header.mapMagic != uint32(MAP_MAGIC) ||
+ header.versionMagic != uint32(MAP_VERSION_MAGIC))
{
sLog.outError("Map file '%s' is non-compatible version (outdated?). Please, create new using ad.exe program.",tmp);
delete [] tmp;
@@ -84,17 +82,17 @@ bool Map::ExistMap(uint32 mapid,int x,int y)
return true;
}
-bool Map::ExistVMap(uint32 mapid,int x,int y)
+bool Map::ExistVMap(uint32 mapid,int gx,int gy)
{
if(VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager())
{
if(vmgr->isMapLoadingEnabled())
{
// x and y are swapped !! => fixed now
- bool exists = vmgr->existsMap((sWorld.GetDataPath()+ "vmaps").c_str(), mapid, x,y);
+ bool exists = vmgr->existsMap((sWorld.GetDataPath()+ "vmaps").c_str(), mapid, gx,gy);
if(!exists)
{
- std::string name = vmgr->getDirFileName(mapid,x,y);
+ std::string name = vmgr->getDirFileName(mapid,gx,gy);
sLog.outError("VMap file '%s' is missing or point to wrong version vmap file, redo vmaps with latest vmap_assembler.exe program", (sWorld.GetDataPath()+"vmaps/"+name).c_str());
return false;
}
@@ -104,91 +102,70 @@ bool Map::ExistVMap(uint32 mapid,int x,int y)
return true;
}
-void Map::LoadVMap(int x,int y)
+void Map::LoadVMap(int gx,int gy)
{
// x and y are swapped !!
- int vmapLoadResult = VMAP::VMapFactory::createOrGetVMapManager()->loadMap((sWorld.GetDataPath()+ "vmaps").c_str(), GetId(), x,y);
+ int vmapLoadResult = VMAP::VMapFactory::createOrGetVMapManager()->loadMap((sWorld.GetDataPath()+ "vmaps").c_str(), GetId(), gx,gy);
switch(vmapLoadResult)
{
case VMAP::VMAP_LOAD_RESULT_OK:
- sLog.outDetail("VMAP loaded name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), x,y, x,y);
+ sLog.outDetail("VMAP loaded name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx,gy,gx,gy);
break;
case VMAP::VMAP_LOAD_RESULT_ERROR:
- sLog.outDetail("Could not load VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), x,y, x,y);
+ sLog.outDetail("Could not load VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx,gy,gx,gy);
break;
case VMAP::VMAP_LOAD_RESULT_IGNORED:
- DEBUG_LOG("Ignored VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), x,y, x,y);
+ DEBUG_LOG("Ignored VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx,gy,gx,gy);
break;
}
}
-void Map::LoadMap(uint32 mapid, uint32 instanceid, int x,int y)
+void Map::LoadMap(int gx,int gy)
{
- if( instanceid != 0 )
+ if( i_InstanceId != 0 )
{
- if(GridMaps[x][y])
+ if(GridMaps[gx][gy])
return;
- Map* baseMap = const_cast<Map*>(MapManager::Instance().GetBaseMap(mapid));
-
- // load gridmap for base map
- if (!baseMap->GridMaps[x][y])
- baseMap->EnsureGridCreated(GridPair(63-x,63-y));
+ Map* baseMap = const_cast<Map*>(MapManager::Instance().GetBaseMap(i_id));
-//+++ if (!baseMap->GridMaps[x][y]) don't check for GridMaps[gx][gy], we need the management for vmaps
-// return;
+ // load grid map for base map
+ if (!baseMap->GridMaps[gx][gy])
+ baseMap->EnsureGridCreated(GridPair(63-gx,63-gy));
- ((MapInstanced*)(baseMap))->AddGridMapReference(GridPair(x,y));
- GridMaps[x][y] = baseMap->GridMaps[x][y];
+ ((MapInstanced*)(baseMap))->AddGridMapReference(GridPair(gx,gy));
+ GridMaps[gx][gy] = baseMap->GridMaps[gx][gy];
return;
}
//map already load, delete it before reloading (Is it necessary? Do we really need the ability the reload maps during runtime?)
- if(GridMaps[x][y])
+ if(GridMaps[gx][gy])
{
- sLog.outDetail("Unloading already loaded map %u before reloading.",mapid);
- delete (GridMaps[x][y]);
- GridMaps[x][y]=NULL;
+ sLog.outDetail("Unloading already loaded map %u before reloading.",i_id);
+ delete (GridMaps[gx][gy]);
+ GridMaps[gx][gy]=NULL;
}
// map file name
char *tmp=NULL;
- // Pihhan: dataPath length + "maps/" + 3+2+2+ ".map" length may be > 32 !
int len = sWorld.GetDataPath().length()+strlen("maps/%03u%02u%02u.map")+1;
tmp = new char[len];
- snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),mapid,x,y);
+ snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),i_id,gx,gy);
sLog.outDetail("Loading map %s",tmp);
// loading data
- FILE *pf=fopen(tmp,"rb");
- if(!pf)
+ GridMaps[gx][gy] = new GridMap();
+ if (!GridMaps[gx][gy]->loadData(tmp))
{
- delete [] tmp;
- return;
- }
-
- char magic[8];
- fread(magic,1,8,pf);
- if(strncmp(MAP_MAGIC,magic,8))
- {
- sLog.outError("Map file '%s' is non-compatible version (outdated?). Please, create new using ad.exe program.",tmp);
- delete [] tmp;
- fclose(pf); //close file before return
- return;
+ sLog.outError("Error load map file: \n %s\n", tmp);
}
- delete [] tmp;
-
- GridMap * buf= new GridMap;
- fread(buf,1,sizeof(GridMap),pf);
- fclose(pf);
-
- GridMaps[x][y] = buf;
+ delete [] tmp;
}
-void Map::LoadMapAndVMap(uint32 mapid, uint32 instanceid, int x,int y)
+void Map::LoadMapAndVMap(int gx,int gy)
{
- LoadMap(mapid,instanceid,x,y);
- if(instanceid == 0)
- LoadVMap(x, y); // Only load the data for the base map
+ LoadMap(gx,gy);
+ if(i_InstanceId == 0)
+ LoadVMap(gx, gy); // Only load the data for the base map
}
void Map::InitStateMachine()
@@ -256,7 +233,7 @@ template<>
void Map::AddToGrid(Creature* obj, NGridType *grid, Cell const& cell)
{
// add to world object registry in grid
- if(obj->isPet() || obj->IsTempWorldObject)
+ if(obj->isWorldCreature() || obj->IsTempWorldObject)
{
(*grid)(cell.CellX(), cell.CellY()).AddWorldObject<Creature>(obj, obj->GetGUID());
}
@@ -308,7 +285,7 @@ template<>
void Map::RemoveFromGrid(Creature* obj, NGridType *grid, Cell const& cell)
{
// remove from world object registry in grid
- if(obj->isPet() || obj->IsTempWorldObject)
+ if(obj->isWorldCreature() || obj->IsTempWorldObject)
{
(*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject<Creature>(obj, obj->GetGUID());
}
@@ -410,7 +387,7 @@ Map::EnsureGridCreated(const GridPair &p)
Guard guard(*this);
if(!getNGrid(p.x_coord, p.y_coord))
{
- sLog.outDebug("Loading grid[%u,%u] for map %u", p.x_coord, p.y_coord, i_id);
+ sLog.outDebug("Creating grid[%u,%u] for map %u instance %u", p.x_coord, p.y_coord, i_id, i_InstanceId);
setNGrid(new NGridType(p.x_coord*MAX_NUMBER_OF_GRIDS + p.y_coord, p.x_coord, p.y_coord, i_gridExpiry, sWorld.getConfig(CONFIG_GRID_UNLOAD)),
p.x_coord, p.y_coord);
@@ -425,20 +402,20 @@ Map::EnsureGridCreated(const GridPair &p)
int gy=63-p.y_coord;
if(!GridMaps[gx][gy])
- Map::LoadMapAndVMap(i_id,i_InstanceId,gx,gy);
+ LoadMapAndVMap(gx,gy);
}
}
}
void
-Map::EnsureGridLoaded(const Cell &cell, Player *player)
+Map::EnsureGridLoadedAtEnter(const Cell &cell, Player *player)
{
- EnsureGridCreated(GridPair(cell.GridX(), cell.GridY()));
- NGridType *grid = getNGrid(cell.GridX(), cell.GridY());
+ NGridType *grid;
- assert(grid != NULL);
- if (!isGridObjectDataLoaded(cell.GridX(), cell.GridY()))
+ if(EnsureGridLoaded(cell))
{
+ grid = getNGrid(cell.GridX(), cell.GridY());
+
if (player)
{
player->SendDelayResponse(MAX_GRID_LOAD_TIME);
@@ -449,19 +426,37 @@ Map::EnsureGridLoaded(const Cell &cell, Player *player)
DEBUG_LOG("Active object nearby triggers of loading grid [%u,%u] on map %u", cell.GridX(), cell.GridY(), i_id);
}
+ ResetGridExpiry(*getNGrid(cell.GridX(), cell.GridY()), 0.1f);
+ grid->SetGridState(GRID_STATE_ACTIVE);
+ }
+ else
+ grid = getNGrid(cell.GridX(), cell.GridY());
+
+ if (player)
+ AddToGrid(player,grid,cell);
+}
+
+bool Map::EnsureGridLoaded(const Cell &cell)
+{
+ EnsureGridCreated(GridPair(cell.GridX(), cell.GridY()));
+ NGridType *grid = getNGrid(cell.GridX(), cell.GridY());
+
+ assert(grid != NULL);
+ if( !isGridObjectDataLoaded(cell.GridX(), cell.GridY()) )
+ {
+ sLog.outDebug("Loading grid[%u,%u] for map %u instance %u", cell.GridX(), cell.GridY(), i_id, i_InstanceId);
+
ObjectGridLoader loader(*grid, this, cell);
loader.LoadN();
- setGridObjectDataLoaded(true, cell.GridX(), cell.GridY());
// Add resurrectable corpses to world object list in grid
ObjectAccessor::Instance().AddCorpsesToGrid(GridPair(cell.GridX(),cell.GridY()),(*grid)(cell.CellX(), cell.CellY()), this);
- ResetGridExpiry(*getNGrid(cell.GridX(), cell.GridY()), 0.1f);
- grid->SetGridState(GRID_STATE_ACTIVE);
+ setGridObjectDataLoaded(true,cell.GridX(), cell.GridY());
+ return true;
}
-
- if(player)
- AddToGrid(player,grid,cell);
+
+ return false;
}
void Map::LoadGrid(float x, float y)
@@ -480,7 +475,7 @@ bool Map::Add(Player *player)
// update player state for other player and visa-versa
CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
Cell cell(p);
- EnsureGridLoaded(cell, player);
+ EnsureGridLoadedAtEnter(cell, player);
player->AddToWorld();
SendInitSelf(player);
@@ -508,7 +503,7 @@ Map::Add(T *obj)
Cell cell(p);
if(obj->isActiveObject())
- EnsureGridLoaded(cell);
+ EnsureGridLoadedAtEnter(cell);
else
EnsureGridCreated(GridPair(cell.GridX(), cell.GridY()));
@@ -517,12 +512,14 @@ Map::Add(T *obj)
AddToGrid(obj,grid,cell);
obj->AddToWorld();
-
+
if(obj->isActiveObject())
AddToActive(obj);
DEBUG_LOG("Object %u enters grid[%u,%u]", GUID_LOPART(obj->GetGUID()), cell.GridX(), cell.GridY());
+ //something, such as vehicle, needs to be update immediately
+ //if(obj->GetTypeId() != TYPEID_UNIT)
UpdateObjectVisibility(obj,cell,p);
//AddNotifier(obj);
@@ -530,92 +527,26 @@ Map::Add(T *obj)
void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self, bool to_possessor)
{
- CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
-
- if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP )
- {
- sLog.outError("Map::MessageBroadcast: Player (GUID: %u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", player->GetGUIDLow(), player->GetPositionX(), player->GetPositionY(), p.x_coord, p.y_coord);
- return;
- }
-
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
-
- if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
- return;
-
Trinity::MessageDeliverer post_man(*player, msg, to_possessor, to_self);
- TypeContainerVisitor<Trinity::MessageDeliverer, WorldTypeMapContainer > message(post_man);
- CellLock<ReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, message, *this);
+ VisitWorld(player->GetPositionX(), player->GetPositionY(), World::GetMaxVisibleDistance(), post_man);
}
void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg, bool to_possessor)
{
- CellPair p = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
-
- if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP )
- {
- sLog.outError("Map::MessageBroadcast: Object " I64FMTD " have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord);
- return;
- }
-
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
- cell.SetNoCreate();
-
- if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
- return;
-
Trinity::ObjectMessageDeliverer post_man(*obj, msg, to_possessor);
- TypeContainerVisitor<Trinity::ObjectMessageDeliverer, WorldTypeMapContainer > message(post_man);
- CellLock<ReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, message, *this);
+ VisitWorld(obj->GetPositionX(), obj->GetPositionY(), World::GetMaxVisibleDistance(), post_man);
}
void Map::MessageDistBroadcast(Player *player, WorldPacket *msg, float dist, bool to_self, bool to_possessor, bool own_team_only)
{
- CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
-
- if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP )
- {
- sLog.outError("Map::MessageBroadcast: Player (GUID: %u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", player->GetGUIDLow(), player->GetPositionX(), player->GetPositionY(), p.x_coord, p.y_coord);
- return;
- }
-
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
-
- if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
- return;
-
Trinity::MessageDistDeliverer post_man(*player, msg, to_possessor, dist, to_self, own_team_only);
- TypeContainerVisitor<Trinity::MessageDistDeliverer , WorldTypeMapContainer > message(post_man);
- CellLock<ReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, message, *this);
+ VisitWorld(player->GetPositionX(), player->GetPositionY(), World::GetMaxVisibleDistance(), post_man);
}
void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist, bool to_possessor)
{
- CellPair p = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
-
- if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP )
- {
- sLog.outError("Map::MessageBroadcast: Object " I64FMTD " have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord);
- return;
- }
-
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
- cell.SetNoCreate();
-
- if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
- return;
-
Trinity::ObjectMessageDistDeliverer post_man(*obj, msg, to_possessor, dist);
- TypeContainerVisitor<Trinity::ObjectMessageDistDeliverer, WorldTypeMapContainer > message(post_man);
- CellLock<ReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, message, *this);
+ VisitWorld(obj->GetPositionX(), obj->GetPositionY(), World::GetMaxVisibleDistance(), post_man);
}
bool Map::loaded(const GridPair &p) const
@@ -740,6 +671,13 @@ void Map::Update(const uint32 &t_diff)
}
}
}
+
+ if(plr->m_seer != plr && !plr->hasUnitState(UNIT_STAT_ONVEHICLE))
+ {
+ Trinity::PlayerVisibilityNotifier notifier(*plr);
+ VisitAll(plr->m_seer->GetPositionX(), plr->m_seer->GetPositionY(), World::GetMaxVisibleDistance(), notifier);
+ notifier.Notify();
+ }
}
// non-player active objects
@@ -757,33 +695,6 @@ void Map::Update(const uint32 &t_diff)
if(!obj->IsInWorld())
continue;
- // Update bindsight players
- /*if(obj->isType(TYPEMASK_UNIT))
- {
- if(!((Unit*)obj)->GetSharedVisionList().empty())
- for(SharedVisionList::const_iterator itr = ((Unit*)obj)->GetSharedVisionList().begin(); itr != ((Unit*)obj)->GetSharedVisionList().end(); ++itr)
- {
- if(!*itr)
- {
- sLog.outError("unit %u has invalid shared vision player, list size %u", obj->GetEntry(), ((Unit*)obj)->GetSharedVisionList().size());
- continue;
- }
- Trinity::PlayerVisibilityNotifier notifier(**itr);
- VisitAll(obj->GetPositionX(), obj->GetPositionY(), World::GetMaxVisibleDistance(), notifier);
- notifier.Notify();
- }
- }
- else */if(obj->GetTypeId() == TYPEID_DYNAMICOBJECT)
- {
- if(Unit *caster = ((DynamicObject*)obj)->GetCaster())
- if(caster->GetTypeId() == TYPEID_PLAYER && caster->GetUInt64Value(PLAYER_FARSIGHT) == obj->GetGUID())
- {
- Trinity::PlayerVisibilityNotifier notifier(*((Player*)caster));
- VisitAll(obj->GetPositionX(), obj->GetPositionY(), World::GetMaxVisibleDistance(), notifier);
- notifier.Notify();
- }
- }
-
CellPair standing_cell(Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()));
// Check for correctness of standing_cell, it also avoids problems with update_cell
@@ -960,7 +871,7 @@ Map::PlayerRelocation(Player *player, float x, float y, float z, float orientati
if( !old_cell.DiffGrid(new_cell) )
AddToGrid(player, oldGrid,new_cell);
else
- EnsureGridLoaded(new_cell, player);
+ EnsureGridLoadedAtEnter(new_cell, player);
}
AddUnitToNotify(player);
@@ -998,6 +909,27 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang
creature->Relocate(x, y, z, ang);
AddUnitToNotify(creature);
}
+
+ if(creature->isVehicle())
+ {
+ for(SeatMap::iterator itr = ((Vehicle*)creature)->m_Seats.begin(); itr != ((Vehicle*)creature)->m_Seats.end(); ++itr)
+ if(Unit *passenger = itr->second.passenger)
+ {
+ if(passenger->GetTypeId() == TYPEID_PLAYER)
+ PlayerRelocation((Player*)passenger,
+ x + passenger->m_movementInfo.t_x,
+ y + passenger->m_movementInfo.t_y,
+ z + passenger->m_movementInfo.t_z,
+ ang + passenger->m_movementInfo.t_o);
+ else
+ CreatureRelocation((Creature*)passenger,
+ x + passenger->m_movementInfo.t_x,
+ y + passenger->m_movementInfo.t_y,
+ z + passenger->m_movementInfo.t_z,
+ ang + passenger->m_movementInfo.t_o);
+ }
+ }
+
assert(CheckGridIntegrity(creature,true));
}
@@ -1079,7 +1011,7 @@ bool Map::CreatureCellRelocation(Creature *c, Cell new_cell)
// in diff. grids but active creature
if(c->isActiveObject())
{
- EnsureGridLoaded(new_cell);
+ EnsureGridLoadedAtEnter(new_cell);
#ifdef TRINITY_DEBUG
if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0)
@@ -1190,7 +1122,11 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool unloadAll)
{
if (i_InstanceId == 0)
{
- if(GridMaps[gx][gy]) delete (GridMaps[gx][gy]);
+ if(GridMaps[gx][gy])
+ {
+ GridMaps[gx][gy]->unloadData();
+ delete GridMaps[gx][gy];
+ }
// x and y are swapped
VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(GetId(), gy, gx);
}
@@ -1215,103 +1151,529 @@ void Map::UnloadAll()
}
}
-float Map::GetHeight(float x, float y, float z, bool pUseVmaps) const
+//*****************************
+// Grid function
+//*****************************
+GridMap::GridMap()
{
- GridPair p = Trinity::ComputeGridPair(x, y);
+ m_flags = 0;
+ // Area data
+ m_gridArea = 0;
+ m_area_map = NULL;
+ // Height level data
+ m_gridHeight = INVALID_HEIGHT;
+ m_gridGetHeight = &GridMap::getHeightFromFlat;
+ m_V9 = NULL;
+ m_V8 = NULL;
+ // Liquid data
+ m_liquidType = 0;
+ m_liquid_offX = 0;
+ m_liquid_offY = 0;
+ m_liquid_width = 0;
+ m_liquid_height = 0;
+ m_liquidLevel = INVALID_HEIGHT;
+ m_liquid_type = NULL;
+ m_liquid_map = NULL;
+}
- // half opt method
- int gx=(int)(32-x/SIZE_OF_GRIDS); //grid x
- int gy=(int)(32-y/SIZE_OF_GRIDS); //grid y
+GridMap::~GridMap()
+{
+ unloadData();
+}
- float lx=128*(32 -x/SIZE_OF_GRIDS - gx);
- float ly=128*(32 -y/SIZE_OF_GRIDS - gy);
+bool GridMap::loadData(char *filename)
+{
+ // Unload old data if exist
+ unloadData();
- // ensure GridMap is loaded
- const_cast<Map*>(this)->EnsureGridCreated(GridPair(63-gx,63-gy));
+ map_fileheader header;
+ // Not return error if file not found
+ FILE *in = fopen(filename, "rb");
+ if (!in)
+ return true;
+ fread(&header, sizeof(header),1,in);
+ if (header.mapMagic == uint32(MAP_MAGIC) &&
+ header.versionMagic == uint32(MAP_VERSION_MAGIC))
+ {
+ // loadup area data
+ if (header.areaMapOffset && !loadAreaData(in, header.areaMapOffset, header.areaMapSize))
+ {
+ sLog.outError("Error loading map area data\n");
+ fclose(in);
+ return false;
+ }
+ // loadup height data
+ if (header.heightMapOffset && !loadHeihgtData(in, header.heightMapOffset, header.heightMapSize))
+ {
+ sLog.outError("Error loading map height data\n");
+ fclose(in);
+ return false;
+ }
+ // loadup liquid data
+ if (header.liquidMapOffset && !loadLiquidData(in, header.liquidMapOffset, header.liquidMapSize))
+ {
+ sLog.outError("Error loading map liquids data\n");
+ fclose(in);
+ return false;
+ }
+ fclose(in);
+ return true;
+ }
+ sLog.outError("Map file '%s' is non-compatible version (outdated?). Please, create new using ad.exe program.", filename);
+ fclose(in);
+ return false;
+}
- // find raw .map surface under Z coordinates
- float mapHeight;
- if(GridMap* gmap = GridMaps[gx][gy])
+void GridMap::unloadData()
+{
+ if (m_area_map) delete[] m_area_map;
+ if (m_V9) delete[] m_V9;
+ if (m_V8) delete[] m_V8;
+ if (m_liquid_type) delete[] m_liquid_type;
+ if (m_liquid_map) delete[] m_liquid_map;
+ m_area_map = NULL;
+ m_V9 = NULL;
+ m_V8 = NULL;
+ m_liquid_type = NULL;
+ m_liquid_map = NULL;
+ m_gridGetHeight = &GridMap::getHeightFromFlat;
+}
+
+bool GridMap::loadAreaData(FILE *in, uint32 offset, uint32 size)
+{
+ map_areaHeader header;
+ fseek(in, offset, SEEK_SET);
+ fread(&header, sizeof(header), 1, in);
+ if (header.fourcc != uint32(MAP_AREA_MAGIC))
+ return false;
+
+ m_gridArea = header.gridArea;
+ if (!(header.flags & MAP_AREA_NO_AREA))
{
- int lx_int = (int)lx;
- int ly_int = (int)ly;
+ m_area_map = new uint16 [16*16];
+ fread(m_area_map, sizeof(uint16), 16*16, in);
+ }
+ return true;
+}
- lx -= lx_int;
- ly -= ly_int;
+bool GridMap::loadHeihgtData(FILE *in, uint32 offset, uint32 size)
+{
+ map_heightHeader header;
+ fseek(in, offset, SEEK_SET);
+ fread(&header, sizeof(header), 1, in);
+ if (header.fourcc != uint32(MAP_HEIGTH_MAGIC))
+ return false;
- float a,b,c;
- if (lx+ly < 1)
+ m_gridHeight = header.gridHeight;
+ if (!(header.flags & MAP_HEIGHT_NO_HIGHT))
+ {
+ if ((header.flags & MAP_HEIGHT_AS_INT16))
{
- if (lx > ly)
- {
- // 1
- float h1 = gmap->v9[lx_int][ly_int];
- float h2 = gmap->v9[lx_int+1][ly_int];
- float h5 = 2 * gmap->v8[lx_int][ly_int];
- a = h2-h1;
- b = h5-h1-h2;
- c = h1;
- }
- else
- {
- // 2
- float h1 = gmap->v9[lx_int][ly_int];
- float h3 = gmap->v9[lx_int][ly_int+1];
- float h5 = 2 * gmap->v8[lx_int][ly_int];
- a = h5 - h1 - h3;
- b = h3 - h1;
- c = h1;
- }
+ m_uint16_V9 = new uint16 [129*129];
+ m_uint16_V8 = new uint16 [128*128];
+ fread(m_uint16_V9, sizeof(uint16), 129*129, in);
+ fread(m_uint16_V8, sizeof(uint16), 128*128, in);
+ m_gridIntHeightMultiplier = (header.gridMaxHeight - header.gridHeight) / 65535;
+ m_gridGetHeight = &GridMap::getHeightFromUint16;
+ }
+ else if ((header.flags & MAP_HEIGHT_AS_INT8))
+ {
+ m_uint8_V9 = new uint8 [129*129];
+ m_uint8_V8 = new uint8 [128*128];
+ fread(m_uint8_V9, sizeof(uint8), 129*129, in);
+ fread(m_uint8_V8, sizeof(uint8), 128*128, in);
+ m_gridIntHeightMultiplier = (header.gridMaxHeight - header.gridHeight) / 255;
+ m_gridGetHeight = &GridMap::getHeightFromUint8;
}
else
{
- if (lx > ly)
- {
- // 3
- float h2 = gmap->v9[lx_int+1][ly_int];
- float h4 = gmap->v9[lx_int+1][ly_int+1];
- float h5 = 2 * gmap->v8[lx_int][ly_int];
- a = h2 + h4 - h5;
- b = h4 - h2;
- c = h5 - h4;
- }
- else
- {
- // 4
- float h3 = gmap->v9[lx_int][ly_int+1];
- float h4 = gmap->v9[lx_int+1][ly_int+1];
- float h5 = 2 * gmap->v8[lx_int][ly_int];
- a = h4 - h3;
- b = h3 + h4 - h5;
- c = h5 - h4;
- }
+ m_V9 = new float [129*129];
+ m_V8 = new float [128*128];
+ fread(m_V9, sizeof(float), 129*129, in);
+ fread(m_V8, sizeof(float), 128*128, in);
+ m_gridGetHeight = &GridMap::getHeightFromFloat;
}
- float _mapheight = a * lx + b * ly + c;
-
- // In some very rare case this will happen. Need find a better way.
- if(lx_int == MAP_RESOLUTION) --lx_int;
- if(ly_int == MAP_RESOLUTION) --ly_int;
-
- /*
- float zi[4];
- // Probe 4 nearest points (except border cases)
- zi[0] = gmap->Z[lx_int][ly_int];
- zi[1] = lx < MAP_RESOLUTION-1 ? gmap->Z[lx_int+1][ly_int] : zi[0];
- zi[2] = ly < MAP_RESOLUTION-1 ? gmap->Z[lx_int][ly_int+1] : zi[0];
- zi[3] = lx < MAP_RESOLUTION-1 && ly < MAP_RESOLUTION-1 ? gmap->Z[lx_int+1][ly_int+1] : zi[0];
- // Recalculate them like if their x,y positions were in the range 0,1
- float b[4];
- b[0] = zi[0];
- b[1] = zi[1]-zi[0];
- b[2] = zi[2]-zi[0];
- b[3] = zi[0]-zi[1]-zi[2]+zi[3];
- // Normalize the dx and dy to be in range 0..1
- float fact_x = lx - lx_int;
- float fact_y = ly - ly_int;
- // Use the simplified bilinear equation, as described in [url="http://en.wikipedia.org/wiki/Bilinear_interpolation"]http://en.wikipedia.org/wiki/Bilinear_interpolation[/url]
- float _mapheight = b[0] + (b[1]*fact_x) + (b[2]*fact_y) + (b[3]*fact_x*fact_y);
-
- */
+ }
+ else
+ m_gridGetHeight = &GridMap::getHeightFromFlat;
+ return true;
+}
+
+bool GridMap::loadLiquidData(FILE *in, uint32 offset, uint32 size)
+{
+ map_liquidHeader header;
+ fseek(in, offset, SEEK_SET);
+ fread(&header, sizeof(header), 1, in);
+ if (header.fourcc != uint32(MAP_LIQUID_MAGIC))
+ return false;
+
+ m_liquidType = header.liquidType;
+ m_liquid_offX = header.offsetX;
+ m_liquid_offY = header.offsetY;
+ m_liquid_width = header.width;
+ m_liquid_height= header.height;
+ m_liquidLevel = header.liquidLevel;
+
+ if (!(header.flags&MAP_LIQUID_NO_TYPE))
+ {
+ m_liquid_type = new uint8 [16*16];
+ fread(m_liquid_type, sizeof(uint8), 16*16, in);
+ }
+ if (!(header.flags&MAP_LIQUID_NO_HIGHT))
+ {
+ m_liquid_map = new float [m_liquid_width*m_liquid_height];
+ fread(m_liquid_map, sizeof(float), m_liquid_width*m_liquid_height, in);
+ }
+ return true;
+}
+
+uint16 GridMap::getArea(float x, float y)
+{
+ if (!m_area_map)
+ return m_gridArea;
+
+ x = 16 * (32 - x/SIZE_OF_GRIDS);
+ y = 16 * (32 - y/SIZE_OF_GRIDS);
+ int lx = (int)x & 15;
+ int ly = (int)y & 15;
+ return m_area_map[lx*16 + ly];
+}
+
+float GridMap::getHeightFromFlat(float x, float y) const
+{
+ return m_gridHeight;
+}
+
+float GridMap::getHeightFromFloat(float x, float y) const
+{
+ if (!m_V8 || !m_V9)
+ return m_gridHeight;
+
+ x = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS);
+ y = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS);
+
+ int x_int = (int)x;
+ int y_int = (int)y;
+ x -= x_int;
+ y -= y_int;
+ x_int&=(MAP_RESOLUTION - 1);
+ y_int&=(MAP_RESOLUTION - 1);
+
+ // Height stored as: h5 - its v8 grid, h1-h4 - its v9 grid
+ // +--------------> X
+ // | h1-------h2 Coordinates is:
+ // | | \ 1 / | h1 0,0
+ // | | \ / | h2 0,1
+ // | | 2 h5 3 | h3 1,0
+ // | | / \ | h4 1,1
+ // | | / 4 \ | h5 1/2,1/2
+ // | h3-------h4
+ // V Y
+ // For find height need
+ // 1 - detect triangle
+ // 2 - solve linear equation from triangle points
+ // Calculate coefficients for solve h = a*x + b*y + c
+
+ float a,b,c;
+ // Select triangle:
+ if (x+y < 1)
+ {
+ if (x > y)
+ {
+ // 1 triangle (h1, h2, h5 points)
+ float h1 = m_V9[(x_int )*129 + y_int];
+ float h2 = m_V9[(x_int+1)*129 + y_int];
+ float h5 = 2 * m_V8[x_int*128 + y_int];
+ a = h2-h1;
+ b = h5-h1-h2;
+ c = h1;
+ }
+ else
+ {
+ // 2 triangle (h1, h3, h5 points)
+ float h1 = m_V9[x_int*129 + y_int ];
+ float h3 = m_V9[x_int*129 + y_int+1];
+ float h5 = 2 * m_V8[x_int*128 + y_int];
+ a = h5 - h1 - h3;
+ b = h3 - h1;
+ c = h1;
+ }
+ }
+ else
+ {
+ if (x > y)
+ {
+ // 3 triangle (h2, h4, h5 points)
+ float h2 = m_V9[(x_int+1)*129 + y_int ];
+ float h4 = m_V9[(x_int+1)*129 + y_int+1];
+ float h5 = 2 * m_V8[x_int*128 + y_int];
+ a = h2 + h4 - h5;
+ b = h4 - h2;
+ c = h5 - h4;
+ }
+ else
+ {
+ // 4 triangle (h3, h4, h5 points)
+ float h3 = m_V9[(x_int )*129 + y_int+1];
+ float h4 = m_V9[(x_int+1)*129 + y_int+1];
+ float h5 = 2 * m_V8[x_int*128 + y_int];
+ a = h4 - h3;
+ b = h3 + h4 - h5;
+ c = h5 - h4;
+ }
+ }
+ // Calculate height
+ return a * x + b * y + c;
+}
+
+float GridMap::getHeightFromUint8(float x, float y) const
+{
+ if (!m_uint8_V8 || !m_uint8_V9)
+ return m_gridHeight;
+
+ x = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS);
+ y = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS);
+
+ int x_int = (int)x;
+ int y_int = (int)y;
+ x -= x_int;
+ y -= y_int;
+ x_int&=(MAP_RESOLUTION - 1);
+ y_int&=(MAP_RESOLUTION - 1);
+
+ int32 a, b, c;
+ uint8 *V9_h1_ptr = &m_uint8_V9[x_int*128 + x_int + y_int];
+ if (x+y < 1)
+ {
+ if (x > y)
+ {
+ // 1 triangle (h1, h2, h5 points)
+ int32 h1 = V9_h1_ptr[ 0];
+ int32 h2 = V9_h1_ptr[129];
+ int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int];
+ a = h2-h1;
+ b = h5-h1-h2;
+ c = h1;
+ }
+ else
+ {
+ // 2 triangle (h1, h3, h5 points)
+ int32 h1 = V9_h1_ptr[0];
+ int32 h3 = V9_h1_ptr[1];
+ int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int];
+ a = h5 - h1 - h3;
+ b = h3 - h1;
+ c = h1;
+ }
+ }
+ else
+ {
+ if (x > y)
+ {
+ // 3 triangle (h2, h4, h5 points)
+ int32 h2 = V9_h1_ptr[129];
+ int32 h4 = V9_h1_ptr[130];
+ int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int];
+ a = h2 + h4 - h5;
+ b = h4 - h2;
+ c = h5 - h4;
+ }
+ else
+ {
+ // 4 triangle (h3, h4, h5 points)
+ int32 h3 = V9_h1_ptr[ 1];
+ int32 h4 = V9_h1_ptr[130];
+ int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int];
+ a = h4 - h3;
+ b = h3 + h4 - h5;
+ c = h5 - h4;
+ }
+ }
+ // Calculate height
+ return (float)((a * x) + (b * y) + c)*m_gridIntHeightMultiplier + m_gridHeight;
+}
+
+float GridMap::getHeightFromUint16(float x, float y) const
+{
+ if (!m_uint16_V8 || !m_uint16_V9)
+ return m_gridHeight;
+
+ x = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS);
+ y = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS);
+
+ int x_int = (int)x;
+ int y_int = (int)y;
+ x -= x_int;
+ y -= y_int;
+ x_int&=(MAP_RESOLUTION - 1);
+ y_int&=(MAP_RESOLUTION - 1);
+
+ int32 a, b, c;
+ uint16 *V9_h1_ptr = &m_uint16_V9[x_int*128 + x_int + y_int];
+ if (x+y < 1)
+ {
+ if (x > y)
+ {
+ // 1 triangle (h1, h2, h5 points)
+ int32 h1 = V9_h1_ptr[ 0];
+ int32 h2 = V9_h1_ptr[129];
+ int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int];
+ a = h2-h1;
+ b = h5-h1-h2;
+ c = h1;
+ }
+ else
+ {
+ // 2 triangle (h1, h3, h5 points)
+ int32 h1 = V9_h1_ptr[0];
+ int32 h3 = V9_h1_ptr[1];
+ int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int];
+ a = h5 - h1 - h3;
+ b = h3 - h1;
+ c = h1;
+ }
+ }
+ else
+ {
+ if (x > y)
+ {
+ // 3 triangle (h2, h4, h5 points)
+ int32 h2 = V9_h1_ptr[129];
+ int32 h4 = V9_h1_ptr[130];
+ int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int];
+ a = h2 + h4 - h5;
+ b = h4 - h2;
+ c = h5 - h4;
+ }
+ else
+ {
+ // 4 triangle (h3, h4, h5 points)
+ int32 h3 = V9_h1_ptr[ 1];
+ int32 h4 = V9_h1_ptr[130];
+ int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int];
+ a = h4 - h3;
+ b = h3 + h4 - h5;
+ c = h5 - h4;
+ }
+ }
+ // Calculate height
+ return (float)((a * x) + (b * y) + c)*m_gridIntHeightMultiplier + m_gridHeight;
+}
+
+float GridMap::getLiquidLevel(float x, float y)
+{
+ if (!m_liquid_map)
+ return m_liquidLevel;
+
+ x = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS);
+ y = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS);
+
+ int cx_int = ((int)x & (MAP_RESOLUTION-1)) - m_liquid_offY;
+ int cy_int = ((int)y & (MAP_RESOLUTION-1)) - m_liquid_offX;
+
+ if (cx_int < 0 || cx_int >=m_liquid_height)
+ return INVALID_HEIGHT;
+ if (cy_int < 0 || cy_int >=m_liquid_width )
+ return INVALID_HEIGHT;
+
+ return m_liquid_map[cx_int*m_liquid_width + cy_int];
+}
+
+uint8 GridMap::getTerrainType(float x, float y)
+{
+ if (!m_liquid_type)
+ return m_liquidType;
+
+ x = 16 * (32 - x/SIZE_OF_GRIDS);
+ y = 16 * (32 - y/SIZE_OF_GRIDS);
+ int lx = (int)x & 15;
+ int ly = (int)y & 15;
+ return m_liquid_type[lx*16 + ly];
+}
+
+// Get water state on map
+inline ZLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data)
+{
+ // Check water type (if no water return)
+ if (!m_liquid_type && !m_liquidType)
+ return LIQUID_MAP_NO_WATER;
+
+ // Get cell
+ float cx = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS);
+ float cy = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS);
+
+ int x_int = (int)cx & (MAP_RESOLUTION-1);
+ int y_int = (int)cy & (MAP_RESOLUTION-1);
+
+ // Check water type in cell
+ uint8 type = m_liquid_type ? m_liquid_type[(x_int>>3)*16 + (y_int>>3)] : m_liquidType;
+ if (type == 0)
+ return LIQUID_MAP_NO_WATER;
+
+ // Check req liquid type mask
+ if (ReqLiquidType && !(ReqLiquidType&type))
+ return LIQUID_MAP_NO_WATER;
+
+ // Check water level:
+ // Check water height map
+ int lx_int = x_int - m_liquid_offY;
+ int ly_int = y_int - m_liquid_offX;
+ if (lx_int < 0 || lx_int >=m_liquid_height)
+ return LIQUID_MAP_NO_WATER;
+ if (ly_int < 0 || ly_int >=m_liquid_width )
+ return LIQUID_MAP_NO_WATER;
+
+ // Get water level
+ float liquid_level = m_liquid_map ? m_liquid_map[lx_int*m_liquid_width + ly_int] : m_liquidLevel;
+ // Get ground level (sub 0.2 for fix some errors)
+ float ground_level = getHeight(x, y);
+
+ // Check water level and ground level
+ if (liquid_level < ground_level || z < ground_level - 2)
+ return LIQUID_MAP_NO_WATER;
+
+ // All ok in water -> store data
+ if (data)
+ {
+ data->type = type;
+ data->level = liquid_level;
+ data->depth_level = ground_level;
+ }
+
+ // For speed check as int values
+ int delta = int((liquid_level - z) * 10);
+
+ // Get position delta
+ if (delta > 20) // Under water
+ return LIQUID_MAP_UNDER_WATER;
+ if (delta > 0 ) // In water
+ return LIQUID_MAP_IN_WATER;
+ if (delta > -1) // Walk on water
+ return LIQUID_MAP_WATER_WALK;
+ // Above water
+ return LIQUID_MAP_ABOVE_WATER;
+}
+
+inline GridMap *Map::GetGrid(float x, float y)
+{
+ // half opt method
+ int gx=(int)(32-x/SIZE_OF_GRIDS); //grid x
+ int gy=(int)(32-y/SIZE_OF_GRIDS); //grid y
+
+ // ensure GridMap is loaded
+ EnsureGridCreated(GridPair(63-gx,63-gy));
+
+ return GridMaps[gx][gy];
+}
+
+float Map::GetHeight(float x, float y, float z, bool pUseVmaps) const
+{
+ // find raw .map surface under Z coordinates
+ float mapHeight;
+ if(GridMap *gmap = const_cast<Map*>(this)->GetGrid(x, y))
+ {
+ float _mapheight = gmap->getHeight(x,y);
+
// look from a bit higher pos to find the floor, ignore under surface case
if(z + 2.0f > _mapheight)
mapHeight = _mapheight;
@@ -1387,76 +1749,122 @@ float Map::GetVmapHeight(float x, float y, float z, bool useMaps) const
return vmapHeight;
}
-uint16 Map::GetAreaFlag(float x, float y ) const
+uint16 Map::GetAreaFlag(float x, float y, float z) const
{
- //local x,y coords
- float lx,ly;
- int gx,gy;
- GridPair p = Trinity::ComputeGridPair(x, y);
-
- // half opt method
- gx=(int)(32-x/SIZE_OF_GRIDS) ; //grid x
- gy=(int)(32-y/SIZE_OF_GRIDS); //grid y
-
- lx=16*(32 -x/SIZE_OF_GRIDS - gx);
- ly=16*(32 -y/SIZE_OF_GRIDS - gy);
- //DEBUG_LOG("my %d %d si %d %d",gx,gy,p.x_coord,p.y_coord);
-
- // ensure GridMap is loaded
- const_cast<Map*>(this)->EnsureGridCreated(GridPair(63-gx,63-gy));
-
- if(GridMaps[gx][gy])
- return GridMaps[gx][gy]->area_flag[(int)(lx)][(int)(ly)];
+ uint16 areaflag;
+ if(GridMap *gmap = const_cast<Map*>(this)->GetGrid(x, y))
+ areaflag = gmap->getArea(x, y);
// this used while not all *.map files generated (instances)
else
- return GetAreaFlagByMapId(i_id);
+ areaflag = GetAreaFlagByMapId(i_id);
+
+ //FIXME: some hacks for areas above or underground for ground area
+ // required for area specific spells/etc, until map/vmap data
+ // not provided correct areaflag with this hacks
+ switch(areaflag)
+ {
+ // Acherus: The Ebon Hold (Plaguelands: The Scarlet Enclave)
+ case 1984: // Plaguelands: The Scarlet Enclave
+ case 2076: // Death's Breach (Plaguelands: The Scarlet Enclave)
+ case 2745: // The Noxious Pass (Plaguelands: The Scarlet Enclave)
+ if(z > 350.0f) areaflag = 2048; break;
+ // Acherus: The Ebon Hold (Eastern Plaguelands)
+ case 856: // The Noxious Glade (Eastern Plaguelands)
+ case 2456: // Death's Breach (Eastern Plaguelands)
+ if(z > 350.0f) areaflag = 1950; break;
+ // Dalaran
+ case 1593: // Crystalsong Forest
+ case 2484: // The Twilight Rivulet (Crystalsong Forest)
+ case 2492: // Forlorn Woods (Crystalsong Forest)
+ if (x > 5568.0f && x < 6116.0f && y > 282.0f && y < 982.0f && z > 563.0f) areaflag = 2153; break;
+ // Maw of Neltharion (cave)
+ case 164: // Dragonblight
+ case 1797: // Obsidian Dragonshrine (Dragonblight)
+ case 1827: // Wintergrasp
+ case 2591: // The Cauldron of Flames (Wintergrasp)
+ if (x > 4364.0f && x < 4632.0f && y > 1545.0f && y < 1886.0f && z < 200.0f) areaflag = 1853; break;
+ // Undercity (sewers enter and path)
+ case 179: // Tirisfal Glades
+ if (x > 1595.0f && x < 1699.0f && y > 535.0f && y < 643.5f && z < 30.5f) areaflag = 685; break;
+ // Undercity (Royal Quarter)
+ case 210: // Silverpine Forest
+ case 316: // The Shining Strand (Silverpine Forest)
+ case 438: // Lordamere Lake (Silverpine Forest)
+ if (x > 1237.0f && x < 1401.0f && y > 284.0f && y < 440.0f && z < -40.0f) areaflag = 685; break;
+ // Undercity (cave and ground zone, part of royal quarter)
+ case 607: // Ruins of Lordaeron (Tirisfal Glades)
+ // ground and near to ground (by city walls)
+ if(z > 0.0f)
+ {
+ if (x > 1510.0f && x < 1839.0f && y > 29.77f && y < 433.0f) areaflag = 685;
+ }
+ // more wide underground, part of royal quarter
+ else
+ {
+ if (x > 1299.0f && x < 1839.0f && y > 10.0f && y < 440.0f) areaflag = 685;
+ }
+ break;
+ // The Makers' Perch (ground) and Makers' Overlook (ground and cave)
+ case 1335: // Sholazar Basin
+ // The Makers' Perch ground (fast box)
+ if (x > 6100.0f && x < 6250.0f && y > 5650.0f && y < 5800.0f)
+ {
+ // nice slow circle
+ if ((x-6183.0f)*(x-6183.0f)+(y-5717.0f)*(y-5717.0f) < 2500.0f)
+ areaflag = 2189;
+ }
+ // Makers' Overlook (ground and cave)
+ else if (x > 5634.48f && x < 5774.53f && y < 3475.0f && z > 300.0f)
+ {
+ if(y > 3380.26f || y > 3265.0f && z < 360.0f) areaflag = 2187;
+ }
+ break;
+ // The Makers' Perch (underground)
+ case 2147: // The Stormwright's Shelf (Sholazar Basin)
+ if (x > 6199.0f && x < 6283.0f && y > 5705.0f && y < 5817.0f && z < 38.0f) areaflag = 2189; break;
+ // Makers' Overlook (deep cave)
+ case 267: // Icecrown
+ if (x > 5684.0f && x < 5798.0f && y > 3035.0f && y < 3367.0f && z < 358.0f) areaflag = 2187; break;
+ // Wyrmrest Temple (Dragonblight)
+ case 1814: // Path of the Titans (Dragonblight)
+ case 1897: // The Dragon Wastes (Dragonblight)
+ // fast box
+ if (x > 3400.0f && x < 3700.0f && y > 130.0f && y < 420.0f)
+ {
+ // nice slow circle
+ if ((x-3546.87f)*(x-3546.87f)+(y-272.71f)*(y-272.71f) < 19600.0f) areaflag = 1791;
+ }
+ break;
+ }
+
+ return areaflag;
}
uint8 Map::GetTerrainType(float x, float y ) const
{
- //local x,y coords
- float lx,ly;
- int gx,gy;
-
- // half opt method
- gx=(int)(32-x/SIZE_OF_GRIDS) ; //grid x
- gy=(int)(32-y/SIZE_OF_GRIDS); //grid y
-
- lx=16*(32 -x/SIZE_OF_GRIDS - gx);
- ly=16*(32 -y/SIZE_OF_GRIDS - gy);
-
- // ensure GridMap is loaded
- const_cast<Map*>(this)->EnsureGridCreated(GridPair(63-gx,63-gy));
-
- if(GridMaps[gx][gy])
- return GridMaps[gx][gy]->terrain_type[(int)(lx)][(int)(ly)];
+ if(GridMap *gmap = const_cast<Map*>(this)->GetGrid(x, y))
+ return gmap->getTerrainType(x, y);
else
return 0;
}
-float Map::GetWaterLevel(float x, float y ) const
+ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data) const
{
- //local x,y coords
- float lx,ly;
- int gx,gy;
-
- // half opt method
- gx=(int)(32-x/SIZE_OF_GRIDS) ; //grid x
- gy=(int)(32-y/SIZE_OF_GRIDS); //grid y
-
- lx=128*(32 -x/SIZE_OF_GRIDS - gx);
- ly=128*(32 -y/SIZE_OF_GRIDS - gy);
-
- // ensure GridMap is loaded
- const_cast<Map*>(this)->EnsureGridCreated(GridPair(63-gx,63-gy));
+ if(GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y))
+ return gmap->getLiquidStatus(x, y, z, ReqLiquidType, data);
+ else
+ return LIQUID_MAP_NO_WATER;
+}
- if(GridMaps[gx][gy])
- return GridMaps[gx][gy]->liquid_level[(int)(lx)][(int)(ly)];
+float Map::GetWaterLevel(float x, float y ) const
+{
+ if(GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y))
+ return gmap->getLiquidLevel(x, y);
else
return 0;
}
-uint32 Map::GetAreaId(uint16 areaflag,uint32 map_id)
+uint32 Map::GetAreaIdByAreaFlag(uint16 areaflag,uint32 map_id)
{
AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id);
@@ -1466,7 +1874,7 @@ uint32 Map::GetAreaId(uint16 areaflag,uint32 map_id)
return 0;
}
-uint32 Map::GetZoneId(uint16 areaflag,uint32 map_id)
+uint32 Map::GetZoneIdByAreaFlag(uint16 areaflag,uint32 map_id)
{
AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id);
@@ -1476,26 +1884,37 @@ uint32 Map::GetZoneId(uint16 areaflag,uint32 map_id)
return 0;
}
-bool Map::IsInWater(float x, float y, float pZ) const
+void Map::GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 areaflag,uint32 map_id)
{
- // This method is called too often to use vamps for that (4. parameter = false).
- // The pZ pos is taken anyway for future use
- float z = GetHeight(x,y,pZ,false); // use .map base surface height
+ AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id);
- // underground or instance without vmap
- if(z <= INVALID_HEIGHT)
- return false;
+ areaid = entry ? entry->ID : 0;
+ zoneid = entry ? (( entry->zone != 0 ) ? entry->zone : entry->ID) : 0;
+}
- float water_z = GetWaterLevel(x,y);
- uint8 flag = GetTerrainType(x,y);
- return (z < (water_z-2)) && (flag & 0x01);
+bool Map::IsInWater(float x, float y, float pZ) const
+{
+ // Check surface in x, y point for liquid
+ if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y))
+ {
+ LiquidData liquid_status;
+ if (getLiquidStatus(x, y, pZ, MAP_ALL_LIQUIDS, &liquid_status))
+ {
+ if (liquid_status.level - liquid_status.depth_level > 2)
+ return true;
+ }
+ }
+ return false;
}
bool Map::IsUnderWater(float x, float y, float z) const
{
- float water_z = GetWaterLevel(x,y);
- uint8 flag = GetTerrainType(x,y);
- return (z < (water_z-2)) && (flag & 0x01);
+ if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y))
+ {
+ if (getLiquidStatus(x, y, z, MAP_LIQUID_TYPE_WATER|MAP_LIQUID_TYPE_OCEAN)&LIQUID_MAP_UNDER_WATER)
+ return true;
+ }
+ return false;
}
bool Map::CheckGridIntegrity(Creature* c, bool moved) const
@@ -1583,9 +2002,10 @@ void Map::SendInitTransports( Player * player )
bool hasTransport = false;
- for (MapManager::TransportSet::iterator i = tset.begin(); i != tset.end(); ++i)
+ for (MapManager::TransportSet::const_iterator i = tset.begin(); i != tset.end(); ++i)
{
- if((*i) != player->GetTransport()) // send data for current transport in other place
+ // send data for current transport in other place
+ if((*i) != player->GetTransport() && (*i)->GetMapId()==i_id)
{
hasTransport = true;
(*i)->BuildCreateUpdateBlockForPlayer(&transData, player);
@@ -1611,8 +2031,8 @@ void Map::SendRemoveTransports( Player * player )
MapManager::TransportSet& tset = tmap[player->GetMapId()];
// except used transport
- for (MapManager::TransportSet::iterator i = tset.begin(); i != tset.end(); ++i)
- if(player->GetTransport() != (*i))
+ for (MapManager::TransportSet::const_iterator i = tset.begin(); i != tset.end(); ++i)
+ if((*i) != player->GetTransport() && (*i)->GetMapId()!=i_id)
(*i)->BuildOutOfRangeUpdateBlock(&transData);
WorldPacket packet;
@@ -1669,7 +2089,7 @@ void Map::RemoveAllObjectsInRemoveList()
switch(obj->GetTypeId())
{
case TYPEID_UNIT:
- if(!((Creature*)obj)->isPet())
+ if(!((Creature*)obj)->isWorldCreature())
SwitchGridContainers((Creature*)obj, on);
break;
}
@@ -1816,8 +2236,9 @@ template void Map::Remove(DynamicObject *, bool);
/* ******* Dungeon Instance Maps ******* */
InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
- : Map(id, expiry, InstanceId, SpawnMode), i_data(NULL),
- m_resetAfterUnload(false), m_unloadWhenEmpty(false)
+ : Map(id, expiry, InstanceId, SpawnMode),
+ m_resetAfterUnload(false), m_unloadWhenEmpty(false),
+ i_data(NULL), i_script_id(0)
{
// the timer is started by default, and stopped when the first player joins
// this make sure it gets unloaded if for some reason no player joins
@@ -1846,10 +2267,10 @@ bool InstanceMap::CanEnter(Player *player)
}
// cannot enter if the instance is full (player cap), GMs don't count
- InstanceTemplate const* iTemplate = objmgr.GetInstanceTemplate(GetId());
- if (!player->isGameMaster() && GetPlayersCountExceptGMs() >= iTemplate->maxPlayers)
+ uint32 maxPlayers = GetMaxPlayers();
+ if (!player->isGameMaster() && GetPlayersCountExceptGMs() >= maxPlayers)
{
- sLog.outDetail("MAP: Instance '%u' of map '%s' cannot have more than '%u' players. Player '%s' rejected", GetInstanceId(), GetMapName(), iTemplate->maxPlayers, player->GetName());
+ sLog.outDetail("MAP: Instance '%u' of map '%s' cannot have more than '%u' players. Player '%s' rejected", GetInstanceId(), GetMapName(), maxPlayers, player->GetName());
player->SendTransferAborted(GetId(), TRANSFER_ABORT_MAX_PLAYERS);
return false;
}
@@ -1879,79 +2300,81 @@ bool InstanceMap::Add(Player *player)
if(!CanEnter(player))
return false;
- // get or create an instance save for the map
- InstanceSave *mapSave = sInstanceSaveManager.GetInstanceSave(GetInstanceId());
- if(!mapSave)
+ // Dungeon only code
+ if(IsDungeon())
{
- sLog.outDetail("InstanceMap::Add: creating instance save for map %d spawnmode %d with instance id %d", GetId(), GetSpawnMode(), GetInstanceId());
- mapSave = sInstanceSaveManager.AddInstanceSave(GetId(), GetInstanceId(), GetSpawnMode(), 0, true);
- }
-
- // check for existing instance binds
- InstancePlayerBind *playerBind = player->GetBoundInstance(GetId(), GetSpawnMode());
- if(playerBind && playerBind->perm)
- {
- // cannot enter other instances if bound permanently
- if(playerBind->save != mapSave)
+ // get or create an instance save for the map
+ InstanceSave *mapSave = sInstanceSaveManager.GetInstanceSave(GetInstanceId());
+ if(!mapSave)
{
- sLog.outError("InstanceMap::Add: player %s(%d) is permanently bound to instance %d,%d,%d,%d,%d,%d but he is being put in instance %d,%d,%d,%d,%d,%d", player->GetName(), player->GetGUIDLow(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset());
- assert(false);
+ sLog.outDetail("InstanceMap::Add: creating instance save for map %d spawnmode %d with instance id %d", GetId(), GetSpawnMode(), GetInstanceId());
+ mapSave = sInstanceSaveManager.AddInstanceSave(GetId(), GetInstanceId(), GetSpawnMode(), 0, true);
}
- }
- else
- {
- Group *pGroup = player->GetGroup();
- if(pGroup)
+
+ // check for existing instance binds
+ InstancePlayerBind *playerBind = player->GetBoundInstance(GetId(), GetSpawnMode());
+ if(playerBind && playerBind->perm)
{
- // solo saves should be reset when entering a group
- InstanceGroupBind *groupBind = pGroup->GetBoundInstance(GetId(), GetSpawnMode());
- if(playerBind)
+ // cannot enter other instances if bound permanently
+ if(playerBind->save != mapSave)
{
- sLog.outError("InstanceMap::Add: player %s(%d) is being put in instance %d,%d,%d,%d,%d,%d but he is in group %d and is bound to instance %d,%d,%d,%d,%d,%d!", player->GetName(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), GUID_LOPART(pGroup->GetLeaderGUID()), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset());
- if(groupBind) sLog.outError("InstanceMap::Add: the group is bound to instance %d,%d,%d,%d,%d,%d", groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(), groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset());
- sLog.outError("InstanceMap::Add: do not let player %s enter instance otherwise crash will happen", player->GetName());
- return false;
- //player->UnbindInstance(GetId(), GetSpawnMode());
- //assert(false);
+ sLog.outError("InstanceMap::Add: player %s(%d) is permanently bound to instance %d,%d,%d,%d,%d,%d but he is being put in instance %d,%d,%d,%d,%d,%d", player->GetName(), player->GetGUIDLow(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset());
+ assert(false);
}
- // bind to the group or keep using the group save
- if(!groupBind)
- pGroup->BindToInstance(mapSave, false);
- else
+ }
+ else
+ {
+ Group *pGroup = player->GetGroup();
+ if(pGroup)
{
- // cannot jump to a different instance without resetting it
- if(groupBind->save != mapSave)
+ // solo saves should be reset when entering a group
+ InstanceGroupBind *groupBind = pGroup->GetBoundInstance(GetId(), GetSpawnMode());
+ if(playerBind)
{
- sLog.outError("InstanceMap::Add: player %s(%d) is being put in instance %d,%d,%d but he is in group %d which is bound to instance %d,%d,%d!", player->GetName(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), GUID_LOPART(pGroup->GetLeaderGUID()), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty());
- if(mapSave)
- sLog.outError("MapSave players: %d, group count: %d", mapSave->GetPlayerCount(), mapSave->GetGroupCount());
- else
- sLog.outError("MapSave NULL");
- if(groupBind->save)
- sLog.outError("GroupBind save players: %d, group count: %d", groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount());
- else
- sLog.outError("GroupBind save NULL");
- assert(false);
+ sLog.outError("InstanceMap::Add: player %s(%d) is being put in instance %d,%d,%d,%d,%d,%d but he is in group %d and is bound to instance %d,%d,%d,%d,%d,%d!", player->GetName(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), GUID_LOPART(pGroup->GetLeaderGUID()), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset());
+ if(groupBind) sLog.outError("InstanceMap::Add: the group is bound to instance %d,%d,%d,%d,%d,%d", groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(), groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset());
+ //assert(false);
+ return false;
}
- // if the group/leader is permanently bound to the instance
- // players also become permanently bound when they enter
- if(groupBind->perm)
+ // bind to the group or keep using the group save
+ if(!groupBind)
+ pGroup->BindToInstance(mapSave, false);
+ else
{
- WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4);
- data << uint32(0);
- player->GetSession()->SendPacket(&data);
- player->BindToInstance(mapSave, true);
+ // cannot jump to a different instance without resetting it
+ if(groupBind->save != mapSave)
+ {
+ sLog.outError("InstanceMap::Add: player %s(%d) is being put in instance %d,%d,%d but he is in group %d which is bound to instance %d,%d,%d!", player->GetName(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), GUID_LOPART(pGroup->GetLeaderGUID()), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty());
+ if(mapSave)
+ sLog.outError("MapSave players: %d, group count: %d", mapSave->GetPlayerCount(), mapSave->GetGroupCount());
+ else
+ sLog.outError("MapSave NULL");
+ if(groupBind->save)
+ sLog.outError("GroupBind save players: %d, group count: %d", groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount());
+ else
+ sLog.outError("GroupBind save NULL");
+ assert(false);
+ }
+ // if the group/leader is permanently bound to the instance
+ // players also become permanently bound when they enter
+ if(groupBind->perm)
+ {
+ WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4);
+ data << uint32(0);
+ player->GetSession()->SendPacket(&data);
+ player->BindToInstance(mapSave, true);
+ }
}
}
- }
- else
- {
- // set up a solo bind or continue using it
- if(!playerBind)
- player->BindToInstance(mapSave, false);
else
- // cannot jump to a different instance without resetting it
- assert(playerBind->save == mapSave);
+ {
+ // set up a solo bind or continue using it
+ if(!playerBind)
+ player->BindToInstance(mapSave, false);
+ else
+ // cannot jump to a different instance without resetting it
+ assert(playerBind->save == mapSave);
+ }
}
}
@@ -1960,7 +2383,6 @@ bool InstanceMap::Add(Player *player)
// first player enters (no players yet)
SetResetSchedule(false);
- player->SendInitWorldStates();
sLog.outDetail("MAP: Player '%s' entered the instance '%u' of map '%s'", player->GetName(), GetInstanceId(), GetMapName());
// initialize unload state
m_unloadTimer = 0;
@@ -1992,20 +2414,6 @@ void InstanceMap::Remove(Player *player, bool remove)
SetResetSchedule(true);
}
-Creature * Map::GetCreatureInMap(uint64 guid)
-{
- Creature * obj = HashMapHolder<Creature>::Find(guid);
- if(obj && obj->GetInstanceId() != GetInstanceId()) obj = NULL;
- return obj;
-}
-
-GameObject * Map::GetGameObjectInMap(uint64 guid)
-{
- GameObject * obj = HashMapHolder<GameObject>::Find(guid);
- if(obj && obj->GetInstanceId() != GetInstanceId()) obj = NULL;
- return obj;
-}
-
void InstanceMap::CreateInstanceData(bool load)
{
if(i_data != NULL)
@@ -2087,10 +2495,13 @@ bool InstanceMap::Reset(uint8 method)
void InstanceMap::PermBindAllPlayers(Player *player)
{
+ if(!IsDungeon())
+ return;
+
InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId());
if(!save)
{
- sLog.outError("Cannot bind players, no instance save available for map!\n");
+ sLog.outError("Cannot bind players, no instance save available for map!");
return;
}
@@ -2116,12 +2527,6 @@ void InstanceMap::PermBindAllPlayers(Player *player)
}
}
-time_t InstanceMap::GetResetTime()
-{
- InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId());
- return save ? save->GetDifficulty() : DIFFICULTY_NORMAL;
-}
-
void InstanceMap::UnloadAll()
{
if(HavePlayers())
@@ -2151,7 +2556,7 @@ void InstanceMap::SetResetSchedule(bool on)
// only for normal instances
// the reset time is only scheduled when there are no payers inside
// it is assumed that the reset time will rarely (if ever) change while the reset is scheduled
- if(!HavePlayers() && !IsRaid() && !IsHeroic())
+ if(IsDungeon() && !HavePlayers() && !IsRaid() && !IsHeroic())
{
InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId());
if(!save) sLog.outError("InstanceMap::SetResetSchedule: cannot turn schedule %s, no save available for instance %d of %d", on ? "on" : "off", GetInstanceId(), GetId());
@@ -2159,6 +2564,14 @@ void InstanceMap::SetResetSchedule(bool on)
}
}
+uint32 InstanceMap::GetMaxPlayers() const
+{
+ InstanceTemplate const* iTemplate = objmgr.GetInstanceTemplate(GetId());
+ if(!iTemplate)
+ return 0;
+ return IsHeroic() ? iTemplate->maxPlayersHeroic : iTemplate->maxPlayers;
+}
+
/* ******* Battleground Instance Maps ******* */
BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId)
@@ -2216,7 +2629,7 @@ void BattleGroundMap::UnloadAll()
{
if(Player * plr = m_mapRefManager.getFirst()->getSource())
{
- plr->TeleportTo(plr->m_homebindMapId, plr->m_homebindX, plr->m_homebindY, plr->m_homebindZ, plr->GetOrientation());
+ plr->TeleportTo(plr->GetBattleGroundEntryPoint());
// TeleportTo removes the player from this map (if the map exists) -> calls BattleGroundMap::Remove -> invalidates the iterator.
// just in case, remove the player from the list explicitly here as well to prevent a possible infinite loop
// note that this remove is not needed if the code works well in other places
@@ -2227,5 +2640,44 @@ void BattleGroundMap::UnloadAll()
Map::UnloadAll();
}
-/*--------------------------TRINITY-------------------------*/
+Creature*
+Map::GetCreature(uint64 guid)
+{
+ Creature * ret = ObjectAccessor::GetObjectInWorld(guid, (Creature*)NULL);
+ if(!ret)
+ return NULL;
+
+ if(ret->GetMapId() != GetId())
+ return NULL;
+
+ if(ret->GetInstanceId() != GetInstanceId())
+ return NULL;
+
+ return ret;
+}
+
+GameObject*
+Map::GetGameObject(uint64 guid)
+{
+ GameObject * ret = ObjectAccessor::GetObjectInWorld(guid, (GameObject*)NULL);
+ if(!ret)
+ return NULL;
+ if(ret->GetMapId() != GetId())
+ return NULL;
+ if(ret->GetInstanceId() != GetInstanceId())
+ return NULL;
+ return ret;
+}
+DynamicObject*
+Map::GetDynamicObject(uint64 guid)
+{
+ DynamicObject * ret = ObjectAccessor::GetObjectInWorld(guid, (DynamicObject*)NULL);
+ if(!ret)
+ return NULL;
+ if(ret->GetMapId() != GetId())
+ return NULL;
+ if(ret->GetInstanceId() != GetInstanceId())
+ return NULL;
+ return ret;
+}
diff --git a/src/game/Map.h b/src/game/Map.h
index f117a1c1cec..d85eb459171 100644
--- a/src/game/Map.h
+++ b/src/game/Map.h
@@ -26,7 +26,7 @@
#include "zthread/Lockable.h"
#include "zthread/Mutex.h"
#include "zthread/FairReadWriteLock.h"
-#include "Database/DBCStructure.h"
+#include "DBCStructure.h"
#include "GridDefines.h"
#include "Cell.h"
#include "Timer.h"
@@ -43,6 +43,7 @@ class InstanceData;
class Group;
class InstanceSave;
class WorldObject;
+class TempSummon;
class CreatureGroup;
namespace ZThread
@@ -71,15 +72,135 @@ typedef RGuard<GridRWLock, ZThread::Lockable> GridReadGuard;
typedef WGuard<GridRWLock, ZThread::Lockable> GridWriteGuard;
typedef Trinity::SingleThreaded<GridRWLock>::Lock NullGuard;
-typedef struct
+//******************************************
+// Map file format defines
+//******************************************
+#define MAP_MAGIC 'SPAM'
+#define MAP_VERSION_MAGIC '0.1w'
+#define MAP_AREA_MAGIC 'AERA'
+#define MAP_HEIGTH_MAGIC 'TGHM'
+#define MAP_LIQUID_MAGIC 'QILM'
+
+struct map_fileheader{
+ uint32 mapMagic;
+ uint32 versionMagic;
+ uint32 areaMapOffset;
+ uint32 areaMapSize;
+ uint32 heightMapOffset;
+ uint32 heightMapSize;
+ uint32 liquidMapOffset;
+ uint32 liquidMapSize;
+};
+
+#define MAP_AREA_NO_AREA 0x0001
+struct map_areaHeader{
+ uint32 fourcc;
+ uint16 flags;
+ uint16 gridArea;
+};
+
+#define MAP_HEIGHT_NO_HIGHT 0x0001
+#define MAP_HEIGHT_AS_INT16 0x0002
+#define MAP_HEIGHT_AS_INT8 0x0004
+
+struct map_heightHeader{
+ uint32 fourcc;
+ uint32 flags;
+ float gridHeight;
+ float gridMaxHeight;
+};
+
+#define MAP_LIQUID_NO_TYPE 0x0001
+#define MAP_LIQUID_NO_HIGHT 0x0002
+struct map_liquidHeader{
+ uint32 fourcc;
+ uint16 flags;
+ uint16 liquidType;
+ uint8 offsetX;
+ uint8 offsetY;
+ uint8 width;
+ uint8 height;
+ float liquidLevel;
+};
+
+enum ZLiquidStatus{
+ LIQUID_MAP_NO_WATER = 0x00000000,
+ LIQUID_MAP_ABOVE_WATER = 0x00000001,
+ LIQUID_MAP_WATER_WALK = 0x00000002,
+ LIQUID_MAP_IN_WATER = 0x00000004,
+ LIQUID_MAP_UNDER_WATER = 0x00000008
+};
+
+#define MAP_LIQUID_TYPE_NO_WATER 0x00
+#define MAP_LIQUID_TYPE_WATER 0x01
+#define MAP_LIQUID_TYPE_OCEAN 0x02
+#define MAP_LIQUID_TYPE_MAGMA 0x04
+#define MAP_LIQUID_TYPE_SLIME 0x08
+
+#define MAP_ALL_LIQUIDS (MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN | MAP_LIQUID_TYPE_MAGMA | MAP_LIQUID_TYPE_SLIME)
+
+#define MAP_LIQUID_TYPE_DARK_WATER 0x10
+#define MAP_LIQUID_TYPE_WMO_WATER 0x20
+
+struct LiquidData{
+ uint32 type;
+ float level;
+ float depth_level;
+};
+
+class GridMap
{
- uint16 area_flag[16][16];
- uint8 terrain_type[16][16];
- float liquid_level[128][128];
- float v9[16 * 8 + 1][16 * 8 + 1];
- float v8[16 * 8][16 * 8];
- //float Z[MAP_RESOLUTION][MAP_RESOLUTION];
-}GridMap;
+ uint32 m_flags;
+ // Area data
+ uint16 m_gridArea;
+ uint16 *m_area_map;
+ // Height level data
+ float m_gridHeight;
+ float m_gridIntHeightMultiplier;
+ union{
+ float *m_V9;
+ uint16 *m_uint16_V9;
+ uint8 *m_uint8_V9;
+ };
+ union{
+ float *m_V8;
+ uint16 *m_uint16_V8;
+ uint8 *m_uint8_V8;
+ };
+ // Liquid data
+ uint16 m_liquidType;
+ uint8 m_liquid_offX;
+ uint8 m_liquid_offY;
+ uint8 m_liquid_width;
+ uint8 m_liquid_height;
+ float m_liquidLevel;
+ uint8 *m_liquid_type;
+ float *m_liquid_map;
+
+ bool loadAreaData(FILE *in, uint32 offset, uint32 size);
+ bool loadHeihgtData(FILE *in, uint32 offset, uint32 size);
+ bool loadLiquidData(FILE *in, uint32 offset, uint32 size);
+
+ // Get height functions and pointers
+ typedef float (GridMap::*pGetHeightPtr) (float x, float y) const;
+ pGetHeightPtr m_gridGetHeight;
+ float getHeightFromFloat(float x, float y) const;
+ float getHeightFromUint16(float x, float y) const;
+ float getHeightFromUint8(float x, float y) const;
+ float getHeightFromFlat(float x, float y) const;
+
+public:
+ GridMap();
+ ~GridMap();
+ bool loadData(char *filaname);
+ void unloadData();
+
+ uint16 getArea(float x, float y);
+ inline float getHeight(float x, float y) {return (this->*m_gridGetHeight)(x, y);}
+ float getLiquidLevel(float x, float y);
+ uint8 getTerrainType(float x, float y);
+ ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data = 0);
+};
struct CreatureMover
{
@@ -99,9 +220,10 @@ struct CreatureMover
struct InstanceTemplate
{
uint32 map;
- uint32 parent;
+ uint32 parent;
uint32 maxPlayers;
- uint32 reset_delay;
+ uint32 maxPlayersHeroic;
+ uint32 reset_delay; // FIX ME: now exist normal/heroic raids with possible different time of reset.
uint32 access_id;
float startLocX;
float startLocY;
@@ -182,9 +304,8 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
time_t GetGridExpiry(void) const { return i_gridExpiry; }
uint32 GetId(void) const { return i_id; }
- static bool ExistMap(uint32 mapid, int x, int y);
- static bool ExistVMap(uint32 mapid, int x, int y);
- void LoadMapAndVMap(uint32 mapid, uint32 instanceid, int x, int y);
+ static bool ExistMap(uint32 mapid, int gx, int gy);
+ static bool ExistVMap(uint32 mapid, int gx, int gy);
static void InitStateMachine();
static void DeleteStateMachine();
@@ -195,22 +316,30 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
float GetVmapHeight(float x, float y, float z, bool useMaps) const;
bool IsInWater(float x, float y, float z) const; // does not use z pos. This is for future use
- uint16 GetAreaFlag(float x, float y ) const;
+ ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data = 0) const;
+
+ uint16 GetAreaFlag(float x, float y, float z) const;
uint8 GetTerrainType(float x, float y ) const;
float GetWaterLevel(float x, float y ) const;
bool IsUnderWater(float x, float y, float z) const;
- static uint32 GetAreaId(uint16 areaflag,uint32 map_id);
- static uint32 GetZoneId(uint16 areaflag,uint32 map_id);
+ static uint32 GetAreaIdByAreaFlag(uint16 areaflag,uint32 map_id);
+ static uint32 GetZoneIdByAreaFlag(uint16 areaflag,uint32 map_id);
+ static void GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 areaflag,uint32 map_id);
- uint32 GetAreaId(float x, float y) const
+ uint32 GetAreaId(float x, float y, float z) const
{
- return GetAreaId(GetAreaFlag(x,y),i_id);
+ return GetAreaIdByAreaFlag(GetAreaFlag(x,y,z),i_id);
}
- uint32 GetZoneId(float x, float y) const
+ uint32 GetZoneId(float x, float y, float z) const
{
- return GetZoneId(GetAreaFlag(x,y),i_id);
+ return GetZoneIdByAreaFlag(GetAreaFlag(x,y,z),i_id);
+ }
+
+ void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const
+ {
+ GetZoneAndAreaIdByAreaFlag(zoneid,areaid,GetAreaFlag(x,y,z),i_id);
}
virtual void MoveAllCreaturesInMoveList();
@@ -221,8 +350,8 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
// assert print helper
bool CheckGridIntegrity(Creature* c, bool moved) const;
- uint32 GetInstanceId() { return i_InstanceId; }
- uint8 GetSpawnMode() { return (i_spawnMode); }
+ uint32 GetInstanceId() const { return i_InstanceId; }
+ uint8 GetSpawnMode() const { return (i_spawnMode); }
virtual bool CanEnter(Player* /*player*/) { return true; }
const char* GetMapName() const;
@@ -234,6 +363,17 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
bool IsBattleGround() const { return i_mapEntry && i_mapEntry->IsBattleGround(); }
bool IsBattleArena() const { return i_mapEntry && i_mapEntry->IsBattleArena(); }
bool IsBattleGroundOrArena() const { return i_mapEntry && i_mapEntry->IsBattleGroundOrArena(); }
+ bool GetEntrancePos(int32 &mapid, float &x, float &y)
+ {
+ if(!i_mapEntry)
+ return false;
+ if(i_mapEntry->entrance_map < 0)
+ return false;
+ mapid = i_mapEntry->entrance_map;
+ x = i_mapEntry->entrance_x;
+ y = i_mapEntry->entrance_y;
+ return true;
+ }
void AddObjectToRemoveList(WorldObject *obj);
void AddObjectToSwitchList(WorldObject *obj, bool on);
@@ -246,8 +386,6 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
void resetMarkedCells() { marked_cells.reset(); }
bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); }
void markCell(uint32 pCellId) { marked_cells.set(pCellId); }
- Creature* GetCreatureInMap(uint64 guid);
- GameObject* GetGameObjectInMap(uint64 guid);
bool HavePlayers() const { return !m_mapRefManager.isEmpty(); }
uint32 GetPlayersCountExceptGMs() const;
@@ -277,10 +415,19 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
template<class NOTIFIER> void VisitAll(const float &x, const float &y, float radius, NOTIFIER &notifier);
template<class NOTIFIER> void VisitWorld(const float &x, const float &y, float radius, NOTIFIER &notifier);
template<class NOTIFIER> void VisitGrid(const float &x, const float &y, float radius, NOTIFIER &notifier);
- CreatureGroupHolderType CreatureGroupHolder;
+
+ TempSummon *SummonCreature(uint32 entry, float x, float y, float z, float angle, SummonPropertiesEntry const *properties = NULL, uint32 duration = 0, Unit *summoner = NULL);
+
+ CreatureGroupHolderType CreatureGroupHolder;
+
+ Creature* GetCreature(uint64 guid);
+ GameObject* GetGameObject(uint64 guid);
+ DynamicObject* GetDynamicObject(uint64 guid);
private:
- void LoadVMap(int pX, int pY);
- void LoadMap(uint32 mapid, uint32 instanceid, int x,int y);
+ void LoadMapAndVMap(int gx, int gy);
+ void LoadVMap(int gx, int gy);
+ void LoadMap(int gx,int gy);
+ GridMap *GetGrid(float x, float y);
void SetTimer(uint32 t) { i_gridExpiry = t < MIN_GRID_DELAY ? MIN_GRID_DELAY : t; }
//uint64 CalculateGridMask(const uint32 &y) const;
@@ -296,8 +443,9 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
CreatureMoveList i_creaturesToMove;
bool loaded(const GridPair &) const;
- void EnsureGridLoaded(const Cell&, Player* player = NULL);
- void EnsureGridCreated(const GridPair &);
+ void EnsureGridCreated(const GridPair &);
+ bool EnsureGridLoaded(Cell const&);
+ void EnsureGridLoadedAtEnter(Cell const&, Player* player = NULL);
void buildNGridLinkage(NGridType* pNGridType) { pNGridType->link(this); }
@@ -410,11 +558,11 @@ class TRINITY_DLL_SPEC InstanceMap : public Map
uint32 GetScriptId() { return i_script_id; }
InstanceData* GetInstanceData() { return i_data; }
void PermBindAllPlayers(Player *player);
- time_t GetResetTime();
void UnloadAll();
bool CanEnter(Player* player);
void SendResetWarnings(uint32 timeLeft) const;
void SetResetSchedule(bool on);
+ uint32 GetMaxPlayers() const;
private:
bool m_resetAfterUnload;
bool m_unloadWhenEmpty;
diff --git a/src/game/MapInstanced.cpp b/src/game/MapInstanced.cpp
index fcdc2f76c11..2494a07e20c 100644
--- a/src/game/MapInstanced.cpp
+++ b/src/game/MapInstanced.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -221,7 +221,7 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save,
}
// some instances only have one difficulty
- if(!entry->SupportsHeroicMode()) difficulty = DIFFICULTY_NORMAL;
+ if (entry && !entry->SupportsHeroicMode()) difficulty = DIFFICULTY_NORMAL;
sLog.outDebug("MapInstanced::CreateInstance: %smap instance %d for %d created with difficulty %s", save?"":"new ", InstanceId, GetId(), difficulty?"heroic":"normal");
diff --git a/src/game/MapInstanced.h b/src/game/MapInstanced.h
index d34a5cf2dfb..70e59065577 100644
--- a/src/game/MapInstanced.h
+++ b/src/game/MapInstanced.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -52,7 +52,7 @@ class TRINITY_DLL_DECL MapInstanced : public Map
SetUnloadReferenceLock(GridPair(63-p.x_coord, 63-p.y_coord), true);
}
- void RemoveGridMapReference(const GridPair &p)
+ void RemoveGridMapReference(GridPair const& p)
{
--GridMapReference[p.x_coord][p.y_coord];
if (!GridMapReference[p.x_coord][p.y_coord])
diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp
index 6a8cd130691..061e0252a13 100644
--- a/src/game/MapManager.cpp
+++ b/src/game/MapManager.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -32,6 +32,7 @@
#include "CellImpl.h"
#include "Corpse.h"
#include "ObjectMgr.h"
+#include "Language.h"
#define CLASS_LOCK Trinity::ClassLevelLockable<MapManager, ZThread::Mutex>
INSTANTIATE_SINGLETON_2(MapManager, CLASS_LOCK);
@@ -165,7 +166,7 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)
{
// probably there must be special opcode, because client has this string constant in GlobalStrings.lua
// TODO: this is not a good place to send the message
- player->GetSession()->SendAreaTriggerMessage(player->GetSession()->GetTrinityString(810), mapName);
+ player->GetSession()->SendAreaTriggerMessage(player->GetSession()->GetTrinityString(LANG_INSTANCE_RAID_GROUP_ONLY), mapName);
sLog.outDebug("MAP: Player '%s' must be in a raid group to enter instance of '%s'", player->GetName(), mapName);
return false;
}
@@ -175,7 +176,8 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)
//The player has a heroic mode and tries to enter into instance which has no a heroic mode
if (!entry->SupportsHeroicMode() && player->GetDifficulty() == DIFFICULTY_HEROIC)
{
- player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY2); //Send aborted message
+ //Send aborted message
+ player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY, DIFFICULTY_HEROIC);
return false;
}
@@ -213,7 +215,7 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)
InstanceTemplate const* instance = objmgr.GetInstanceTemplate(mapid);
if(!instance)
return false;
-
+
return player->Satisfy(objmgr.GetAccessRequirement(instance->access_id), mapid, true);
}
else
@@ -238,7 +240,7 @@ void MapManager::RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y)
}
void
-MapManager::Update(time_t diff)
+MapManager::Update(uint32 diff)
{
i_timer.Update(diff);
if( !i_timer.Passed() )
@@ -284,7 +286,8 @@ bool MapManager::ExistMapAndVMap(uint32 mapid, float x,float y)
bool MapManager::IsValidMAP(uint32 mapid)
{
MapEntry const* mEntry = sMapStore.LookupEntry(mapid);
- return mEntry && (!mEntry->Instanceable() || objmgr.GetInstanceTemplate(mapid));
+ return mEntry && (!mEntry->IsDungeon() || objmgr.GetInstanceTemplate(mapid));
+ // TODO: add check for battleground template
}
/*void MapManager::LoadGrid(int mapid, float x, float y, const WorldObject* obj, bool no_unload)
diff --git a/src/game/MapManager.h b/src/game/MapManager.h
index ce2e9ab012b..143248de162 100644
--- a/src/game/MapManager.h
+++ b/src/game/MapManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -47,18 +47,28 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit
Map const* GetBaseMap(uint32 id) const { return const_cast<MapManager*>(this)->_GetBaseMap(id); }
void DeleteInstance(uint32 mapid, uint32 instanceId);
- inline uint16 GetAreaFlag(uint32 mapid, float x, float y) const
+ uint16 GetAreaFlag(uint32 mapid, float x, float y, float z) const
{
Map const* m = GetBaseMap(mapid);
- return m->GetAreaFlag(x, y);
+ return m->GetAreaFlag(x, y, z);
+ }
+ uint32 GetAreaId(uint32 mapid, float x, float y, float z) const
+ {
+ return Map::GetAreaIdByAreaFlag(GetAreaFlag(mapid, x, y, z),mapid);
+ }
+ uint32 GetZoneId(uint32 mapid, float x, float y, float z) const
+ {
+ return Map::GetZoneIdByAreaFlag(GetAreaFlag(mapid, x, y, z),mapid);
+ }
+ void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, uint32 mapid, float x, float y, float z)
+ {
+ Map::GetZoneAndAreaIdByAreaFlag(zoneid,areaid,GetAreaFlag(mapid, x, y, z),mapid);
}
- inline uint32 GetAreaId(uint32 mapid, float x, float y) { return Map::GetAreaId(GetAreaFlag(mapid, x, y),mapid); }
- inline uint32 GetZoneId(uint32 mapid, float x, float y) { return Map::GetZoneId(GetAreaFlag(mapid, x, y),mapid); }
void Initialize(void);
- void Update(time_t);
+ void Update(uint32);
- inline void SetGridCleanUpDelay(uint32 t)
+ void SetGridCleanUpDelay(uint32 t)
{
if( t < MIN_GRID_DELAY )
i_gridCleanUpDelay = MIN_GRID_DELAY;
@@ -66,7 +76,7 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit
i_gridCleanUpDelay = t;
}
- inline void SetMapUpdateInterval(uint32 t)
+ void SetMapUpdateInterval(uint32 t)
{
if( t > MIN_MAP_UPDATE_DELAY )
t = MIN_MAP_UPDATE_DELAY;
@@ -96,6 +106,11 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit
return IsValidMAP(mapid) && Trinity::IsValidMapCoord(x,y,z,o);
}
+ static bool IsValidMapCoord(WorldLocation const& loc)
+ {
+ return IsValidMapCoord(loc.mapid,loc.x,loc.y,loc.z,loc.o);
+ }
+
void DoDelayedMovesAndRemoves();
void LoadTransports();
@@ -108,7 +123,7 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit
bool CanPlayerEnter(uint32 mapid, Player* player);
void RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y);
- inline uint32 GenerateInstanceId() { return ++i_MaxInstanceId; }
+ uint32 GenerateInstanceId() { return ++i_MaxInstanceId; }
void InitMaxInstanceId();
/* statistics */
diff --git a/src/game/MapRefManager.h b/src/game/MapRefManager.h
index cf8170a7bb3..4337aa75fd9 100644
--- a/src/game/MapRefManager.h
+++ b/src/game/MapRefManager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
+ * Copyright (C) 2005-2009 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
diff --git a/src/game/MapReference.h b/src/game/MapReference.h
index 50a7dcea5a4..ae485af7487 100644
--- a/src/game/MapReference.h
+++ b/src/game/MapReference.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
+ * Copyright (C) 2005-2009 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
diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp
index 1bed4c6a483..21342753909 100644
--- a/src/game/MiscHandler.cpp
+++ b/src/game/MiscHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -37,15 +37,14 @@
#include "Chat.h"
#include "ScriptCalls.h"
#include <zlib/zlib.h>
-#include "MapManager.h"
#include "ObjectAccessor.h"
#include "Object.h"
#include "BattleGround.h"
#include "OutdoorPvP.h"
-#include "SpellAuras.h"
#include "Pet.h"
#include "SocialMgr.h"
#include "CellImpl.h"
+#include "Vehicle.h"
void WorldSession::HandleRepopRequestOpcode( WorldPacket & /*recv_data*/ )
{
@@ -97,7 +96,7 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data )
GameObject *go = NULL;
if(IS_CREATURE_GUID(guid))
{
- unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_NONE);
+ unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
if (!unit)
{
sLog.outDebug( "WORLD: HandleGossipSelectOptionOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
@@ -106,7 +105,7 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data )
}
else if(IS_GAMEOBJECT_GUID(guid))
{
- go = ObjectAccessor::GetGameObject(*_player, guid);
+ go = _player->GetMap()->GetGameObject(guid);
if (!go)
{
sLog.outDebug( "WORLD: HandleGossipSelectOptionOpcode - GameObject (GUID: %u) not found.", uint32(GUID_LOPART(guid)) );
@@ -121,7 +120,7 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
if(!code.empty())
{
@@ -180,7 +179,7 @@ void WorldSession::HandleWhoOpcode( WorldPacket & recv_data )
// recheck
CHECK_PACKET_SIZE(recv_data,4+4+(player_name.size()+1)+(guild_name.size()+1)+4+4+4+(4*zones_count)+4);
- for(uint32 i = 0; i < zones_count; i++)
+ for(uint32 i = 0; i < zones_count; ++i)
{
uint32 temp;
recv_data >> temp; // zone id, 0 if zone is unknown...
@@ -199,7 +198,7 @@ void WorldSession::HandleWhoOpcode( WorldPacket & recv_data )
sLog.outDebug("Minlvl %u, maxlvl %u, name %s, guild %s, racemask %u, classmask %u, zones %u, strings %u", level_min, level_max, player_name.c_str(), guild_name.c_str(), racemask, classmask, zones_count, str_count);
std::wstring str[4]; // 4 is client limit
- for(uint32 i = 0; i < str_count; i++)
+ for(uint32 i = 0; i < str_count; ++i)
{
// recheck (have one more byte)
CHECK_PACKET_SIZE(recv_data,recv_data.rpos());
@@ -238,7 +237,7 @@ void WorldSession::HandleWhoOpcode( WorldPacket & recv_data )
//TODO: Guard Player map
HashMapHolder<Player>::MapType& m = ObjectAccessor::Instance().GetPlayers();
- for(HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr)
+ for(HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
{
if (security == SEC_PLAYER)
{
@@ -273,7 +272,7 @@ void WorldSession::HandleWhoOpcode( WorldPacket & recv_data )
uint32 pzoneid = itr->second->GetZoneId();
bool z_show = true;
- for(uint32 i = 0; i < zones_count; i++)
+ for(uint32 i = 0; i < zones_count; ++i)
{
if(zoneids[i] == pzoneid)
{
@@ -309,7 +308,7 @@ void WorldSession::HandleWhoOpcode( WorldPacket & recv_data )
aname = areaEntry->area_name[GetSessionDbcLocale()];
bool s_show = true;
- for(uint32 i = 0; i < str_count; i++)
+ for(uint32 i = 0; i < str_count; ++i)
{
if (!str[i].empty())
{
@@ -357,7 +356,7 @@ void WorldSession::HandleLogoutRequestOpcode( WorldPacket & /*recv_data*/ )
//Can not logout if...
if( GetPlayer()->isInCombat() || //...is in combat
GetPlayer()->duel || //...is in Duel
- GetPlayer()->HasAura(9454,0) || //...is frozen by GM via freeze command
+ GetPlayer()->HasAura(9454) || //...is frozen by GM via freeze command
//...is jumping ...is falling
GetPlayer()->HasUnitMovementFlag(MOVEMENTFLAG_JUMPING | MOVEMENTFLAG_FALLING))
{
@@ -381,13 +380,13 @@ void WorldSession::HandleLogoutRequestOpcode( WorldPacket & /*recv_data*/ )
// not set flags if player can't free move to prevent lost state at logout cancel
if(GetPlayer()->CanFreeMove())
{
- GetPlayer()->SetStandState(PLAYER_STATE_SIT);
+ GetPlayer()->SetStandState(UNIT_STAND_STATE_SIT);
WorldPacket data( SMSG_FORCE_MOVE_ROOT, (8+4) ); // guess size
data.append(GetPlayer()->GetPackGUID());
data << (uint32)2;
SendPacket( &data );
- GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
+ GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
}
WorldPacket data( SMSG_LOGOUT_RESPONSE, 5 );
@@ -421,10 +420,10 @@ void WorldSession::HandleLogoutCancelOpcode( WorldPacket & /*recv_data*/ )
SendPacket( &data );
//! Stand Up
- GetPlayer()->SetStandState(PLAYER_STATE_NONE);
+ GetPlayer()->SetStandState(UNIT_STAND_STATE_STAND);
//! DISABLE_ROTATE
- GetPlayer()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
+ GetPlayer()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
}
sLog.outDebug( "WORLD: sent SMSG_LOGOUT_CANCEL_ACK Message" );
@@ -438,10 +437,12 @@ void WorldSession::HandleTogglePvP( WorldPacket & recv_data )
bool newPvPStatus;
recv_data >> newPvPStatus;
GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP, newPvPStatus);
+ GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER, !newPvPStatus);
}
else
{
GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP);
+ GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER);
}
if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP))
@@ -470,9 +471,11 @@ void WorldSession::HandleZoneUpdateOpcode( WorldPacket & recv_data )
sLog.outDetail("WORLD: Recvd ZONE_UPDATE: %u", newZone);
- GetPlayer()->UpdateZone(newZone);
-
- GetPlayer()->SendInitWorldStates(true,newZone);
+ // use server size data
+ uint32 newzone, newarea;
+ GetPlayer()->GetZoneAndAreaId(newzone,newarea);
+ GetPlayer()->UpdateZone(newzone,newarea);
+ //GetPlayer()->SendInitWorldStates(true,newZone);
}
void WorldSession::HandleSetTargetOpcode( WorldPacket & recv_data )
@@ -490,7 +493,8 @@ void WorldSession::HandleSetTargetOpcode( WorldPacket & recv_data )
if(!unit)
return;
- _player->SetFactionVisibleForFactionTemplateId(unit->getFaction());
+ if(FactionTemplateEntry const* factionTemplateEntry = sFactionTemplateStore.LookupEntry(unit->getFaction()))
+ _player->GetReputationMgr().SetVisible(factionTemplateEntry);
}
void WorldSession::HandleSetSelectionOpcode( WorldPacket & recv_data )
@@ -507,7 +511,8 @@ void WorldSession::HandleSetSelectionOpcode( WorldPacket & recv_data )
if(!unit)
return;
- _player->SetFactionVisibleForFactionTemplateId(unit->getFaction());
+ if(FactionTemplateEntry const* factionTemplateEntry = sFactionTemplateStore.LookupEntry(unit->getFaction()))
+ _player->GetReputationMgr().SetVisible(factionTemplateEntry);
}
void WorldSession::HandleStandStateChangeOpcode( WorldPacket & recv_data )
@@ -563,12 +568,12 @@ void WorldSession::HandleAddFriendOpcodeCallBack(QueryResult *result, uint32 acc
uint64 friendGuid;
uint32 team;
FriendsResult friendResult;
-
+
WorldSession * session = sWorld.FindSession(accountId);
if(!session || !session->GetPlayer())
return;
-
+
friendResult = FRIEND_NOT_FOUND;
friendGuid = 0;
@@ -652,12 +657,12 @@ void WorldSession::HandleAddIgnoreOpcodeCallBack(QueryResult *result, uint32 acc
{
uint64 IgnoreGuid;
FriendsResult ignoreResult;
-
+
WorldSession * session = sWorld.FindSession(accountId);
if(!session || !session->GetPlayer())
return;
-
+
ignoreResult = FRIEND_IGNORE_NOT_FOUND;
IgnoreGuid = 0;
@@ -676,7 +681,7 @@ void WorldSession::HandleAddIgnoreOpcodeCallBack(QueryResult *result, uint32 acc
else
{
ignoreResult = FRIEND_IGNORE_ADDED;
-
+
// ignore list full
if(!session->GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(IgnoreGuid), true))
ignoreResult = FRIEND_IGNORE_FULL;
@@ -903,7 +908,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
GetPlayer()->SetRestType(REST_TYPE_IN_TAVERN);
if(sWorld.IsFFAPvPRealm())
- GetPlayer()->RemoveFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ GetPlayer()->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
return;
}
@@ -935,16 +940,96 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,TELE_TO_NOT_LEAVE_TRANSPORT);
}
-void WorldSession::HandleUpdateAccountData(WorldPacket &/*recv_data*/)
+void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)
{
sLog.outDetail("WORLD: Received CMSG_UPDATE_ACCOUNT_DATA");
- //recv_data.hexlike();
+
+ CHECK_PACKET_SIZE(recv_data, 4+4+4);
+
+ uint32 type, timestamp, decompressedSize;
+ recv_data >> type >> timestamp >> decompressedSize;
+
+ sLog.outDebug("UAD: type %u, time %u, decompressedSize %u", type, timestamp, decompressedSize);
+
+ if(type > NUM_ACCOUNT_DATA_TYPES)
+ return;
+
+ if(decompressedSize == 0) // erase
+ {
+ SetAccountData(type, 0, "");
+
+ WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, 4+4);
+ data << uint32(type);
+ data << uint32(0);
+ SendPacket(&data);
+
+ return;
+ }
+
+ if(decompressedSize > 0xFFFF)
+ {
+ sLog.outError("UAD: Account data packet too big, size %u", decompressedSize);
+ return;
+ }
+
+ ByteBuffer dest;
+ dest.resize(decompressedSize);
+
+ uLongf realSize = decompressedSize;
+ if(uncompress(const_cast<uint8*>(dest.contents()), &realSize, const_cast<uint8*>(recv_data.contents() + recv_data.rpos()), recv_data.size() - recv_data.rpos()) != Z_OK)
+ {
+ sLog.outError("UAD: Failed to decompress account data");
+ return;
+ }
+
+ std::string adata;
+ dest >> adata;
+
+ SetAccountData(type, timestamp, adata);
+
+ WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, 4+4);
+ data << uint32(type);
+ data << uint32(0);
+ SendPacket(&data);
}
-void WorldSession::HandleRequestAccountData(WorldPacket& /*recv_data*/)
+void WorldSession::HandleRequestAccountData(WorldPacket& recv_data)
{
sLog.outDetail("WORLD: Received CMSG_REQUEST_ACCOUNT_DATA");
- //recv_data.hexlike();
+
+ CHECK_PACKET_SIZE(recv_data, 4);
+
+ uint32 type;
+ recv_data >> type;
+
+ sLog.outDebug("RAD: type %u", type);
+
+ if(type > NUM_ACCOUNT_DATA_TYPES)
+ return;
+
+ AccountData *adata = GetAccountData(type);
+
+ uint32 size = adata->Data.size();
+
+ ByteBuffer dest;
+ dest.resize(size);
+
+ uLongf destSize = size;
+ if(size && compress(const_cast<uint8*>(dest.contents()), &destSize, (uint8*)adata->Data.c_str(), size) != Z_OK)
+ {
+ sLog.outDebug("RAD: Failed to compress account data");
+ return;
+ }
+
+ dest.resize(destSize);
+
+ WorldPacket data (SMSG_UPDATE_ACCOUNT_DATA, 8+4+4+4+destSize);
+ data << uint64(_player->GetGUID()); // player guid
+ data << uint32(type); // type (0-7)
+ data << uint32(adata->Time); // unix time
+ data << uint32(size); // decompressed length
+ data.append(dest); // compressed data
+ SendPacket(&data);
}
void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data)
@@ -971,7 +1056,7 @@ void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data)
}
else if(type==ACTION_BUTTON_SPELL)
{
- sLog.outDetail( "MISC: Added Action %u into button %u", action, button );
+ sLog.outDetail( "MISC: Added Spell %u into button %u", action, button );
GetPlayer()->addActionButton(button,action,type,misc);
}
else if(type==ACTION_BUTTON_ITEM)
@@ -1088,22 +1173,6 @@ void WorldSession::HandleMoveRootAck(WorldPacket&/* recv_data*/)
*/
}
-void WorldSession::HandleMoveTeleportAck(WorldPacket&/* recv_data*/)
-{
- /*
- CHECK_PACKET_SIZE(recv_data,8+4);
-
- sLog.outDebug("MSG_MOVE_TELEPORT_ACK");
- uint64 guid;
- uint32 flags, time;
-
- recv_data >> guid;
- recv_data >> flags >> time;
- DEBUG_LOG("Guid " I64FMTD,guid);
- DEBUG_LOG("Flags %u, time %u",flags, time/1000);
- */
-}
-
void WorldSession::HandleSetActionBar(WorldPacket& recv_data)
{
CHECK_PACKET_SIZE(recv_data,1);
@@ -1191,7 +1260,7 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recv_data)
// find talent rank
uint32 curtalent_maxrank = 0;
- for(uint32 k = 5; k > 0; --k)
+ for(uint32 k = MAX_TALENT_RANK; k > 0; --k)
{
if(talentInfo->RankID[k-1] && plr->HasSpell(talentInfo->RankID[k-1]))
{
@@ -1363,7 +1432,10 @@ void WorldSession::HandleReportSpamOpcode( WorldPacket & recv_data )
uint8 spam_type; // 0 - mail, 1 - chat
uint64 spammer_guid;
- uint32 unk1, unk2, unk3, unk4 = 0;
+ uint32 unk1 = 0;
+ uint32 unk2 = 0;
+ uint32 unk3 = 0;
+ uint32 unk4 = 0;
std::string description = "";
recv_data >> spam_type; // unk 0x01 const, may be spam type (mail/chat)
recv_data >> spammer_guid; // player guid
@@ -1428,22 +1500,18 @@ void WorldSession::HandleFarSightOpcode( WorldPacket & recv_data )
uint8 apply;
recv_data >> apply;
- CellPair pair;
-
switch(apply)
{
case 0:
- _player->SetFarsightVision(false);
- pair = Trinity::ComputeCellPair(_player->GetPositionX(), _player->GetPositionY());
- sLog.outDebug("Player %u set vision to himself", _player->GetGUIDLow());
+ sLog.outDebug("Player %u set vision to self", _player->GetGUIDLow());
+ _player->SetSeer(_player);
break;
case 1:
- _player->SetFarsightVision(true);
- if (WorldObject* obj = _player->GetFarsightTarget())
- pair = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
+ sLog.outDebug("Added FarSight " I64FMT " to player %u", _player->GetUInt64Value(PLAYER_FARSIGHT), _player->GetGUIDLow());
+ if(WorldObject *target = _player->GetViewpoint())
+ _player->SetSeer(target);
else
- return;
- sLog.outDebug("Added FarSight " I64FMT " to player %u", _player->GetFarSight(), _player->GetGUIDLow());
+ sLog.outError("Player %s requests non-existing seer", _player->GetName());
break;
default:
sLog.outDebug("Unhandled mode in CMSG_FAR_SIGHT: %u", apply);
@@ -1476,11 +1544,11 @@ void WorldSession::HandleChooseTitleOpcode( WorldPacket & recv_data )
GetPlayer()->SetUInt32Value(PLAYER_CHOSEN_TITLE, title);
}
-void WorldSession::HandleAllowMoveAckOpcode( WorldPacket & recv_data )
+void WorldSession::HandleTimeSyncResp( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data, 4+4);
- sLog.outDebug("CMSG_ALLOW_MOVE_ACK");
+ sLog.outDebug("CMSG_TIME_SYNC_RESP");
uint32 counter, time_;
recv_data >> counter >> time_;
@@ -1550,26 +1618,6 @@ void WorldSession::HandleDungeonDifficultyOpcode( WorldPacket & recv_data )
}
}
-void WorldSession::HandleNewUnknownOpcode( WorldPacket & recv_data )
-{
- sLog.outDebug("New Unknown Opcode %u", recv_data.GetOpcode());
- recv_data.hexlike();
- /*
- New Unknown Opcode 837
- STORAGE_SIZE: 60
- 02 00 00 00 00 00 00 00 | 00 00 00 00 01 20 00 00
- 89 EB 33 01 71 5C 24 C4 | 15 03 35 45 74 47 8B 42
- BA B8 1B 40 00 00 00 00 | 00 00 00 00 77 66 42 BF
- 23 91 26 3F 00 00 60 41 | 00 00 00 00
-
- New Unknown Opcode 837
- STORAGE_SIZE: 44
- 02 00 00 00 00 00 00 00 | 00 00 00 00 00 00 80 00
- 7B 80 34 01 84 EA 2B C4 | 5F A1 36 45 C9 39 1C 42
- BA B8 1B 40 CE 06 00 00 | 00 00 80 3F
- */
-}
-
void WorldSession::HandleDismountOpcode( WorldPacket & /*recv_data*/ )
{
sLog.outDebug("WORLD: CMSG_CANCEL_MOUNT_AURA");
@@ -1589,7 +1637,7 @@ void WorldSession::HandleDismountOpcode( WorldPacket & /*recv_data*/ )
}
_player->Unmount();
- _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+ _player->RemoveAurasByType(SPELL_AURA_MOUNTED);
}
void WorldSession::HandleMoveFlyModeChangeAckOpcode( WorldPacket & recv_data )
@@ -1637,3 +1685,34 @@ void WorldSession::HandleSetTaxiBenchmarkOpcode( WorldPacket & recv_data )
sLog.outDebug("Client used \"/timetest %d\" command", mode);
}
+void WorldSession::HandleSpellClick( WorldPacket & recv_data )
+{
+ CHECK_PACKET_SIZE(recv_data, 8);
+
+ uint64 guid;
+ recv_data >> guid;
+
+ Vehicle *vehicle = ObjectAccessor::GetVehicle(guid);
+
+ if(!vehicle)
+ {
+ sLog.outError("Player %s cannot find vehicle %u", _player->GetName(), guid);
+ return;
+ }
+
+ _player->EnterVehicle(vehicle);
+}
+
+void WorldSession::HandleInspectAchievements( WorldPacket & recv_data )
+{
+ CHECK_PACKET_SIZE(recv_data, 1);
+ uint64 guid;
+ if(!recv_data.readPackGUID(guid))
+ return;
+
+ Player *player = objmgr.GetPlayer(guid);
+ if(!player)
+ return;
+
+ player->GetAchievementMgr().SendRespondInspectAchievements(_player);
+}
diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp
index 9beecf9c5cf..51e684c5a6c 100644
--- a/src/game/MotionMaster.cpp
+++ b/src/game/MotionMaster.cpp
@@ -50,17 +50,20 @@ MotionMaster::Initialize()
if(curr) DirectDelete(curr);
}
- // set new default movement generator
+ InitDefault();
+}
+
+// set new default movement generator
+void MotionMaster::InitDefault()
+{
if(i_owner->GetTypeId() == TYPEID_UNIT)
{
MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)i_owner);
- push( movement == NULL ? &si_idleMovement : movement );
- InitTop();
+ Mutate(movement == NULL ? &si_idleMovement : movement, MOTION_SLOT_IDLE);
}
else
{
- push(&si_idleMovement);
- needInit[MOTION_SLOT_IDLE] = false;
+ Mutate(&si_idleMovement, MOTION_SLOT_IDLE);
}
}
@@ -200,28 +203,22 @@ MotionMaster::MoveTargetedHome()
Clear(false);
- if(i_owner->GetTypeId()==TYPEID_UNIT && !((Creature*)i_owner)->GetCharmerOrOwnerGUID())
+ if(Unit *target = i_owner->GetCharmerOrOwner())
{
- DEBUG_LOG("Creature (Entry: %u GUID: %u) targeted home", i_owner->GetEntry(), i_owner->GetGUIDLow());
- Mutate(new HomeMovementGenerator<Creature>(), MOTION_SLOT_ACTIVE);
+ DEBUG_LOG("Pet or controlled unit (Entry: %u GUID: %u) targeting home",
+ i_owner->GetEntry(), i_owner->GetGUIDLow() );
+
+ MoveFollow(target, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE, MOTION_SLOT_IDLE);
}
- else if(i_owner->GetTypeId()==TYPEID_UNIT && ((Creature*)i_owner)->GetCharmerOrOwnerGUID())
+ else if(i_owner->GetTypeId() == TYPEID_UNIT)
{
- DEBUG_LOG("Pet or controlled creature (Entry: %u GUID: %u) targeting home",
- i_owner->GetEntry(), i_owner->GetGUIDLow() );
- Unit *target = ((Creature*)i_owner)->GetCharmerOrOwner();
- if(target)
- {
- i_owner->addUnitState(UNIT_STAT_FOLLOW);
- DEBUG_LOG("Following %s (GUID: %u)",
- target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
- target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() );
- Mutate(new TargetedMovementGenerator<Creature>(*target,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE), MOTION_SLOT_ACTIVE);
- }
+ DEBUG_LOG("Creature (Entry: %u GUID: %u) targeted home", i_owner->GetEntry(), i_owner->GetGUIDLow());
+ Mutate(new HomeMovementGenerator<Creature>(), MOTION_SLOT_ACTIVE);
}
else
{
sLog.outError("Player (GUID: %u) attempt targeted home", i_owner->GetGUIDLow() );
+ return;
}
}
@@ -268,7 +265,7 @@ MotionMaster::MoveChase(Unit* target, float dist, float angle)
}
void
-MotionMaster::MoveFollow(Unit* target, float dist, float angle)
+MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlot slot)
{
// ignore movement request if target not exist
if(!target || target == i_owner)
@@ -280,7 +277,7 @@ MotionMaster::MoveFollow(Unit* target, float dist, float angle)
DEBUG_LOG("Player (GUID: %u) follow to %s (GUID: %u)", i_owner->GetGUIDLow(),
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId()==TYPEID_PLAYER ? i_owner->GetGUIDLow() : ((Creature*)i_owner)->GetDBTableGUIDLow() );
- Mutate(new TargetedMovementGenerator<Player>(*target,dist,angle), MOTION_SLOT_ACTIVE);
+ Mutate(new TargetedMovementGenerator<Player>(*target,dist,angle), slot);
}
else
{
@@ -288,7 +285,7 @@ MotionMaster::MoveFollow(Unit* target, float dist, float angle)
i_owner->GetEntry(), i_owner->GetGUIDLow(),
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() );
- Mutate(new TargetedMovementGenerator<Creature>(*target,dist,angle), MOTION_SLOT_ACTIVE);
+ Mutate(new TargetedMovementGenerator<Creature>(*target,dist,angle), slot);
}
}
@@ -308,13 +305,59 @@ MotionMaster::MovePoint(uint32 id, float x, float y, float z)
}
}
+void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ)
+{
+ //this function may make players fall below map
+ if(i_owner->GetTypeId()==TYPEID_PLAYER)
+ return;
+
+ float x, y, z;
+ float dist = speedXY * speedZ * 0.1f;
+ i_owner->GetNearPoint(i_owner, x, y, z, i_owner->GetObjectSize(), dist, i_owner->GetAngle(srcX, srcY) + M_PI);
+ MoveJump(x, y, z, speedXY, speedZ);
+}
+
+void MotionMaster::MoveJumpTo(float angle, float speedXY, float speedZ)
+{
+ //this function may make players fall below map
+ if(i_owner->GetTypeId()==TYPEID_PLAYER)
+ return;
+
+ float x, y, z;
+ float dist = speedXY * speedZ * 0.1f;
+ i_owner->GetClosePoint(x, y, z, i_owner->GetObjectSize(), dist, angle);
+ MoveJump(x, y, z, speedXY, speedZ);
+}
+
+void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float speedZ)
+{
+ uint32 moveFlag = MOVEFLAG_JUMP | MOVEFLAG_WALK;
+ uint32 time = speedZ * 100;
+ i_owner->SendMonsterMove(x, y, z, moveFlag, time, speedZ);
+
+ i_owner->addUnitState(UNIT_STAT_CHARGING | UNIT_STAT_JUMPING);
+ i_owner->m_TempSpeed = speedXY;
+ if(i_owner->GetTypeId()==TYPEID_PLAYER)
+ {
+ DEBUG_LOG("Player (GUID: %u) jump to point (X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), x, y, z );
+ Mutate(new PointMovementGenerator<Player>(0,x,y,z), MOTION_SLOT_CONTROLLED);
+ }
+ else
+ {
+ DEBUG_LOG("Creature (Entry: %u GUID: %u) jump to point (X: %f Y: %f Z: %f)",
+ i_owner->GetEntry(), i_owner->GetGUIDLow(), x, y, z );
+ Mutate(new PointMovementGenerator<Creature>(0,x,y,z), MOTION_SLOT_CONTROLLED);
+ }
+}
+
void
-MotionMaster::MoveCharge(float x, float y, float z)
+MotionMaster::MoveCharge(float x, float y, float z, float speed)
{
if(Impl[MOTION_SLOT_CONTROLLED] && Impl[MOTION_SLOT_CONTROLLED]->GetMovementGeneratorType() != DISTRACT_MOTION_TYPE)
return;
i_owner->addUnitState(UNIT_STAT_CHARGING);
+ i_owner->m_TempSpeed = speed;
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) charge point (X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), x, y, z );
@@ -484,7 +527,7 @@ void MotionMaster::DirectDelete(_Ty curr)
void MotionMaster::DelayedDelete(_Ty curr)
{
- sLog.outError("CRASH ALARM! Unit (Entry %u) is trying to delete its updating MG (Type %u)!", i_owner->GetEntry(), curr->GetMovementGeneratorType());
+ sLog.outCrash("Unit (Entry %u) is trying to delete its updating MG (Type %u)!", i_owner->GetEntry(), curr->GetMovementGeneratorType());
if(isStatic(curr))
return;
if(!m_expList)
@@ -494,9 +537,9 @@ void MotionMaster::DelayedDelete(_Ty curr)
bool MotionMaster::GetDestination(float &x, float &y, float &z)
{
- if(empty())
+ if(empty())
return false;
-
- return top()->GetDestination(x,y,z);
+
+ return top()->GetDestination(x,y,z);
}
diff --git a/src/game/MotionMaster.h b/src/game/MotionMaster.h
index d68a94b7a1f..ea71495d216 100644
--- a/src/game/MotionMaster.h
+++ b/src/game/MotionMaster.h
@@ -63,6 +63,9 @@ enum MMCleanFlag
MMCF_RESET = 2 // Flag if need top()->Reset()
};
+// assume it is 25 yard per 0.6 second
+#define SPEED_CHARGE 42.0f
+
class TRINITY_DLL_SPEC MotionMaster //: private std::stack<MovementGenerator *>
{
private:
@@ -73,7 +76,7 @@ class TRINITY_DLL_SPEC MotionMaster //: private std::stack<MovementGenerator *>
typedef std::vector<_Ty> ExpireList;
int i_top;
- bool empty() const { return i_top < 0; }
+ bool empty() const { return (i_top < 0); }
void pop() { Impl[i_top] = NULL; --i_top; }
void push(_Ty _Val) { ++i_top; Impl[i_top] = _Val; }
@@ -92,6 +95,7 @@ class TRINITY_DLL_SPEC MotionMaster //: private std::stack<MovementGenerator *>
~MotionMaster();
void Initialize();
+ void InitDefault();
int size() const { return i_top + 1; }
_Ty top() const { return Impl[i_top]; }
@@ -131,12 +135,15 @@ class TRINITY_DLL_SPEC MotionMaster //: private std::stack<MovementGenerator *>
void MoveIdle(MovementSlot slot = MOTION_SLOT_ACTIVE);
void MoveTargetedHome();
void MoveRandom(float spawndist = 0.0f);
- void MoveFollow(Unit* target, float dist, float angle);
+ void MoveFollow(Unit* target, float dist, float angle, MovementSlot slot = MOTION_SLOT_ACTIVE);
void MoveChase(Unit* target, float dist = 0.0f, float angle = 0.0f);
void MoveConfused();
void MoveFleeing(Unit* enemy);
void MovePoint(uint32 id, float x,float y,float z);
- void MoveCharge(float x, float y, float z);
+ void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE);
+ void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ);
+ void MoveJumpTo(float angle, float speedXY, float speedZ);
+ void MoveJump(float x, float y, float z, float speedXY, float speedZ);
void MoveTaxiFlight(uint32 path, uint32 pathnode);
void MoveDistract(uint32 time);
void MovePath(uint32 path_id, bool repeatable);
diff --git a/src/game/MovementGenerator.cpp b/src/game/MovementGenerator.cpp
index ee314ffae3f..7784df315c9 100644
--- a/src/game/MovementGenerator.cpp
+++ b/src/game/MovementGenerator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/MovementGenerator.h b/src/game/MovementGenerator.h
index 49d0ce8798a..cb352b7f1c6 100644
--- a/src/game/MovementGenerator.h
+++ b/src/game/MovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/MovementGeneratorImpl.h b/src/game/MovementGeneratorImpl.h
index 7197adb5dfe..fc676704d3a 100644
--- a/src/game/MovementGeneratorImpl.h
+++ b/src/game/MovementGeneratorImpl.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp
index 2eb3bab12e7..2ef75c24be7 100644
--- a/src/game/MovementHandler.cpp
+++ b/src/game/MovementHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -23,14 +23,15 @@
#include "WorldSession.h"
#include "Opcodes.h"
#include "Log.h"
-#include "World.h"
#include "Corpse.h"
#include "Player.h"
+#include "Vehicle.h"
#include "MapManager.h"
#include "Transports.h"
#include "BattleGround.h"
#include "WaypointMovementGenerator.h"
#include "InstanceSaveMgr.h"
+#include "ObjectMgr.h"
void WorldSession::HandleMoveWorldportAckOpcode( WorldPacket & /*recv_data*/ )
{
@@ -40,6 +41,10 @@ void WorldSession::HandleMoveWorldportAckOpcode( WorldPacket & /*recv_data*/ )
void WorldSession::HandleMoveWorldportAckOpcode()
{
+ // ignore unexpected far teleports
+ if(!GetPlayer()->IsBeingTeleportedFar())
+ return;
+
// get the teleport destination
WorldLocation &loc = GetPlayer()->GetTeleportDest();
@@ -58,7 +63,7 @@ void WorldSession::HandleMoveWorldportAckOpcode()
if(GetPlayer()->m_InstanceValid == false && !mInstance)
GetPlayer()->m_InstanceValid = true;
- GetPlayer()->SetSemaphoreTeleport(false);
+ GetPlayer()->SetSemaphoreTeleportFar(false);
// relocate the player to the teleport destination
GetPlayer()->SetMapId(loc.mapid);
@@ -78,7 +83,6 @@ void WorldSession::HandleMoveWorldportAckOpcode()
{
sLog.outDebug("WORLD: teleport of player %s (%d) to location %d,%f,%f,%f,%f failed", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.x, loc.y, loc.z, loc.o);
// teleport the player home
- GetPlayer()->SetDontMove(false);
if(!GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()))
{
// the player must always be able to teleport home
@@ -87,6 +91,26 @@ void WorldSession::HandleMoveWorldportAckOpcode()
}
return;
}
+
+ // battleground state prepare (in case join to BG), at relogin/tele player not invited
+ // only add to bg group and object, if the player was invited (else he entered through command)
+ if(_player->InBattleGround())
+ {
+ // cleanup seting if outdated
+ if(!mEntry->IsBattleGroundOrArena())
+ {
+ _player->SetBattleGroundId(0, BATTLEGROUND_TYPE_NONE); // We're not in BG.
+ // reset destination bg team
+ _player->SetBGTeam(0);
+ }
+ // join to bg case
+ else if(BattleGround *bg = _player->GetBattleGround())
+ {
+ if(_player->IsInvitedForBattleGroundInstance(_player->GetBattleGroundId()))
+ bg->AddPlayer(_player);
+ }
+ }
+
GetPlayer()->SendInitialPacketsAfterAddToMap();
// flight fast teleport case
@@ -95,7 +119,6 @@ void WorldSession::HandleMoveWorldportAckOpcode()
if(!_player->InBattleGround())
{
// short preparations to continue flight
- GetPlayer()->SetDontMove(false);
FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top());
flight->Initialize(*GetPlayer());
return;
@@ -129,113 +152,77 @@ void WorldSession::HandleMoveWorldportAckOpcode()
// mount allow check
if(!mEntry->IsMountAllowed())
- _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
-
- // battleground state prepare
- // only add to bg group and object, if the player was invited (else he entered through command)
- if(_player->InBattleGround() && _player->IsInvitedForBattleGroundInstance(_player->GetBattleGroundId()))
- {
- BattleGround *bg = _player->GetBattleGround();
- if(bg)
- {
- bg->AddPlayer(_player);
- if(bg->GetMapId() == _player->GetMapId()) // we teleported to bg
- {
- // get the team this way, because arenas might 'override' the teams.
- uint32 team = bg->GetPlayerTeam(_player->GetGUID());
- if(!team)
- team = _player->GetTeam();
- if(!bg->GetBgRaid(team)) // first player joined
- {
- Group *group = new Group;
- bg->SetBgRaid(team, group);
- group->Create(_player->GetGUIDLow(), _player->GetName());
- }
- else // raid already exist
- {
- bg->GetBgRaid(team)->AddMember(_player->GetGUID(), _player->GetName());
- }
- }
- }
- }
+ _player->RemoveAurasByType(SPELL_AURA_MOUNTED);
// honorless target
if(GetPlayer()->pvpInfo.inHostileArea)
GetPlayer()->CastSpell(GetPlayer(), 2479, true);
// resummon pet
- if(GetPlayer()->m_temporaryUnsummonedPetNumber)
- {
- Pet* NewPet = new Pet;
- if(!NewPet->LoadPetFromDB(GetPlayer(), 0, GetPlayer()->m_temporaryUnsummonedPetNumber, true))
- delete NewPet;
-
- GetPlayer()->m_temporaryUnsummonedPetNumber = 0;
- }
-
- GetPlayer()->SetDontMove(false);
+ GetPlayer()->ResummonPetTemporaryUnSummonedIfAny();
}
-void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
+void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data)
{
- CHECK_PACKET_SIZE(recv_data, 4+1+4+4+4+4+4);
+ CHECK_PACKET_SIZE(recv_data,8+4);
- /* extract packet */
- MovementInfo movementInfo;
- uint32 MovementFlags;
+ sLog.outDebug("MSG_MOVE_TELEPORT_ACK");
+ uint64 guid;
+ uint32 flags, time;
- recv_data >> MovementFlags;
- recv_data >> movementInfo.unk1;
- recv_data >> movementInfo.time;
- recv_data >> movementInfo.x;
- recv_data >> movementInfo.y;
- recv_data >> movementInfo.z;
- recv_data >> movementInfo.o;
+ recv_data >> guid;
+ recv_data >> flags >> time;
+ DEBUG_LOG("Guid " I64FMTD,guid);
+ DEBUG_LOG("Flags %u, time %u",flags, time/IN_MILISECONDS);
- if(MovementFlags & MOVEMENTFLAG_ONTRANSPORT)
- {
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4+4+4+4+4);
-
- recv_data >> movementInfo.t_guid;
- recv_data >> movementInfo.t_x;
- recv_data >> movementInfo.t_y;
- recv_data >> movementInfo.t_z;
- recv_data >> movementInfo.t_o;
- recv_data >> movementInfo.t_time;
- }
+ Unit *mover = _player->m_mover;
+ Player *plMover = mover->GetTypeId()==TYPEID_PLAYER ? (Player*)mover : NULL;
- if(MovementFlags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2))
- {
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
+ if(!plMover || !plMover->IsBeingTeleportedNear())
+ return;
- recv_data >> movementInfo.s_pitch; // pitch, -1.55=looking down, 0=looking straight forward, +1.55=looking up
- }
+ if(guid != plMover->GetGUID())
+ return;
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
+ plMover->SetSemaphoreTeleportNear(false);
- recv_data >> movementInfo.fallTime; // duration of last jump (when in jump duration from jump begin to now)
+ uint32 old_zone = plMover->GetZoneId();
- if(MovementFlags & MOVEMENTFLAG_JUMPING)
- {
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4+4+4);
+ WorldLocation const& dest = plMover->GetTeleportDest();
- recv_data >> movementInfo.j_unk; // constant, but different when jumping in water and on land?
- recv_data >> movementInfo.j_sinAngle; // sin of angle between orientation0 and players orientation
- recv_data >> movementInfo.j_cosAngle; // cos of angle between orientation0 and players orientation
- recv_data >> movementInfo.j_xyspeed; // speed of xy movement
- }
+ plMover->SetPosition(dest.x, dest.y, dest.z, dest.o, true);
- if(MovementFlags & MOVEMENTFLAG_SPLINE)
- {
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
+ uint32 newzone, newarea;
+ plMover->GetZoneAndAreaId(newzone,newarea);
+ plMover->UpdateZone(newzone,newarea);
- recv_data >> movementInfo.u_unk1; // unknown
+ // new zone
+ if(old_zone != newzone)
+ {
+ // honorless target
+ if(plMover->pvpInfo.inHostileArea)
+ plMover->CastSpell(plMover, 2479, true);
}
+
+ // resummon pet
+ GetPlayer()->ResummonPetTemporaryUnSummonedIfAny();
+}
+
+void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
+{
+ uint32 opcode = recv_data.GetOpcode();
+ //sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode);
+
+ Unit *mover = _player->m_mover;
+ Player *plMover = mover->GetTypeId()==TYPEID_PLAYER ? (Player*)mover : NULL;
+
+ // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
+ if(plMover && plMover->IsBeingTeleported())
+ return;
+
+ /* extract packet */
+ MovementInfo movementInfo;
+ ReadMovementInfo(recv_data, &movementInfo);
/*----------------*/
if(recv_data.size() != recv_data.rpos())
@@ -248,22 +235,8 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
if (!Trinity::IsValidMapCoord(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o))
return;
- // Handle possessed unit movement separately
- Unit* pos_unit = GetPlayer()->GetCharm();
- if (pos_unit && pos_unit->isPossessed()) // can be charmed but not possessed
- {
- HandlePossessedMovement(recv_data, movementInfo, MovementFlags);
- return;
- }
-
- if (GetPlayer()->GetDontMove())
- return;
-
- //Save movement flags
- GetPlayer()->SetUnitMovementFlags(MovementFlags);
-
/* handle special cases */
- if (MovementFlags & MOVEMENTFLAG_ONTRANSPORT)
+ if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT)
{
// transports size limited
// (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
@@ -275,141 +248,115 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
return;
// if we boarded a transport, add us to it
- if (!GetPlayer()->m_transport)
+ if (plMover && !plMover->m_transport)
{
// elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list
- for (MapManager::TransportSet::iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter)
+ for (MapManager::TransportSet::const_iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter)
{
if ((*iter)->GetGUID() == movementInfo.t_guid)
{
- // unmount before boarding
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
-
- GetPlayer()->m_transport = (*iter);
- (*iter)->AddPassenger(GetPlayer());
+ plMover->m_transport = (*iter);
+ (*iter)->AddPassenger(plMover);
break;
}
}
}
+
+ if(!mover->GetTransport() && !mover->m_Vehicle)
+ movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT;
}
- else if (GetPlayer()->m_transport) // if we were on a transport, leave
+ else if (plMover && plMover->m_transport) // if we were on a transport, leave
{
- GetPlayer()->m_transport->RemovePassenger(GetPlayer());
- GetPlayer()->m_transport = NULL;
+ plMover->m_transport->RemovePassenger(plMover);
+ plMover->m_transport = NULL;
movementInfo.t_x = 0.0f;
movementInfo.t_y = 0.0f;
movementInfo.t_z = 0.0f;
movementInfo.t_o = 0.0f;
movementInfo.t_time = 0;
+ movementInfo.t_seat = -1;
}
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
- if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight())
- GetPlayer()->HandleFallDamage(movementInfo);
+ if (opcode == MSG_MOVE_FALL_LAND && plMover && !plMover->isInFlight())
+ plMover->HandleFall(movementInfo);
- if(((MovementFlags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater())
+ if (plMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plMover->IsInWater())
{
// now client not include swimming flag in case jumping under water
- GetPlayer()->SetInWater( !GetPlayer()->IsInWater() || GetPlayer()->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) );
+ plMover->SetInWater( !plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) );
}
/*----------------------*/
/* process position-change */
- recv_data.put<uint32>(5, getMSTime()); // offset flags(4) + unk(1)
- WorldPacket data(recv_data.GetOpcode(), (GetPlayer()->GetPackGUID().size()+recv_data.size()));
- data.append(GetPlayer()->GetPackGUID());
+ recv_data.put<uint32>(6, getMSTime()); // fix time, offset flags(4) + unk(2)
+ WorldPacket data(recv_data.GetOpcode(), (mover->GetPackGUID().size()+recv_data.size()));
+ data.append(mover->GetPackGUID()); // use mover guid
data.append(recv_data.contents(), recv_data.size());
GetPlayer()->SendMessageToSet(&data, false);
- GetPlayer()->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
- GetPlayer()->m_movementInfo = movementInfo;
- if (GetPlayer()->m_lastFallTime >= movementInfo.fallTime || GetPlayer()->m_lastFallZ <=movementInfo.z || recv_data.GetOpcode() == MSG_MOVE_FALL_LAND)
- GetPlayer()->SetFallInformation(movementInfo.fallTime, movementInfo.z);
+ mover->m_movementInfo = movementInfo;
+ mover->SetUnitMovementFlags(movementInfo.flags);
- if(GetPlayer()->isMovingOrTurning())
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
-
- if(movementInfo.z < -500.0f)
- GetPlayer()->HandleFallUnderMap();
-}
-
-void WorldSession::HandlePossessedMovement(WorldPacket& recv_data, MovementInfo& movementInfo, uint32& MovementFlags)
-{
- // Whatever the client is controlling, it will send the GUID of the original player.
- // If current player is controlling, it must be handled like the controlled player sent these opcodes
-
- Unit* pos_unit = GetPlayer()->GetCharm();
-
- if (pos_unit->GetTypeId() == TYPEID_PLAYER && ((Player*)pos_unit)->GetDontMove())
- return;
-
- //Save movement flags
- pos_unit->SetUnitMovementFlags(MovementFlags);
-
- // Remove possession if possessed unit enters a transport
- if (MovementFlags & MOVEMENTFLAG_ONTRANSPORT)
+ if(plMover) // nothing is charmed, or player charmed
{
- GetPlayer()->Uncharm();
- return;
- }
+ plMover->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
+ plMover->UpdateFallInformationIfNeed(movementInfo,recv_data.GetOpcode());
- recv_data.put<uint32>(5, getMSTime());
- WorldPacket data(recv_data.GetOpcode(), pos_unit->GetPackGUID().size()+recv_data.size());
- data.append(pos_unit->GetPackGUID());
- data.append(recv_data.contents(), recv_data.size());
- // Send the packet to self but not to the possessed player; for creatures the first bool is irrelevant
- pos_unit->SendMessageToSet(&data, true, false);
-
- // Possessed is a player
- if (pos_unit->GetTypeId() == TYPEID_PLAYER)
- {
- Player* plr = (Player*)pos_unit;
-
- if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND)
- plr->HandleFallDamage(movementInfo);
-
- if(((MovementFlags & MOVEMENTFLAG_SWIMMING) != 0) != plr->IsInWater())
- {
- // Now client not include swimming flag in case jumping under water
- plr->SetInWater( !plr->IsInWater() || plr->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) );
- }
-
- plr->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o, false);
- plr->m_movementInfo = movementInfo;
-
- if(plr->isMovingOrTurning())
- plr->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ if(plMover->isMovingOrTurning())
+ plMover->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
if(movementInfo.z < -500.0f)
{
- GetPlayer()->Uncharm();
- plr->HandleFallUnderMap();
+ if(plMover->InBattleGround()
+ && plMover->GetBattleGround()
+ && plMover->GetBattleGround()->HandlePlayerUnderMap(_player))
+ {
+ // do nothing, the handle already did if returned true
+ }
+ else
+ {
+ // NOTE: this is actually called many times while falling
+ // even after the player has been teleported away
+ // TODO: discard movement packets after the player is rooted
+ if(plMover->isAlive())
+ {
+ plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
+ // pl can be alive if GM/etc
+ if(!plMover->isAlive())
+ {
+ // change the death state to CORPSE to prevent the death timer from
+ // starting in the next player update
+ plMover->KillPlayer();
+ plMover->BuildPlayerRepop();
+ }
+ }
+
+ // cancel the death timer here if started
+ plMover->RepopAtGraveyard();
+ }
}
}
- else // Possessed unit is a creature
+ else // creature charmed
{
- Map* map = MapManager::Instance().GetMap(pos_unit->GetMapId(), pos_unit);
- map->CreatureRelocation((Creature*)pos_unit, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
+ if(Map *map = mover->GetMap())
+ {
+ map->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
+ }
+ mover->SetUnitMovementFlags(movementInfo.flags);
}
}
void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
{
- CHECK_PACKET_SIZE(recv_data, 8+4+4+1+4+4+4+4+4);
+ //sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(recv_data.GetOpcode()), recv_data.GetOpcode(), recv_data.GetOpcode());
+
+ CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4);
/* extract packet */
uint64 guid;
- uint8 unkB;
- uint32 unk1, flags, time, fallTime;
- float x, y, z, orientation;
-
- uint64 t_GUID;
- float t_x, t_y, t_z, t_o;
- uint32 t_time;
- float s_pitch;
- float j_unk1, j_sinAngle, j_cosAngle, j_xyspeed;
- float u_unk1;
+ uint32 unk1;
float newspeed;
recv_data >> guid;
@@ -420,47 +367,10 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
// continue parse packet
- recv_data >> unk1;
- recv_data >> flags >> unkB >> time;
- recv_data >> x >> y >> z >> orientation;
- if (flags & MOVEMENTFLAG_ONTRANSPORT)
- {
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4+4+4+4+4);
-
- recv_data >> t_GUID;
- recv_data >> t_x >> t_y >> t_z >> t_o >> t_time;
- }
- if (flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2))
- {
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
-
- recv_data >> s_pitch; // pitch, -1.55=looking down, 0=looking straight forward, +1.55=looking up
- }
+ recv_data >> unk1; // counter or moveEvent
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
-
- recv_data >> fallTime; // duration of last jump (when in jump duration from jump begin to now)
-
- if ((flags & MOVEMENTFLAG_JUMPING) || (flags & MOVEMENTFLAG_FALLING))
- {
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4+4+4);
-
- recv_data >> j_unk1; // ?constant, but different when jumping in water and on land?
- recv_data >> j_sinAngle >> j_cosAngle; // sin + cos of angle between orientation0 and players orientation
- recv_data >> j_xyspeed; // speed of xy movement
- }
-
- if(flags & MOVEMENTFLAG_SPLINE)
- {
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
-
- recv_data >> u_unk1; // unknown
- }
+ MovementInfo movementInfo;
+ ReadMovementInfo(recv_data, &movementInfo);
// recheck
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
@@ -473,7 +383,7 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
UnitMoveType move_type;
UnitMoveType force_move_type;
- static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack" };
+ static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack", "PitchRate" };
uint16 opcode = recv_data.GetOpcode();
switch(opcode)
@@ -486,6 +396,7 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
case CMSG_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN_RATE; force_move_type = MOVE_TURN_RATE; break;
case CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT; force_move_type = MOVE_FLIGHT; break;
case CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT_BACK; force_move_type = MOVE_FLIGHT_BACK; break;
+ case CMSG_FORCE_PITCH_RATE_CHANGE_ACK: move_type = MOVE_PITCH_RATE; force_move_type = MOVE_PITCH_RATE; break;
default:
sLog.outError("WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: %u", opcode);
return;
@@ -521,19 +432,100 @@ void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: Recvd CMSG_SET_ACTIVE_MOVER");
- CHECK_PACKET_SIZE(recv_data,8);
+ CHECK_PACKET_SIZE(recv_data, 8);
uint64 guid;
recv_data >> guid;
- WorldPacket data(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement
- data << uint32(0x00000000); // on blizz it increments periodically
- SendPacket(&data);
+ if(guid == GetPlayer()->m_mover->GetGUID())
+ return;
+
+ if(Unit *mover = ObjectAccessor::GetUnit(*GetPlayer(), guid))
+ GetPlayer()->SetMover(mover);
+ else
+ {
+ sLog.outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is " I64FMT " and should be " I64FMT, guid, _player->m_mover->GetGUID());
+ GetPlayer()->SetMover(GetPlayer());
+ }
}
-void WorldSession::HandleNotActiveMoverOpcode(WorldPacket& /*recv_data*/)
+void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER");
+
+ CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8);
+
+ uint64 old_mover_guid;
+ recv_data >> old_mover_guid;
+
+ /*if(_player->m_mover->GetGUID() == old_mover_guid)
+ {
+ sLog.outError("HandleMoveNotActiveMover: incorrect mover guid: mover is " I64FMT " and should be " I64FMT " instead of " I64FMT, _player->m_mover->GetGUID(), _player->GetGUID(), old_mover_guid);
+ return;
+ }*/
+
+ MovementInfo mi;
+ ReadMovementInfo(recv_data, &mi);
+ _player->m_movementInfo = mi;
+}
+
+void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: Recvd CMSG_DISMISS_CONTROLLED_VEHICLE");
+ recv_data.hexlike();
+
+ uint64 vehicleGUID = _player->GetCharmGUID();
+
+ if(!vehicleGUID) // something wrong here...
+ return;
+
+ MovementInfo mi;
+ ReadMovementInfo(recv_data, &mi);
+ _player->m_movementInfo = mi;
+ _player->ExitVehicle();
+}
+
+void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: Recvd CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE");
+ recv_data.hexlike();
+
+ if(!GetPlayer()->m_Vehicle)
+ return;
+
+ if(recv_data.GetOpcode() == CMSG_REQUEST_VEHICLE_PREV_SEAT)
+ {
+ GetPlayer()->ChangeSeat(-1, false);
+ return;
+ }
+ else if(recv_data.GetOpcode() == CMSG_REQUEST_VEHICLE_NEXT_SEAT)
+ {
+ GetPlayer()->ChangeSeat(-1, true);
+ return;
+ }
+ else if(recv_data.GetOpcode() == CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE)
+ ReadMovementInfo(recv_data, &GetPlayer()->m_Vehicle->m_movementInfo);
+
+ CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1);
+ uint64 guid;
+ if(!recv_data.readPackGUID(guid))
+ return;
+
+ CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1);
+ int8 seatId;
+ recv_data >> seatId;
+
+ if(!guid)
+ GetPlayer()->ChangeSeat(-1, seatId > 0);
+ else if(Vehicle *vehicle = ObjectAccessor::GetVehicle(guid))
+ GetPlayer()->EnterVehicle(vehicle, seatId);
+}
+
+void WorldSession::HandleRequestVehicleExit(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: Recvd CMSG_REQUEST_VEHICLE_EXIT");
+ recv_data.hexlike();
+ GetPlayer()->ExitVehicle();
}
void WorldSession::HandleMountSpecialAnimOpcode(WorldPacket& /*recvdata*/)
diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp
index df027a48acd..7d2985c0643 100644
--- a/src/game/NPCHandler.cpp
+++ b/src/game/NPCHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -25,17 +25,14 @@
#include "WorldSession.h"
#include "Opcodes.h"
#include "Log.h"
-#include "World.h"
#include "ObjectMgr.h"
#include "SpellMgr.h"
#include "Player.h"
#include "GossipDef.h"
-#include "SpellAuras.h"
#include "UpdateMask.h"
#include "ScriptCalls.h"
#include "ObjectAccessor.h"
#include "Creature.h"
-#include "MapManager.h"
#include "Pet.h"
#include "BattleGroundMgr.h"
#include "BattleGround.h"
@@ -48,7 +45,7 @@ void WorldSession::HandleTabardVendorActivateOpcode( WorldPacket & recv_data )
uint64 guid;
recv_data >> guid;
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_TABARDDESIGNER);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_TABARDDESIGNER);
if (!unit)
{
sLog.outDebug( "WORLD: HandleTabardVendorActivateOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
@@ -57,7 +54,7 @@ void WorldSession::HandleTabardVendorActivateOpcode( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
SendTabardVendorActivate(guid);
}
@@ -79,7 +76,7 @@ void WorldSession::HandleBankerActivateOpcode( WorldPacket & recv_data )
recv_data >> guid;
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_BANKER);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_BANKER);
if (!unit)
{
sLog.outDebug( "WORLD: HandleBankerActivateOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
@@ -88,7 +85,7 @@ void WorldSession::HandleBankerActivateOpcode( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
SendShowBank(guid);
}
@@ -120,7 +117,7 @@ void WorldSession::SendTrainerList( uint64 guid, const std::string& strTitle )
{
sLog.outDebug( "WORLD: SendTrainerList" );
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_TRAINER);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_TRAINER);
if (!unit)
{
sLog.outDebug( "WORLD: SendTrainerList - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
@@ -129,7 +126,7 @@ void WorldSession::SendTrainerList( uint64 guid, const std::string& strTitle )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
// trainer list loaded at check;
if(!unit->isCanTrainingOf(_player,true))
@@ -162,29 +159,29 @@ void WorldSession::SendTrainerList( uint64 guid, const std::string& strTitle )
float fDiscountMod = _player->GetReputationPriceDiscount(unit);
uint32 count = 0;
- for(TrainerSpellList::const_iterator itr = trainer_spells->spellList.begin(); itr != trainer_spells->spellList.end(); ++itr)
+ for(TrainerSpellMap::const_iterator itr = trainer_spells->spellList.begin(); itr != trainer_spells->spellList.end(); ++itr)
{
- TrainerSpell const* tSpell = *itr;
+ TrainerSpell const* tSpell = &itr->second;
- if(!_player->IsSpellFitByClassAndRace(tSpell->spell))
+ if(!_player->IsSpellFitByClassAndRace(tSpell->learnedSpell))
continue;
++count;
- bool primary_prof_first_rank = spellmgr.IsPrimaryProfessionFirstRankSpell(tSpell->spell);
+ bool primary_prof_first_rank = spellmgr.IsPrimaryProfessionFirstRankSpell(tSpell->learnedSpell);
- SpellChainNode const* chain_node = spellmgr.GetSpellChainNode(tSpell->spell);
+ SpellChainNode const* chain_node = spellmgr.GetSpellChainNode(tSpell->learnedSpell);
uint32 req_spell = spellmgr.GetSpellRequired(tSpell->spell);
- data << uint32(tSpell->spell);
+ data << uint32(tSpell->spell); // learned spell (or cast-spell in profession case)
data << uint8(_player->GetTrainerSpellState(tSpell));
- data << uint32(floor(tSpell->spellcost * fDiscountMod));
+ data << uint32(floor(tSpell->spellCost * fDiscountMod));
data << uint32(primary_prof_first_rank ? 1 : 0); // primary prof. learn confirmation dialog
data << uint32(primary_prof_first_rank ? 1 : 0); // must be equal prev. field to have learn button in enabled state
- data << uint8(tSpell->reqlevel);
- data << uint32(tSpell->reqskill);
- data << uint32(tSpell->reqskillvalue);
+ data << uint8(tSpell->reqLevel);
+ data << uint32(tSpell->reqSkill);
+ data << uint32(tSpell->reqSkillValue);
data << uint32(chain_node && chain_node->prev ? chain_node->prev : req_spell);
data << uint32(chain_node && chain_node->prev ? req_spell : 0);
data << uint32(0);
@@ -206,7 +203,7 @@ void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket & recv_data )
recv_data >> guid >> spellId;
sLog.outDebug( "WORLD: Received CMSG_TRAINER_BUY_SPELL NpcGUID=%u, learn spell id is: %u",uint32(GUID_LOPART(guid)), spellId );
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_TRAINER);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_TRAINER);
if (!unit)
{
sLog.outDebug( "WORLD: HandleTrainerBuySpellOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
@@ -215,7 +212,7 @@ void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
if(!unit->isCanTrainingOf(_player,true))
return;
@@ -235,12 +232,14 @@ void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket & recv_data )
return;
// apply reputation discount
- uint32 nSpellCost = uint32(floor(trainer_spell->spellcost * _player->GetReputationPriceDiscount(unit)));
+ uint32 nSpellCost = uint32(floor(trainer_spell->spellCost * _player->GetReputationPriceDiscount(unit)));
// check money requirement
if(_player->GetMoney() < nSpellCost )
return;
+ _player->ModifyMoney( -int32(nSpellCost) );
+
WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 12); // visual effect on trainer
data << uint64(guid) << uint32(0xB3);
SendPacket(&data);
@@ -249,13 +248,15 @@ void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket & recv_data )
data << uint64(_player->GetGUID()) << uint32(0x016A);
SendPacket(&data);
- _player->ModifyMoney( -int32(nSpellCost) );
-
- // learn explicitly to prevent lost money at lags, learning spell will be only show spell animation
- _player->learnSpell(trainer_spell->spell);
+ // learn explicitly or cast explicitly
+ if(trainer_spell->IsCastable ())
+ //FIXME: prof. spell entry in trainer list not marked gray until list re-open.
+ _player->CastSpell(_player,trainer_spell->spell,true);
+ else
+ _player->learnSpell(spellId,false);
data.Initialize(SMSG_TRAINER_BUY_SUCCEEDED, 12);
- data << uint64(guid) << uint32(spellId);
+ data << uint64(guid) << uint32(trainer_spell->spell);
SendPacket(&data);
}
@@ -268,7 +269,7 @@ void WorldSession::HandleGossipHelloOpcode( WorldPacket & recv_data )
uint64 guid;
recv_data >> guid;
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_NONE);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
if (!unit)
{
sLog.outDebug( "WORLD: HandleGossipHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
@@ -278,7 +279,7 @@ void WorldSession::HandleGossipHelloOpcode( WorldPacket & recv_data )
GetPlayer()->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK);
// remove fake death
//if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- // GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ // GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
if( unit->isArmorer() || unit->isCivilian() || unit->isQuestGiver() || unit->isServiceProvider())
{
@@ -327,7 +328,7 @@ void WorldSession::HandleGossipHelloOpcode( WorldPacket & recv_data )
sLog.outDebug("string read: %s", code.c_str());
}
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_NONE);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
if (!unit)
{
sLog.outDebug( "WORLD: HandleGossipSelectOptionOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
@@ -336,7 +337,7 @@ void WorldSession::HandleGossipHelloOpcode( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
if(!code.empty())
{
@@ -360,7 +361,7 @@ void WorldSession::HandleSpiritHealerActivateOpcode( WorldPacket & recv_data )
recv_data >> guid;
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_SPIRITHEALER);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_SPIRITHEALER);
if (!unit)
{
sLog.outDebug( "WORLD: HandleSpiritHealerActivateOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
@@ -369,7 +370,7 @@ void WorldSession::HandleSpiritHealerActivateOpcode( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
SendSpiritResurrect();
}
@@ -421,7 +422,7 @@ void WorldSession::HandleBinderActivateOpcode( WorldPacket & recv_data )
if(!GetPlayer()->isAlive())
return;
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, npcGUID,UNIT_NPC_FLAG_INNKEEPER);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(npcGUID,UNIT_NPC_FLAG_INNKEEPER);
if (!unit)
{
sLog.outDebug( "WORLD: HandleBinderActivateOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID)) );
@@ -430,7 +431,7 @@ void WorldSession::HandleBinderActivateOpcode( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
SendBindPoint(unit);
}
@@ -438,11 +439,12 @@ void WorldSession::HandleBinderActivateOpcode( WorldPacket & recv_data )
void WorldSession::SendBindPoint(Creature *npc)
{
uint32 bindspell = 3286;
+ uint32 zone_id = _player->GetZoneId();
// update sql homebind
- CharacterDatabase.PExecute("UPDATE character_homebind SET map = '%u', zone = '%u', position_x = '%f', position_y = '%f', position_z = '%f' WHERE guid = '%u'", _player->GetMapId(), _player->GetZoneId(), _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetGUIDLow());
+ CharacterDatabase.PExecute("UPDATE character_homebind SET map = '%u', zone = '%u', position_x = '%f', position_y = '%f', position_z = '%f' WHERE guid = '%u'", _player->GetMapId(), zone_id, _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetGUIDLow());
_player->m_homebindMapId = _player->GetMapId();
- _player->m_homebindZoneId = _player->GetZoneId();
+ _player->m_homebindZoneId = zone_id;
_player->m_homebindX = _player->GetPositionX();
_player->m_homebindY = _player->GetPositionY();
_player->m_homebindZ = _player->GetPositionZ();
@@ -461,25 +463,24 @@ void WorldSession::SendBindPoint(Creature *npc)
data << float(_player->GetPositionY());
data << float(_player->GetPositionZ());
data << uint32(_player->GetMapId());
- data << uint32(_player->GetZoneId());
+ data << uint32(zone_id);
SendPacket( &data );
DEBUG_LOG("New Home Position X is %f",_player->GetPositionX());
DEBUG_LOG("New Home Position Y is %f",_player->GetPositionY());
DEBUG_LOG("New Home Position Z is %f",_player->GetPositionZ());
DEBUG_LOG("New Home MapId is %u",_player->GetMapId());
- DEBUG_LOG("New Home ZoneId is %u",_player->GetZoneId());
+ DEBUG_LOG("New Home ZoneId is %u",zone_id);
// zone update
data.Initialize( SMSG_PLAYERBOUND, 8+4 );
data << uint64(_player->GetGUID());
- data << uint32(_player->GetZoneId());
+ data << uint32(zone_id);
SendPacket( &data );
_player->PlayerTalkClass->CloseGossip();
}
-//Need fix
void WorldSession::HandleListStabledPetsOpcode( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data,8);
@@ -489,7 +490,7 @@ void WorldSession::HandleListStabledPetsOpcode( WorldPacket & recv_data )
recv_data >> npcGUID;
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, npcGUID, UNIT_NPC_FLAG_STABLEMASTER);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(npcGUID, UNIT_NPC_FLAG_STABLEMASTER);
if (!unit)
{
sLog.outDebug( "WORLD: HandleListStabledPetsOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID)) );
@@ -498,11 +499,11 @@ void WorldSession::HandleListStabledPetsOpcode( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
// remove mounts this fix bug where getting pet from stable while mounted deletes pet.
if(GetPlayer()->IsMounted())
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_MOUNTED);
SendStablePet(npcGUID);
}
@@ -516,7 +517,9 @@ void WorldSession::SendStablePet(uint64 guid )
Pet *pet = _player->GetPet();
+ size_t wpos = data.wpos();
data << uint8(0); // place holder for slot show number
+
data << uint8(GetPlayer()->m_stableSlots);
uint8 num = 0; // counter for place holder
@@ -528,13 +531,13 @@ void WorldSession::SendStablePet(uint64 guid )
data << uint32(pet->GetEntry());
data << uint32(pet->getLevel());
data << pet->GetName(); // petname
- data << uint32(pet->GetLoyaltyLevel()); // loyalty
- data << uint8(0x01); // client slot 1 == current pet (0)
+ data << uint8(1); // 1 = current, 2/3 = in stable (any from 4,5,... create problems with proper show)
++num;
}
- // 0 1 2 3 4 5 6
- QueryResult* result = CharacterDatabase.PQuery("SELECT owner, slot, id, entry, level, loyalty, name FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 3",_player->GetGUIDLow());
+ // 0 1 2 3 4
+ QueryResult* result = CharacterDatabase.PQuery("SELECT owner, id, entry, level, name FROM character_pet WHERE owner = '%u' AND slot >= '%u' AND slot <= '%u' ORDER BY slot",
+ _player->GetGUIDLow(),PET_SAVE_FIRST_STABLE_SLOT,PET_SAVE_LAST_STABLE_SLOT);
if(result)
{
@@ -542,12 +545,11 @@ void WorldSession::SendStablePet(uint64 guid )
{
Field *fields = result->Fetch();
- data << uint32(fields[2].GetUInt32()); // petnumber
- data << uint32(fields[3].GetUInt32()); // creature entry
- data << uint32(fields[4].GetUInt32()); // level
- data << fields[6].GetString(); // name
- data << uint32(fields[5].GetUInt32()); // loyalty
- data << uint8(fields[1].GetUInt32()+1); // slot
+ data << uint32(fields[1].GetUInt32()); // petnumber
+ data << uint32(fields[2].GetUInt32()); // creature entry
+ data << uint32(fields[3].GetUInt32()); // level
+ data << fields[4].GetString(); // name
+ data << uint8(2); // 1 = current, 2/3 = in stable (any from 4,5,... create problems with proper show)
++num;
}while( result->NextRow() );
@@ -555,7 +557,7 @@ void WorldSession::SendStablePet(uint64 guid )
delete result;
}
- data.put<uint8>(8, num); // set real data to placeholder
+ data.put<uint8>(wpos, num); // set real data to placeholder
SendPacket(&data);
}
@@ -571,7 +573,7 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data )
if(!GetPlayer()->isAlive())
return;
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, npcGUID, UNIT_NPC_FLAG_STABLEMASTER);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(npcGUID, UNIT_NPC_FLAG_STABLEMASTER);
if (!unit)
{
sLog.outDebug( "WORLD: HandleStablePet - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID)) );
@@ -580,7 +582,7 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
Pet *pet = _player->GetPet();
@@ -596,7 +598,8 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data )
uint32 free_slot = 1;
- QueryResult *result = CharacterDatabase.PQuery("SELECT owner,slot,id FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 3 ORDER BY slot ",_player->GetGUIDLow());
+ QueryResult *result = CharacterDatabase.PQuery("SELECT owner,slot,id FROM character_pet WHERE owner = '%u' AND slot >= '%u' AND slot <= '%u' ORDER BY slot ",
+ _player->GetGUIDLow(),PET_SAVE_FIRST_STABLE_SLOT,PET_SAVE_LAST_STABLE_SLOT);
if(result)
{
do
@@ -605,11 +608,16 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data )
uint32 slot = fields[1].GetUInt32();
- if(slot==free_slot) // this slot not free
- ++free_slot;
+ // slots ordered in query, and if not equal then free
+ if(slot!=free_slot)
+ break;
+
+ // this slot not free, skip
+ ++free_slot;
}while( result->NextRow() );
+
+ delete result;
}
- delete result;
if( free_slot > 0 && free_slot <= GetPlayer()->m_stableSlots)
{
@@ -632,7 +640,7 @@ void WorldSession::HandleUnstablePet( WorldPacket & recv_data )
recv_data >> npcGUID >> petnumber;
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, npcGUID, UNIT_NPC_FLAG_STABLEMASTER);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(npcGUID, UNIT_NPC_FLAG_STABLEMASTER);
if (!unit)
{
sLog.outDebug( "WORLD: HandleUnstablePet - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID)) );
@@ -641,15 +649,14 @@ void WorldSession::HandleUnstablePet( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
WorldPacket data(SMSG_STABLE_RESULT, 200); // guess size
Pet* pet = _player->GetPet();
if(pet && pet->isAlive())
{
- uint8 i = 0x06;
- data << uint8(i);
+ data << uint8(0x06);
SendPacket(&data);
return;
}
@@ -660,13 +667,14 @@ void WorldSession::HandleUnstablePet( WorldPacket & recv_data )
Pet *newpet = NULL;
- QueryResult *result = CharacterDatabase.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot > 0 AND slot < 3",_player->GetGUIDLow(),petnumber);
+ QueryResult *result = CharacterDatabase.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot >='%u' AND slot <= '%u'",
+ _player->GetGUIDLow(),petnumber,PET_SAVE_FIRST_STABLE_SLOT,PET_SAVE_LAST_STABLE_SLOT);
if(result)
{
Field *fields = result->Fetch();
uint32 petentry = fields[0].GetUInt32();
- newpet = new Pet(HUNTER_PET);
+ newpet = new Pet(_player, HUNTER_PET);
if(!newpet->LoadPetFromDB(_player,petentry,petnumber))
{
delete newpet;
@@ -691,7 +699,7 @@ void WorldSession::HandleBuyStableSlot( WorldPacket & recv_data )
recv_data >> npcGUID;
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, npcGUID, UNIT_NPC_FLAG_STABLEMASTER);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(npcGUID, UNIT_NPC_FLAG_STABLEMASTER);
if (!unit)
{
sLog.outDebug( "WORLD: HandleBuyStableSlot - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID)) );
@@ -700,11 +708,11 @@ void WorldSession::HandleBuyStableSlot( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
WorldPacket data(SMSG_STABLE_RESULT, 200);
- if(GetPlayer()->m_stableSlots < 2) // max slots amount = 2
+ if(GetPlayer()->m_stableSlots < MAX_PET_STABLES)
{
StableSlotPricesEntry const *SlotPrice = sStableSlotPricesStore.LookupEntry(GetPlayer()->m_stableSlots+1);
if(_player->GetMoney() >= SlotPrice->Price)
@@ -737,7 +745,7 @@ void WorldSession::HandleStableSwapPet( WorldPacket & recv_data )
recv_data >> npcGUID >> pet_number;
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, npcGUID, UNIT_NPC_FLAG_STABLEMASTER);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(npcGUID, UNIT_NPC_FLAG_STABLEMASTER);
if (!unit)
{
sLog.outDebug( "WORLD: HandleStableSwapPet - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID)) );
@@ -746,7 +754,7 @@ void WorldSession::HandleStableSwapPet( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
WorldPacket data(SMSG_STABLE_RESULT, 200); // guess size
@@ -756,7 +764,8 @@ void WorldSession::HandleStableSwapPet( WorldPacket & recv_data )
return;
// find swapped pet slot in stable
- QueryResult *result = CharacterDatabase.PQuery("SELECT slot,entry FROM character_pet WHERE owner = '%u' AND id = '%u'",_player->GetGUIDLow(),pet_number);
+ QueryResult *result = CharacterDatabase.PQuery("SELECT slot,entry FROM character_pet WHERE owner = '%u' AND id = '%u'",
+ _player->GetGUIDLow(),pet_number);
if(!result)
return;
@@ -766,11 +775,11 @@ void WorldSession::HandleStableSwapPet( WorldPacket & recv_data )
uint32 petentry = fields[1].GetUInt32();
delete result;
- // move alive pet to slot or delele dead pet
+ // move alive pet to slot or delete dead pet
_player->RemovePet(pet,pet->isAlive() ? PetSaveMode(slot) : PET_SAVE_AS_DELETED);
// summon unstabled pet
- Pet *newpet = new Pet;
+ Pet *newpet = new Pet(_player);
if(!newpet->LoadPetFromDB(_player,petentry,pet_number))
{
delete newpet;
@@ -793,7 +802,7 @@ void WorldSession::HandleRepairItemOpcode( WorldPacket & recv_data )
recv_data >> npcGUID >> itemGUID >> guildBank;
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, npcGUID, UNIT_NPC_FLAG_REPAIR);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(npcGUID, UNIT_NPC_FLAG_REPAIR);
if (!unit)
{
sLog.outDebug( "WORLD: HandleRepairItemOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID)) );
@@ -802,7 +811,7 @@ void WorldSession::HandleRepairItemOpcode( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
// reputation discount
float discountMod = _player->GetReputationPriceDiscount(unit);
diff --git a/src/game/NPCHandler.h b/src/game/NPCHandler.h
index e359878173f..4d0395a0c87 100644
--- a/src/game/NPCHandler.h
+++ b/src/game/NPCHandler.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -60,7 +60,6 @@ struct GossipTextOption
struct GossipText
{
- uint32 Text_ID;
GossipTextOption Options[8];
};
diff --git a/src/game/NullCreatureAI.cpp b/src/game/NullCreatureAI.cpp
index 8bea03d0216..be59ed6e40d 100644
--- a/src/game/NullCreatureAI.cpp
+++ b/src/game/NullCreatureAI.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/NullCreatureAI.h b/src/game/NullCreatureAI.h
index d20d727690a..d5c12d8c9a0 100644
--- a/src/game/NullCreatureAI.h
+++ b/src/game/NullCreatureAI.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -26,7 +26,7 @@
class TRINITY_DLL_DECL PassiveAI : public CreatureAI
{
public:
- PassiveAI(Creature *c) : CreatureAI(c) {}
+ explicit PassiveAI(Creature *c) : CreatureAI(c) {}
~PassiveAI() {}
void MoveInLineOfSight(Unit *) {}
@@ -39,7 +39,7 @@ class TRINITY_DLL_DECL PassiveAI : public CreatureAI
class TRINITY_DLL_DECL PossessedAI : public PassiveAI
{
public:
- PossessedAI(Creature *c) : PassiveAI(c) {}
+ explicit PossessedAI(Creature *c) : PassiveAI(c) {}
void AttackStart(Unit *target);
void UpdateAI(const uint32);
@@ -52,7 +52,7 @@ class TRINITY_DLL_DECL PossessedAI : public PassiveAI
class TRINITY_DLL_DECL NullCreatureAI : public PassiveAI
{
public:
- NullCreatureAI(Creature *c) : PassiveAI(c) {}
+ explicit NullCreatureAI(Creature *c) : PassiveAI(c) {}
void UpdateAI(const uint32) {}
void EnterEvadeMode() {}
@@ -61,7 +61,7 @@ class TRINITY_DLL_DECL NullCreatureAI : public PassiveAI
class TRINITY_DLL_DECL CritterAI : public PassiveAI
{
public:
- CritterAI(Creature *c) : PassiveAI(c) {}
+ explicit CritterAI(Creature *c) : PassiveAI(c) {}
void DamageTaken(Unit *done_by, uint32 & /*damage*/);
void EnterEvadeMode();
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index fe3239e9d6b..eb7ce37734d 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -27,8 +27,8 @@
#include "Object.h"
#include "Creature.h"
#include "Player.h"
+#include "Vehicle.h"
#include "ObjectMgr.h"
-#include "WorldSession.h"
#include "UpdateData.h"
#include "UpdateMask.h"
#include "Util.h"
@@ -44,6 +44,7 @@
#include "GridNotifiersImpl.h"
#include "TemporarySummon.h"
+#include "Totem.h"
uint32 GuidHigh2TypeId(uint32 guid_hi)
{
@@ -58,8 +59,9 @@ uint32 GuidHigh2TypeId(uint32 guid_hi)
case HIGHGUID_DYNAMICOBJECT:return TYPEID_DYNAMICOBJECT;
case HIGHGUID_CORPSE: return TYPEID_CORPSE;
case HIGHGUID_MO_TRANSPORT: return TYPEID_GAMEOBJECT;
+ case HIGHGUID_VEHICLE: return TYPEID_UNIT;
}
- return 10; // unknown
+ return MAX_TYPEID; // unknown
}
Object::Object( )
@@ -83,17 +85,16 @@ Object::~Object( )
//if(m_objectUpdated)
// ObjectAccessor::Instance().RemoveUpdateObject(this);
- if(m_uint32Values)
+ if(IsInWorld())
{
- if(IsInWorld())
- {
- ///- Do NOT call RemoveFromWorld here, if the object is a player it will crash
- sLog.outError("Object::~Object - guid="I64FMTD", typeid=%d deleted but still in world!!", GetGUID(), GetTypeId());
- assert(false);
- }
+ sLog.outCrash("Object::~Object - guid="I64FMTD", typeid=%d deleted but still in world!!", GetGUID(), GetTypeId());
+ assert(false);
+ }
- assert(!m_objectUpdated);
+ assert(!m_objectUpdated);
+ if(m_uint32Values)
+ {
//DEBUG_LOG("Object desctr 1 check (%p)",(void*)this);
delete [] m_uint32Values;
delete [] m_uint32Values_mirror;
@@ -132,7 +133,7 @@ void Object::BuildMovementUpdateBlock(UpdateData * data, uint32 flags ) const
buf << uint8( UPDATETYPE_MOVEMENT );
buf << GetGUID();
- _BuildMovementUpdate(&buf, flags, 0x00000000);
+ _BuildMovementUpdate(&buf, flags);
data->AddUpdateBlock(buf);
}
@@ -146,13 +147,12 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c
uint8 updatetype = UPDATETYPE_CREATE_OBJECT;
uint8 flags = m_updateFlag;
- uint32 flags2 = 0;
/** lower flag1 **/
if(target == this) // building packet for oneself
flags |= UPDATEFLAG_SELF;
- if(flags & UPDATEFLAG_HASPOSITION)
+ if(flags & UPDATEFLAG_HAS_POSITION)
{
// UPDATETYPE_CREATE_OBJECT2 dynamic objects, corpses...
if(isType(TYPEMASK_DYNAMICOBJECT) || isType(TYPEMASK_CORPSE) || isType(TYPEMASK_PLAYER))
@@ -178,6 +178,12 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c
break;
}
}
+
+ if(isType(TYPEMASK_UNIT))
+ {
+ if(((Unit*)this)->getVictim())
+ flags |= UPDATEFLAG_HAS_TARGET;
+ }
}
//sLog.outDebug("BuildCreateUpdate: update-type: %u, object-type: %u got flags: %X, flags2: %X", updatetype, m_objectTypeId, flags, flags2);
@@ -188,7 +194,7 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c
buf << (uint8)0xFF << GetGUID();
buf << (uint8)m_objectTypeId;
- _BuildMovementUpdate(&buf, flags, flags2);
+ _BuildMovementUpdate(&buf, flags);
UpdateMask updateMask;
updateMask.SetCount( m_valuesCount );
@@ -248,34 +254,29 @@ void Object::DestroyForPlayer(Player *target) const
WorldPacket data(SMSG_DESTROY_OBJECT, 8);
data << GetGUID();
+ data << uint8(0); // WotLK (bool)
target->GetSession()->SendPacket( &data );
}
-void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2 ) const
+void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags) const
{
*data << (uint8)flags; // update flags
// 0x20
if (flags & UPDATEFLAG_LIVING)
{
+ uint32 flags2 = ((Unit*)this)->GetUnitMovementFlags();
switch(GetTypeId())
{
case TYPEID_UNIT:
{
- flags2 = ((Unit*)this)->GetUnitMovementFlags();
- flags2 &= ~MOVEMENTFLAG_ONTRANSPORT;
flags2 &= ~MOVEMENTFLAG_SPLINE2;
+ if(((Creature*)this)->isVehicle())
+ ((Unit*)this)->m_movementInfo.unk1 |= 0x20; // always allow pitch
}
break;
case TYPEID_PLAYER:
{
- flags2 = ((Player*)this)->GetUnitMovementFlags();
-
- if(((Player*)this)->GetTransport())
- flags2 |= MOVEMENTFLAG_ONTRANSPORT;
- else
- flags2 &= ~MOVEMENTFLAG_ONTRANSPORT;
-
// remove unknown, unused etc flags for now
flags2 &= ~MOVEMENTFLAG_SPLINE2; // will be set manually
@@ -289,12 +290,12 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
}
*data << uint32(flags2); // movement flags
- *data << uint8(0); // unk 2.3.0
+ *data << uint16(((Unit*)this)->m_movementInfo.unk1);// unknown 2.3.0
*data << uint32(getMSTime()); // time (in milliseconds)
}
// 0x40
- if (flags & UPDATEFLAG_HASPOSITION)
+ if (flags & UPDATEFLAG_HAS_POSITION)
{
// 0x02
if(flags & UPDATEFLAG_TRANSPORT && ((GameObject*)this)->GetGoType() == GAMEOBJECT_TYPE_MO_TRANSPORT)
@@ -316,62 +317,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
// 0x20
if(flags & UPDATEFLAG_LIVING)
{
- // 0x00000200
- if(flags2 & MOVEMENTFLAG_ONTRANSPORT)
- {
- if(GetTypeId() == TYPEID_PLAYER)
- {
- *data << (uint64)((Player*)this)->GetTransport()->GetGUID();
- *data << (float)((Player*)this)->GetTransOffsetX();
- *data << (float)((Player*)this)->GetTransOffsetY();
- *data << (float)((Player*)this)->GetTransOffsetZ();
- *data << (float)((Player*)this)->GetTransOffsetO();
- *data << (uint32)((Player*)this)->GetTransTime();
- }
- //TrinIty currently not have support for other than player on transport
- }
-
- // 0x02200000
- if(flags2 & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2))
- {
- if(GetTypeId() == TYPEID_PLAYER)
- *data << (float)((Player*)this)->m_movementInfo.s_pitch;
- else
- *data << (float)0; // is't part of movement packet, we must store and send it...
- }
-
- if(GetTypeId() == TYPEID_PLAYER)
- *data << (uint32)((Player*)this)->m_movementInfo.fallTime;
- else
- *data << (uint32)0; // last fall time
-
- // 0x00001000
- if(flags2 & MOVEMENTFLAG_JUMPING)
- {
- if(GetTypeId() == TYPEID_PLAYER)
- {
- *data << (float)((Player*)this)->m_movementInfo.j_unk;
- *data << (float)((Player*)this)->m_movementInfo.j_sinAngle;
- *data << (float)((Player*)this)->m_movementInfo.j_cosAngle;
- *data << (float)((Player*)this)->m_movementInfo.j_xyspeed;
- }
- else
- {
- *data << (float)0;
- *data << (float)0;
- *data << (float)0;
- *data << (float)0;
- }
- }
-
- // 0x04000000
- if(flags2 & MOVEMENTFLAG_SPLINE)
- {
- if(GetTypeId() == TYPEID_PLAYER)
- *data << (float)((Player*)this)->m_movementInfo.u_unk1;
- else
- *data << (float)0;
- }
+ ((Unit*)this)->BuildMovementPacket(data);
*data << ((Unit*)this)->GetSpeed( MOVE_WALK );
*data << ((Unit*)this)->GetSpeed( MOVE_RUN );
@@ -381,22 +327,11 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
*data << ((Unit*)this)->GetSpeed( MOVE_FLIGHT );
*data << ((Unit*)this)->GetSpeed( MOVE_FLIGHT_BACK );
*data << ((Unit*)this)->GetSpeed( MOVE_TURN_RATE );
+ *data << ((Unit*)this)->GetSpeed( MOVE_PITCH_RATE );
// 0x08000000
- if(flags2 & MOVEMENTFLAG_SPLINE2)
+ if(GetTypeId() == TYPEID_PLAYER && ((Player*)this)->isInFlight())
{
- if(GetTypeId() != TYPEID_PLAYER)
- {
- sLog.outDebug("_BuildMovementUpdate: MOVEMENTFLAG_SPLINE2 for non-player");
- return;
- }
-
- if(!((Player*)this)->isInFlight())
- {
- sLog.outDebug("_BuildMovementUpdate: MOVEMENTFLAG_SPLINE2 but not in flight");
- return;
- }
-
WPAssert(((Player*)this)->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE);
FlightPathMovementGenerator *fmg = (FlightPathMovementGenerator*)(((Player*)this)->GetMotionMaster()->top());
@@ -445,6 +380,8 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
*data << path.GetNodes()[i].z;
}
+ *data << uint8(0); // added in 3.0.8
+
/*for(uint32 i = 0; i < poscount; i++)
{
// path points
@@ -482,7 +419,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
break;
case TYPEID_PLAYER:
if(flags & UPDATEFLAG_SELF)
- *data << uint32(0x00000015); // unk, can be 0x15 or 0x22
+ *data << uint32(0x0000002F); // unk, can be 0x15 or 0x22
else
*data << uint32(0x00000008); // unk, can be 0x7 or 0x8
break;
@@ -505,6 +442,15 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
case TYPEID_CORPSE:
*data << uint32(GetGUIDHigh()); // GetGUIDHigh()
break;
+ case TYPEID_UNIT:
+ *data << uint32(0x0000000B); // unk, can be 0xB or 0xC
+ break;
+ case TYPEID_PLAYER:
+ if(flags & UPDATEFLAG_SELF)
+ *data << uint32(0x0000002F); // unk, can be 0x15 or 0x22
+ else
+ *data << uint32(0x00000008); // unk, can be 0x7 or 0x8
+ break;
default:
*data << uint32(0x00000000); // unk
break;
@@ -512,9 +458,12 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
}
// 0x4
- if(flags & UPDATEFLAG_FULLGUID)
+ if(flags & UPDATEFLAG_HAS_TARGET) // packed guid (current target guid)
{
- *data << uint8(0); // packed guid (probably target guid)
+ if(Unit *victim = ((Unit*)this)->getVictim())
+ data->append(victim->GetPackGUID());
+ else
+ *data << uint8(0);
}
// 0x2
@@ -522,6 +471,13 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
{
*data << uint32(getMSTime()); // ms time
}
+
+ // 0x80
+ if(flags & UPDATEFLAG_VEHICLE) // unused for now
+ {
+ *data << uint32(((Vehicle*)this)->GetVehicleInfo()->m_ID); // vehicle id
+ *data << float(0); // facing adjustment
+ }
}
void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *updateMask, Player *target) const
@@ -537,10 +493,10 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
if ( ((GameObject*)this)->ActivateToQuest(target) || target->isGameMaster())
{
IsActivateToQuest = true;
- updateMask->SetBit(GAMEOBJECT_DYN_FLAGS);
+ updateMask->SetBit(GAMEOBJECT_DYNAMIC);
}
- if (GetUInt32Value(GAMEOBJECT_ARTKIT))
- updateMask->SetBit(GAMEOBJECT_ARTKIT);
+ if (((GameObject*)this)->GetGoArtKit())
+ updateMask->SetBit(GAMEOBJECT_BYTES_1);
}
}
else //case UPDATETYPE_VALUES
@@ -551,8 +507,8 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
{
IsActivateToQuest = true;
}
- updateMask->SetBit(GAMEOBJECT_DYN_FLAGS);
- updateMask->SetBit(GAMEOBJECT_ANIMPROGRESS);
+ updateMask->SetBit(GAMEOBJECT_DYNAMIC);
+ updateMask->SetBit(GAMEOBJECT_BYTES_1);
}
}
@@ -625,33 +581,32 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
// FG: pretend that OTHER players in own group are friendly ("blue")
else if(index == UNIT_FIELD_BYTES_2 || index == UNIT_FIELD_FACTIONTEMPLATE)
{
- bool ch = false;
- if(target->GetTypeId() == TYPEID_PLAYER && GetTypeId() == TYPEID_PLAYER && target != this)
- {
- if(target->IsInSameGroupWith((Player*)this) || target->IsInSameRaidWith((Player*)this))
+ bool ch = false;
+ if(GetTypeId() == TYPEID_PLAYER && target != this
+ && ((Player*)this)->IsInSameRaidWith(target))
{
- if(index == UNIT_FIELD_BYTES_2)
+ // Allow targetting opposite faction in party when enabled in config
+ if(sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && index == UNIT_FIELD_BYTES_2)
{
DEBUG_LOG("-- VALUES_UPDATE: Sending '%s' the blue-group-fix from '%s' (flag)", target->GetName(), ((Player*)this)->GetName());
- *data << ( m_uint32Values[ index ] & ((UNIT_BYTE2_FLAG_SANCTUARY | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5) << 8) ); // this flag is at uint8 offset 1 !!
+ *data << ( m_uint32Values[ index ] & ((UNIT_BYTE2_FLAG_SANCTUARY /*| UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5*/) << 8) ); // this flag is at uint8 offset 1 !!
ch = true;
}
- else if(index == UNIT_FIELD_FACTIONTEMPLATE)
+ else
{
FactionTemplateEntry const *ft1, *ft2;
ft1 = ((Player*)this)->getFactionTemplateEntry();
- ft2 = ((Player*)target)->getFactionTemplateEntry();
+ ft2 = target->getFactionTemplateEntry();
if(ft1 && ft2 && !ft1->IsFriendlyTo(*ft2))
{
- uint32 faction = ((Player*)target)->getFaction(); // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work)
+ uint32 faction = target->getFaction(); // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work)
DEBUG_LOG("-- VALUES_UPDATE: Sending '%s' the blue-group-fix from '%s' (faction %u)", target->GetName(), ((Player*)this)->GetName(), faction);
*data << uint32(faction);
ch = true;
}
}
}
- }
if(!ch)
*data << m_uint32Values[ index ];
}
@@ -670,7 +625,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
if( updateMask->GetBit( index ) )
{
// send in current format (float as float, uint32 as uint32)
- if ( index == GAMEOBJECT_DYN_FLAGS )
+ if ( index == GAMEOBJECT_DYNAMIC )
{
if(IsActivateToQuest )
{
@@ -710,11 +665,10 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
void Object::ClearUpdateMask(bool remove)
{
- for( uint16 index = 0; index < m_valuesCount; index ++ )
- {
- if(m_uint32Values_mirror[index]!= m_uint32Values[index])
- m_uint32Values_mirror[index] = m_uint32Values[index];
- }
+ uint32 *temp = m_uint32Values;
+
+ memcpy(m_uint32Values_mirror, m_uint32Values, m_valuesCount*sizeof(uint32));
+
if(m_objectUpdated)
{
if(remove)
@@ -758,18 +712,23 @@ bool Object::LoadValues(const char* data)
void Object::_SetUpdateBits(UpdateMask *updateMask, Player* /*target*/) const
{
- for( uint16 index = 0; index < m_valuesCount; index ++ )
+ uint32 *value = m_uint32Values;
+ uint32 *mirror = m_uint32Values_mirror;
+
+ for(uint16 index = 0; index < m_valuesCount; ++index, ++value, ++mirror)
{
- if(m_uint32Values_mirror[index]!= m_uint32Values[index])
+ if(*mirror != *value)
updateMask->SetBit(index);
}
}
void Object::_SetCreateBits(UpdateMask *updateMask, Player* /*target*/) const
{
- for( uint16 index = 0; index < m_valuesCount; index++ )
+ uint32 *value = m_uint32Values;
+
+ for(uint16 index = 0; index < m_valuesCount; ++index, ++value)
{
- if(GetUInt32Value(index) != 0)
+ if(*value)
updateMask->SetBit(index);
}
}
@@ -831,6 +790,48 @@ void Object::SetUInt64Value( uint16 index, const uint64 &value )
}
}
+bool Object::AddUInt64Value(uint16 index, const uint64 &value)
+{
+ ASSERT( index + 1 < m_valuesCount || PrintIndexError( index , true ) );
+ if(value && !*((uint64*)&(m_uint32Values[index])))
+ {
+ m_uint32Values[ index ] = *((uint32*)&value);
+ m_uint32Values[ index + 1 ] = *(((uint32*)&value) + 1);
+
+ if(m_inWorld)
+ {
+ if(!m_objectUpdated)
+ {
+ ObjectAccessor::Instance().AddUpdateObject(this);
+ m_objectUpdated = true;
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+bool Object::RemoveUInt64Value(uint16 index, const uint64 &value)
+{
+ ASSERT( index + 1 < m_valuesCount || PrintIndexError( index , true ) );
+ if(value && *((uint64*)&(m_uint32Values[index])) == value)
+ {
+ m_uint32Values[ index ] = 0;
+ m_uint32Values[ index + 1 ] = 0;
+
+ if(m_inWorld)
+ {
+ if(!m_objectUpdated)
+ {
+ ObjectAccessor::Instance().AddUpdateObject(this);
+ m_objectUpdated = true;
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
void Object::SetFloatValue( uint16 index, float value )
{
ASSERT( index < m_valuesCount || PrintIndexError( index , true ) );
@@ -1051,6 +1052,8 @@ bool Object::PrintIndexError(uint32 index, bool set) const
}
WorldObject::WorldObject()
+ : m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL),
+ m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f)
{
m_positionX = 0.0f;
m_positionY = 0.0f;
@@ -1063,8 +1066,6 @@ WorldObject::WorldObject()
m_name = "";
- mSemaphoreTeleport = false;
-
m_isActive = false;
IsTempWorldObject = false;
}
@@ -1073,8 +1074,8 @@ void WorldObject::SetWorldObject(bool on)
{
if(!IsInWorld())
return;
-
- GetMap()->AddObjectToSwitchList(this, on);
+
+ GetMap()->AddObjectToSwitchList(this, on);
}
void WorldObject::setActive( bool on )
@@ -1110,21 +1111,27 @@ void WorldObject::setActive( bool on )
}
}
-void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid )
+void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid, uint32 phaseMask )
{
Object::_Create(guidlow, 0, guidhigh);
m_mapId = mapid;
+ m_phaseMask = phaseMask;
}
uint32 WorldObject::GetZoneId() const
{
- return MapManager::Instance().GetBaseMap(m_mapId)->GetZoneId(m_positionX,m_positionY);
+ return MapManager::Instance().GetBaseMap(m_mapId)->GetZoneId(m_positionX,m_positionY,m_positionZ);
}
uint32 WorldObject::GetAreaId() const
{
- return MapManager::Instance().GetBaseMap(m_mapId)->GetAreaId(m_positionX,m_positionY);
+ return MapManager::Instance().GetBaseMap(m_mapId)->GetAreaId(m_positionX,m_positionY,m_positionZ);
+}
+
+void WorldObject::GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const
+{
+ MapManager::Instance().GetBaseMap(m_mapId)->GetZoneAndAreaId(zoneid,areaid,m_positionX,m_positionY,m_positionZ);
}
InstanceData* WorldObject::GetInstanceData()
@@ -1246,6 +1253,25 @@ float WorldObject::GetAngle( const float x, const float y ) const
return ang;
}
+void WorldObject::GetSinCos(const float x, const float y, float &vsin, float &vcos)
+{
+ float dx = GetPositionX() - x;
+ float dy = GetPositionY() - y;
+
+ if(dx < 0.001f && dy < 0.001f)
+ {
+ float angle = rand_norm()*2*M_PI;
+ vcos = cos(angle);
+ vsin = sin(angle);
+ }
+ else
+ {
+ float dist = sqrt((dx*dx) + (dy*dy));
+ vcos = dx / dist;
+ vsin = dy / dist;
+ }
+}
+
bool WorldObject::HasInArc(const float arcangle, const WorldObject* obj) const
{
// always have self in arc
@@ -1367,50 +1393,17 @@ void Object::ForceValuesUpdateAtIndex(uint32 i)
namespace Trinity
{
- class MessageChatLocaleCacheDo
+ class MonsterChatBuilder
{
public:
- MessageChatLocaleCacheDo(WorldObject const& obj, ChatMsg msgtype, int32 textId, uint32 language, uint64 targetGUID, float dist)
- : i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language),
- i_targetGUID(targetGUID), i_dist(dist)
+ MonsterChatBuilder(WorldObject const& obj, ChatMsg msgtype, int32 textId, uint32 language, uint64 targetGUID)
+ : i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language), i_targetGUID(targetGUID) {}
+ void operator()(WorldPacket& data, int32 loc_idx)
{
- }
+ char const* text = objmgr.GetMangosString(i_textId,loc_idx);
- ~MessageChatLocaleCacheDo()
- {
- for(int i = 0; i < i_data_cache.size(); ++i)
- delete i_data_cache[i];
- }
-
- void operator()(Player* p)
- {
- // skip far away players
- if(p->GetDistance(&i_object) > i_dist)
- return;
-
- uint32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex();
- uint32 cache_idx = loc_idx+1;
- WorldPacket* data;
-
- // create if not cached yet
- if(i_data_cache.size() < cache_idx+1 || !i_data_cache[cache_idx])
- {
- if(i_data_cache.size() < cache_idx+1)
- i_data_cache.resize(cache_idx+1);
-
- char const* text = objmgr.GetTrinityString(i_textId,loc_idx);
-
- data = new WorldPacket(SMSG_MESSAGECHAT, 200);
-
- // TODO: i_object.GetName() also must be localized?
- i_object.BuildMonsterChat(data,i_msgtype,text,i_language,i_object.GetNameForLocaleIdx(loc_idx),i_targetGUID);
-
- i_data_cache[cache_idx] = data;
- }
- else
- data = i_data_cache[cache_idx];
-
- p->SendDirectMessage(data);
+ // TODO: i_object.GetName() also must be localized?
+ i_object.BuildMonsterChat(&data,i_msgtype,text,i_language,i_object.GetNameForLocaleIdx(loc_idx),i_targetGUID);
}
private:
@@ -1419,8 +1412,6 @@ namespace Trinity
int32 i_textId;
uint32 i_language;
uint64 i_targetGUID;
- float i_dist;
- std::vector<WorldPacket*> i_data_cache; // 0 = default, i => i-1 locale index
};
} // namespace Trinity
@@ -1432,9 +1423,10 @@ void WorldObject::MonsterSay(int32 textId, uint32 language, uint64 TargetGuid)
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
- Trinity::MessageChatLocaleCacheDo say_do(*this, CHAT_MSG_MONSTER_SAY, textId,language,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY));
- Trinity::PlayerWorker<Trinity::MessageChatLocaleCacheDo> say_worker(say_do);
- TypeContainerVisitor<Trinity::PlayerWorker<Trinity::MessageChatLocaleCacheDo>, WorldTypeMapContainer > message(say_worker);
+ MaNGOS::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_SAY, textId,language,TargetGuid);
+ MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> say_do(say_build);
+ MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY),say_do);
+ TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *GetMap());
}
@@ -1447,13 +1439,27 @@ void WorldObject::MonsterYell(int32 textId, uint32 language, uint64 TargetGuid)
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
- Trinity::MessageChatLocaleCacheDo say_do(*this, CHAT_MSG_MONSTER_YELL, textId,language,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL));
- Trinity::PlayerWorker<Trinity::MessageChatLocaleCacheDo> say_worker(say_do);
- TypeContainerVisitor<Trinity::PlayerWorker<Trinity::MessageChatLocaleCacheDo>, WorldTypeMapContainer > message(say_worker);
+ MaNGOS::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_YELL, textId,language,TargetGuid);
+ MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> say_do(say_build);
+ MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL),say_do);
+ TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *GetMap());
}
+void WorldObject::MonsterYellToZone(int32 textId, uint32 language, uint64 TargetGuid)
+{
+ MaNGOS::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_YELL, textId,language,TargetGuid);
+ MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> say_do(say_build);
+
+ uint32 zoneid = GetZoneId();
+
+ Map::PlayerList const& pList = GetMap()->GetPlayers();
+ for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
+ if(itr->getSource()->GetZoneId()==zoneid)
+ say_do(itr->getSource());
+}
+
void WorldObject::MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote)
{
CellPair p = Trinity::ComputeCellPair(GetPositionX(), GetPositionY());
@@ -1462,9 +1468,10 @@ void WorldObject::MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossE
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
- Trinity::MessageChatLocaleCacheDo say_do(*this, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, textId,LANG_UNIVERSAL,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
- Trinity::PlayerWorker<Trinity::MessageChatLocaleCacheDo> say_worker(say_do);
- TypeContainerVisitor<Trinity::PlayerWorker<Trinity::MessageChatLocaleCacheDo>, WorldTypeMapContainer > message(say_worker);
+ MaNGOS::MonsterChatBuilder say_build(*this, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, textId,LANG_UNIVERSAL,TargetGuid);
+ MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> say_do(say_build);
+ MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),say_do);
+ TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *GetMap());
}
@@ -1479,7 +1486,7 @@ void WorldObject::MonsterWhisper(int32 textId, uint64 receiver, bool IsBossWhisp
char const* text = objmgr.GetTrinityString(textId,loc_idx);
WorldPacket data(SMSG_MESSAGECHAT, 200);
- BuildMonsterChat(&data,IsBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER,text,LANG_UNIVERSAL,GetName(),receiver);
+ BuildMonsterChat(&data,IsBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER,text,LANG_UNIVERSAL,GetNameForLocaleIdx(loc_idx),receiver);
player->GetSession()->SendPacket(&data);
}
@@ -1516,13 +1523,14 @@ void WorldObject::BuildHeartBeatMsg(WorldPacket *data) const
data->Initialize(MSG_MOVE_HEARTBEAT, 32);
data->append(GetPackGUID());
*data << uint32(((Unit*)this)->GetUnitMovementFlags()); // movement flags
- *data << uint8(0); // 2.3.0
+ *data << uint16(0); // 2.3.0
*data << getMSTime(); // time
*data << m_positionX;
*data << m_positionY;
*data << m_positionZ;
*data << m_orientation;
- *data << uint32(0);
+
+ ((Unit*)this)->BuildMovementPacket(data);
}
void WorldObject::BuildTeleportAckMsg(WorldPacket *data, float x, float y, float z, float ang) const
@@ -1535,13 +1543,14 @@ void WorldObject::BuildTeleportAckMsg(WorldPacket *data, float x, float y, float
data->append(GetPackGUID());
*data << uint32(0); // this value increments every time
*data << uint32(((Unit*)this)->GetUnitMovementFlags()); // movement flags
- *data << uint8(0); // 2.3.0
+ *data << uint16(0); // 2.3.0
*data << getMSTime(); // time
*data << x;
*data << y;
*data << z;
*data << ang;
- *data << uint32(0);
+
+ ((Unit*)this)->BuildMovementPacket(data);
}
void WorldObject::SendMessageToSet(WorldPacket *data, bool /*fake*/, bool bToPossessor)
@@ -1590,60 +1599,127 @@ void WorldObject::AddObjectToRemoveList()
map->AddObjectToRemoveList(this);
}
-Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime)
+TempSummon *Map::SummonCreature(uint32 entry, float x, float y, float z, float angle, SummonPropertiesEntry const *properties, uint32 duration, Unit *summoner)
{
- TemporarySummon* pCreature = new TemporarySummon(GetGUID());
+ uint32 mask = SUMMON_MASK_SUMMON;
+ if(properties)
+ {
+ if(properties->Category == SUMMON_CATEGORY_PET
+ || properties->Type == SUMMON_TYPE_GUARDIAN
+ || properties->Type == SUMMON_TYPE_MINION)
+ mask = SUMMON_MASK_GUARDIAN;
+ else if(properties->Type == SUMMON_TYPE_TOTEM)
+ mask = SUMMON_MASK_TOTEM;
+ else if(properties->Category == SUMMON_CATEGORY_VEHICLE
+ || properties->Type == SUMMON_TYPE_VEHICLE
+ || properties->Type == SUMMON_TYPE_VEHICLE2)
+ mask = SUMMON_MASK_VEHICLE;
+ }
- uint32 team = 0;
- if (GetTypeId()==TYPEID_PLAYER)
- team = ((Player*)this)->GetTeam();
+ uint32 phase = PHASEMASK_NORMAL, team = 0;
+ if(summoner)
+ {
+ phase = summoner->GetPhaseMask();
+ if(summoner->GetTypeId() == TYPEID_PLAYER)
+ team = ((Player*)summoner)->GetTeam();
+ }
+
+ TempSummon *summon = NULL;
+ switch(mask)
+ {
+ case SUMMON_MASK_SUMMON: summon = new TempSummon (properties, summoner); break;
+ case SUMMON_MASK_GUARDIAN: summon = new Guardian (properties, summoner); break;
+ case SUMMON_MASK_TOTEM: summon = new Totem (properties, summoner); break;
+ default: return NULL;
+ }
+ if(!summon->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), this, phase, entry, team))
+ {
+ delete summon;
+ return NULL;
+ }
- if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), GetMap(), id, team))
+ summon->Relocate(x, y, z, angle);
+ if(!summon->IsPositionValid())
{
- delete pCreature;
+ sLog.outError("Creature (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)",summon->GetGUIDLow(),summon->GetEntry(),summon->GetPositionX(),summon->GetPositionY());
+ delete summon;
return NULL;
}
+ Add((Creature*)summon);
+ summon->InitSummon(duration);
+
+ return summon;
+}
+
+TempSummon* WorldObject::SummonCreature(uint32 entry, float x, float y, float z, float ang, TempSummonType spwtype, uint32 duration)
+{
+ Map *map = FindMap();
+ if(!map)
+ return NULL;
+
if (x == 0.0f && y == 0.0f && z == 0.0f)
- GetClosePoint(x, y, z, pCreature->GetObjectSize());
+ GetClosePoint(x, y, z, GetObjectSize());
+
+ TempSummon *pCreature = map->SummonCreature(entry, x, y, z, ang, NULL, duration, isType(TYPEMASK_UNIT) ? (Unit*)this : NULL);
+ if(!pCreature)
+ return NULL;
+
+ pCreature->SetHomePosition(x, y, z, ang);
+ pCreature->SetTempSummonType(spwtype);
+
+ return pCreature;
+}
- pCreature->Relocate(x, y, z, ang);
+Vehicle* WorldObject::SummonVehicle(uint32 entry, float x, float y, float z, float ang)
+{
+ CreatureInfo const *ci = objmgr.GetCreatureTemplate(entry);
+ if(!ci)
+ return NULL;
- if(!pCreature->IsPositionValid())
+ uint32 id = ci->VehicleId; //temp store id here
+ if(!id) id = 156;
+ VehicleEntry const *ve = sVehicleStore.LookupEntry(id);
+ if(!ve)
+ return NULL;
+
+ Vehicle *v = new Vehicle;
+ Map *map = GetMap();
+ uint32 team = 0;
+ if (GetTypeId()==TYPEID_PLAYER)
+ team = ((Player*)this)->GetTeam();
+ if(!v->Create(objmgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, GetPhaseMask(), entry, id, team))
{
- sLog.outError("ERROR: Creature (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
- delete pCreature;
+ delete v;
return NULL;
}
- pCreature->SetHomePosition(x, y, z, ang);
- pCreature->Summon(spwtype, despwtime);
-
- if(GetTypeId()==TYPEID_UNIT && ((Creature*)this)->IsAIEnabled)
- ((Creature*)this)->AI()->JustSummoned(pCreature);
+ v->Relocate(x, y, z, ang);
- if(pCreature->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER && pCreature->m_spells[0])
+ if(!v->IsPositionValid())
{
- if(GetTypeId() == TYPEID_UNIT || GetTypeId() == TYPEID_PLAYER)
- pCreature->setFaction(((Unit*)this)->getFaction());
- pCreature->CastSpell(pCreature, pCreature->m_spells[0], false, 0, 0, GetGUID());
+ sLog.outError("ERROR: Vehicle (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
+ v->GetGUIDLow(), v->GetEntry(), v->GetPositionX(), v->GetPositionY());
+ delete v;
+ return NULL;
}
- //return the creature therewith the summoner has access to it
- return pCreature;
+ map->Add((Creature*)v);
+
+ return v;
}
Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 duration)
{
- Pet* pet = new Pet(petType);
+ Pet* pet = new Pet(this, petType);
if(petType == SUMMON_PET && pet->LoadPetFromDB(this, entry))
{
// Remove Demonic Sacrifice auras (known pet)
- Unit::AuraList const& auraClassScripts = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(Unit::AuraList::const_iterator itr = auraClassScripts.begin();itr!=auraClassScripts.end();)
+ Unit::AuraEffectList const& auraClassScripts = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ for(Unit::AuraEffectList::const_iterator itr = auraClassScripts.begin();itr!=auraClassScripts.end();)
{
- if((*itr)->GetModifier()->m_miscvalue==2228)
+ if((*itr)->GetMiscValue()==2228)
{
RemoveAurasDueToSpell((*itr)->GetId());
itr = auraClassScripts.begin();
@@ -1667,7 +1743,7 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
Map *map = GetMap();
uint32 pet_number = objmgr.GeneratePetNumber();
- if(!pet->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map, entry, pet_number))
+ if(!pet->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map, GetPhaseMask(), entry, pet_number))
{
sLog.outError("no such creature entry %u", entry);
delete pet;
@@ -1683,15 +1759,12 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
return NULL;
}
- pet->SetOwnerGUID(GetGUID());
pet->SetCreatorGUID(GetGUID());
pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction());
// this enables pet details window (Shift+P)
pet->GetCharmInfo()->SetPetNumber(pet_number, false);
- pet->AIM_Initialize();
-
map->Add((Creature*)pet);
pet->setPowerType(POWER_MANA);
@@ -1699,12 +1772,12 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
pet->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
pet->InitStatsForLevel(getLevel());
+ SetGuardian(pet, true);
+
switch(petType)
{
- case GUARDIAN_PET:
case POSSESSED_PET:
pet->SetUInt32Value(UNIT_FIELD_FLAGS,0);
- AddGuardian(pet);
break;
case SUMMON_PET:
pet->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
@@ -1714,7 +1787,6 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
pet->SetPower(POWER_MANA, pet->GetMaxPower(POWER_MANA));
pet->InitPetCreateSpells();
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
- SetPet(pet);
PetSpellInitialize();
break;
}
@@ -1722,10 +1794,10 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
if(petType == SUMMON_PET)
{
// Remove Demonic Sacrifice auras (known pet)
- Unit::AuraList const& auraClassScripts = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(Unit::AuraList::const_iterator itr = auraClassScripts.begin();itr!=auraClassScripts.end();)
+ Unit::AuraEffectList const& auraClassScripts = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ for(Unit::AuraEffectList::const_iterator itr = auraClassScripts.begin();itr!=auraClassScripts.end();)
{
- if((*itr)->GetModifier()->m_miscvalue==2228)
+ if((*itr)->GetMiscValue()==2228)
{
RemoveAurasDueToSpell((*itr)->GetId());
itr = auraClassScripts.begin();
@@ -1754,7 +1826,7 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float
}
Map *map = GetMap();
GameObject *go = new GameObject();
- if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),entry,map,x,y,z,ang,rotation0,rotation1,rotation2,rotation3,100,1))
+ if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, map, GetPhaseMask(), x,y,z,ang,rotation0,rotation1,rotation2,rotation3,100,GO_STATE_READY))
{
delete go;
return NULL;
@@ -1816,5 +1888,31 @@ void WorldObject::GetGroundPoint(float &x, float &y, float &z, float dist, float
UpdateGroundPositionZ(x, y, z);
}
+void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)
+{
+ m_phaseMask = newPhaseMask;
+
+ if(update && IsInWorld())
+ ObjectAccessor::UpdateObjectVisibility(this);
+}
+void WorldObject::PlayDistanceSound( uint32 sound_id, Player* target /*= NULL*/ )
+{
+ WorldPacket data(SMSG_PLAY_OBJECT_SOUND,4+8);
+ data << uint32(sound_id);
+ data << GetGUID();
+ if (target)
+ target->SendDirectMessage( &data );
+ else
+ SendMessageToSet( &data, true );
+}
+void WorldObject::PlayDirectSound( uint32 sound_id, Player* target /*= NULL*/ )
+{
+ WorldPacket data(SMSG_PLAY_SOUND, 4);
+ data << uint32(sound_id);
+ if (target)
+ target->SendDirectMessage( &data );
+ else
+ SendMessageToSet( &data, true );
+}
diff --git a/src/game/Object.h b/src/game/Object.h
index 328df30492a..68438c4df85 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -28,7 +28,6 @@
#include "GameSystem/GridReference.h"
#include "ObjectDefines.h"
#include "GridDefines.h"
-#include "CreatureAI.h"
#include "Map.h"
#include <set>
@@ -50,13 +49,14 @@ enum TypeMask
TYPEMASK_OBJECT = 0x0001,
TYPEMASK_ITEM = 0x0002,
TYPEMASK_CONTAINER = 0x0006, // TYPEMASK_ITEM | 0x0004
- TYPEMASK_UNIT = 0x0008,
+ TYPEMASK_UNIT = 0x0008, //creature or player
TYPEMASK_PLAYER = 0x0010,
TYPEMASK_GAMEOBJECT = 0x0020,
TYPEMASK_DYNAMICOBJECT = 0x0040,
TYPEMASK_CORPSE = 0x0080,
TYPEMASK_AIGROUP = 0x0100,
- TYPEMASK_AREATRIGGER = 0x0200
+ TYPEMASK_AREATRIGGER = 0x0200,
+ TYPEMASK_SEER = TYPEMASK_UNIT | TYPEMASK_DYNAMICOBJECT
};
enum TypeID
@@ -72,6 +72,7 @@ enum TypeID
TYPEID_AIGROUP = 8,
TYPEID_AREATRIGGER = 9
};
+#define MAX_TYPEID 10
uint32 GuidHigh2TypeId(uint32 guid_hi);
@@ -87,6 +88,12 @@ enum TempSummonType
TEMPSUMMON_MANUAL_DESPAWN = 8 // despawns when UnSummon() is called
};
+enum PhaseMasks
+{
+ PHASEMASK_NORMAL = 0x00000001,
+ PHASEMASK_ANYWHERE = 0xFFFFFFFF
+};
+
class WorldPacket;
class UpdateData;
class ByteBuffer;
@@ -96,6 +103,9 @@ class Player;
class UpdateMask;
class InstanceData;
class GameObject;
+class TempSummon;
+class Vehicle;
+class CreatureAI;
typedef UNORDERED_MAP<Player*, UpdateData> UpdateDataMapType;
@@ -117,7 +127,7 @@ class TRINITY_DLL_SPEC Object
public:
virtual ~Object ( );
- const bool& IsInWorld() const { return m_inWorld; }
+ const bool IsInWorld() const { return m_inWorld; }
virtual void AddToWorld()
{
if(m_inWorld)
@@ -193,7 +203,7 @@ class TRINITY_DLL_SPEC Object
return *(((uint8*)&m_uint32Values[ index ])+offset);
}
- uint8 GetUInt16Value( uint16 index, uint8 offset) const
+ uint16 GetUInt16Value( uint16 index, uint8 offset) const
{
ASSERT( index < m_valuesCount || PrintIndexError( index , false) );
ASSERT( offset < 2 );
@@ -210,6 +220,9 @@ class TRINITY_DLL_SPEC Object
void SetStatFloatValue( uint16 index, float value);
void SetStatInt32Value( uint16 index, int32 value);
+ bool AddUInt64Value( uint16 index, const uint64 &value );
+ bool RemoveUInt64Value( uint16 index, const uint64 &value );
+
void ApplyModUInt32Value(uint16 index, int32 val, bool apply);
void ApplyModInt32Value(uint16 index, int32 val, bool apply);
void ApplyModUInt64Value(uint16 index, int32 val, bool apply);
@@ -318,7 +331,7 @@ class TRINITY_DLL_SPEC Object
virtual void _SetUpdateBits(UpdateMask *updateMask, Player *target) const;
virtual void _SetCreateBits(UpdateMask *updateMask, Player *target) const;
- void _BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2 ) const;
+ void _BuildMovementUpdate(ByteBuffer * data, uint8 flags) const;
void _BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target ) const;
uint16 m_objectType;
@@ -357,7 +370,15 @@ class TRINITY_DLL_SPEC WorldObject : public Object
virtual void Update ( uint32 /*time_diff*/ ) { }
- void _Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid );
+ void _Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid, uint32 phaseMask);
+
+ void Relocate(WorldObject *obj)
+ {
+ m_positionX = obj->GetPositionX();
+ m_positionY = obj->GetPositionY();
+ m_positionZ = obj->GetPositionZ();
+ m_orientation = obj->GetOrientation();
+ }
void Relocate(float x, float y, float z, float orientation)
{
@@ -423,8 +444,14 @@ class TRINITY_DLL_SPEC WorldObject : public Object
void SetInstanceId(uint32 val) { m_InstanceId = val; m_map = NULL; }
uint32 GetInstanceId() const { return m_InstanceId; }
+ virtual void SetPhaseMask(uint32 newPhaseMask, bool update);
+ uint32 GetPhaseMask() const { return m_phaseMask; }
+ bool InSamePhase(WorldObject const* obj) const { return InSamePhase(obj->GetPhaseMask()); }
+ bool InSamePhase(uint32 phasemask) const { return (GetPhaseMask() & phasemask); }
+
uint32 GetZoneId() const;
uint32 GetAreaId() const;
+ void GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const;
InstanceData* GetInstanceData();
@@ -440,21 +467,24 @@ class TRINITY_DLL_SPEC WorldObject : public Object
float GetDistance2d(const float x, const float y) const;
float GetExactDistance2d(const float x, const float y) const;
float GetDistanceZ(const WorldObject* obj) const;
- bool IsInMap(const WorldObject* obj) const { return GetMapId()==obj->GetMapId() && GetInstanceId()==obj->GetInstanceId(); }
+ bool IsInMap(const WorldObject* obj) const
+ {
+ return IsInWorld() && obj->IsInWorld() && GetMapId()==obj->GetMapId() &&
+ GetInstanceId()==obj->GetInstanceId() && InSamePhase(obj);
+ }
bool IsWithinDistInMap(const WorldObject* obj, const float dist2compare, const bool is3D = true) const;
bool IsWithinLOS(const float x, const float y, const float z ) const;
bool IsWithinLOSInMap(const WorldObject* obj) const;
float GetAngle( const WorldObject* obj ) const;
float GetAngle( const float x, const float y ) const;
+ void GetSinCos(const float x, const float y, float &vsin, float &vcos);
bool HasInArc( const float arcangle, const WorldObject* obj ) const;
virtual void SendMessageToSet(WorldPacket *data, bool self, bool to_possessor = true);
virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool to_possessor = true);
void BuildHeartBeatMsg( WorldPacket *data ) const;
void BuildTeleportAckMsg( WorldPacket *data, float x, float y, float z, float ang) const;
- bool IsBeingTeleported() { return mSemaphoreTeleport; }
- void SetSemaphoreTeleport(bool semphsetting) { mSemaphoreTeleport = semphsetting; }
void MonsterSay(const char* text, uint32 language, uint64 TargetGuid);
void MonsterYell(const char* text, uint32 language, uint64 TargetGuid);
@@ -464,8 +494,12 @@ class TRINITY_DLL_SPEC WorldObject : public Object
void MonsterYell(int32 textId, uint32 language, uint64 TargetGuid);
void MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote = false);
void MonsterWhisper(int32 textId, uint64 receiver, bool IsBossWhisper = false);
+ void MonsterYellToZone(int32 textId, uint32 language, uint64 TargetGuid);
void BuildMonsterChat(WorldPacket *data, uint8 msgtype, char const* text, uint32 language, char const* name, uint64 TargetGuid) const;
+ void PlayDistanceSound(uint32 sound_id, Player* target = NULL);
+ void PlayDirectSound(uint32 sound_id, Player* target = NULL);
+
void SendObjectDeSpawnAnim(uint64 guid);
virtual void SaveRespawnTime() {}
@@ -484,9 +518,10 @@ class TRINITY_DLL_SPEC WorldObject : public Object
Map * GetMap() const { return m_map ? m_map : const_cast<WorldObject*>(this)->_getMap(); }
Map * FindMap() const { return m_map ? m_map : const_cast<WorldObject*>(this)->_findMap(); }
Map const* GetBaseMap() const;
- Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
+ TempSummon* SummonCreature(uint32 id, float x, float y, float z, float ang = 0,TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN,uint32 despwtime = 0);
+ Vehicle* SummonVehicle(uint32 entry, float x, float y, float z, float ang = 0);
GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime);
- Creature* SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI* (*GetAI)(Creature*) = NULL);
+ Creature* SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI* (*GetAI)(Creature*) = NULL);
bool isActiveObject() const { return m_isActive; }
void setActive(bool isActiveObject);
void SetWorldObject(bool apply);
@@ -501,8 +536,9 @@ class TRINITY_DLL_SPEC WorldObject : public Object
bool m_isActive;
private:
- uint32 m_mapId;
- uint32 m_InstanceId;
+ uint32 m_mapId; // object at map with map_id
+ uint32 m_InstanceId; // in map copy with instance id
+ uint32 m_phaseMask; // in area phase state
Map *m_map;
Map* _getMap();
@@ -512,8 +548,6 @@ class TRINITY_DLL_SPEC WorldObject : public Object
float m_positionY;
float m_positionZ;
float m_orientation;
-
- bool mSemaphoreTeleport;
};
#endif
diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp
index 5ad5f036813..1fa0bd6d1ca 100644
--- a/src/game/ObjectAccessor.cpp
+++ b/src/game/ObjectAccessor.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -25,8 +25,7 @@
#include "Creature.h"
#include "GameObject.h"
#include "DynamicObject.h"
-#include "Corpse.h"
-#include "WorldSession.h"
+#include "Vehicle.h"
#include "WorldPacket.h"
#include "Item.h"
#include "Corpse.h"
@@ -38,6 +37,7 @@
#include "Opcodes.h"
#include "ObjectDefines.h"
#include "MapInstanced.h"
+#include "World.h"
#include <cmath>
@@ -45,112 +45,19 @@
INSTANTIATE_SINGLETON_2(ObjectAccessor, CLASS_LOCK);
INSTANTIATE_CLASS_MUTEX(ObjectAccessor, ZThread::FastMutex);
-namespace Trinity
-{
- struct TRINITY_DLL_DECL BuildUpdateForPlayer
- {
- Player &i_player;
- UpdateDataMapType &i_updatePlayers;
-
- BuildUpdateForPlayer(Player &player, UpdateDataMapType &data_map) : i_player(player), i_updatePlayers(data_map) {}
-
- void Visit(PlayerMapType &m)
- {
- for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
- {
- if( iter->getSource() == &i_player )
- continue;
-
- UpdateDataMapType::iterator iter2 = i_updatePlayers.find(iter->getSource());
- if( iter2 == i_updatePlayers.end() )
- {
- std::pair<UpdateDataMapType::iterator, bool> p = i_updatePlayers.insert( ObjectAccessor::UpdateDataValueType(iter->getSource(), UpdateData()) );
- assert(p.second);
- iter2 = p.first;
- }
-
- i_player.BuildValuesUpdateBlockForPlayer(&iter2->second, iter2->first);
- }
- }
-
- template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
- };
-}
-
ObjectAccessor::ObjectAccessor() {}
ObjectAccessor::~ObjectAccessor() {}
Creature*
-ObjectAccessor::GetNPCIfCanInteractWith(Player const &player, uint64 guid, uint32 npcflagmask)
-{
- // unit checks
- if (!guid)
- return NULL;
-
- // exist
- Creature *unit = GetCreature(player, guid);
- if (!unit)
- return NULL;
-
- // player check
- if(!player.CanInteractWithNPCs(!unit->isSpiritService()))
- return NULL;
-
- // appropriate npc type
- if(npcflagmask && !unit->HasFlag( UNIT_NPC_FLAGS, npcflagmask ))
- return NULL;
-
- // alive or spirit healer
- if(!unit->isAlive() && (!unit->isSpiritService() || player.isAlive() ))
- return NULL;
-
- // not allow interaction under control
- if(unit->GetCharmerOrOwnerGUID())
- return NULL;
-
- // not enemy
- if( unit->IsHostileTo(&player))
- return NULL;
-
- // not unfriendly
- FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(unit->getFaction());
- if(factionTemplate)
- {
- FactionEntry const* faction = sFactionStore.LookupEntry(factionTemplate->faction);
- if( faction->reputationListID >= 0 && player.GetReputationRank(faction) <= REP_UNFRIENDLY)
- return NULL;
- }
-
- // not too far
- if(!unit->IsWithinDistInMap(&player,INTERACTION_DISTANCE))
- return NULL;
-
- return unit;
-}
-
-Creature*
-ObjectAccessor::GetCreatureOrPet(WorldObject const &u, uint64 guid)
+ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid)
{
if(Creature *unit = GetPet(guid))
return unit;
- return GetCreature(u, guid);
-}
-
-Creature*
-ObjectAccessor::GetCreature(WorldObject const &u, uint64 guid)
-{
- Creature * ret = GetObjectInWorld(guid, (Creature*)NULL);
- if(!ret)
- return NULL;
-
- if(ret->GetMapId() != u.GetMapId())
- return NULL;
-
- if(ret->GetInstanceId() != u.GetInstanceId())
- return NULL;
+ if(Creature *unit = GetVehicle(guid))
+ return unit;
- return ret;
+ return u.GetMap()->GetCreature(guid);
}
Unit*
@@ -162,18 +69,23 @@ ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid)
if(IS_PLAYER_GUID(guid))
return FindPlayer(guid);
- return GetCreatureOrPet(u, guid);
+ return GetCreatureOrPetOrVehicle(u, guid);
}
Corpse*
ObjectAccessor::GetCorpse(WorldObject const &u, uint64 guid)
{
Corpse * ret = GetObjectInWorld(guid, (Corpse*)NULL);
- if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL;
+ if(!ret)
+ return NULL;
+ if(ret->GetMapId() != u.GetMapId())
+ return NULL;
+ if(ret->GetInstanceId() != u.GetInstanceId())
+ return NULL;
return ret;
}
-Object* ObjectAccessor::GetObjectByTypeMask(Player const &p, uint64 guid, uint32 typemask)
+Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const &p, uint64 guid, uint32 typemask)
{
Object *obj = NULL;
@@ -185,47 +97,31 @@ Object* ObjectAccessor::GetObjectByTypeMask(Player const &p, uint64 guid, uint32
if(typemask & TYPEMASK_UNIT)
{
- obj = GetCreatureOrPet(p,guid);
+ obj = GetCreatureOrPetOrVehicle(p,guid);
if(obj) return obj;
}
if(typemask & TYPEMASK_GAMEOBJECT)
{
- obj = GetGameObject(p,guid);
+ obj = p.GetMap()->GetGameObject(guid);
if(obj) return obj;
}
if(typemask & TYPEMASK_DYNAMICOBJECT)
{
- obj = GetDynamicObject(p,guid);
+ obj = p.GetMap()->GetDynamicObject(guid);
if(obj) return obj;
}
- if(typemask & TYPEMASK_ITEM)
+ if(typemask & TYPEMASK_ITEM && p.GetTypeId() == TYPEID_PLAYER)
{
- obj = p.GetItemByGuid( guid );
+ obj = ((Player const &)p).GetItemByGuid( guid );
if(obj) return obj;
}
return NULL;
}
-GameObject*
-ObjectAccessor::GetGameObject(WorldObject const &u, uint64 guid)
-{
- GameObject * ret = GetObjectInWorld(guid, (GameObject*)NULL);
- if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL;
- return ret;
-}
-
-DynamicObject*
-ObjectAccessor::GetDynamicObject(Unit const &u, uint64 guid)
-{
- DynamicObject * ret = GetObjectInWorld(guid, (DynamicObject*)NULL);
- if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL;
- return ret;
-}
-
Player*
ObjectAccessor::FindPlayer(uint64 guid)
{
@@ -273,48 +169,15 @@ ObjectAccessor::UpdateObject(Object* obj, Player* exceptPlayer)
}
void
-ObjectAccessor::AddUpdateObject(Object *obj)
-{
- Guard guard(i_updateGuard);
- i_objects.insert(obj);
-}
-
-void
-ObjectAccessor::RemoveUpdateObject(Object *obj)
-{
- Guard guard(i_updateGuard);
- std::set<Object *>::iterator iter = i_objects.find(obj);
- if( iter != i_objects.end() )
- i_objects.erase( iter );
-}
-
-void
ObjectAccessor::_buildUpdateObject(Object *obj, UpdateDataMapType &update_players)
{
- bool build_for_all = true;
- Player *pl = NULL;
- if( obj->isType(TYPEMASK_ITEM) )
- {
- Item *item = static_cast<Item *>(obj);
- pl = item->GetOwner();
- build_for_all = false;
- }
-
- if( pl != NULL )
- _buildPacket(pl, obj, update_players);
-
- // Capt: okey for all those fools who think its a real fix
- // THIS IS A TEMP FIX
- if( build_for_all )
+ if(obj->isType(TYPEMASK_ITEM))
{
- WorldObject * temp = dynamic_cast<WorldObject*>(obj);
-
- //assert(dynamic_cast<WorldObject*>(obj)!=NULL);
- if (temp)
- _buildChangeObjectForPlayer(temp, update_players);
- else
- sLog.outDebug("ObjectAccessor: Ln 405 Temp bug fix");
+ if(Player *owner = ((Item*)obj)->GetOwner())
+ _buildPacket(owner, obj, update_players);
}
+ else
+ _buildChangeObjectForPlayer((WorldObject*)obj, update_players);
}
void
@@ -351,6 +214,12 @@ ObjectAccessor::GetPet(uint64 guid)
return GetObjectInWorld(guid, (Pet*)NULL);
}
+Vehicle*
+ObjectAccessor::GetVehicle(uint64 guid)
+{
+ return GetObjectInWorld(guid, (Vehicle*)NULL);
+}
+
Corpse*
ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid)
{
@@ -423,18 +292,18 @@ ObjectAccessor::AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* ma
}
Corpse*
-ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid)
+ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool insignia)
{
Corpse *corpse = GetCorpseForPlayerGUID(player_guid);
if(!corpse)
{
//in fact this function is called from several places
//even when player doesn't have a corpse, not an error
- //sLog.outError("ERROR: Try remove corpse that not in map for GUID %ul", player_guid);
+ //sLog.outError("Try remove corpse that not in map for GUID %ul", player_guid);
return NULL;
}
- DEBUG_LOG("Deleting Corpse and spawning bones.\n");
+ DEBUG_LOG("Deleting Corpse and spawning bones.");
// remove corpse from player_guid -> corpse map
RemoveCorpse(corpse);
@@ -449,7 +318,10 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid)
Corpse *bones = NULL;
// create the bones only if the map and the grid is loaded at the corpse's location
- if(map && !map->IsRemovalGrid(corpse->GetPositionX(), corpse->GetPositionY()))
+ // ignore bones creating option in case insignia
+ if (map && (insignia ||
+ (map->IsBattleGroundOrArena() ? sWorld.getConfig(CONFIG_DEATH_BONES_BG_OR_ARENA) : sWorld.getConfig(CONFIG_DEATH_BONES_WORLD))) &&
+ !map->IsRemovalGrid(corpse->GetPositionX(), corpse->GetPositionY()))
{
// Create bones, don't change Corpse
bones = new Corpse;
@@ -465,6 +337,7 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid)
bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation());
bones->SetMapId(corpse->GetMapId());
bones->SetInstanceId(corpse->GetInstanceId());
+ bones->SetPhaseMask(corpse->GetPhaseMask(),false);
bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES);
bones->SetUInt64Value(CORPSE_FIELD_OWNER, 0);
@@ -494,9 +367,8 @@ ObjectAccessor::Update(uint32 diff)
while(!i_objects.empty())
{
Object* obj = *i_objects.begin();
+ assert(obj && obj->IsInWorld());
i_objects.erase(i_objects.begin());
- if (!obj || !obj->IsInWorld())
- continue;
_buildUpdateObject(obj, update_players);
obj->ClearUpdateMask(false);
}
@@ -554,11 +426,13 @@ ObjectAccessor::WorldObjectChangeAccumulator::Visit(DynamicObjectMapType &m)
{
for(DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
- if (IS_PLAYER_GUID(iter->getSource()->GetCasterGUID()))
+ uint64 guid = iter->getSource()->GetCasterGUID();
+ if(IS_PLAYER_GUID(guid))
{
- Player* caster = (Player*)iter->getSource()->GetCaster();
- if (caster->GetUInt64Value(PLAYER_FARSIGHT) == iter->getSource()->GetGUID())
- BuildPacket(caster);
+ //Caster may be NULL if DynObj is in removelist
+ if(Player *caster = FindPlayer(guid))
+ if (caster->GetUInt64Value(PLAYER_FARSIGHT) == iter->getSource()->GetGUID())
+ BuildPacket(caster);
}
}
}
@@ -602,6 +476,7 @@ template <class T> ZThread::FastMutex HashMapHolder<T>::i_lock;
template class HashMapHolder<Player>;
template class HashMapHolder<Pet>;
+template class HashMapHolder<Vehicle>;
template class HashMapHolder<GameObject>;
template class HashMapHolder<DynamicObject>;
template class HashMapHolder<Creature>;
@@ -609,6 +484,7 @@ template class HashMapHolder<Corpse>;
template Player* ObjectAccessor::GetObjectInWorld<Player>(uint32 mapid, float x, float y, uint64 guid, Player* /*fake*/);
template Pet* ObjectAccessor::GetObjectInWorld<Pet>(uint32 mapid, float x, float y, uint64 guid, Pet* /*fake*/);
+template Vehicle* ObjectAccessor::GetObjectInWorld<Vehicle>(uint32 mapid, float x, float y, uint64 guid, Vehicle* /*fake*/);
template Creature* ObjectAccessor::GetObjectInWorld<Creature>(uint32 mapid, float x, float y, uint64 guid, Creature* /*fake*/);
template Corpse* ObjectAccessor::GetObjectInWorld<Corpse>(uint32 mapid, float x, float y, uint64 guid, Corpse* /*fake*/);
template GameObject* ObjectAccessor::GetObjectInWorld<GameObject>(uint32 mapid, float x, float y, uint64 guid, GameObject* /*fake*/);
diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h
index bbfc06b78b6..dd8e02b81ab 100644
--- a/src/game/ObjectAccessor.h
+++ b/src/game/ObjectAccessor.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -41,6 +41,7 @@ class Corpse;
class Unit;
class GameObject;
class DynamicObject;
+class Vehicle;
class WorldObject;
class Map;
@@ -58,9 +59,7 @@ class HashMapHolder
static void Remove(T* o)
{
Guard guard(i_lock);
- typename MapType::iterator itr = m_objectMap.find(o->GetGUID());
- if (itr != m_objectMap.end())
- m_objectMap.erase(itr);
+ m_objectMap.erase(o->GetGUID());
}
static T* Find(uint64 guid)
@@ -139,17 +138,14 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor
else return NULL;
}
- static Object* GetObjectByTypeMask(Player const &, uint64, uint32 typemask);
- static Creature* GetNPCIfCanInteractWith(Player const &player, uint64 guid, uint32 npcflagmask);
- static Creature* GetCreature(WorldObject const &, uint64);
- static Creature* GetCreatureOrPet(WorldObject const &, uint64);
+ static Object* GetObjectByTypeMask(WorldObject const &, uint64, uint32 typemask);
+ static Creature* GetCreatureOrPetOrVehicle(WorldObject const &, uint64);
static Unit* GetUnit(WorldObject const &, uint64);
static Pet* GetPet(Unit const &, uint64 guid) { return GetPet(guid); }
static Player* GetPlayer(Unit const &, uint64 guid) { return FindPlayer(guid); }
- static GameObject* GetGameObject(WorldObject const &, uint64);
- static DynamicObject* GetDynamicObject(Unit const &, uint64);
static Corpse* GetCorpse(WorldObject const &u, uint64 guid);
static Pet* GetPet(uint64 guid);
+ static Vehicle* GetVehicle(uint64 guid);
static Player* FindPlayer(uint64);
Player* FindPlayerByName(const char *name) ;
@@ -159,6 +155,16 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor
return HashMapHolder<Player>::GetContainer();
}
+ HashMapHolder<Creature>::MapType& GetCreatures()
+ {
+ return HashMapHolder<Creature>::GetContainer();
+ }
+
+ HashMapHolder<GameObject>::MapType& GetGameObjects()
+ {
+ return HashMapHolder<GameObject>::GetContainer();
+ }
+
template<class T> void AddObject(T *object)
{
HashMapHolder<T>::Insert(object);
@@ -174,16 +180,22 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor
HashMapHolder<Player>::Remove(pl);
Guard guard(i_updateGuard);
-
- std::set<Object *>::iterator iter2 = std::find(i_objects.begin(), i_objects.end(), (Object *)pl);
- if( iter2 != i_objects.end() )
- i_objects.erase(iter2);
+ i_objects.erase((Object *)pl);
}
void SaveAllPlayers();
- void AddUpdateObject(Object *obj);
- void RemoveUpdateObject(Object *obj);
+ void AddUpdateObject(Object *obj)
+ {
+ Guard guard(i_updateGuard);
+ i_objects.insert(obj);
+ }
+
+ void RemoveUpdateObject(Object *obj)
+ {
+ Guard guard(i_updateGuard);
+ i_objects.erase( obj );
+ }
void Update(uint32 diff);
void UpdatePlayers(uint32 diff);
@@ -192,7 +204,7 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor
void RemoveCorpse(Corpse *corpse);
void AddCorpse(Corpse* corpse);
void AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map);
- Corpse* ConvertCorpseForPlayer(uint64 player_guid);
+ Corpse* ConvertCorpseForPlayer(uint64 player_guid, bool insignia = false);
static void UpdateObject(Object* obj, Player* exceptPlayer);
static void _buildUpdateObject(Object* obj, UpdateDataMapType &);
diff --git a/src/game/ObjectDefines.h b/src/game/ObjectDefines.h
index 53a0174ba2f..ee58e8a5f34 100644
--- a/src/game/ObjectDefines.h
+++ b/src/game/ObjectDefines.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -41,6 +41,7 @@ enum HighGuid
HIGHGUID_TRANSPORT = 0xF120, // blizz F120 (for GAMEOBJECT_TYPE_TRANSPORT)
HIGHGUID_UNIT = 0xF130, // blizz F130
HIGHGUID_PET = 0xF140, // blizz F140
+ HIGHGUID_VEHICLE = 0xF150, // blizz F550
HIGHGUID_DYNAMICOBJECT = 0xF100, // blizz F100
HIGHGUID_CORPSE = 0xF101, // blizz F100
HIGHGUID_MO_TRANSPORT = 0x1FC0, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT)
@@ -50,6 +51,7 @@ enum HighGuid
#define IS_CREATURE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_UNIT )
#define IS_PET_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_PET )
+#define IS_VEHICLE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_VEHICLE )
#define IS_CREATURE_OR_PET_GUID(Guid)( IS_CREATURE_GUID(Guid) || IS_PET_GUID(Guid) )
#define IS_PLAYER_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_PLAYER && Guid!=0 )
#define IS_UNIT_GUID(Guid) ( IS_CREATURE_OR_PET_GUID(Guid) || IS_PLAYER_GUID(Guid) )
@@ -87,6 +89,7 @@ inline bool IsGuidHaveEnPart(uint64 const& guid)
case HIGHGUID_TRANSPORT:
case HIGHGUID_UNIT:
case HIGHGUID_PET:
+ case HIGHGUID_VEHICLE:
case HIGHGUID_MO_TRANSPORT:
default:
return true;
@@ -106,6 +109,7 @@ inline char const* GetLogNameForGuid(uint64 guid)
case HIGHGUID_TRANSPORT: return "transport";
case HIGHGUID_UNIT: return "creature";
case HIGHGUID_PET: return "pet";
+ case HIGHGUID_VEHICLE: return "vehicle";
case HIGHGUID_DYNAMICOBJECT:return "dynobject";
case HIGHGUID_CORPSE: return "corpse";
case HIGHGUID_MO_TRANSPORT: return "mo_transport";
diff --git a/src/game/ObjectGridLoader.cpp b/src/game/ObjectGridLoader.cpp
index b819182a50d..368edce0a53 100644
--- a/src/game/ObjectGridLoader.cpp
+++ b/src/game/ObjectGridLoader.cpp
@@ -22,11 +22,13 @@
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Creature.h"
+#include "Vehicle.h"
#include "GameObject.h"
#include "DynamicObject.h"
#include "Corpse.h"
#include "World.h"
#include "CellImpl.h"
+#include "CreatureAI.h"
class TRINITY_DLL_DECL ObjectGridRespawnMover
{
@@ -57,7 +59,7 @@ ObjectGridRespawnMover::Visit(CreatureMapType &m)
Creature * c = iter->getSource();
++iter;
- assert(!c->isPet() && "ObjectGridRespawnMover don't must be called for pets");
+ assert(!c->isWorldCreature() && "ObjectGridRespawnMover don't must be called for pets");
Cell const& cur_cell = c->GetCurrentCell();
@@ -133,6 +135,36 @@ void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &
}
}
+void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, CreatureMapType &m, uint32 &count, Map* map)
+{
+ for(CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid)
+ {
+ Creature* obj = new Creature;
+ uint32 guid = *i_guid;
+ //sLog.outString("DEBUG: LoadHelper from table: %s for (guid: %u) Loading",table,guid);
+ if(!obj->LoadFromDB(guid, map))
+ {
+ delete obj;
+ obj = new Vehicle;
+ if(!((Vehicle*)obj)->LoadFromDB(guid, map))
+ {
+ delete (Vehicle*)obj;
+ continue;
+ }
+ }
+
+ obj->GetGridRef().link(&m, obj);
+
+ addUnitState(obj,cell);
+ obj->AddToWorld();
+ if(obj->isActiveObject())
+ map->AddToActive(obj);
+
+ ++count;
+
+ }
+}
+
void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType &m, uint32 &count, Map* map)
{
if(cell_corpses.empty())
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index c948ad9d073..18242265fcb 100644
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -30,14 +30,13 @@
#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 "Language.h"
-#include "GameEvent.h"
+#include "GameEventMgr.h"
#include "Spell.h"
#include "Chat.h"
#include "AccountMgr.h"
@@ -116,6 +115,7 @@ ObjectMgr::ObjectMgr()
m_hiCharGuid = 1;
m_hiCreatureGuid = 1;
m_hiPetGuid = 1;
+ m_hiVehicleGuid = 1;
m_hiItemGuid = 1;
m_hiGoGuid = 1;
m_hiDoGuid = 1;
@@ -142,24 +142,10 @@ ObjectMgr::ObjectMgr()
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_)
@@ -251,7 +237,7 @@ Group * ObjectMgr::GetGroupByLeader(const uint64 &guid) const
return NULL;
}
-Guild * ObjectMgr::GetGuildById(const uint32 GuildId) const
+Guild * ObjectMgr::GetGuildById(uint32 GuildId) const
{
GuildMap::const_iterator itr = mGuildMap.find(GuildId);
if (itr != mGuildMap.end())
@@ -269,7 +255,7 @@ Guild * ObjectMgr::GetGuildByName(const std::string& guildname) const
return NULL;
}
-std::string ObjectMgr::GetGuildNameById(const uint32 GuildId) const
+std::string ObjectMgr::GetGuildNameById(uint32 GuildId) const
{
GuildMap::const_iterator itr = mGuildMap.find(GuildId);
if (itr != mGuildMap.end())
@@ -296,7 +282,8 @@ void ObjectMgr::RemoveGuild(uint32 Id)
{
mGuildMap.erase(Id);
}
-ArenaTeam* ObjectMgr::GetArenaTeamById(const uint32 arenateamid) const
+
+ArenaTeam* ObjectMgr::GetArenaTeamById(uint32 arenateamid) const
{
ArenaTeamMap::const_iterator itr = mArenaTeamMap.find(arenateamid);
if (itr != mArenaTeamMap.end())
@@ -350,7 +337,7 @@ void ObjectMgr::LoadCreatureLocales()
bar.step();
- sLog.outString("");
+ sLog.outString();
sLog.outString(">> Loaded 0 creature locale strings. DB table `locales_creature` is empty.");
return;
}
@@ -398,7 +385,7 @@ void ObjectMgr::LoadCreatureLocales()
delete result;
sLog.outString();
- sLog.outString( ">> Loaded %u creature locale strings", mCreatureLocaleMap.size() );
+ sLog.outString( ">> Loaded %lu creature locale strings", (unsigned long)mCreatureLocaleMap.size() );
}
void ObjectMgr::LoadNpcOptionLocales()
@@ -418,7 +405,7 @@ void ObjectMgr::LoadNpcOptionLocales()
bar.step();
- sLog.outString("");
+ sLog.outString();
sLog.outString(">> Loaded 0 npc_option locale strings. DB table `locales_npc_option` is empty.");
return;
}
@@ -466,13 +453,64 @@ void ObjectMgr::LoadNpcOptionLocales()
delete result;
sLog.outString();
- sLog.outString( ">> Loaded %u npc_option locale strings", mNpcOptionLocaleMap.size() );
+ sLog.outString( ">> Loaded %lu npc_option locale strings", (unsigned long)mNpcOptionLocaleMap.size() );
+}
+
+void ObjectMgr::LoadPointOfInterestLocales()
+{
+ mPointOfInterestLocaleMap.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query("SELECT entry,icon_name_loc1,icon_name_loc2,icon_name_loc3,icon_name_loc4,icon_name_loc5,icon_name_loc6,icon_name_loc7,icon_name_loc8 FROM locales_points_of_interest");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outString(">> Loaded 0 points_of_interest locale strings. DB table `locales_points_of_interest` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 entry = fields[0].GetUInt32();
+
+ PointOfInterestLocale& data = mPointOfInterestLocaleMap[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.IconName.size() <= idx)
+ data.IconName.resize(idx+1);
+
+ data.IconName[idx] = str;
+ }
+ }
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %lu points_of_interest locale strings", (unsigned long)mPointOfInterestLocaleMap.size() );
}
struct SQLCreatureLoader : public SQLStorageLoaderBase<SQLCreatureLoader>
{
template<class D>
- void convert_from_str(uint32 field_pos, char *src, D &dst)
+ void convert_from_str(uint32 /*field_pos*/, char *src, D &dst)
{
dst = D(objmgr.GetScriptId(src));
}
@@ -553,6 +591,18 @@ void ObjectMgr::LoadCreatureTemplates()
continue;
}
+ if(heroicInfo->AIName && *heroicInfo->AIName)
+ {
+ sLog.outErrorDb("Heroic mode creature (Entry: %u) has `AIName`, but in any case will used normal mode creature (Entry: %u) AIName.",cInfo->HeroicEntry,i);
+ continue;
+ }
+
+ if(heroicInfo->ScriptID)
+ {
+ sLog.outErrorDb("Heroic mode creature (Entry: %u) has `ScriptName`, but in any case will used normal mode creature (Entry: %u) ScriptName.",cInfo->HeroicEntry,i);
+ continue;
+ }
+
hasHeroicEntries.insert(i);
heroicEntries.insert(cInfo->HeroicEntry);
}
@@ -602,6 +652,19 @@ void ObjectMgr::LoadCreatureTemplates()
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->type && !sCreatureTypeStore.LookupEntry(cInfo->type))
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has invalid creature type (%u) in `type`",cInfo->Entry,cInfo->type);
+ const_cast<CreatureInfo*>(cInfo)->type = CREATURE_TYPE_HUMANOID;
+ }
+
+ // must exist or used hidden but used in data horse case
+ if(cInfo->family && !sCreatureFamilyStore.LookupEntry(cInfo->family) && cInfo->family != CREATURE_FAMILY_HORSE_CUSTOM )
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has invalid creature family (%u) in `family`",cInfo->Entry,cInfo->family);
+ const_cast<CreatureInfo*>(cInfo)->family = 0;
+ }
+
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);
@@ -615,6 +678,15 @@ void ObjectMgr::LoadCreatureTemplates()
sLog.outErrorDb("Creature (Entry: %u) has non-existing PetSpellDataId (%u)", cInfo->Entry, cInfo->PetSpellDataId);
}
+ for(int j = 0; j < CREATURE_MAX_SPELLS; ++j)
+ {
+ if(cInfo->spells[j] && !sSpellStore.LookupEntry(cInfo->spells[j]))
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has non-existing Spell%d (%u), set to 0", cInfo->Entry, j+1,cInfo->spells[j]);
+ const_cast<CreatureInfo*>(cInfo)->spells[j] = 0;
+ }
+ }
+
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);
@@ -763,8 +835,47 @@ void ObjectMgr::LoadEquipmentTemplates()
{
sEquipmentStorage.Load();
+ for(uint32 i=0; i< sEquipmentStorage.MaxEntry; ++i)
+ {
+ EquipmentInfo const* eqInfo = sEquipmentStorage.LookupEntry<EquipmentInfo>(i);
+
+ if(!eqInfo)
+ continue;
+
+ for(uint8 j=0; j<3; j++)
+ {
+ if(!eqInfo->equipentry[j])
+ continue;
+
+ ItemEntry const *dbcitem = sItemStore.LookupEntry(eqInfo->equipentry[j]);
+
+ if(!dbcitem)
+ {
+ sLog.outErrorDb("Unknown item (entry=%u) in creature_equip_template.equipentry%u for entry = %u, forced to 0.", eqInfo->equipentry[j], j+1, i);
+ const_cast<EquipmentInfo*>(eqInfo)->equipentry[j] = 0;
+ continue;
+ }
+
+ if(dbcitem->InventoryType != INVTYPE_WEAPON &&
+ dbcitem->InventoryType != INVTYPE_SHIELD &&
+ dbcitem->InventoryType != INVTYPE_RANGED &&
+ dbcitem->InventoryType != INVTYPE_2HWEAPON &&
+ dbcitem->InventoryType != INVTYPE_WEAPONMAINHAND &&
+ dbcitem->InventoryType != INVTYPE_WEAPONOFFHAND &&
+ dbcitem->InventoryType != INVTYPE_HOLDABLE &&
+ dbcitem->InventoryType != INVTYPE_THROWN &&
+ dbcitem->InventoryType != INVTYPE_RANGEDRIGHT)
+ {
+ sLog.outErrorDb("Item (entry=%u) in creature_equip_template.equipentry%u for entry = %u is not equipable in a hand, forced to 0.", eqInfo->equipentry[j], j+1, i);
+ const_cast<EquipmentInfo*>(eqInfo)->equipentry[j] = 0;
+ }
+ }
+ }
sLog.outString( ">> Loaded %u equipment template", sEquipmentStorage.RecordCount );
sLog.outString();
+
+ // This DBC is currently only used for item templates and creature equipments checks.
+ sItemStore.Clear();
}
CreatureModelInfo const* ObjectMgr::GetCreatureModelInfo(uint32 modelid)
@@ -924,9 +1035,10 @@ void ObjectMgr::LoadCreatures()
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");
+ // 12 13 14 15 16 17 18 19
+ "curhealth, curmana, DeathState, MovementType, spawnMask, phaseMask, event, pool_entry "
+ "FROM creature LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid "
+ "LEFT OUTER JOIN pool_creature ON creature.guid = pool_creature.guid");
if(!result)
{
@@ -934,7 +1046,7 @@ void ObjectMgr::LoadCreatures()
bar.step();
- sLog.outString("");
+ sLog.outString();
sLog.outErrorDb(">> Loaded 0 creature. DB table `creature` is empty.");
return;
}
@@ -953,11 +1065,19 @@ void ObjectMgr::LoadCreatures()
Field *fields = result->Fetch();
bar.step();
- uint32 guid = fields[0].GetUInt32();
+ uint32 guid = fields[ 0].GetUInt32();
+ uint32 entry = fields[ 1].GetUInt32();
+
+ CreatureInfo const* cInfo = GetCreatureTemplate(entry);
+ if(!cInfo)
+ {
+ sLog.outErrorDb("Table `creature` has creature (GUID: %u) with non existing creature entry %u, skipped.", guid, entry);
+ continue;
+ }
CreatureData& data = mCreatureDataMap[guid];
- data.id = fields[ 1].GetUInt32();
+ data.id = entry;
data.mapid = fields[ 2].GetUInt32();
data.displayid = fields[ 3].GetUInt32();
data.equipmentId = fields[ 4].GetUInt32();
@@ -973,14 +1093,9 @@ void ObjectMgr::LoadCreatures()
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;
- }
+ data.phaseMask = fields[17].GetUInt16();
+ int16 gameEvent = fields[18].GetInt16();
+ int16 PoolId = fields[19].GetInt16();
if(heroicCreatures.find(data.id)!=heroicCreatures.end())
{
@@ -1003,6 +1118,13 @@ void ObjectMgr::LoadCreatures()
data.curhealth = cInfo->minhealth;
}
+ if(cInfo->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND)
+ {
+ MapEntry const* map = sMapStore.LookupEntry(data.mapid);
+ if(!map || !map->IsDungeon())
+ sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `creature_template`.`flags_extra` including CREATURE_FLAG_EXTRA_INSTANCE_BIND but creature are not in instance.",guid,data.id);
+ }
+
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 );
@@ -1031,8 +1153,15 @@ void ObjectMgr::LoadCreatures()
}
}
- if (gameEvent==0) // if not this is to be managed by GameEvent System
+ if(data.phaseMask==0)
+ {
+ sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `phaseMask`=0 (not visible for anyone), set to 1.",guid,data.id );
+ data.phaseMask = 1;
+ }
+
+ if (gameEvent==0 && PoolId==0) // if not this is to be managed by GameEvent System or Pool system
AddCreatureToGrid(guid, &data);
+
++count;
} while (result->NextRow());
@@ -1040,7 +1169,7 @@ void ObjectMgr::LoadCreatures()
delete result;
sLog.outString();
- sLog.outString( ">> Loaded %u creatures", mCreatureDataMap.size() );
+ sLog.outString( ">> Loaded %lu creatures", (unsigned long)mCreatureDataMap.size() );
}
void ObjectMgr::AddCreatureToGrid(uint32 guid, CreatureData const* data)
@@ -1081,9 +1210,10 @@ void ObjectMgr::LoadGameobjects()
// 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");
+ // 7 8 9 10 11 12 13 14 15 16 17
+ "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, event, pool_entry "
+ "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid "
+ "LEFT OUTER JOIN pool_gameobject ON gameobject.guid = pool_gameobject.guid");
if(!result)
{
@@ -1103,11 +1233,19 @@ void ObjectMgr::LoadGameobjects()
Field *fields = result->Fetch();
bar.step();
- uint32 guid = fields[0].GetUInt32();
+ uint32 guid = fields[ 0].GetUInt32();
+ uint32 entry = fields[ 1].GetUInt32();
+
+ GameObjectInfo const* gInfo = GetGameObjectInfo(entry);
+ if(!gInfo)
+ {
+ sLog.outErrorDb("Table `gameobject` has gameobject (GUID: %u) with non existing gameobject entry %u, skipped.", guid, entry);
+ continue;
+ }
GameObjectData& data = mGameObjectDataMap[guid];
- data.id = fields[ 1].GetUInt32();
+ data.id = entry;
data.mapid = fields[ 2].GetUInt32();
data.posX = fields[ 3].GetFloat();
data.posY = fields[ 4].GetFloat();
@@ -1119,19 +1257,46 @@ void ObjectMgr::LoadGameobjects()
data.rotation3 = fields[10].GetFloat();
data.spawntimesecs = fields[11].GetInt32();
data.animprogress = fields[12].GetUInt32();
- data.go_state = fields[13].GetUInt32();
data.ArtKit = 0;
+
+ uint32 go_state = fields[13].GetUInt32();
+ if (go_state >= MAX_GO_STATE)
+ {
+ sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with invalid `state` (%u) value, skip",guid,data.id,go_state);
+ continue;
+ }
+ data.go_state = GOState(go_state);
+
data.spawnMask = fields[14].GetUInt8();
- int16 gameEvent = fields[15].GetInt16();
+ data.phaseMask = fields[15].GetUInt16();
+ int16 gameEvent = fields[16].GetInt16();
+ int16 PoolId = fields[17].GetInt16();
- GameObjectInfo const* gInfo = GetGameObjectInfo(data.id);
- if(!gInfo)
+ if(data.rotation2 < -1.0f || data.rotation2 > 1.0f)
+ {
+ sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with invalid rotation2 (%f) value, skip",guid,data.id,data.rotation2 );
+ continue;
+ }
+
+ if(data.rotation3 < -1.0f || data.rotation3 > 1.0f)
+ {
+ sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with invalid rotation3 (%f) value, skip",guid,data.id,data.rotation3 );
+ continue;
+ }
+
+ if(!MapManager::IsValidMapCoord(data.mapid,data.posX,data.posY,data.posZ,data.orientation))
{
- sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u) with not existed gameobject entry %u, skipped.",guid,data.id );
+ sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with invalid coordinates, skip",guid,data.id );
continue;
}
- if (gameEvent==0) // if not this is to be managed by GameEvent System
+ if(data.phaseMask==0)
+ {
+ sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with `phaseMask`=0 (not visible for anyone), set to 1.",guid,data.id );
+ data.phaseMask = 1;
+ }
+
+ if (gameEvent==0 && PoolId==0) // if not this is to be managed by GameEvent System or Pool system
AddGameobjectToGrid(guid, &data);
++count;
@@ -1140,7 +1305,7 @@ void ObjectMgr::LoadGameobjects()
delete result;
sLog.outString();
- sLog.outString( ">> Loaded %u gameobjects", mGameObjectDataMap.size());
+ sLog.outString( ">> Loaded %lu gameobjects", (unsigned long)mGameObjectDataMap.size());
}
void ObjectMgr::AddGameobjectToGrid(uint32 guid, GameObjectData const* data)
@@ -1210,7 +1375,7 @@ void ObjectMgr::LoadCreatureRespawnTimes()
delete result;
- sLog.outString( ">> Loaded %u creature respawn times", mCreatureRespawnTimes.size() );
+ sLog.outString( ">> Loaded %lu creature respawn times", (unsigned long)mCreatureRespawnTimes.size() );
sLog.outString();
}
@@ -1252,7 +1417,7 @@ void ObjectMgr::LoadGameobjectRespawnTimes()
delete result;
- sLog.outString( ">> Loaded %u gameobject respawn times", mGORespawnTimes.size() );
+ sLog.outString( ">> Loaded %lu gameobject respawn times", (unsigned long)mGORespawnTimes.size() );
sLog.outString();
}
@@ -1355,7 +1520,7 @@ void ObjectMgr::LoadItemLocales()
bar.step();
- sLog.outString("");
+ sLog.outString();
sLog.outString(">> Loaded 0 Item locale strings. DB table `locales_item` is empty.");
return;
}
@@ -1404,13 +1569,13 @@ void ObjectMgr::LoadItemLocales()
delete result;
sLog.outString();
- sLog.outString( ">> Loaded %u Item locale strings", mItemLocaleMap.size() );
+ sLog.outString( ">> Loaded %lu Item locale strings", (unsigned long)mItemLocaleMap.size() );
}
struct SQLItemLoader : public SQLStorageLoaderBase<SQLItemLoader>
{
template<class D>
- void convert_from_str(uint32 field_pos, char *src, D &dst)
+ void convert_from_str(uint32 /*field_pos*/, char *src, D &dst)
{
dst = D(objmgr.GetScriptId(src));
}
@@ -1439,6 +1604,32 @@ void ObjectMgr::LoadItemPrototypes()
if(dbcitem)
{
+ if(proto->Class != dbcitem->Class)
+ {
+ sLog.outErrorDb("Item (Entry: %u) not correct class %u, must be %u (still using DB value).",i,proto->Class,dbcitem->Class);
+ // It safe let use Class from DB
+ }
+ /* disabled: have some strange wrong cases for Subclass values.
+ for enable also uncomment Subclass field in ItemEntry structure and in Itemfmt[]
+ if(proto->SubClass != dbcitem->SubClass)
+ {
+ sLog.outErrorDb("Item (Entry: %u) not correct (Class: %u, Sub: %u) pair, must be (Class: %u, Sub: %u) (still using DB value).",i,proto->Class,proto->SubClass,dbcitem->Class,dbcitem->SubClass);
+ // It safe let use Subclass from DB
+ }
+ */
+
+ if(proto->Unk0 != dbcitem->Unk0)
+ {
+ sLog.outErrorDb("Item (Entry: %u) not correct %i Unk0, must be %i (still using DB value).",i,proto->Unk0,dbcitem->Unk0);
+ // It safe let use Unk0 from DB
+ }
+
+ if(proto->Material != dbcitem->Material)
+ {
+ sLog.outErrorDb("Item (Entry: %u) not correct %i material, must be %i (still using DB value).",i,proto->Material,dbcitem->Material);
+ // It safe let use Material from DB
+ }
+
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);
@@ -1464,7 +1655,7 @@ void ObjectMgr::LoadItemPrototypes()
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;
+ const_cast<ItemPrototype*>(proto)->Class = ITEM_CLASS_MISC;
}
if(proto->SubClass >= MaxItemSubclassValues[proto->Class])
@@ -1497,14 +1688,30 @@ void ObjectMgr::LoadItemPrototypes()
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);
+ // can be used in equip slot, as page read use in inventory, or spell casting at use
+ bool req = proto->InventoryType!=INVTYPE_NON_EQUIP || proto->PageText;
+ if(!req)
+ {
+ for (int j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j)
+ {
+ if(proto->Spells[j].SpellId)
+ {
+ req = true;
+ break;
+ }
+ }
+ }
+
+ if(req)
+ {
+ if(!(proto->AllowableClass & CLASSMASK_ALL_PLAYABLE))
+ sLog.outErrorDb("Item (Entry: %u) not have in `AllowableClass` any playable classes (%u) and can't be equipped or use.",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 or use.",i,proto->AllowableRace);
+ }
}
if(proto->RequiredSpell && !sSpellStore.LookupEntry(proto->RequiredSpell))
@@ -1530,18 +1737,35 @@ void ObjectMgr::LoadItemPrototypes()
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->MaxCount < -1)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has too large negative in maxcount (%i), replace by value (-1) no storing limits.",i,proto->MaxCount);
+ const_cast<ItemPrototype*>(proto)->MaxCount = -1;
+ }
+
if(proto->Stackable==0)
{
- sLog.outErrorDb("Item (Entry: %u) has wrong value in stackable (%u), replace by default 1.",i,proto->Stackable);
+ sLog.outErrorDb("Item (Entry: %u) has wrong value in stackable (%i), replace by default 1.",i,proto->Stackable);
const_cast<ItemPrototype*>(proto)->Stackable = 1;
}
+ else if(proto->Stackable < -1)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has too large negative in stackable (%i), replace by value (-1) no stacking limits.",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++)
+ if(proto->StatsCount > MAX_ITEM_PROTO_STATS)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has too large value in statscount (%u), replace by hardcoded limit (%u).",i,proto->StatsCount,MAX_ITEM_PROTO_STATS);
+ const_cast<ItemPrototype*>(proto)->StatsCount = MAX_ITEM_PROTO_STATS;
+ }
+
+ for (int j = 0; j < MAX_ITEM_PROTO_STATS; ++j)
{
// for ItemStatValue != 0
if(proto->ItemStat[j].ItemStatValue && proto->ItemStat[j].ItemStatType >= MAX_ITEM_MOD)
@@ -1551,7 +1775,7 @@ void ObjectMgr::LoadItemPrototypes()
}
}
- for (int j = 0; j < 5; j++)
+ for (int j = 0; j < MAX_ITEM_PROTO_DAMAGES; ++j)
{
if(proto->Damage[j].DamageType >= MAX_SPELL_SCHOOL)
{
@@ -1561,7 +1785,7 @@ void ObjectMgr::LoadItemPrototypes()
}
// special format
- if(proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN)
+ if((proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN) || (proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN_PET))
{
// spell_1
if(proto->Spells[0].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
@@ -1598,7 +1822,7 @@ void ObjectMgr::LoadItemPrototypes()
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)
+ else if((proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN) || (proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN_PET))
{
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;
@@ -1608,7 +1832,7 @@ void ObjectMgr::LoadItemPrototypes()
}
// spell_3*,spell_4*,spell_5* is empty
- for (int j = 2; j < 5; j++)
+ for (int j = 2; j < MAX_ITEM_PROTO_SPELLS; ++j)
{
if(proto->Spells[j].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
{
@@ -1626,7 +1850,7 @@ void ObjectMgr::LoadItemPrototypes()
// normal spell list
else
{
- for (int j = 0; j < 5; j++)
+ for (int j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j)
{
if(proto->Spells[j].SpellTrigger >= MAX_ITEM_SPELLTRIGGER || proto->Spells[j].SpellTrigger == ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
{
@@ -1644,7 +1868,7 @@ void ObjectMgr::LoadItemPrototypes()
const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0;
}
// allowed only in special format
- else if(proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN)
+ else if((proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN) || (proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN_PET))
{
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;
@@ -1692,10 +1916,39 @@ void ObjectMgr::LoadItemPrototypes()
if(proto->Map && !sMapStore.LookupEntry(proto->Map))
sLog.outErrorDb("Item (Entry: %u) has wrong Map (%u)",i,proto->Map);
+ if(proto->BagFamily)
+ {
+ // check bits
+ for(uint32 j = 0; j < sizeof(proto->BagFamily)*8; ++j)
+ {
+ uint32 mask = 1 << j;
+ if((proto->BagFamily & mask)==0)
+ continue;
+
+ ItemBagFamilyEntry const* bf = sItemBagFamilyStore.LookupEntry(j+1);
+ if(!bf)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has bag family bit set not listed in ItemBagFamily.dbc, remove bit",i);
+ const_cast<ItemPrototype*>(proto)->BagFamily &= ~mask;
+ continue;
+ }
+
+ if(BAG_FAMILY_MASK_CURRENCY_TOKENS & mask)
+ {
+ CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(proto->ItemId);
+ if(!ctEntry)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has currency bag family bit set in BagFamily but not listed in CurrencyTypes.dbc, remove bit",i);
+ const_cast<ItemPrototype*>(proto)->BagFamily &= ~mask;
+ }
+ }
+ }
+ }
+
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++)
+ for (int j = 0; j < MAX_ITEM_PROTO_SOCKETS; j++)
{
if(proto->Socket[j].Color && (proto->Socket[j].Color & SOCKET_COLOR_ALL) != proto->Socket[j].Color)
{
@@ -1712,10 +1965,13 @@ void ObjectMgr::LoadItemPrototypes()
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();
+ if(proto->ItemLimitCategory && !sItemLimitCategoryStore.LookupEntry(proto->ItemLimitCategory))
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong LimitCategory value (%u)",i,proto->ItemLimitCategory);
+ const_cast<ItemPrototype*>(proto)->ItemLimitCategory = 0;
+ }
+ }
}
void ObjectMgr::LoadPetLevelInfo()
@@ -1756,7 +2012,10 @@ void ObjectMgr::LoadPetLevelInfo()
if(current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
sLog.outErrorDb("Wrong (> %u) level %u in `pet_levelstats` table, ignoring.",STRONG_MAX_LEVEL,current_level);
else
+ {
sLog.outDetail("Unused (> MaxPlayerLevel in Trinityd.conf) level %u in `pet_levelstats` table, ignoring.",current_level);
+ ++count; // make result loading percent "expected" correct in case disabled detail mode for example.
+ }
continue;
}
else if(current_level < 1)
@@ -1999,7 +2258,7 @@ void ObjectMgr::LoadPlayerInfo()
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");
+ result = WorldDatabase.Query("SELECT race, class, Spell FROM playercreateinfo_spell");
uint32 count = 0;
@@ -2034,7 +2293,7 @@ void ObjectMgr::LoadPlayerInfo()
}
PlayerInfo* pInfo = &playerInfo[current_race][current_class];
- pInfo->spell.push_back(CreateSpellPair(fields[2].GetUInt16(), fields[3].GetUInt8()));
+ pInfo->spell.push_back(fields[2].GetUInt32());
bar.step();
++count;
@@ -2139,7 +2398,10 @@ void ObjectMgr::LoadPlayerInfo()
if(current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
sLog.outErrorDb("Wrong (> %u) level %u in `player_classlevelstats` table, ignoring.",STRONG_MAX_LEVEL,current_level);
else
+ {
sLog.outDetail("Unused (> MaxPlayerLevel in Trinityd.conf) level %u in `player_classlevelstats` table, ignoring.",current_level);
+ ++count; // make result loading percent "expected" correct in case disabled detail mode for example.
+ }
continue;
}
@@ -2234,7 +2496,10 @@ void ObjectMgr::LoadPlayerInfo()
if(current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
sLog.outErrorDb("Wrong (> %u) level %u in `player_levelstats` table, ignoring.",STRONG_MAX_LEVEL,current_level);
else
+ {
sLog.outDetail("Unused (> MaxPlayerLevel in Trinityd.conf) level %u in `player_levelstats` table, ignoring.",current_level);
+ ++count; // make result loading percent "expected" correct in case disabled detail mode for example.
+ }
continue;
}
@@ -2306,6 +2571,70 @@ void ObjectMgr::LoadPlayerInfo()
}
}
}
+
+ // Loading xp per level data
+ {
+ mPlayerXPperLevel.resize(sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
+ for (uint32 level = 0; level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
+ mPlayerXPperLevel[level] = 0;
+
+ // 0 1
+ QueryResult *result = WorldDatabase.Query("SELECT lvl, xp_for_next_level FROM player_xp_for_level");
+
+ uint32 count = 0;
+
+ if (!result)
+ {
+ barGoLink bar( 1 );
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u xp for level definitions", count );
+ sLog.outErrorDb( "Error loading `player_xp_for_level` table or empty table.");
+ exit(1);
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 current_level = fields[0].GetUInt32();
+ uint32 current_xp = fields[1].GetUInt32();
+
+ if(current_level >= sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ {
+ if(current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
+ sLog.outErrorDb("Wrong (> %u) level %u in `player_xp_for_level` table, ignoring.", STRONG_MAX_LEVEL,current_level);
+ else
+ {
+ sLog.outDetail("Unused (> MaxPlayerLevel in mangosd.conf) level %u in `player_xp_for_levels` table, ignoring.",current_level);
+ ++count; // make result loading percent "expected" correct in case disabled detail mode for example.
+ }
+ continue;
+ }
+ //PlayerXPperLevel
+ mPlayerXPperLevel[current_level] = current_xp;
+ bar.step();
+ ++count;
+ }
+ while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u xp for level definitions", count );
+ }
+
+ // fill level gaps
+ for (uint32 level = 1; level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
+ {
+ if( mPlayerXPperLevel[level] == 0)
+ {
+ sLog.outErrorDb("Level %i does not have XP for level data. Using data of level [%i] + 100.",level+1, level);
+ mPlayerXPperLevel[level] = mPlayerXPperLevel[level-1]+100;
+ }
+ }
}
void ObjectMgr::GetPlayerClassLevelInfo(uint32 class_, uint32 level, PlayerClassLevelInfo* info) const
@@ -2550,15 +2879,15 @@ void ObjectMgr::LoadGroups()
result = CharacterDatabase.Query("SELECT memberGuid, assistant, subgroup, leaderGuid FROM group_member ORDER BY leaderGuid");
if(!result)
{
- barGoLink bar( 1 );
- bar.step();
+ barGoLink bar2( 1 );
+ bar2.step();
}
else
{
- barGoLink bar( result->GetRowCount() );
+ barGoLink bar2( result->GetRowCount() );
do
{
- bar.step();
+ bar2.step();
Field *fields = result->Fetch();
count++;
leaderGuid = MAKE_NEW_GUID(fields[3].GetUInt32(), 0, HIGHGUID_PLAYER);
@@ -2610,15 +2939,15 @@ void ObjectMgr::LoadGroups()
if(!result)
{
- barGoLink bar( 1 );
- bar.step();
+ barGoLink bar2( 1 );
+ bar2.step();
}
else
{
- barGoLink bar( result->GetRowCount() );
+ barGoLink bar2( result->GetRowCount() );
do
{
- bar.step();
+ bar2.step();
Field *fields = result->Fetch();
count++;
leaderGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
@@ -2632,7 +2961,14 @@ void ObjectMgr::LoadGroups()
}
}
- InstanceSave *save = sInstanceSaveManager.AddInstanceSave(fields[1].GetUInt32(), fields[2].GetUInt32(), fields[4].GetUInt8(), (time_t)fields[5].GetUInt64(), (fields[6].GetUInt32() == 0), true);
+ MapEntry const* mapEntry = sMapStore.LookupEntry(fields[1].GetUInt32());
+ if(!mapEntry || !mapEntry->IsDungeon())
+ {
+ sLog.outErrorDb("Incorrect entry in group_instance table : no dungeon map %d", fields[1].GetUInt32());
+ continue;
+ }
+
+ InstanceSave *save = sInstanceSaveManager.AddInstanceSave(mapEntry->MapID, 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;
@@ -2658,31 +2994,31 @@ void ObjectMgr::LoadQuests()
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
+ // 17 18 19 20 21 22 23 24 25 26 27 28
+ "QuestFlags, SpecialFlags, CharTitleId, PlayersSlain, BonusTalents, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, SrcItemId, SrcItemCount, SrcSpell,"
+ // 29 30 31 32 33 34 35 36 37 38
"Title, Details, Objectives, OfferRewardText, RequestItemsText, EndText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4,"
- // 37 38 39 40 41 42 43 44
+ // 39 40 41 42 43 44 45 46
"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
+ // 47 48 49 50 51 52 53 54
+ "ReqSourceId1, ReqSourceId2, ReqSourceId3, ReqSourceId4, ReqSourceCount1, ReqSourceCount2, ReqSourceCount3, ReqSourceCount4,"
+ // 55 56 57 58 59 60 61 62
"ReqCreatureOrGOId1, ReqCreatureOrGOId2, ReqCreatureOrGOId3, ReqCreatureOrGOId4, ReqCreatureOrGOCount1, ReqCreatureOrGOCount2, ReqCreatureOrGOCount3, ReqCreatureOrGOCount4,"
- // 65 66 67 68
+ // 63 64 65 66
"ReqSpellCast1, ReqSpellCast2, ReqSpellCast3, ReqSpellCast4,"
- // 69 70 71 72 73 74
+ // 67 68 69 70 71 72
"RewChoiceItemId1, RewChoiceItemId2, RewChoiceItemId3, RewChoiceItemId4, RewChoiceItemId5, RewChoiceItemId6,"
- // 75 76 77 78 79 80
+ // 73 74 75 76 77 78
"RewChoiceItemCount1, RewChoiceItemCount2, RewChoiceItemCount3, RewChoiceItemCount4, RewChoiceItemCount5, RewChoiceItemCount6,"
- // 81 82 83 84 85 86 87 88
+ // 79 80 81 82 83 84 85 86
"RewItemId1, RewItemId2, RewItemId3, RewItemId4, RewItemCount1, RewItemCount2, RewItemCount3, RewItemCount4,"
- // 89 90 91 92 93 94 95 96 97 98
+ // 87 88 89 90 91 92 93 94 95 96
"RewRepFaction1, RewRepFaction2, RewRepFaction3, RewRepFaction4, RewRepFaction5, RewRepValue1, RewRepValue2, RewRepValue3, RewRepValue4, RewRepValue5,"
- // 99 100 101 102 103 104 105 106 107 108 109
+ // 97 98 99 100 101 102 103 104 105 106 107
"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
+ // 108 109 110 111 112 113 114 115 116 117
+ "DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4, IncompleteEmote, CompleteEmote, OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4,"
+ // 118 119
"StartScript, CompleteScript"
" FROM quest_template");
if(result == NULL)
@@ -2854,10 +3190,10 @@ void ObjectMgr::LoadQuests()
// no changes, quest can't be done for this requirement
}
- if(qinfo->RequiredMinRepValue && qinfo->RequiredMinRepValue > Player::Reputation_Cap)
+ if(qinfo->RequiredMinRepValue && qinfo->RequiredMinRepValue > ReputationMgr::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);
+ qinfo->GetQuestId(),qinfo->RequiredMinRepValue,ReputationMgr::Reputation_Cap);
// no changes, quest can't be done for this requirement
}
@@ -2976,20 +3312,6 @@ void ObjectMgr::LoadQuests()
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
{
@@ -2999,41 +3321,6 @@ void ObjectMgr::LoadQuests()
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
- }
}
}
@@ -3047,7 +3334,7 @@ void ObjectMgr::LoadQuests()
{
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
+ continue;
}
if(!qinfo->ReqCreatureOrGOId[j])
@@ -3254,14 +3541,15 @@ void ObjectMgr::LoadQuests()
if(qinfo->NextQuestInChain)
{
- if(mQuestTemplates.find(qinfo->NextQuestInChain) == mQuestTemplates.end())
+ QuestMap::iterator qNextItr = mQuestTemplates.find(qinfo->NextQuestInChain);
+ if(qNextItr == 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());
+ qNextItr->second->prevChainQuests.push_back(qinfo->GetQuestId());
}
// fill additional data stores
@@ -3279,14 +3567,15 @@ void ObjectMgr::LoadQuests()
if(qinfo->NextQuestId)
{
- if (mQuestTemplates.find(abs(qinfo->GetNextQuestId())) == mQuestTemplates.end())
+ QuestMap::iterator qNextItr = mQuestTemplates.find(abs(qinfo->GetNextQuestId()));
+ if (qNextItr == 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);
+ qNextItr->second->prevQuests.push_back(signedQuestId);
}
}
@@ -3327,7 +3616,7 @@ void ObjectMgr::LoadQuests()
}
sLog.outString();
- sLog.outString( ">> Loaded %u quests definitions", mQuestTemplates.size() );
+ sLog.outString( ">> Loaded %lu quests definitions", (unsigned long)mQuestTemplates.size() );
}
void ObjectMgr::LoadQuestLocales()
@@ -3352,7 +3641,7 @@ void ObjectMgr::LoadQuestLocales()
bar.step();
- sLog.outString("");
+ sLog.outString();
sLog.outString(">> Loaded 0 Quest locale strings. DB table `locales_quest` is empty.");
return;
}
@@ -3463,7 +3752,7 @@ void ObjectMgr::LoadQuestLocales()
delete result;
sLog.outString();
- sLog.outString( ">> Loaded %u Quest locale strings", mQuestLocaleMap.size() );
+ sLog.outString( ">> Loaded %lu Quest locale strings", (unsigned long)mQuestLocaleMap.size() );
}
void ObjectMgr::LoadPetCreateSpells()
@@ -3584,6 +3873,16 @@ void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename)
break;
}
+ case SCRIPT_COMMAND_EMOTE:
+ {
+ if(!sEmotesStore.LookupEntry(tmp.datalong))
+ {
+ sLog.outErrorDb("Table `%s` has invalid emote id (datalong = %u) in SCRIPT_COMMAND_EMOTE for script id %u",tablename,tmp.datalong,tmp.id);
+ continue;
+ }
+ break;
+ }
+
case SCRIPT_COMMAND_TELEPORT_TO:
{
if(!sMapStore.LookupEntry(tmp.datalong))
@@ -3712,6 +4011,21 @@ void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename)
}
case SCRIPT_COMMAND_REMOVE_AURA:
+ {
+ 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;
+ }
+ if(tmp.datalong2 & ~0x1) // 1 bits (0,1)
+ {
+ sLog.outErrorDb("Table `%s` using unknown flags in datalong2 (%u)i n SCRIPT_COMMAND_CAST_SPELL for script id %u",
+ tablename,tmp.datalong2,tmp.id);
+ continue;
+ }
+ break;
+ }
case SCRIPT_COMMAND_CAST_SPELL:
{
if(!sSpellStore.LookupEntry(tmp.datalong))
@@ -3720,6 +4034,12 @@ void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename)
tablename,tmp.datalong,tmp.id);
continue;
}
+ if(tmp.datalong2 & ~0x3) // 2 bits
+ {
+ sLog.outErrorDb("Table `%s` using unknown flags in datalong2 (%u)i n SCRIPT_COMMAND_CAST_SPELL for script id %u",
+ tablename,tmp.datalong2,tmp.id);
+ continue;
+ }
break;
}
}
@@ -3968,7 +4288,7 @@ void ObjectMgr::LoadPageTextLocales()
bar.step();
- sLog.outString("");
+ sLog.outString();
sLog.outString(">> Loaded 0 PageText locale strings. DB table `locales_page_text` is empty.");
return;
}
@@ -4005,13 +4325,13 @@ void ObjectMgr::LoadPageTextLocales()
delete result;
sLog.outString();
- sLog.outString( ">> Loaded %u PageText locale strings", mPageTextLocaleMap.size() );
+ sLog.outString( ">> Loaded %lu PageText locale strings", (unsigned long)mPageTextLocaleMap.size() );
}
struct SQLInstanceLoader : public SQLStorageLoaderBase<SQLInstanceLoader>
{
template<class D>
- void convert_from_str(uint32 field_pos, char *src, D &dst)
+ void convert_from_str(uint32 /*field_pos*/, char *src, D &dst)
{
dst = D(objmgr.GetScriptId(src));
}
@@ -4035,14 +4355,20 @@ void ObjectMgr::LoadInstanceTemplate()
else if(!entry->HasResetTime())
continue;
+ //FIXME: now exist heroic instance, normal/heroic raid instances
+ // entry->resetTimeHeroic store reset time for both heroic mode instance (raid and non-raid)
+ // entry->resetTimeRaid store reset time for normal raid only
+ // for current state entry->resetTimeRaid == entry->resetTimeHeroic in case raid instances with heroic mode.
+ // but at some point wee need implement reset time dependent from raid instance mode
if(temp->reset_delay == 0)
{
// use defaults from the DBC
- if(entry->SupportsHeroicMode())
+ if(entry->resetTimeHeroic) // for both raid and non raids, read above
{
temp->reset_delay = entry->resetTimeHeroic / DAY;
}
else if (entry->resetTimeRaid && entry->map_type == MAP_RAID)
+ // for normal raid only
{
temp->reset_delay = entry->resetTimeRaid / DAY;
}
@@ -4056,27 +4382,16 @@ void ObjectMgr::LoadInstanceTemplate()
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)
+GossipText const *ObjectMgr::GetGossipText(uint32 Text_ID) const
{
- GossipTextMap::const_iterator itr;
- for (itr = mGossipText.begin(); itr != mGossipText.end(); ++itr)
- {
- if(itr->second->Text_ID == Text_ID)
- return itr->second;
- }
+ GossipTextMap::const_iterator itr = mGossipText.find(Text_ID);
+ if(itr != mGossipText.end())
+ return &itr->second;
return NULL;
}
void ObjectMgr::LoadGossipText()
{
- GossipText *pGText;
QueryResult *result = WorldDatabase.Query( "SELECT * FROM npc_text" );
int count = 0;
@@ -4103,30 +4418,29 @@ void ObjectMgr::LoadGossipText()
bar.step();
- pGText = new GossipText;
- pGText->Text_ID = fields[cic++].GetUInt32();
-
- for (int i=0; i< 8; i++)
+ uint32 Text_ID = fields[cic++].GetUInt32();
+ if(!Text_ID)
{
- pGText->Options[i].Text_0 = fields[cic++].GetCppString();
- pGText->Options[i].Text_1 = fields[cic++].GetCppString();
+ sLog.outErrorDb("Table `npc_text` has record wit reserved id 0, ignore.");
+ continue;
+ }
- pGText->Options[i].Language = fields[cic++].GetUInt32();
- pGText->Options[i].Probability = fields[cic++].GetFloat();
+ GossipText& gText = mGossipText[Text_ID];
- pGText->Options[i].Emotes[0]._Delay = fields[cic++].GetUInt32();
- pGText->Options[i].Emotes[0]._Emote = fields[cic++].GetUInt32();
+ for (int i=0; i< 8; i++)
+ {
+ gText.Options[i].Text_0 = fields[cic++].GetCppString();
+ gText.Options[i].Text_1 = fields[cic++].GetCppString();
- pGText->Options[i].Emotes[1]._Delay = fields[cic++].GetUInt32();
- pGText->Options[i].Emotes[1]._Emote = fields[cic++].GetUInt32();
+ gText.Options[i].Language = fields[cic++].GetUInt32();
+ gText.Options[i].Probability = fields[cic++].GetFloat();
- pGText->Options[i].Emotes[2]._Delay = fields[cic++].GetUInt32();
- pGText->Options[i].Emotes[2]._Emote = fields[cic++].GetUInt32();
+ for(int j=0; j < 3; ++j)
+ {
+ gText.Options[i].Emotes[j]._Delay = fields[cic++].GetUInt32();
+ gText.Options[i].Emotes[j]._Emote = fields[cic++].GetUInt32();
+ }
}
-
- if ( !pGText->Text_ID ) continue;
- AddGossipText( pGText );
-
} while( result->NextRow() );
sLog.outString();
@@ -4155,8 +4469,8 @@ void ObjectMgr::LoadNpcTextLocales()
bar.step();
- sLog.outString("");
- sLog.outString(">> Loaded 0 Quest locale strings. DB table `locales_npc_text` is empty.");
+ sLog.outString();
+ sLog.outString(">> Loaded 0 NpcText locale strings. DB table `locales_npc_text` is empty.");
return;
}
@@ -4206,7 +4520,7 @@ void ObjectMgr::LoadNpcTextLocales()
delete result;
sLog.outString();
- sLog.outString( ">> Loaded %u NpcText locale strings", mNpcTextLocaleMap.size() );
+ sLog.outString( ">> Loaded %lu NpcText locale strings", (unsigned long)mNpcTextLocaleMap.size() );
}
//not very fast function but it is called only once a day, or on starting-up
@@ -4220,14 +4534,27 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
// 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 )
+ {
+ barGoLink bar(1);
+ bar.step();
+ sLog.outString();
+ sLog.outString(">> Only expired mails (need to be return or delete) or DB table `mail` is empty.");
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 ( "
+
+ barGoLink bar( result->GetRowCount() );
+ uint32 count = 0;
+ Field *fields;
+
do
{
+ bar.step();
+
fields = result->Fetch();
Mail *m = new Mail;
m->messageID = fields[0].GetUInt32();
@@ -4293,8 +4620,12 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
//delmails << m->messageID << ", ";
CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", m->messageID);
delete m;
+ ++count;
} while (result->NextRow());
delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u mails", count );
}
void ObjectMgr::LoadQuestAreaTriggers()
@@ -4451,7 +4782,7 @@ void ObjectMgr::LoadAreaTriggerScripts()
sLog.outString( ">> Loaded %u areatrigger scripts", count );
}
-uint32 ObjectMgr::GetNearestTaxiNode( float x, float y, float z, uint32 mapid )
+uint32 ObjectMgr::GetNearestTaxiNode( float x, float y, float z, uint32 mapid, uint32 team )
{
bool found = false;
float dist;
@@ -4460,24 +4791,31 @@ uint32 ObjectMgr::GetNearestTaxiNode( float x, float y, float z, uint32 mapid )
for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
{
TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i);
- if(node && node->map_id == mapid)
+ if(!node || node->map_id != mapid || !node->MountCreatureID[team == ALLIANCE ? 1 : 0])
+ continue;
+
+ uint8 field = (uint8)((i - 1) / 32);
+ uint32 submask = 1<<((i-1)%32);
+
+ // skip not taxi network nodes
+ if((sTaxiNodesMask[field] & submask)==0)
+ continue;
+
+ float dist2 = (node->x - x)*(node->x - x)+(node->y - y)*(node->y - y)+(node->z - z)*(node->z - z);
+ if(found)
{
- 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
+ if(dist2 < dist)
{
- found = true;
dist = dist2;
id = i;
}
}
+ else
+ {
+ found = true;
+ dist = dist2;
+ id = i;
+ }
}
return id;
@@ -4515,17 +4853,19 @@ uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team )
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 (team == ALLIANCE)
{
- 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;
- }
+ mount_entry = node->MountCreatureID[1];
+ CreatureInfo const *ci = GetCreatureTemplate(mount_entry);
+ if(ci)
+ mount_id = ci->Modelid_A1;
+ }
+ if (team == HORDE)
+ {
+ mount_entry = node->MountCreatureID[0];
+ CreatureInfo const *ci = GetCreatureTemplate(mount_entry);
+ if(ci)
+ mount_id = ci->Modelid_H1;
}
}
@@ -4653,7 +4993,7 @@ void ObjectMgr::LoadGraveyardZones()
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);
+ uint32 zoneId = MapManager::Instance().GetZoneId(MapId,x,y,z);
// Simulate std. algorithm:
// found some graveyard associated to (ghost_zone,ghost_map)
@@ -4664,7 +5004,10 @@ WorldSafeLocsEntry const *ObjectMgr::GetClosestGraveYard(float x, float y, float
// then check faction
GraveYardMap::const_iterator graveLow = mGraveYardMap.lower_bound(zoneId);
GraveYardMap::const_iterator graveUp = mGraveYardMap.upper_bound(zoneId);
- if(graveLow==graveUp)
+ MapEntry const* map = sMapStore.LookupEntry(MapId);
+ // not need to check validity of map object; MapId _MUST_ be valid here
+
+ if(graveLow==graveUp && !map->IsBattleArena())
{
sLog.outErrorDb("Table `game_graveyard_zone` incomplete: Zone %u Team %u does not have a linked graveyard.",zoneId,team);
return NULL;
@@ -4851,7 +5194,7 @@ void ObjectMgr::LoadAreaTriggerTeleports()
uint32 count = 0;
- // 0 1 2 3 4 5 6
+ // 0 1 2 3 4 5 6
QueryResult *result = WorldDatabase.Query("SELECT id, access_id, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM areatrigger_teleport");
if( !result )
{
@@ -4892,7 +5235,7 @@ void ObjectMgr::LoadAreaTriggerTeleports()
sLog.outErrorDb("Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.",Trigger_ID);
continue;
}
-
+
MapEntry const* mapEntry = sMapStore.LookupEntry(at.target_mapId);
if(!mapEntry)
{
@@ -5003,7 +5346,8 @@ void ObjectMgr::LoadAccessRequirements()
if(ar.heroicQuest)
{
- if(!GetQuestTemplate(ar.heroicQuest))
+ QuestMap::iterator qReqItr = mQuestTemplates.find(ar.heroicQuest);
+ if(qReqItr == mQuestTemplates.end())
{
sLog.outErrorDb("Required Heroic Quest %u not exist for trigger %u, remove heroic quest done requirement.",ar.heroicQuest,requiremt_ID);
ar.heroicQuest = 0;
@@ -5012,7 +5356,8 @@ void ObjectMgr::LoadAccessRequirements()
if(ar.quest)
{
- if(!GetQuestTemplate(ar.quest))
+ QuestMap::iterator qReqItr = mQuestTemplates.find(ar.quest);
+ if(qReqItr == mQuestTemplates.end())
{
sLog.outErrorDb("Required Quest %u not exist for trigger %u, remove quest done requirement.",ar.quest,requiremt_ID);
ar.quest = 0;
@@ -5029,6 +5374,9 @@ void ObjectMgr::LoadAccessRequirements()
sLog.outString( ">> Loaded %u access requirement definitions", count );
}
+/*
+ * Searches for the areatrigger which teleports players out of the given map
+ */
AreaTrigger const* ObjectMgr::GetGoBackTrigger(uint32 Map) const
{
const MapEntry *mapEntry = sMapStore.LookupEntry(Map);
@@ -5045,6 +5393,23 @@ AreaTrigger const* ObjectMgr::GetGoBackTrigger(uint32 Map) const
return NULL;
}
+/**
+ * Searches for the areatrigger which teleports players to the given map
+ */
+AreaTrigger const* ObjectMgr::GetMapEntranceTrigger(uint32 Map) const
+{
+ for (AreaTriggerMap::const_iterator itr = mAreaTriggers.begin(); itr != mAreaTriggers.end(); ++itr)
+ {
+ if(itr->second.target_mapId == Map)
+ {
+ AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(itr->first);
+ if(atEntry)
+ return &itr->second;
+ }
+ }
+ return NULL;
+}
+
void ObjectMgr::SetHighestGuids()
{
QueryResult *result = CharacterDatabase.Query( "SELECT MAX(guid) FROM characters" );
@@ -5061,9 +5426,6 @@ void ObjectMgr::SetHighestGuids()
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 )
{
@@ -5137,24 +5499,24 @@ uint32 ObjectMgr::GenerateArenaTeamId()
return m_arenaTeamId++;
}
-uint32 ObjectMgr::GenerateGuildId()
+uint32 ObjectMgr::GenerateAuctionID()
{
- if(m_guildId>=0xFFFFFFFE)
+ if(m_auctionid>=0xFFFFFFFE)
{
- sLog.outError("Guild ids overflow!! Can't continue, shutting down server. ");
+ sLog.outError("Auctions ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
- return m_guildId++;
+ return m_auctionid++;
}
-uint32 ObjectMgr::GenerateAuctionID()
+uint32 ObjectMgr::GenerateGuildId()
{
- if(m_auctionid>=0xFFFFFFFE)
+ if(m_guildId>=0xFFFFFFFE)
{
- sLog.outError("Auctions ids overflow!! Can't continue, shutting down server. ");
+ sLog.outError("Guild ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
- return m_auctionid++;
+ return m_guildId++;
}
uint32 ObjectMgr::GenerateMailID()
@@ -5216,6 +5578,13 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiPetGuid++;
+ case HIGHGUID_VEHICLE:
+ if(m_hiVehicleGuid>=0x00FFFFFF)
+ {
+ sLog.outError("Vehicle guid overflow!! Can't continue, shutting down server. ");
+ World::StopNow(ERROR_EXIT_CODE);
+ }
+ return m_hiVehicleGuid++;
case HIGHGUID_PLAYER:
if(m_hiCharGuid>=0xFFFFFFFE)
{
@@ -5267,7 +5636,7 @@ void ObjectMgr::LoadGameObjectLocales()
bar.step();
- sLog.outString("");
+ sLog.outString();
sLog.outString(">> Loaded 0 gameobject locale strings. DB table `locales_gameobject` is empty.");
return;
}
@@ -5299,9 +5668,9 @@ void ObjectMgr::LoadGameObjectLocales()
}
}
- for(int i = MAX_LOCALE; i < MAX_LOCALE*2-1; ++i)
+ for(int i = 1; i < MAX_LOCALE; ++i)
{
- std::string str = fields[i].GetCppString();
+ std::string str = fields[i+(MAX_LOCALE-1)].GetCppString();
if(!str.empty())
{
int idx = GetOrNewIndexForLocale(LocaleConstant(i));
@@ -5320,18 +5689,73 @@ void ObjectMgr::LoadGameObjectLocales()
delete result;
sLog.outString();
- sLog.outString( ">> Loaded %u gameobject locale strings", mGameObjectLocaleMap.size() );
+ sLog.outString( ">> Loaded %lu gameobject locale strings", (unsigned long)mGameObjectLocaleMap.size() );
}
struct SQLGameObjectLoader : public SQLStorageLoaderBase<SQLGameObjectLoader>
{
template<class D>
- void convert_from_str(uint32 field_pos, char *src, D &dst)
+ void convert_from_str(uint32 /*field_pos*/, char *src, D &dst)
{
dst = D(objmgr.GetScriptId(src));
}
};
+inline void CheckGOLockId(GameObjectInfo const* goInfo,uint32 dataN,uint32 N)
+{
+ if (sLockStore.LookupEntry(dataN))
+ return;
+
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data%d=%u but lock (Id: %u) not found.",
+ goInfo->id,goInfo->type,N,goInfo->door.lockId,goInfo->door.lockId);
+}
+
+inline void CheckGOLinkedTrapId(GameObjectInfo const* goInfo,uint32 dataN,uint32 N)
+{
+ if (GameObjectInfo const* trapInfo = sGOStorage.LookupEntry<GameObjectInfo>(dataN))
+ {
+ if (trapInfo->type!=GAMEOBJECT_TYPE_TRAP)
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data%d=%u but GO (Entry %u) have not GAMEOBJECT_TYPE_TRAP (%u) type.",
+ goInfo->id,goInfo->type,N,dataN,dataN,GAMEOBJECT_TYPE_TRAP);
+ }
+ /* disable check for while (too many error reports baout not existed in trap templates
+ else
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data%d=%u but trap GO (Entry %u) not exist in `gameobject_template`.",
+ goInfo->id,goInfo->type,N,dataN,dataN);
+ */
+}
+
+inline void CheckGOSpellId(GameObjectInfo const* goInfo,uint32 dataN,uint32 N)
+{
+ if (sSpellStore.LookupEntry(dataN))
+ return;
+
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data%d=%u but Spell (Entry %u) not exist.",
+ goInfo->id,goInfo->type,N,dataN,dataN);
+}
+
+inline void CheckAndFixGOChairHeightId(GameObjectInfo const* goInfo,uint32 const& dataN,uint32 N)
+{
+ if (dataN <= (UNIT_STAND_STATE_SIT_HIGH_CHAIR-UNIT_STAND_STATE_SIT_LOW_CHAIR) )
+ return;
+
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data%d=%u but correct chair height in range 0..%i.",
+ goInfo->id,goInfo->type,N,dataN,UNIT_STAND_STATE_SIT_HIGH_CHAIR-UNIT_STAND_STATE_SIT_LOW_CHAIR);
+
+ // prevent client and server unexpected work
+ const_cast<uint32&>(dataN) = 0;
+}
+
+inline void CheckGONoDamageImmuneId(GameObjectInfo const* goInfo,uint32 dataN,uint32 N)
+{
+ // 0/1 correct values
+ if (dataN <= 1)
+ return;
+
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data%d=%u but expected boolean (0/1) noDamageImmune field value.",
+ goInfo->id,goInfo->type,N,dataN);
+}
+
void ObjectMgr::LoadGameobjectInfo()
{
SQLGameObjectLoader loader;
@@ -5341,139 +5765,104 @@ void ObjectMgr::LoadGameobjectInfo()
for(uint32 id = 1; id < sGOStorage.MaxEntry; id++)
{
GameObjectInfo const* goInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
- if(!goInfo)
+ 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);
- }
+ if (goInfo->door.lockId)
+ CheckGOLockId(goInfo,goInfo->door.lockId,1);
+ CheckGONoDamageImmuneId(goInfo,goInfo->door.noDamageImmune,3);
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);
- }
+ if (goInfo->button.lockId)
+ CheckGOLockId(goInfo,goInfo->button.lockId,1);
+ CheckGONoDamageImmuneId(goInfo,goInfo->button.noDamageImmune,4);
+ break;
+ }
+ case GAMEOBJECT_TYPE_QUESTGIVER: //2
+ {
+ if (goInfo->questgiver.lockId)
+ CheckGOLockId(goInfo,goInfo->questgiver.lockId,0);
+ CheckGONoDamageImmuneId(goInfo,goInfo->questgiver.noDamageImmune,5);
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);
- */
- }
+ if (goInfo->chest.lockId)
+ CheckGOLockId(goInfo,goInfo->chest.lockId,0);
+
+ if (goInfo->chest.linkedTrapId) // linked trap
+ CheckGOLinkedTrapId(goInfo,goInfo->chest.linkedTrapId,7);
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);
- }
+ if (goInfo->trap.lockId)
+ CheckGOLockId(goInfo,goInfo->trap.lockId,0);
+ /* disable check for while, too many not existed spells
+ if (goInfo->trap.spellId) // spell
+ CheckGOSpellId(goInfo,goInfo->trap.spellId,3);
*/
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;
- }
+ CheckAndFixGOChairHeightId(goInfo,goInfo->chair.height,1);
break;
case GAMEOBJECT_TYPE_SPELL_FOCUS: //8
{
- if(goInfo->spellFocus.focusId)
+ if (goInfo->spellFocus.focusId)
{
- if(!sSpellFocusObjectStore.LookupEntry(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);
- */
- }
+ if (goInfo->spellFocus.linkedTrapId) // linked trap
+ CheckGOLinkedTrapId(goInfo,goInfo->spellFocus.linkedTrapId,2);
break;
}
case GAMEOBJECT_TYPE_GOOBER: //10
{
- if(goInfo->goober.pageId) // pageId
+ if (goInfo->goober.lockId)
+ CheckGOLockId(goInfo,goInfo->goober.lockId,0);
+
+ if (goInfo->goober.pageId) // pageId
{
- if(!sPageTextStore.LookupEntry<PageText>(goInfo->goober.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);
- }
+ /* disable check for while, too many not existed spells
+ if (goInfo->goober.spellId) // spell
+ CheckGOSpellId(goInfo,goInfo->goober.spellId,10);
*/
- 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);
- */
- }
+ CheckGONoDamageImmuneId(goInfo,goInfo->goober.noDamageImmune,11);
+ if (goInfo->goober.linkedTrapId) // linked trap
+ CheckGOLinkedTrapId(goInfo,goInfo->goober.linkedTrapId,12);
+ break;
+ }
+ case GAMEOBJECT_TYPE_AREADAMAGE: //12
+ {
+ if (goInfo->areadamage.lockId)
+ CheckGOLockId(goInfo,goInfo->areadamage.lockId,0);
+ break;
+ }
+ case GAMEOBJECT_TYPE_CAMERA: //13
+ {
+ if (goInfo->camera.lockId)
+ CheckGOLockId(goInfo,goInfo->camera.lockId,0);
break;
}
case GAMEOBJECT_TYPE_MO_TRANSPORT: //15
{
- if(goInfo->moTransport.taxiPathId)
+ if (goInfo->moTransport.taxiPathId)
{
- if(goInfo->moTransport.taxiPathId >= sTaxiPathNodesByPath.size() || sTaxiPathNodesByPath[goInfo->moTransport.taxiPathId].empty())
+ 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);
}
@@ -5481,26 +5870,41 @@ void ObjectMgr::LoadGameobjectInfo()
}
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);
- }
+ /* disable check for while, too many not existed spells
+ // always must have spell
+ CheckGOSpellId(goInfo,goInfo->summoningRitual.spellId,1);
*/
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);
- }
+ // always must have spell
+ CheckGOSpellId(goInfo,goInfo->spellcaster.spellId,0);
+ break;
+ }
+ case GAMEOBJECT_TYPE_FLAGSTAND: //24
+ {
+ if (goInfo->flagstand.lockId)
+ CheckGOLockId(goInfo,goInfo->flagstand.lockId,0);
+ CheckGONoDamageImmuneId(goInfo,goInfo->flagstand.noDamageImmune,5);
+ break;
+ }
+ case GAMEOBJECT_TYPE_FISHINGHOLE: //25
+ {
+ if (goInfo->fishinghole.lockId)
+ CheckGOLockId(goInfo,goInfo->fishinghole.lockId,4);
break;
}
+ case GAMEOBJECT_TYPE_FLAGDROP: //26
+ {
+ if (goInfo->flagdrop.lockId)
+ CheckGOLockId(goInfo,goInfo->flagdrop.lockId,0);
+ CheckGONoDamageImmuneId(goInfo,goInfo->flagdrop.noDamageImmune,3);
+ break;
+ }
+ case GAMEOBJECT_TYPE_BARBER_CHAIR: //32
+ CheckAndFixGOChairHeightId(goInfo,goInfo->barberChair.chairheight,0);
+ break;
}
}
@@ -5549,6 +5953,13 @@ uint32 ObjectMgr::GetBaseXP(uint32 level)
return mBaseXPTable[level] ? mBaseXPTable[level] : 0;
}
+uint32 ObjectMgr::GetXPForLevel(uint32 level)
+{
+ if (level < mPlayerXPperLevel.size())
+ return mPlayerXPperLevel[level];
+ return 0;
+}
+
void ObjectMgr::LoadPetNames()
{
uint32 count = 0;
@@ -5750,6 +6161,58 @@ void ObjectMgr::LoadReputationOnKill()
sLog.outString(">> Loaded %u creature award reputation definitions", count);
}
+void ObjectMgr::LoadPointsOfInterest()
+{
+ uint32 count = 0;
+
+ // 0 1 2 3 4 5
+ QueryResult *result = WorldDatabase.Query("SELECT entry, x, y, icon, flags, data, icon_name FROM points_of_interest");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded 0 Points of Interest definitions. DB table `points_of_interest` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 point_id = fields[0].GetUInt32();
+
+ PointOfInterest POI;
+ POI.x = fields[1].GetFloat();
+ POI.y = fields[2].GetFloat();
+ POI.icon = fields[3].GetUInt32();
+ POI.flags = fields[4].GetUInt32();
+ POI.data = fields[5].GetUInt32();
+ POI.icon_name = fields[6].GetCppString();
+
+ if(!MaNGOS::IsValidMapCoord(POI.x,POI.y))
+ {
+ sLog.outErrorDb("Table `points_of_interest` (Entry: %u) have invalid coordinates (X: %f Y: %f), ignored.",point_id,POI.x,POI.y);
+ continue;
+ }
+
+ mPointsOfInterest[point_id] = POI;
+
+ ++count;
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u Points of Interest definitions", count);
+}
+
void ObjectMgr::LoadWeatherZoneChances()
{
uint32 count = 0;
@@ -5788,19 +6251,19 @@ void ObjectMgr::LoadWeatherZoneChances()
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);
+ 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);
+ 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);
+ sLog.outErrorDb("Weather for zone %u season %u has wrong storm chance > 100%%",zone_id,season);
}
}
@@ -6017,11 +6480,18 @@ void ObjectMgr::LoadReservedPlayersNames()
bar.step();
fields = result->Fetch();
std::string name= fields[0].GetCppString();
- if(normalizePlayerName(name))
+
+ std::wstring wstr;
+ if(!Utf8toWStr (name,wstr))
{
- m_ReservedNames.insert(name);
- ++count;
+ sLog.outError("Table `reserved_name` have invalid name: %s", name.c_str() );
+ continue;
}
+
+ wstrToLower(wstr);
+
+ m_ReservedNames.insert(wstr);
+ ++count;
} while ( result->NextRow() );
delete result;
@@ -6030,6 +6500,17 @@ void ObjectMgr::LoadReservedPlayersNames()
sLog.outString( ">> Loaded %u reserved player names", count );
}
+bool ObjectMgr::IsReservedName( const std::string& name ) const
+{
+ std::wstring wstr;
+ if(!Utf8toWStr (name,wstr))
+ return false;
+
+ wstrToLower(wstr);
+
+ return m_ReservedNames.find(wstr) != m_ReservedNames.end();
+}
+
enum LanguageType
{
LT_BASIC_LATIN = 0x0000,
@@ -6178,55 +6659,26 @@ int ObjectMgr::GetOrNewIndexForLocale( LocaleConstant loc )
return m_LocalForIndex.size()-1;
}
-void ObjectMgr::LoadBattleMastersEntry()
+void ObjectMgr::LoadGameObjectForQuests()
{
- mBattleMastersMap.clear(); // need for reload case
-
- QueryResult *result = WorldDatabase.Query( "SELECT entry,bg_template FROM battlemaster_entry" );
-
- uint32 count = 0;
+ mGameObjectForQuestSet.clear(); // need for reload case
- if( !result )
+ if( !sGOStorage.MaxEntry )
{
barGoLink bar( 1 );
bar.step();
-
sLog.outString();
- sLog.outString( ">> Loaded 0 battlemaster entries - table is empty!" );
+ sLog.outString( ">> Loaded 0 GameObjects for quests" );
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
-
+ barGoLink bar( sGOStorage.MaxEntry - 1 );
uint32 count = 0;
// collect GO entries for GO that must activated
for(uint32 go_entry = 1; go_entry < sGOStorage.MaxEntry; ++go_entry)
{
+ bar.step();
GameObjectInfo const* goInfo = sGOStorage.LookupEntry<GameObjectInfo>(go_entry);
if(!goInfo)
continue;
@@ -6261,7 +6713,7 @@ void ObjectMgr::LoadGameObjectForQuests()
}
sLog.outString();
- sLog.outString( ">> Loaded %u GameObject for quests", count );
+ sLog.outString( ">> Loaded %u GameObjects for quests", count );
}
bool ObjectMgr::LoadTrinityStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value)
@@ -6287,7 +6739,7 @@ bool ObjectMgr::LoadTrinityStrings(DatabaseType& db, char const* table, int32 mi
bar.step();
- sLog.outString("");
+ sLog.outString();
if(min_value == MIN_TRINITY_STRING_ID) // error only in case internal strings
sLog.outErrorDb(">> Loaded 0 trinity strings. DB table `%s` is empty. Cannot continue.",table);
else
@@ -6530,17 +6982,17 @@ bool PlayerCondition::Meets(Player const * player) const
case CONDITION_NONE:
return true; // empty condition, always met
case CONDITION_AURA:
- return player->HasAura(value1, value2);
+ return player->HasAuraEffect(value1, value2);
case CONDITION_ITEM:
return player->HasItemCount(value1, value2);
case CONDITION_ITEM_EQUIPPED:
- return player->GetItemOrItemWithGemEquipped(value1) != NULL;
+ return player->HasItemOrGemWithIdEquipped(value1,1);
case CONDITION_ZONEID:
return player->GetZoneId() == value1;
case CONDITION_REPUTATION_RANK:
{
FactionEntry const* faction = sFactionStore.LookupEntry(value1);
- return faction && player->GetReputationRank(faction) >= value2;
+ return faction && player->GetReputationMgr().GetRank(faction) >= value2;
}
case CONDITION_TEAM:
return player->GetTeam() == value1;
@@ -6557,12 +7009,12 @@ bool PlayerCondition::Meets(Player const * player) const
{
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)
+ if((itr->second->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetSpellProto()->SpellVisual[0]==3580)
return true;
return false;
}
case CONDITION_NO_AURA:
- return !player->HasAura(value1, value2);
+ return !player->HasAuraEffect(value1, value2);
case CONDITION_ACTIVE_EVENT:
return gameeventmgr.IsActiveEvent(value1);
case CONDITION_INSTANCE_DATA:
@@ -6707,7 +7159,7 @@ bool PlayerCondition::IsValid(ConditionType condition, uint32 value1, uint32 val
}
case CONDITION_ACTIVE_EVENT:
{
- GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+ GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
if(value1 >=events.size() || !events[value1].isValid())
{
sLog.outErrorDb("Active event condition requires existed event id (%u), skipped", value1);
@@ -6734,7 +7186,7 @@ SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial)
return SKILL_RANGE_MONO;
case SKILL_CATEGORY_ARMOR:
case SKILL_CATEGORY_CLASS:
- if(pSkill->id != SKILL_POISONS && pSkill->id != SKILL_LOCKPICKING)
+ if(pSkill->id != SKILL_LOCKPICKING)
return SKILL_RANGE_MONO;
else
return SKILL_RANGE_LEVEL;
@@ -6749,7 +7201,7 @@ SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial)
return SKILL_RANGE_MONO;
default:
case SKILL_CATEGORY_ATTRIBUTES: //not found in dbc
- case SKILL_CATEGORY_NOT_DISPLAYED: //only GENEREC(DND)
+ case SKILL_CATEGORY_GENERIC: //only GENERIC(DND)
return SKILL_RANGE_NONE;
}
}
@@ -6810,11 +7262,10 @@ void ObjectMgr::LoadGameTele()
++count;
}
while (result->NextRow());
-
delete result;
sLog.outString();
- sLog.outString( ">> Loaded %u game tele's", count );
+ sLog.outString( ">> Loaded %u GameTeleports", count );
}
GameTele const* ObjectMgr::GetGameTele(const std::string& name) const
@@ -6950,30 +7401,41 @@ void ObjectMgr::LoadTrainerSpell()
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();
+ TrainerSpellData& data = m_mCacheTrainerSpellMap[entry];
- if(!pTrainerSpell->reqlevel)
- pTrainerSpell->reqlevel = spellinfo->spellLevel;
+ TrainerSpell& trainerSpell = data.spellList[spell];
+ trainerSpell.spell = spell;
+ trainerSpell.spellCost = fields[2].GetUInt32();
+ trainerSpell.reqSkill = fields[3].GetUInt32();
+ trainerSpell.reqSkillValue = fields[4].GetUInt32();
+ trainerSpell.reqLevel = fields[5].GetUInt32();
+ if(!trainerSpell.reqLevel)
+ trainerSpell.reqLevel = spellinfo->spellLevel;
- TrainerSpellData& data = m_mCacheTrainerSpellMap[entry];
+ // calculate learned spell for profession case when stored cast-spell
+ trainerSpell.learnedSpell = spell;
+ for(int i = 0; i <3; ++i)
+ {
+ if(spellinfo->Effect[i] != SPELL_EFFECT_LEARN_SPELL)
+ continue;
+ if(SpellMgr::IsProfessionOrRidingSpell(spellinfo->EffectTriggerSpell[i]))
+ {
+ trainerSpell.learnedSpell = spellinfo->EffectTriggerSpell[i];
+ break;
+ }
+ }
- if(SpellMgr::IsProfessionSpell(spell))
+ if(SpellMgr::IsProfessionSpell(trainerSpell.learnedSpell))
data.trainerType = 2;
- data.spellList.push_back(pTrainerSpell);
++count;
} while (result->NextRow());
delete result;
sLog.outString();
- sLog.outString( ">> Loaded Trainers %d", count );
+ sLog.outString( ">> Loaded %d Trainers", count );
}
void ObjectMgr::LoadVendors()
@@ -7251,16 +7713,30 @@ void ObjectMgr::LoadScriptNames()
"SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' "
"UNION "
"SELECT DISTINCT(script) FROM instance_template WHERE script <> ''");
- if(result)
+
+ if( !result )
{
- do
- {
- m_scriptNames.push_back((*result)[0].GetString());
- } while (result->NextRow());
- delete result;
+ barGoLink bar( 1 );
+ bar.step();
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded empty set of Script Names!");
+ return;
}
+ barGoLink bar( result->GetRowCount() );
+ uint32 count = 0;
+
+ do
+ {
+ bar.step();
+ m_scriptNames.push_back((*result)[0].GetString());
+ ++count;
+ } while (result->NextRow());
+ delete result;
+
std::sort(m_scriptNames.begin(), m_scriptNames.end());
+ sLog.outString();
+ sLog.outString( ">> Loaded %d Script Names", count );
}
uint32 ObjectMgr::GetScriptId(const char *name)
@@ -7280,13 +7756,16 @@ void ObjectMgr::CheckScripts(ScriptMapMap const& scripts,std::set<int32>& ids)
{
for(ScriptMap::const_iterator itrM = itrMM->second.begin(); itrM != itrMM->second.end(); ++itrM)
{
- if(itrM->second.dataint)
+ switch(itrM->second.command)
{
- if(!GetTrinityStringLocale (itrM->second.dataint))
- sLog.outErrorDb( "Table `db_script_string` has not existed string id %u", itrM->first);
+ case SCRIPT_COMMAND_TALK:
+ {
+ if(!GetTrinityStringLocale (itrM->second.dataint))
+ sLog.outErrorDb( "Table `db_script_string` not has string id %u used db script (ID: %u)", itrM->second.dataint, itrMM->first);
- if(ids.count(itrM->second.dataint))
- ids.erase(itrM->second.dataint);
+ if(ids.count(itrM->second.dataint))
+ ids.erase(itrM->second.dataint);
+ }
}
}
}
@@ -7353,16 +7832,6 @@ CreatureInfo const *GetCreatureInfo(uint32 id)
return objmgr.GetCreatureTemplate(id);
}
-CreatureInfo const* GetCreatureTemplateStore(uint32 entry)
-{
- return sCreatureStorage.LookupEntry<CreatureInfo>(entry);
-}
-
-Quest const* GetQuestTemplateStore(uint32 entry)
-{
- return objmgr.GetQuestTemplate(entry);
-}
-
void ObjectMgr::LoadTransportEvents()
{
@@ -7399,3 +7868,12 @@ void ObjectMgr::LoadTransportEvents()
delete result;
}
+CreatureInfo const* GetCreatureTemplateStore(uint32 entry)
+{
+ return sCreatureStorage.LookupEntry<CreatureInfo>(entry);
+}
+
+Quest const* GetQuestTemplateStore(uint32 entry)
+{
+ return objmgr.GetQuestTemplate(entry);
+}
diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h
index 8de6c3333b3..626869b7e3e 100644
--- a/src/game/ObjectMgr.h
+++ b/src/game/ObjectMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -145,6 +145,7 @@ 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 UNORDERED_MAP<uint32,PointOfInterestLocale> PointOfInterestLocaleMap;
typedef std::multimap<uint32,uint32> QuestRelations;
@@ -171,6 +172,17 @@ struct ReputationOnKillEntry
bool team_dependent;
};
+struct PointOfInterest
+{
+ uint32 entry;
+ float x;
+ float y;
+ uint32 icon;
+ uint32 flags;
+ uint32 data;
+ std::string icon_name;
+};
+
struct PetCreateSpellEntry
{
uint32 spellid[4];
@@ -311,6 +323,7 @@ class ObjectMgr
typedef UNORDERED_MAP<uint32, AccessRequirement> AccessRequirementMap;
typedef UNORDERED_MAP<uint32, ReputationOnKillEntry> RepOnKillMap;
+ typedef UNORDERED_MAP<uint32, PointOfInterest> PointOfInterestMap;
typedef UNORDERED_MAP<uint32, WeatherZoneChances> WeatherZoneMap;
@@ -333,13 +346,13 @@ class ObjectMgr
void RemoveGroup(Group* group) { mGroupSet.erase( group ); }
Guild* GetGuildByLeader(uint64 const&guid) const;
- Guild* GetGuildById(const uint32 GuildId) const;
+ Guild* GetGuildById(uint32 GuildId) const;
Guild* GetGuildByName(const std::string& guildname) const;
- std::string GetGuildNameById(const uint32 GuildId) const;
+ std::string GetGuildNameById(uint32 GuildId) const;
void AddGuild(Guild* guild);
void RemoveGuild(uint32 Id);
- ArenaTeam* GetArenaTeamById(const uint32 arenateamid) const;
+ ArenaTeam* GetArenaTeamById(uint32 arenateamid) const;
ArenaTeam* GetArenaTeamByName(const std::string& arenateamname) const;
ArenaTeam* GetArenaTeamByCaptain(uint64 const& guid) const;
void AddArenaTeam(ArenaTeam* arenaTeam);
@@ -394,7 +407,7 @@ class ObjectMgr
uint32 GetPlayerAccountIdByGUID(const uint64 &guid) const;
uint32 GetPlayerAccountIdByPlayerName(const std::string& name) const;
- uint32 GetNearestTaxiNode( float x, float y, float z, uint32 mapid );
+ uint32 GetNearestTaxiNode( float x, float y, float z, uint32 mapid, uint32 team );
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 );
@@ -414,26 +427,17 @@ class ObjectMgr
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
+ bool IsTavernAreaTrigger(uint32 Trigger_ID) const
{
- if(GameObject *go = ObjectAccessor::GetGameObject(*player, guid))
- if(go->GetGoType() == GAMEOBJECT_TYPE_GUILD_BANK)
- return true;
- return false;
+ return mTavernAreaTriggerSet.find(Trigger_ID) != mTavernAreaTriggerSet.end();
}
- uint32 GetBattleMasterBG(uint32 entry) const
+ bool IsGameObjectForQuests(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!
+ return mGameObjectForQuestSet.find(entry) != mGameObjectForQuestSet.end();
}
- void AddGossipText(GossipText *pGText);
- GossipText *GetGossipText(uint32 Text_ID);
+ GossipText const* GetGossipText(uint32 Text_ID) const;
WorldSafeLocsEntry const *GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team);
bool AddGraveYardLink(uint32 id, uint32 zone, uint32 team, bool inDB = true);
@@ -458,6 +462,7 @@ class ObjectMgr
}
AreaTrigger const* GetGoBackTrigger(uint32 Map) const;
+ AreaTrigger const* GetMapEntranceTrigger(uint32 Map) const;
uint32 GetAreaTriggerScriptId(uint32 trigger_id);
@@ -469,6 +474,14 @@ class ObjectMgr
return NULL;
}
+ PointOfInterest const* GetPointOfInterest(uint32 id) const
+ {
+ PointOfInterestMap::const_iterator itr = mPointsOfInterest.find(id);
+ if(itr != mPointsOfInterest.end())
+ return &itr->second;
+ return NULL;
+ }
+
PetCreateSpellEntry const* GetPetCreateSpellEntry(uint32 id) const
{
PetCreateSpellMap::const_iterator itr = mPetCreateSpell.find(id);
@@ -530,6 +543,7 @@ class ObjectMgr
void LoadNpcTextLocales();
void LoadPageTextLocales();
void LoadNpcOptionLocales();
+ void LoadPointOfInterestLocales();
void LoadInstanceTemplate();
void LoadGossipText();
@@ -539,7 +553,6 @@ class ObjectMgr
void LoadQuestAreaTriggers();
void LoadAreaTriggerScripts();
void LoadTavernAreaTriggers();
- void LoadBattleMastersEntry();
void LoadGameObjectForQuests();
void LoadItemTexts();
@@ -554,6 +567,7 @@ class ObjectMgr
void LoadFishingBaseSkillLevel();
void LoadReputationOnKill();
+ void LoadPointsOfInterest();
void LoadWeatherZoneChances();
void LoadGameTele();
@@ -565,6 +579,7 @@ class ObjectMgr
std::string GeneratePetName(uint32 entry);
uint32 GetBaseXP(uint32 level);
+ uint32 GetXPForLevel(uint32 level);
int32 GetFishingBaseSkillLevel(uint32 entry) const
{
@@ -576,12 +591,12 @@ class ObjectMgr
void SetHighestGuids();
uint32 GenerateLowGuid(HighGuid guidhigh);
+ uint32 GenerateArenaTeamId();
uint32 GenerateAuctionID();
- uint32 GenerateMailID();
+ uint32 GenerateGuildId();
uint32 GenerateItemTextID();
+ uint32 GenerateMailID();
uint32 GeneratePetNumber();
- uint32 GenerateArenaTeamId();
- uint32 GenerateGuildId();
void LoadPlayerInfoInCache();
PCachePlayerInfo GetPlayerInfoFromCache(uint32 unPlayerGuid) const;
@@ -670,6 +685,12 @@ class ObjectMgr
if(itr==mNpcOptionLocaleMap.end()) return NULL;
return &itr->second;
}
+ PointOfInterestLocale const* GetPointOfInterestLocale(uint32 poi_id) const
+ {
+ PointOfInterestLocaleMap::const_iterator itr = mPointOfInterestLocaleMap.find(poi_id);
+ if(itr==mPointOfInterestLocaleMap.end()) return NULL;
+ return &itr->second;
+ }
GameObjectData const* GetGOData(uint32 guid) const
{
@@ -708,10 +729,7 @@ class ObjectMgr
// reserved names
void LoadReservedPlayersNames();
- bool IsReservedName(const std::string& name) const
- {
- return m_ReservedNames.find(name) != m_ReservedNames.end();
- }
+ bool IsReservedName(const std::string& name) const;
// name with valid structure and symbols
static bool IsValidName( const std::string& name, bool create = false );
@@ -786,20 +804,23 @@ class ObjectMgr
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);
+
+ int GetOrNewIndexForLocale(LocaleConstant loc);
protected:
// first free id for selected id type
- uint32 m_auctionid;
- uint32 m_mailid;
- uint32 m_ItemTextId;
uint32 m_arenaTeamId;
+ uint32 m_auctionid;
uint32 m_guildId;
+ uint32 m_ItemTextId;
+ uint32 m_mailid;
uint32 m_hiPetNumber;
// first free low guid for seelcted guid type
uint32 m_hiCharGuid;
uint32 m_hiCreatureGuid;
uint32 m_hiPetGuid;
+ uint32 m_hiVehicleGuid;
uint32 m_hiItemGuid;
uint32 m_hiGoGuid;
uint32 m_hiDoGuid;
@@ -807,9 +828,8 @@ class ObjectMgr
QuestMap mQuestTemplates;
- typedef UNORDERED_MAP<uint32, GossipText*> GossipTextMap;
+ 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;
@@ -818,12 +838,9 @@ class ObjectMgr
GuildMap mGuildMap;
ArenaTeamMap mArenaTeamMap;
- ItemMap mItems;
-
ItemTextMap mItemTexts;
QuestAreaTriggerMap mQuestAreaTriggerMap;
- BattleMastersMap mBattleMastersMap;
TavernAreaTriggerSet mTavernAreaTriggerSet;
GameObjectForQuestSet mGameObjectForQuestSet;
GossipTextMap mGossipText;
@@ -833,12 +850,14 @@ class ObjectMgr
RepOnKillMap mRepOnKill;
+ PointOfInterestMap mPointsOfInterest;
+
WeatherZoneMap mWeatherZoneMap;
PetCreateSpellMap mPetCreateSpell;
//character reserved names
- typedef std::set<std::string> ReservedNamesMap;
+ typedef std::set<std::wstring> ReservedNamesMap;
ReservedNamesMap m_ReservedNames;
std::set<uint32> m_DisabledPlayerSpells;
@@ -853,7 +872,6 @@ class ObjectMgr
typedef std::vector<LocaleConstant> LocalForIndex;
LocalForIndex m_LocalForIndex;
- int GetOrNewIndexForLocale(LocaleConstant loc);
int DBCLocaleIndex;
@@ -872,6 +890,9 @@ class ObjectMgr
void BuildPlayerLevelInfo(uint8 race, uint8 class_, uint8 level, PlayerLevelInfo* plinfo) const;
PlayerInfo playerInfo[MAX_RACES][MAX_CLASSES];
+ typedef std::vector<uint32> PlayerXPperLevel; // [level]
+ PlayerXPperLevel mPlayerXPperLevel;
+
typedef std::map<uint32,uint32> BaseXPMap; // [area level][base xp]
BaseXPMap mBaseXPTable;
@@ -894,6 +915,7 @@ class ObjectMgr
PageTextLocaleMap mPageTextLocaleMap;
TrinityStringLocaleMap mTrinityStringLocaleMap;
NpcOptionLocaleMap mNpcOptionLocaleMap;
+ PointOfInterestLocaleMap mPointOfInterestLocaleMap;
RespawnTimes mCreatureRespawnTimes;
RespawnTimes mGORespawnTimes;
diff --git a/src/game/ObjectPosSelector.cpp b/src/game/ObjectPosSelector.cpp
new file mode 100644
index 00000000000..899dfec3fdb
--- /dev/null
+++ b/src/game/ObjectPosSelector.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2005-2009 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 "ObjectPosSelector.h"
+
+ObjectPosSelector::ObjectPosSelector(float x,float y,float size,float dist)
+: m_center_x(x),m_center_y(y),m_size(size),m_dist(dist)
+{
+ m_anglestep = acos(m_dist/(m_dist+2*m_size));
+
+ m_nextUsedPos[USED_POS_PLUS] = m_UsedPosLists[USED_POS_PLUS].end();
+ m_nextUsedPos[USED_POS_MINUS] = m_UsedPosLists[USED_POS_MINUS].end();
+
+ m_smallStepAngle[USED_POS_PLUS] = 0;
+ m_smallStepAngle[USED_POS_MINUS] = 0;
+
+ m_smallStepOk[USED_POS_PLUS] = false;
+ m_smallStepOk[USED_POS_MINUS] = false;
+
+ m_smallStepNextUsedPos[USED_POS_PLUS] = NULL;
+ m_smallStepNextUsedPos[USED_POS_MINUS] = NULL;
+}
+
+ObjectPosSelector::UsedPosList::value_type const* ObjectPosSelector::nextUsedPos(UsedPosType uptype)
+{
+ UsedPosList::const_iterator itr = m_nextUsedPos[uptype];
+ if(itr!=m_UsedPosLists[uptype].end())
+ ++itr;
+
+ if(itr==m_UsedPosLists[uptype].end())
+ {
+ if(!m_UsedPosLists[~uptype].empty())
+ return &*m_UsedPosLists[~uptype].rbegin();
+ else
+ return NULL;
+ }
+ else
+ return &*itr;
+}
+
+void ObjectPosSelector::AddUsedPos(float size,float angle,float dist)
+{
+ if(angle>=0)
+ m_UsedPosLists[USED_POS_PLUS].insert(UsedPosList::value_type(angle,UsedPos(1.0,size,dist)));
+ else
+ m_UsedPosLists[USED_POS_MINUS].insert(UsedPosList::value_type(-angle,UsedPos(-1.0,size,dist)));
+}
+
+void ObjectPosSelector::InitializeAngle()
+{
+ m_nextUsedPos[USED_POS_PLUS] = m_UsedPosLists[USED_POS_PLUS].begin();
+ m_nextUsedPos[USED_POS_MINUS] = m_UsedPosLists[USED_POS_MINUS].begin();
+
+ m_smallStepAngle[USED_POS_PLUS] = 0;
+ m_smallStepAngle[USED_POS_MINUS] = 0;
+
+ m_smallStepOk[USED_POS_PLUS] = true;
+ m_smallStepOk[USED_POS_MINUS] = true;
+}
+
+bool ObjectPosSelector::FirstAngle(float& angle)
+{
+ if(m_UsedPosLists[USED_POS_PLUS].empty() && !m_UsedPosLists[USED_POS_MINUS].empty() )
+ return NextAngleFor(*m_UsedPosLists[USED_POS_MINUS].begin(),1.0,USED_POS_PLUS,angle);
+ else if(m_UsedPosLists[USED_POS_MINUS].empty() && !m_UsedPosLists[USED_POS_PLUS].empty() )
+ return NextAngleFor(*m_UsedPosLists[USED_POS_PLUS].begin(),-1.0,USED_POS_MINUS,angle);
+
+ return false;
+}
+
+bool ObjectPosSelector::NextAngle(float& angle)
+{
+ while(m_nextUsedPos[USED_POS_PLUS]!=m_UsedPosLists[USED_POS_PLUS].end() ||
+ m_nextUsedPos[USED_POS_MINUS]!=m_UsedPosLists[USED_POS_MINUS].end() ||
+ m_smallStepOk[USED_POS_PLUS] || m_smallStepOk[USED_POS_MINUS] )
+ {
+ // calculate next possible angle
+ if(NextPosibleAngle(angle))
+ return true;
+ }
+
+ return false;
+}
+
+bool ObjectPosSelector::NextUsedAngle(float& angle)
+{
+ while(m_nextUsedPos[USED_POS_PLUS]!=m_UsedPosLists[USED_POS_PLUS].end() ||
+ m_nextUsedPos[USED_POS_MINUS]!=m_UsedPosLists[USED_POS_MINUS].end() )
+ {
+ // calculate next possible angle
+ if(!NextPosibleAngle(angle))
+ return true;
+ }
+
+ return false;
+}
+
+bool ObjectPosSelector::NextPosibleAngle( float& angle )
+{
+ // ++ direction less updated
+ if( m_nextUsedPos[USED_POS_PLUS]!=m_UsedPosLists[USED_POS_PLUS].end() &&
+ (m_nextUsedPos[USED_POS_MINUS]==m_UsedPosLists[USED_POS_MINUS].end() || m_nextUsedPos[USED_POS_PLUS]->first <= m_nextUsedPos[USED_POS_MINUS]->first) )
+ {
+ bool ok;
+ if(m_smallStepOk[USED_POS_PLUS])
+ ok = NextSmallStepAngle(1.0,USED_POS_PLUS,angle);
+ else
+ ok = NextAngleFor(*m_nextUsedPos[USED_POS_PLUS],1.0,USED_POS_PLUS,angle);
+
+ if(!ok)
+ ++m_nextUsedPos[USED_POS_PLUS]; // increase. only at fail (original or checked)
+ return ok;
+ }
+ // -- direction less updated
+ else if( m_nextUsedPos[USED_POS_MINUS]!=m_UsedPosLists[USED_POS_MINUS].end())
+ {
+ bool ok;
+ if(m_smallStepOk[USED_POS_MINUS])
+ ok = NextSmallStepAngle(-1.0,USED_POS_MINUS,angle);
+ else
+ ok = NextAngleFor(*m_nextUsedPos[USED_POS_MINUS],-1.0,USED_POS_MINUS,angle);
+
+ if(!ok)
+ ++m_nextUsedPos[USED_POS_MINUS];
+ return ok;
+ }
+ else // both list empty
+ {
+ if( m_smallStepOk[USED_POS_PLUS] && (!m_smallStepOk[USED_POS_MINUS] || m_smallStepAngle[USED_POS_PLUS] <= m_smallStepAngle[USED_POS_MINUS]) )
+ {
+ return NextSmallStepAngle(1.0,USED_POS_PLUS,angle);
+ }
+ // -- direction less updated
+ else if( m_smallStepOk[USED_POS_MINUS] )
+ {
+ return NextSmallStepAngle(-1.0,USED_POS_MINUS,angle);
+ }
+ }
+
+ // no angles
+ return false;
+}
diff --git a/src/game/ObjectPosSelector.h b/src/game/ObjectPosSelector.h
new file mode 100644
index 00000000000..84050611121
--- /dev/null
+++ b/src/game/ObjectPosSelector.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2005-2009 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 _OBJECT_POS_SELECTOR_H
+#define _OBJECT_POS_SELECTOR_H
+
+#include<Common.h>
+
+#include<map>
+
+enum UsedPosType { USED_POS_PLUS, USED_POS_MINUS };
+
+inline UsedPosType operator ~(UsedPosType uptype)
+{
+ return uptype==USED_POS_PLUS ? USED_POS_MINUS : USED_POS_PLUS;
+}
+
+struct ObjectPosSelector
+{
+ struct UsedPos
+ {
+ UsedPos(float sign_, float size_,float dist_) : sign(sign_), size(size_),dist(dist_) {}
+
+ float sign;
+
+ float size; // size of point
+ float dist; // dist to central point (including central point size)
+ };
+
+ typedef std::multimap<float,UsedPos> UsedPosList; // abs(angle)->Node
+
+ ObjectPosSelector(float x,float y,float size,float dist);
+
+ void AddUsedPos(float size,float angle,float dist);
+ void InitializeAngle();
+
+ bool FirstAngle(float& angle);
+ bool NextAngle(float& angle);
+ bool NextUsedAngle(float& angle);
+
+ bool NextPosibleAngle( float& angle );
+
+ bool CheckAngle(UsedPosList::value_type const& nextUsedPos, float sign, float angle ) const
+ {
+ float angle_step2 = GetAngle(nextUsedPos.second);
+
+ float next_angle = nextUsedPos.first;
+ if(nextUsedPos.second.sign * sign < 0) // last node from diff. list (-pi+alpha)
+ next_angle = 2*M_PI-next_angle; // move to positive
+
+ return fabs(angle)+angle_step2 <= next_angle;
+ }
+
+ bool CheckOriginal() const
+ {
+ return (m_UsedPosLists[USED_POS_PLUS].empty() || CheckAngle( *m_UsedPosLists[USED_POS_PLUS].begin(),1.0,0)) &&
+ (m_UsedPosLists[USED_POS_MINUS].empty() || CheckAngle( *m_UsedPosLists[USED_POS_MINUS].begin(),-1.0,0));
+ }
+
+ bool IsNonBalanced() const { return m_UsedPosLists[USED_POS_PLUS].empty() != m_UsedPosLists[USED_POS_MINUS].empty(); }
+
+ bool NextAngleFor( UsedPosList::value_type const& usedPos, float sign, UsedPosType uptype, float &angle )
+ {
+ float angle_step = GetAngle(usedPos.second);
+
+ // next possible angle
+ angle = usedPos.first * usedPos.second.sign + angle_step * sign;
+
+ UsedPosList::value_type const* nextNode = nextUsedPos(uptype);
+ if(nextNode)
+ {
+ // if next node permit use selected angle, then do it
+ if(!CheckAngle(*nextNode, sign, angle))
+ {
+ m_smallStepOk[uptype] = false;
+ return false;
+ }
+ }
+
+ // possible more points
+ m_smallStepOk[uptype] = true;
+ m_smallStepAngle[uptype] = angle;
+ m_smallStepNextUsedPos[uptype] = nextNode;
+
+ return true;
+ }
+
+ bool NextSmallStepAngle( float sign, UsedPosType uptype, float &angle )
+ {
+ // next possible angle
+ angle = m_smallStepAngle[uptype] + m_anglestep * sign;
+
+ if(fabs(angle) > M_PI)
+ {
+ m_smallStepOk[uptype] = false;
+ return false;
+ }
+
+ if(m_smallStepNextUsedPos[uptype])
+ {
+ if(fabs(angle) >= m_smallStepNextUsedPos[uptype]->first)
+ {
+ m_smallStepOk[uptype] = false;
+ return false;
+ }
+
+ // if next node permit use selected angle, then do it
+ if(!CheckAngle(*m_smallStepNextUsedPos[uptype], sign, angle))
+ {
+ m_smallStepOk[uptype] = false;
+ return false;
+ }
+ }
+
+ // possible more points
+ m_smallStepAngle[uptype] = angle;
+ return true;
+ }
+
+ // next used post for m_nextUsedPos[uptype]
+ UsedPosList::value_type const* nextUsedPos(UsedPosType uptype);
+
+ // angle from used pos to next possible free pos
+ float GetAngle(UsedPos const& usedPos) const { return acos(m_dist/(usedPos.dist+usedPos.size+m_size)); }
+
+ float m_center_x;
+ float m_center_y;
+ float m_size; // size of object in center
+ float m_dist; // distance for searching pos (including central object size)
+ float m_anglestep;
+
+ UsedPosList m_UsedPosLists[2];
+ UsedPosList::const_iterator m_nextUsedPos[2];
+
+ // field for small step from first after next used pos until next pos
+ float m_smallStepAngle[2];
+ bool m_smallStepOk[2];
+ UsedPosList::value_type const* m_smallStepNextUsedPos[2];
+};
+#endif
diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp
index eebe4343797..536423345c6 100644
--- a/src/game/Opcodes.cpp
+++ b/src/game/Opcodes.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -28,1065 +28,1202 @@
/// Correspondence between opcodes and their names
OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
{
- /*0x000*/ { "MSG_NULL_ACTION", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x001*/ { "CMSG_BOOTME", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x002*/ { "CMSG_DBLOOKUP", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x003*/ { "SMSG_DBLOOKUP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x004*/ { "CMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x005*/ { "SMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x006*/ { "CMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x007*/ { "SMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x008*/ { "CMSG_WORLD_TELEPORT", STATUS_LOGGEDIN, &WorldSession::HandleWorldTeleportOpcode },
- /*0x009*/ { "CMSG_TELEPORT_TO_UNIT", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
- /*0x00A*/ { "CMSG_ZONE_MAP", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x00B*/ { "SMSG_ZONE_MAP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x00C*/ { "CMSG_DEBUG_CHANGECELLZONE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x00D*/ { "CMSG_EMBLAZON_TABARD_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x00E*/ { "CMSG_UNEMBLAZON_TABARD_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x00F*/ { "CMSG_RECHARGE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x010*/ { "CMSG_LEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x011*/ { "CMSG_CREATEMONSTER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x012*/ { "CMSG_DESTROYMONSTER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x013*/ { "CMSG_CREATEITEM", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x014*/ { "CMSG_CREATEGAMEOBJECT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x015*/ { "SMSG_CHECK_FOR_BOTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x016*/ { "CMSG_MAKEMONSTERATTACKGUID", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x017*/ { "CMSG_BOT_DETECTED2", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x018*/ { "CMSG_FORCEACTION", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x019*/ { "CMSG_FORCEACTIONONOTHER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x01A*/ { "CMSG_FORCEACTIONSHOW", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x01B*/ { "SMSG_FORCEACTIONSHOW", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x01C*/ { "CMSG_PETGODMODE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x01D*/ { "SMSG_PETGODMODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x01E*/ { "SMSG_DEBUGINFOSPELLMISS_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x01F*/ { "CMSG_WEATHER_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x020*/ { "CMSG_UNDRESSPLAYER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x021*/ { "CMSG_BEASTMASTER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x022*/ { "CMSG_GODMODE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x023*/ { "SMSG_GODMODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x024*/ { "CMSG_CHEAT_SETMONEY", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x025*/ { "CMSG_LEVEL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x026*/ { "CMSG_PET_LEVEL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x027*/ { "CMSG_SET_WORLDSTATE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x028*/ { "CMSG_COOLDOWN_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x029*/ { "CMSG_USE_SKILL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x02A*/ { "CMSG_FLAG_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x02B*/ { "CMSG_FLAG_QUEST_FINISH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x02C*/ { "CMSG_CLEAR_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x02D*/ { "CMSG_SEND_EVENT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x02E*/ { "CMSG_DEBUG_AISTATE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x02F*/ { "SMSG_DEBUG_AISTATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x030*/ { "CMSG_DISABLE_PVP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x031*/ { "CMSG_ADVANCE_SPAWN_TIME", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x032*/ { "CMSG_PVP_PORT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x033*/ { "CMSG_AUTH_SRP6_BEGIN", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x034*/ { "CMSG_AUTH_SRP6_PROOF", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x035*/ { "CMSG_AUTH_SRP6_RECODE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x036*/ { "CMSG_CHAR_CREATE", STATUS_AUTHED, &WorldSession::HandleCharCreateOpcode },
- /*0x037*/ { "CMSG_CHAR_ENUM", STATUS_AUTHED, &WorldSession::HandleCharEnumOpcode },
- /*0x038*/ { "CMSG_CHAR_DELETE", STATUS_AUTHED, &WorldSession::HandleCharDeleteOpcode },
- /*0x039*/ { "SMSG_AUTH_SRP6_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x03A*/ { "SMSG_CHAR_CREATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x03B*/ { "SMSG_CHAR_ENUM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x03C*/ { "SMSG_CHAR_DELETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x03D*/ { "CMSG_PLAYER_LOGIN", STATUS_AUTHED, &WorldSession::HandlePlayerLoginOpcode },
- /*0x03E*/ { "SMSG_NEW_WORLD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x03F*/ { "SMSG_TRANSFER_PENDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x040*/ { "SMSG_TRANSFER_ABORTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x041*/ { "SMSG_CHARACTER_LOGIN_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x042*/ { "SMSG_LOGIN_SETTIMESPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x043*/ { "SMSG_GAMETIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x044*/ { "CMSG_GAMETIME_SET", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x045*/ { "SMSG_GAMETIME_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x046*/ { "CMSG_GAMESPEED_SET", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x047*/ { "SMSG_GAMESPEED_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x048*/ { "CMSG_SERVERTIME", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x049*/ { "SMSG_SERVERTIME", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x04A*/ { "CMSG_PLAYER_LOGOUT", STATUS_LOGGEDIN, &WorldSession::HandlePlayerLogoutOpcode },
- /*0x04B*/ { "CMSG_LOGOUT_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleLogoutRequestOpcode },
- /*0x04C*/ { "SMSG_LOGOUT_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x04D*/ { "SMSG_LOGOUT_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x04E*/ { "CMSG_LOGOUT_CANCEL", STATUS_LOGGEDIN, &WorldSession::HandleLogoutCancelOpcode },
- /*0x04F*/ { "SMSG_LOGOUT_CANCEL_ACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x050*/ { "CMSG_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleNameQueryOpcode },
- /*0x051*/ { "SMSG_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x052*/ { "CMSG_PET_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePetNameQuery },
- /*0x053*/ { "SMSG_PET_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x054*/ { "CMSG_GUILD_QUERY", STATUS_AUTHED, &WorldSession::HandleGuildQueryOpcode },
- /*0x055*/ { "SMSG_GUILD_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x056*/ { "CMSG_ITEM_QUERY_SINGLE", STATUS_LOGGEDIN, &WorldSession::HandleItemQuerySingleOpcode },
- /*0x057*/ { "CMSG_ITEM_QUERY_MULTIPLE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x058*/ { "SMSG_ITEM_QUERY_SINGLE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x059*/ { "SMSG_ITEM_QUERY_MULTIPLE_RESPONSE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x05A*/ { "CMSG_PAGE_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePageQueryOpcode },
- /*0x05B*/ { "SMSG_PAGE_TEXT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x05C*/ { "CMSG_QUEST_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestQueryOpcode },
- /*0x05D*/ { "SMSG_QUEST_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x05E*/ { "CMSG_GAMEOBJECT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGameObjectQueryOpcode },
- /*0x05F*/ { "SMSG_GAMEOBJECT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x060*/ { "CMSG_CREATURE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCreatureQueryOpcode },
- /*0x061*/ { "SMSG_CREATURE_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x062*/ { "CMSG_WHO", STATUS_LOGGEDIN, &WorldSession::HandleWhoOpcode },
- /*0x063*/ { "SMSG_WHO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x064*/ { "CMSG_WHOIS", STATUS_LOGGEDIN, &WorldSession::HandleWhoisOpcode },
- /*0x065*/ { "SMSG_WHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x066*/ { "CMSG_CONTACT_LIST", STATUS_LOGGEDIN, &WorldSession::HandleFriendListOpcode },
- /*0x067*/ { "SMSG_CONTACT_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x068*/ { "SMSG_FRIEND_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x069*/ { "CMSG_ADD_FRIEND", STATUS_LOGGEDIN, &WorldSession::HandleAddFriendOpcode },
- /*0x06A*/ { "CMSG_DEL_FRIEND", STATUS_LOGGEDIN, &WorldSession::HandleDelFriendOpcode },
- /*0x06B*/ { "CMSG_SET_CONTACT_NOTES", STATUS_LOGGEDIN, &WorldSession::HandleSetFriendNoteOpcode },
- /*0x06C*/ { "CMSG_ADD_IGNORE", STATUS_LOGGEDIN, &WorldSession::HandleAddIgnoreOpcode },
- /*0x06D*/ { "CMSG_DEL_IGNORE", STATUS_LOGGEDIN, &WorldSession::HandleDelIgnoreOpcode },
- /*0x06E*/ { "CMSG_GROUP_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleGroupInviteOpcode },
- /*0x06F*/ { "SMSG_GROUP_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x070*/ { "CMSG_GROUP_CANCEL", STATUS_LOGGEDIN, &WorldSession::Handle_Deprecated },
- /*0x071*/ { "SMSG_GROUP_CANCEL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x072*/ { "CMSG_GROUP_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleGroupAcceptOpcode },
- /*0x073*/ { "CMSG_GROUP_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleGroupDeclineOpcode },
- /*0x074*/ { "SMSG_GROUP_DECLINE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x075*/ { "CMSG_GROUP_UNINVITE", STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteNameOpcode },
- /*0x076*/ { "CMSG_GROUP_UNINVITE_GUID", STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteGuidOpcode },
- /*0x077*/ { "SMSG_GROUP_UNINVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x078*/ { "CMSG_GROUP_SET_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGroupSetLeaderOpcode },
- /*0x079*/ { "SMSG_GROUP_SET_LEADER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x07A*/ { "CMSG_LOOT_METHOD", STATUS_LOGGEDIN, &WorldSession::HandleLootMethodOpcode },
- /*0x07B*/ { "CMSG_GROUP_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleGroupLeaveOpcode },
- /*0x07C*/ { "SMSG_GROUP_DESTROYED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x07D*/ { "SMSG_GROUP_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x07E*/ { "SMSG_PARTY_MEMBER_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x07F*/ { "SMSG_PARTY_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x080*/ { "UMSG_UPDATE_GROUP_MEMBERS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x081*/ { "CMSG_GUILD_CREATE", STATUS_LOGGEDIN, &WorldSession::HandleGuildCreateOpcode },
- /*0x082*/ { "CMSG_GUILD_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleGuildInviteOpcode },
- /*0x083*/ { "SMSG_GUILD_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x084*/ { "CMSG_GUILD_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleGuildAcceptOpcode },
- /*0x085*/ { "CMSG_GUILD_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleGuildDeclineOpcode },
- /*0x086*/ { "SMSG_GUILD_DECLINE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x087*/ { "CMSG_GUILD_INFO", STATUS_LOGGEDIN, &WorldSession::HandleGuildInfoOpcode },
- /*0x088*/ { "SMSG_GUILD_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x089*/ { "CMSG_GUILD_ROSTER", STATUS_LOGGEDIN, &WorldSession::HandleGuildRosterOpcode },
- /*0x08A*/ { "SMSG_GUILD_ROSTER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x08B*/ { "CMSG_GUILD_PROMOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildPromoteOpcode },
- /*0x08C*/ { "CMSG_GUILD_DEMOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildDemoteOpcode },
- /*0x08D*/ { "CMSG_GUILD_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaveOpcode },
- /*0x08E*/ { "CMSG_GUILD_REMOVE", STATUS_LOGGEDIN, &WorldSession::HandleGuildRemoveOpcode },
- /*0x08F*/ { "CMSG_GUILD_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleGuildDisbandOpcode },
- /*0x090*/ { "CMSG_GUILD_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaderOpcode },
- /*0x091*/ { "CMSG_GUILD_MOTD", STATUS_LOGGEDIN, &WorldSession::HandleGuildMOTDOpcode },
- /*0x092*/ { "SMSG_GUILD_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x093*/ { "SMSG_GUILD_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x094*/ { "UMSG_UPDATE_GUILD", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x095*/ { "CMSG_MESSAGECHAT", STATUS_LOGGEDIN, &WorldSession::HandleMessagechatOpcode },
- /*0x096*/ { "SMSG_MESSAGECHAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x097*/ { "CMSG_JOIN_CHANNEL", STATUS_LOGGEDIN, &WorldSession::HandleChannelJoin },
- /*0x098*/ { "CMSG_LEAVE_CHANNEL", STATUS_LOGGEDIN, &WorldSession::HandleChannelLeave },
- /*0x099*/ { "SMSG_CHANNEL_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x09A*/ { "CMSG_CHANNEL_LIST", STATUS_LOGGEDIN, &WorldSession::HandleChannelList },
- /*0x09B*/ { "SMSG_CHANNEL_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x09C*/ { "CMSG_CHANNEL_PASSWORD", STATUS_LOGGEDIN, &WorldSession::HandleChannelPassword },
- /*0x09D*/ { "CMSG_CHANNEL_SET_OWNER", STATUS_LOGGEDIN, &WorldSession::HandleChannelSetOwner },
- /*0x09E*/ { "CMSG_CHANNEL_OWNER", STATUS_LOGGEDIN, &WorldSession::HandleChannelOwner },
- /*0x09F*/ { "CMSG_CHANNEL_MODERATOR", STATUS_LOGGEDIN, &WorldSession::HandleChannelModerator },
- /*0x0A0*/ { "CMSG_CHANNEL_UNMODERATOR", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmoderator },
- /*0x0A1*/ { "CMSG_CHANNEL_MUTE", STATUS_LOGGEDIN, &WorldSession::HandleChannelMute },
- /*0x0A2*/ { "CMSG_CHANNEL_UNMUTE", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmute },
- /*0x0A3*/ { "CMSG_CHANNEL_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleChannelInvite },
- /*0x0A4*/ { "CMSG_CHANNEL_KICK", STATUS_LOGGEDIN, &WorldSession::HandleChannelKick },
- /*0x0A5*/ { "CMSG_CHANNEL_BAN", STATUS_LOGGEDIN, &WorldSession::HandleChannelBan },
- /*0x0A6*/ { "CMSG_CHANNEL_UNBAN", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnban },
- /*0x0A7*/ { "CMSG_CHANNEL_ANNOUNCEMENTS", STATUS_LOGGEDIN, &WorldSession::HandleChannelAnnounce },
- /*0x0A8*/ { "CMSG_CHANNEL_MODERATE", STATUS_LOGGEDIN, &WorldSession::HandleChannelModerate },
- /*0x0A9*/ { "SMSG_UPDATE_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0AA*/ { "SMSG_DESTROY_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0AB*/ { "CMSG_USE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleUseItemOpcode },
- /*0x0AC*/ { "CMSG_OPEN_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleOpenItemOpcode },
- /*0x0AD*/ { "CMSG_READ_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleReadItem },
- /*0x0AE*/ { "SMSG_READ_ITEM_OK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0AF*/ { "SMSG_READ_ITEM_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0B0*/ { "SMSG_ITEM_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0B1*/ { "CMSG_GAMEOBJ_USE", STATUS_LOGGEDIN, &WorldSession::HandleGameObjectUseOpcode },
- /*0x0B2*/ { "CMSG_GAMEOBJ_CHAIR_USE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0B3*/ { "SMSG_GAMEOBJECT_CUSTOM_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0B4*/ { "CMSG_AREATRIGGER", STATUS_LOGGEDIN, &WorldSession::HandleAreaTriggerOpcode },
- /*0x0B5*/ { "MSG_MOVE_START_FORWARD", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0B6*/ { "MSG_MOVE_START_BACKWARD", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0B7*/ { "MSG_MOVE_STOP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0B8*/ { "MSG_MOVE_START_STRAFE_LEFT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0B9*/ { "MSG_MOVE_START_STRAFE_RIGHT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0BA*/ { "MSG_MOVE_STOP_STRAFE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0BB*/ { "MSG_MOVE_JUMP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0BC*/ { "MSG_MOVE_START_TURN_LEFT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0BD*/ { "MSG_MOVE_START_TURN_RIGHT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0BE*/ { "MSG_MOVE_STOP_TURN", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0BF*/ { "MSG_MOVE_START_PITCH_UP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0C0*/ { "MSG_MOVE_START_PITCH_DOWN", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0C1*/ { "MSG_MOVE_STOP_PITCH", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0C2*/ { "MSG_MOVE_SET_RUN_MODE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0C3*/ { "MSG_MOVE_SET_WALK_MODE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0C4*/ { "MSG_MOVE_TOGGLE_LOGGING", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0C5*/ { "MSG_MOVE_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0C6*/ { "MSG_MOVE_TELEPORT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0C7*/ { "MSG_MOVE_TELEPORT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveTeleportAck },
- /*0x0C8*/ { "MSG_MOVE_TOGGLE_FALL_LOGGING", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0C9*/ { "MSG_MOVE_FALL_LAND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0CA*/ { "MSG_MOVE_START_SWIM", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0CB*/ { "MSG_MOVE_STOP_SWIM", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0CC*/ { "MSG_MOVE_SET_RUN_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0CD*/ { "MSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0CE*/ { "MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT",STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0CF*/ { "MSG_MOVE_SET_RUN_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D0*/ { "MSG_MOVE_SET_WALK_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D1*/ { "MSG_MOVE_SET_WALK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D2*/ { "MSG_MOVE_SET_SWIM_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D3*/ { "MSG_MOVE_SET_SWIM_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D4*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT",STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D5*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D6*/ { "MSG_MOVE_SET_ALL_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D7*/ { "MSG_MOVE_SET_TURN_RATE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D8*/ { "MSG_MOVE_SET_TURN_RATE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D9*/ { "MSG_MOVE_TOGGLE_COLLISION_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0DA*/ { "MSG_MOVE_SET_FACING", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0DB*/ { "MSG_MOVE_SET_PITCH", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0DC*/ { "MSG_MOVE_WORLDPORT_ACK", STATUS_TRANSFER_PENDING, &WorldSession::HandleMoveWorldportAckOpcode},
- /*0x0DD*/ { "SMSG_MONSTER_MOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0DE*/ { "SMSG_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0DF*/ { "SMSG_MOVE_LAND_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0E0*/ { "MSG_MOVE_SET_RAW_POSITION_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0E1*/ { "CMSG_MOVE_SET_RAW_POSITION", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0E2*/ { "SMSG_FORCE_RUN_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0E3*/ { "CMSG_FORCE_RUN_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
- /*0x0E4*/ { "SMSG_FORCE_RUN_BACK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0E5*/ { "CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck },
- /*0x0E6*/ { "SMSG_FORCE_SWIM_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0E7*/ { "CMSG_FORCE_SWIM_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
- /*0x0E8*/ { "SMSG_FORCE_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0E9*/ { "CMSG_FORCE_MOVE_ROOT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveRootAck },
- /*0x0EA*/ { "SMSG_FORCE_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0EB*/ { "CMSG_FORCE_MOVE_UNROOT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveUnRootAck },
- /*0x0EC*/ { "MSG_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0ED*/ { "MSG_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0EE*/ { "MSG_MOVE_HEARTBEAT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0EF*/ { "SMSG_MOVE_KNOCK_BACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0F0*/ { "CMSG_MOVE_KNOCK_BACK_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveKnockBackAck },
- /*0x0F1*/ { "MSG_MOVE_KNOCK_BACK", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0F2*/ { "SMSG_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0F3*/ { "SMSG_MOVE_NORMAL_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0F4*/ { "SMSG_MOVE_SET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0F5*/ { "SMSG_MOVE_UNSET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0F6*/ { "CMSG_MOVE_HOVER_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveHoverAck },
- /*0x0F7*/ { "MSG_MOVE_HOVER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0F8*/ { "CMSG_TRIGGER_CINEMATIC_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0F9*/ { "CMSG_OPENING_CINEMATIC", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0FA*/ { "SMSG_TRIGGER_CINEMATIC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0FB*/ { "CMSG_NEXT_CINEMATIC_CAMERA", STATUS_LOGGEDIN, &WorldSession::HandleNextCinematicCamera },
- /*0x0FC*/ { "CMSG_COMPLETE_CINEMATIC", STATUS_LOGGEDIN, &WorldSession::HandleCompleteCinema },
- /*0x0FD*/ { "SMSG_TUTORIAL_FLAGS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0FE*/ { "CMSG_TUTORIAL_FLAG", STATUS_LOGGEDIN, &WorldSession::HandleTutorialFlag },
- /*0x0FF*/ { "CMSG_TUTORIAL_CLEAR", STATUS_LOGGEDIN, &WorldSession::HandleTutorialClear },
- /*0x100*/ { "CMSG_TUTORIAL_RESET", STATUS_LOGGEDIN, &WorldSession::HandleTutorialReset },
- /*0x101*/ { "CMSG_STANDSTATECHANGE", STATUS_LOGGEDIN, &WorldSession::HandleStandStateChangeOpcode },
- /*0x102*/ { "CMSG_EMOTE", STATUS_LOGGEDIN, &WorldSession::HandleEmoteOpcode },
- /*0x103*/ { "SMSG_EMOTE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x104*/ { "CMSG_TEXT_EMOTE", STATUS_LOGGEDIN, &WorldSession::HandleTextEmoteOpcode },
- /*0x105*/ { "SMSG_TEXT_EMOTE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x106*/ { "CMSG_AUTOEQUIP_GROUND_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x107*/ { "CMSG_AUTOSTORE_GROUND_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x108*/ { "CMSG_AUTOSTORE_LOOT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutostoreLootItemOpcode },
- /*0x109*/ { "CMSG_STORE_LOOT_IN_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x10A*/ { "CMSG_AUTOEQUIP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemOpcode },
- /*0x10B*/ { "CMSG_AUTOSTORE_BAG_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBagItemOpcode },
- /*0x10C*/ { "CMSG_SWAP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSwapItem },
- /*0x10D*/ { "CMSG_SWAP_INV_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSwapInvItemOpcode },
- /*0x10E*/ { "CMSG_SPLIT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSplitItemOpcode },
- /*0x10F*/ { "CMSG_AUTOEQUIP_ITEM_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemSlotOpcode },
- /*0x110*/ { "OBSOLETE_DROP_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x111*/ { "CMSG_DESTROYITEM", STATUS_LOGGEDIN, &WorldSession::HandleDestroyItemOpcode },
- /*0x112*/ { "SMSG_INVENTORY_CHANGE_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x113*/ { "SMSG_OPEN_CONTAINER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x114*/ { "CMSG_INSPECT", STATUS_LOGGEDIN, &WorldSession::HandleInspectOpcode },
- /*0x115*/ { "SMSG_INSPECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x116*/ { "CMSG_INITIATE_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleInitiateTradeOpcode },
- /*0x117*/ { "CMSG_BEGIN_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleBeginTradeOpcode },
- /*0x118*/ { "CMSG_BUSY_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleBusyTradeOpcode },
- /*0x119*/ { "CMSG_IGNORE_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleIgnoreTradeOpcode },
- /*0x11A*/ { "CMSG_ACCEPT_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleAcceptTradeOpcode },
- /*0x11B*/ { "CMSG_UNACCEPT_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleUnacceptTradeOpcode },
- /*0x11C*/ { "CMSG_CANCEL_TRADE", STATUS_AUTHED, &WorldSession::HandleCancelTradeOpcode },
- /*0x11D*/ { "CMSG_SET_TRADE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSetTradeItemOpcode },
- /*0x11E*/ { "CMSG_CLEAR_TRADE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleClearTradeItemOpcode },
- /*0x11F*/ { "CMSG_SET_TRADE_GOLD", STATUS_LOGGEDIN, &WorldSession::HandleSetTradeGoldOpcode },
- /*0x120*/ { "SMSG_TRADE_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x121*/ { "SMSG_TRADE_STATUS_EXTENDED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x122*/ { "SMSG_INITIALIZE_FACTIONS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x123*/ { "SMSG_SET_FACTION_VISIBLE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x124*/ { "SMSG_SET_FACTION_STANDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x125*/ { "CMSG_SET_FACTION_ATWAR", STATUS_LOGGEDIN, &WorldSession::HandleSetFactionAtWar },
- /*0x126*/ { "CMSG_SET_FACTION_CHEAT", STATUS_LOGGEDIN, &WorldSession::HandleSetFactionCheat },
- /*0x127*/ { "SMSG_SET_PROFICIENCY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x128*/ { "CMSG_SET_ACTION_BUTTON", STATUS_LOGGEDIN, &WorldSession::HandleSetActionButtonOpcode },
- /*0x129*/ { "SMSG_ACTION_BUTTONS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x12A*/ { "SMSG_INITIAL_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x12B*/ { "SMSG_LEARNED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x12C*/ { "SMSG_SUPERCEDED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x12D*/ { "CMSG_NEW_SPELL_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x12E*/ { "CMSG_CAST_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleCastSpellOpcode },
- /*0x12F*/ { "CMSG_CANCEL_CAST", STATUS_LOGGEDIN, &WorldSession::HandleCancelCastOpcode },
- /*0x130*/ { "SMSG_CAST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x131*/ { "SMSG_SPELL_START", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x132*/ { "SMSG_SPELL_GO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x133*/ { "SMSG_SPELL_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x134*/ { "SMSG_SPELL_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x135*/ { "SMSG_COOLDOWN_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x136*/ { "CMSG_CANCEL_AURA", STATUS_LOGGEDIN, &WorldSession::HandleCancelAuraOpcode },
- /*0x137*/ { "SMSG_UPDATE_AURA_DURATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x138*/ { "SMSG_PET_CAST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x139*/ { "MSG_CHANNEL_START", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x13A*/ { "MSG_CHANNEL_UPDATE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x13B*/ { "CMSG_CANCEL_CHANNELLING", STATUS_LOGGEDIN, &WorldSession::HandleCancelChanneling },
- /*0x13C*/ { "SMSG_AI_REACTION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x13D*/ { "CMSG_SET_SELECTION", STATUS_LOGGEDIN, &WorldSession::HandleSetSelectionOpcode },
- /*0x13E*/ { "CMSG_SET_TARGET_OBSOLETE", STATUS_LOGGEDIN, &WorldSession::HandleSetTargetOpcode },
- /*0x13F*/ { "CMSG_UNUSED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x140*/ { "CMSG_UNUSED2", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x141*/ { "CMSG_ATTACKSWING", STATUS_LOGGEDIN, &WorldSession::HandleAttackSwingOpcode },
- /*0x142*/ { "CMSG_ATTACKSTOP", STATUS_LOGGEDIN, &WorldSession::HandleAttackStopOpcode },
- /*0x143*/ { "SMSG_ATTACKSTART", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x144*/ { "SMSG_ATTACKSTOP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x145*/ { "SMSG_ATTACKSWING_NOTINRANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x146*/ { "SMSG_ATTACKSWING_BADFACING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x147*/ { "SMSG_ATTACKSWING_NOTSTANDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x148*/ { "SMSG_ATTACKSWING_DEADTARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x149*/ { "SMSG_ATTACKSWING_CANT_ATTACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x14B*/ { "SMSG_VICTIMSTATEUPDATE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x14C*/ { "SMSG_DAMAGE_DONE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x14D*/ { "SMSG_DAMAGE_TAKEN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x14E*/ { "SMSG_CANCEL_COMBAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x14F*/ { "SMSG_PLAYER_COMBAT_XP_GAIN_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x150*/ { "SMSG_SPELLHEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x151*/ { "SMSG_SPELLENERGIZELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x152*/ { "CMSG_SHEATHE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x153*/ { "CMSG_SAVE_PLAYER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x154*/ { "CMSG_SETDEATHBINDPOINT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x155*/ { "SMSG_BINDPOINTUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x156*/ { "CMSG_GETDEATHBINDZONE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x157*/ { "SMSG_BINDZONEREPLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x158*/ { "SMSG_PLAYERBOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x159*/ { "SMSG_CLIENT_CONTROL_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x15A*/ { "CMSG_REPOP_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleRepopRequestOpcode },
- /*0x15B*/ { "SMSG_RESURRECT_REQUEST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x15C*/ { "CMSG_RESURRECT_RESPONSE", STATUS_LOGGEDIN, &WorldSession::HandleResurrectResponseOpcode },
- /*0x15D*/ { "CMSG_LOOT", STATUS_LOGGEDIN, &WorldSession::HandleLootOpcode },
- /*0x15E*/ { "CMSG_LOOT_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleLootMoneyOpcode },
- /*0x15F*/ { "CMSG_LOOT_RELEASE", STATUS_LOGGEDIN, &WorldSession::HandleLootReleaseOpcode },
- /*0x160*/ { "SMSG_LOOT_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x161*/ { "SMSG_LOOT_RELEASE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x162*/ { "SMSG_LOOT_REMOVED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x163*/ { "SMSG_LOOT_MONEY_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x164*/ { "SMSG_LOOT_ITEM_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x165*/ { "SMSG_LOOT_CLEAR_MONEY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x166*/ { "SMSG_ITEM_PUSH_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x167*/ { "SMSG_DUEL_REQUESTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x168*/ { "SMSG_DUEL_OUTOFBOUNDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x169*/ { "SMSG_DUEL_INBOUNDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x16A*/ { "SMSG_DUEL_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x16B*/ { "SMSG_DUEL_WINNER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x16C*/ { "CMSG_DUEL_ACCEPTED", STATUS_LOGGEDIN, &WorldSession::HandleDuelAcceptedOpcode },
- /*0x16D*/ { "CMSG_DUEL_CANCELLED", STATUS_LOGGEDIN, &WorldSession::HandleDuelCancelledOpcode },
- /*0x16E*/ { "SMSG_MOUNTRESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x16F*/ { "SMSG_DISMOUNTRESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x170*/ { "SMSG_PUREMOUNT_CANCELLED_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x171*/ { "CMSG_MOUNTSPECIAL_ANIM", STATUS_LOGGEDIN, &WorldSession::HandleMountSpecialAnimOpcode },
- /*0x172*/ { "SMSG_MOUNTSPECIAL_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x173*/ { "SMSG_PET_TAME_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x174*/ { "CMSG_PET_SET_ACTION", STATUS_LOGGEDIN, &WorldSession::HandlePetSetAction },
- /*0x175*/ { "CMSG_PET_ACTION", STATUS_LOGGEDIN, &WorldSession::HandlePetAction },
- /*0x176*/ { "CMSG_PET_ABANDON", STATUS_LOGGEDIN, &WorldSession::HandlePetAbandon },
- /*0x177*/ { "CMSG_PET_RENAME", STATUS_LOGGEDIN, &WorldSession::HandlePetRename },
- /*0x178*/ { "SMSG_PET_NAME_INVALID", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x179*/ { "SMSG_PET_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x17A*/ { "SMSG_PET_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x17B*/ { "CMSG_GOSSIP_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleGossipHelloOpcode },
- /*0x17C*/ { "CMSG_GOSSIP_SELECT_OPTION", STATUS_LOGGEDIN, &WorldSession::HandleGossipSelectOptionOpcode },
- /*0x17D*/ { "SMSG_GOSSIP_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x17E*/ { "SMSG_GOSSIP_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x17F*/ { "CMSG_NPC_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleNpcTextQueryOpcode },
- /*0x180*/ { "SMSG_NPC_TEXT_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x181*/ { "SMSG_NPC_WONT_TALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x182*/ { "CMSG_QUESTGIVER_STATUS_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverStatusQueryOpcode},
- /*0x183*/ { "SMSG_QUESTGIVER_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x184*/ { "CMSG_QUESTGIVER_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverHelloOpcode },
- /*0x185*/ { "SMSG_QUESTGIVER_QUEST_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x186*/ { "CMSG_QUESTGIVER_QUERY_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverQuestQueryOpcode},
- /*0x187*/ { "CMSG_QUESTGIVER_QUEST_AUTOLAUNCH", STATUS_LOGGEDIN, &WorldSession::HandleQuestAutoLaunch },
- /*0x188*/ { "SMSG_QUESTGIVER_QUEST_DETAILS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x189*/ { "CMSG_QUESTGIVER_ACCEPT_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverAcceptQuestOpcode},
- /*0x18A*/ { "CMSG_QUESTGIVER_COMPLETE_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestComplete },
- /*0x18B*/ { "SMSG_QUESTGIVER_REQUEST_ITEMS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x18C*/ { "CMSG_QUESTGIVER_REQUEST_REWARD", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverRequestRewardOpcode},
- /*0x18D*/ { "SMSG_QUESTGIVER_OFFER_REWARD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x18E*/ { "CMSG_QUESTGIVER_CHOOSE_REWARD", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverChooseRewardOpcode},
- /*0x18F*/ { "SMSG_QUESTGIVER_QUEST_INVALID", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x190*/ { "CMSG_QUESTGIVER_CANCEL", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverCancel },
- /*0x191*/ { "SMSG_QUESTGIVER_QUEST_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x192*/ { "SMSG_QUESTGIVER_QUEST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x193*/ { "CMSG_QUESTLOG_SWAP_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestLogSwapQuest },
- /*0x194*/ { "CMSG_QUESTLOG_REMOVE_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestLogRemoveQuest },
- /*0x195*/ { "SMSG_QUESTLOG_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x196*/ { "SMSG_QUESTUPDATE_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x197*/ { "SMSG_QUESTUPDATE_FAILEDTIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x198*/ { "SMSG_QUESTUPDATE_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x199*/ { "SMSG_QUESTUPDATE_ADD_KILL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x19A*/ { "SMSG_QUESTUPDATE_ADD_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x19B*/ { "CMSG_QUEST_CONFIRM_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleQuestConfirmAccept },
- /*0x19C*/ { "SMSG_QUEST_CONFIRM_ACCEPT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x19D*/ { "CMSG_PUSHQUESTTOPARTY", STATUS_LOGGEDIN, &WorldSession::HandleQuestPushToParty },
- /*0x19E*/ { "CMSG_LIST_INVENTORY", STATUS_LOGGEDIN, &WorldSession::HandleListInventoryOpcode },
- /*0x19F*/ { "SMSG_LIST_INVENTORY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1A0*/ { "CMSG_SELL_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSellItemOpcode },
- /*0x1A1*/ { "SMSG_SELL_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1A2*/ { "CMSG_BUY_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuyItemOpcode },
- /*0x1A3*/ { "CMSG_BUY_ITEM_IN_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyItemInSlotOpcode },
- /*0x1A4*/ { "SMSG_BUY_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1A5*/ { "SMSG_BUY_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1A6*/ { "CMSG_TAXICLEARALLNODES", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1A7*/ { "CMSG_TAXIENABLEALLNODES", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1A8*/ { "CMSG_TAXISHOWNODES", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1A9*/ { "SMSG_SHOWTAXINODES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1AA*/ { "CMSG_TAXINODE_STATUS_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleTaxiNodeStatusQueryOpcode },
- /*0x1AB*/ { "SMSG_TAXINODE_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1AC*/ { "CMSG_TAXIQUERYAVAILABLENODES", STATUS_LOGGEDIN, &WorldSession::HandleTaxiQueryAvailableNodesOpcode},
- /*0x1AD*/ { "CMSG_ACTIVATETAXI", STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiOpcode },
- /*0x1AE*/ { "SMSG_ACTIVATETAXIREPLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1AF*/ { "SMSG_NEW_TAXI_PATH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1B0*/ { "CMSG_TRAINER_LIST", STATUS_LOGGEDIN, &WorldSession::HandleTrainerListOpcode },
- /*0x1B1*/ { "SMSG_TRAINER_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1B2*/ { "CMSG_TRAINER_BUY_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleTrainerBuySpellOpcode },
- /*0x1B3*/ { "SMSG_TRAINER_BUY_SUCCEEDED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1B4*/ { "SMSG_TRAINER_BUY_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1B5*/ { "CMSG_BINDER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleBinderActivateOpcode },
- /*0x1B6*/ { "SMSG_PLAYERBINDERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1B7*/ { "CMSG_BANKER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleBankerActivateOpcode },
- /*0x1B8*/ { "SMSG_SHOW_BANK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1B9*/ { "CMSG_BUY_BANK_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyBankSlotOpcode },
- /*0x1BA*/ { "SMSG_BUY_BANK_SLOT_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1BB*/ { "CMSG_PETITION_SHOWLIST", STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowListOpcode },
- /*0x1BC*/ { "SMSG_PETITION_SHOWLIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1BD*/ { "CMSG_PETITION_BUY", STATUS_LOGGEDIN, &WorldSession::HandlePetitionBuyOpcode },
- /*0x1BE*/ { "CMSG_PETITION_SHOW_SIGNATURES", STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowSignOpcode },
- /*0x1BF*/ { "SMSG_PETITION_SHOW_SIGNATURES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1C0*/ { "CMSG_PETITION_SIGN", STATUS_LOGGEDIN, &WorldSession::HandlePetitionSignOpcode },
- /*0x1C1*/ { "SMSG_PETITION_SIGN_RESULTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1C2*/ { "MSG_PETITION_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandlePetitionDeclineOpcode },
- /*0x1C3*/ { "CMSG_OFFER_PETITION", STATUS_LOGGEDIN, &WorldSession::HandleOfferPetitionOpcode },
- /*0x1C4*/ { "CMSG_TURN_IN_PETITION", STATUS_LOGGEDIN, &WorldSession::HandleTurnInPetitionOpcode },
- /*0x1C5*/ { "SMSG_TURN_IN_PETITION_RESULTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1C6*/ { "CMSG_PETITION_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePetitionQueryOpcode },
- /*0x1C7*/ { "SMSG_PETITION_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1C8*/ { "SMSG_FISH_NOT_HOOKED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1C9*/ { "SMSG_FISH_ESCAPED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1CA*/ { "CMSG_BUG", STATUS_LOGGEDIN, &WorldSession::HandleBugOpcode },
- /*0x1CB*/ { "SMSG_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1CC*/ { "CMSG_PLAYED_TIME", STATUS_LOGGEDIN, &WorldSession::HandlePlayedTime },
- /*0x1CD*/ { "SMSG_PLAYED_TIME", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1CE*/ { "CMSG_QUERY_TIME", STATUS_LOGGEDIN, &WorldSession::HandleQueryTimeOpcode },
- /*0x1CF*/ { "SMSG_QUERY_TIME_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1D0*/ { "SMSG_LOG_XPGAIN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1D1*/ { "SMSG_AURACASTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1D2*/ { "CMSG_RECLAIM_CORPSE", STATUS_LOGGEDIN, &WorldSession::HandleCorpseReclaimOpcode },
- /*0x1D3*/ { "CMSG_WRAP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleWrapItemOpcode },
- /*0x1D4*/ { "SMSG_LEVELUP_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1D5*/ { "MSG_MINIMAP_PING", STATUS_LOGGEDIN, &WorldSession::HandleMinimapPingOpcode },
- /*0x1D6*/ { "SMSG_RESISTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1D7*/ { "SMSG_ENCHANTMENTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1D8*/ { "CMSG_SET_SKILL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1D9*/ { "SMSG_START_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1DA*/ { "SMSG_PAUSE_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1DB*/ { "SMSG_STOP_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1DC*/ { "CMSG_PING", STATUS_NEVER, &WorldSession::Handle_EarlyProccess },
- /*0x1DD*/ { "SMSG_PONG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1DE*/ { "SMSG_CLEAR_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1DF*/ { "SMSG_GAMEOBJECT_PAGETEXT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1E0*/ { "CMSG_SETSHEATHED", STATUS_LOGGEDIN, &WorldSession::HandleSetSheathedOpcode },
- /*0x1E1*/ { "SMSG_COOLDOWN_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1E2*/ { "SMSG_SPELL_DELAYED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1E3*/ { "CMSG_PLAYER_MACRO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1E4*/ { "SMSG_PLAYER_MACRO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1E5*/ { "CMSG_GHOST", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1E6*/ { "CMSG_GM_INVIS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1E7*/ { "SMSG_INVALID_PROMOTION_CODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1E8*/ { "MSG_GM_BIND_OTHER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1E9*/ { "MSG_GM_SUMMON", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1EA*/ { "SMSG_ITEM_TIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1EB*/ { "SMSG_ITEM_ENCHANT_TIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1EC*/ { "SMSG_AUTH_CHALLENGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1ED*/ { "CMSG_AUTH_SESSION", STATUS_NEVER, &WorldSession::Handle_EarlyProccess },
- /*0x1EE*/ { "SMSG_AUTH_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1EF*/ { "MSG_GM_SHOWLABEL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1F0*/ { "CMSG_PET_CAST_SPELL", STATUS_LOGGEDIN, &WorldSession::HandlePetCastSpellOpcode },
- /*0x1F1*/ { "MSG_SAVE_GUILD_EMBLEM", STATUS_LOGGEDIN, &WorldSession::HandleGuildSaveEmblemOpcode },
- /*0x1F2*/ { "MSG_TABARDVENDOR_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleTabardVendorActivateOpcode},
- /*0x1F3*/ { "SMSG_PLAY_SPELL_VISUAL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1F4*/ { "CMSG_ZONEUPDATE", STATUS_LOGGEDIN, &WorldSession::HandleZoneUpdateOpcode },
- /*0x1F5*/ { "SMSG_PARTYKILLLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1F6*/ { "SMSG_COMPRESSED_UPDATE_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1F7*/ { "SMSG_PLAY_SPELL_IMPACT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1F8*/ { "SMSG_EXPLORATION_EXPERIENCE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1F9*/ { "CMSG_GM_SET_SECURITY_GROUP", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1FA*/ { "CMSG_GM_NUKE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1FB*/ { "MSG_RANDOM_ROLL", STATUS_LOGGEDIN, &WorldSession::HandleRandomRollOpcode },
- /*0x1FC*/ { "SMSG_ENVIRONMENTALDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1FD*/ { "CMSG_RWHOIS_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1FE*/ { "SMSG_RWHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1FF*/ { "MSG_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleLookingForGroup },
- /*0x200*/ { "CMSG_SET_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleSetLfgOpcode },
- /*0x201*/ { "CMSG_UNLEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x202*/ { "CMSG_UNLEARN_SKILL", STATUS_LOGGEDIN, &WorldSession::HandleUnlearnSkillOpcode },
- /*0x203*/ { "SMSG_REMOVED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x204*/ { "CMSG_DECHARGE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x205*/ { "CMSG_GMTICKET_CREATE", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketCreateOpcode },
- /*0x206*/ { "SMSG_GMTICKET_CREATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x207*/ { "CMSG_GMTICKET_UPDATETEXT", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketUpdateOpcode },
- /*0x208*/ { "SMSG_GMTICKET_UPDATETEXT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x209*/ { "SMSG_ACCOUNT_DATA_TIMES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x20A*/ { "CMSG_REQUEST_ACCOUNT_DATA", STATUS_LOGGEDIN, &WorldSession::HandleRequestAccountData },
- /*0x20B*/ { "CMSG_UPDATE_ACCOUNT_DATA", STATUS_LOGGEDIN, &WorldSession::HandleUpdateAccountData },
- /*0x20C*/ { "SMSG_UPDATE_ACCOUNT_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x20D*/ { "SMSG_CLEAR_FAR_SIGHT_IMMEDIATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x20E*/ { "SMSG_POWERGAINLOG_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x20F*/ { "CMSG_GM_TEACH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x210*/ { "CMSG_GM_CREATE_ITEM_TARGET", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x211*/ { "CMSG_GMTICKET_GETTICKET", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketGetTicketOpcode },
- /*0x212*/ { "SMSG_GMTICKET_GETTICKET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x213*/ { "CMSG_UNLEARN_TALENTS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x214*/ { "SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x215*/ { "SMSG_GAMEOBJECT_DESPAWN_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x216*/ { "MSG_CORPSE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCorpseQueryOpcode },
- /*0x217*/ { "CMSG_GMTICKET_DELETETICKET", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketDeleteOpcode },
- /*0x218*/ { "SMSG_GMTICKET_DELETETICKET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x219*/ { "SMSG_CHAT_WRONG_FACTION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x21A*/ { "CMSG_GMTICKET_SYSTEMSTATUS", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketSystemStatusOpcode},
- /*0x21B*/ { "SMSG_GMTICKET_SYSTEMSTATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x21C*/ { "CMSG_SPIRIT_HEALER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleSpiritHealerActivateOpcode},
- /*0x21D*/ { "CMSG_SET_STAT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x21E*/ { "SMSG_SET_REST_START", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x21F*/ { "CMSG_SKILL_BUY_STEP", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x220*/ { "CMSG_SKILL_BUY_RANK", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x221*/ { "CMSG_XP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x222*/ { "SMSG_SPIRIT_HEALER_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x223*/ { "CMSG_CHARACTER_POINT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x224*/ { "SMSG_GOSSIP_POI", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x225*/ { "CMSG_CHAT_IGNORED", STATUS_LOGGEDIN, &WorldSession::HandleChatIgnoredOpcode },
- /*0x226*/ { "CMSG_GM_VISION", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x227*/ { "CMSG_SERVER_COMMAND", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x228*/ { "CMSG_GM_SILENCE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x229*/ { "CMSG_GM_REVEALTO", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x22A*/ { "CMSG_GM_RESURRECT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x22B*/ { "CMSG_GM_SUMMONMOB", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x22C*/ { "CMSG_GM_MOVECORPSE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x22D*/ { "CMSG_GM_FREEZE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x22E*/ { "CMSG_GM_UBERINVIS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x22F*/ { "CMSG_GM_REQUEST_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x230*/ { "SMSG_GM_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x231*/ { "CMSG_GUILD_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildRankOpcode },
- /*0x232*/ { "CMSG_GUILD_ADD_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildAddRankOpcode },
- /*0x233*/ { "CMSG_GUILD_DEL_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildDelRankOpcode },
- /*0x234*/ { "CMSG_GUILD_SET_PUBLIC_NOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildSetPublicNoteOpcode },
- /*0x235*/ { "CMSG_GUILD_SET_OFFICER_NOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildSetOfficerNoteOpcode },
- /*0x236*/ { "SMSG_LOGIN_VERIFY_WORLD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x237*/ { "CMSG_CLEAR_EXPLORATION", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x238*/ { "CMSG_SEND_MAIL", STATUS_LOGGEDIN, &WorldSession::HandleSendMail },
- /*0x239*/ { "SMSG_SEND_MAIL_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x23A*/ { "CMSG_GET_MAIL_LIST", STATUS_LOGGEDIN, &WorldSession::HandleGetMail },
- /*0x23B*/ { "SMSG_MAIL_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x23C*/ { "CMSG_BATTLEFIELD_LIST", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundListOpcode },
- /*0x23D*/ { "SMSG_BATTLEFIELD_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x23E*/ { "CMSG_BATTLEFIELD_JOIN", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x23F*/ { "SMSG_BATTLEFIELD_WIN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x240*/ { "SMSG_BATTLEFIELD_LOSE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x241*/ { "CMSG_TAXICLEARNODE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x242*/ { "CMSG_TAXIENABLENODE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x243*/ { "CMSG_ITEM_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleItemTextQuery },
- /*0x244*/ { "SMSG_ITEM_TEXT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x245*/ { "CMSG_MAIL_TAKE_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleTakeMoney },
- /*0x246*/ { "CMSG_MAIL_TAKE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleTakeItem },
- /*0x247*/ { "CMSG_MAIL_MARK_AS_READ", STATUS_LOGGEDIN, &WorldSession::HandleMarkAsRead },
- /*0x248*/ { "CMSG_MAIL_RETURN_TO_SENDER", STATUS_LOGGEDIN, &WorldSession::HandleReturnToSender },
- /*0x249*/ { "CMSG_MAIL_DELETE", STATUS_LOGGEDIN, &WorldSession::HandleMailDelete },
- /*0x24A*/ { "CMSG_MAIL_CREATE_TEXT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleMailCreateTextItem },
- /*0x24B*/ { "SMSG_SPELLLOGMISS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x24C*/ { "SMSG_SPELLLOGEXECUTE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x24D*/ { "SMSG_DEBUGAURAPROC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x24E*/ { "SMSG_PERIODICAURALOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x24F*/ { "SMSG_SPELLDAMAGESHIELD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x250*/ { "SMSG_SPELLNONMELEEDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x251*/ { "CMSG_LEARN_TALENT", STATUS_LOGGEDIN, &WorldSession::HandleLearnTalentOpcode },
- /*0x252*/ { "SMSG_RESURRECT_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x253*/ { "CMSG_TOGGLE_PVP", STATUS_LOGGEDIN, &WorldSession::HandleTogglePvP },
- /*0x254*/ { "SMSG_ZONE_UNDER_ATTACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x255*/ { "MSG_AUCTION_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleAuctionHelloOpcode },
- /*0x256*/ { "CMSG_AUCTION_SELL_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAuctionSellItem },
- /*0x257*/ { "CMSG_AUCTION_REMOVE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAuctionRemoveItem },
- /*0x258*/ { "CMSG_AUCTION_LIST_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListItems },
- /*0x259*/ { "CMSG_AUCTION_LIST_OWNER_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListOwnerItems },
- /*0x25A*/ { "CMSG_AUCTION_PLACE_BID", STATUS_LOGGEDIN, &WorldSession::HandleAuctionPlaceBid },
- /*0x25B*/ { "SMSG_AUCTION_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x25C*/ { "SMSG_AUCTION_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x25D*/ { "SMSG_AUCTION_OWNER_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x25E*/ { "SMSG_AUCTION_BIDDER_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x25F*/ { "SMSG_AUCTION_OWNER_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x260*/ { "SMSG_PROCRESIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x261*/ { "SMSG_STANDSTATE_CHANGE_FAILURE_OBSOLETE",STATUS_NEVER,&WorldSession::Handle_ServerSide },
- /*0x262*/ { "SMSG_DISPEL_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x263*/ { "SMSG_SPELLORDAMAGE_IMMUNE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x264*/ { "CMSG_AUCTION_LIST_BIDDER_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListBidderItems },
- /*0x265*/ { "SMSG_AUCTION_BIDDER_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x266*/ { "SMSG_SET_FLAT_SPELL_MODIFIER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x267*/ { "SMSG_SET_PCT_SPELL_MODIFIER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x268*/ { "CMSG_SET_AMMO", STATUS_LOGGEDIN, &WorldSession::HandleSetAmmoOpcode },
- /*0x269*/ { "SMSG_CORPSE_RECLAIM_DELAY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x26A*/ { "CMSG_SET_ACTIVE_MOVER", STATUS_LOGGEDIN, &WorldSession::HandleSetActiveMoverOpcode },
- /*0x26B*/ { "CMSG_PET_CANCEL_AURA", STATUS_LOGGEDIN, &WorldSession::HandlePetCancelAuraOpcode },
- /*0x26C*/ { "CMSG_PLAYER_AI_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x26D*/ { "CMSG_CANCEL_AUTO_REPEAT_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleCancelAutoRepeatSpellOpcode},
- /*0x26E*/ { "MSG_GM_ACCOUNT_ONLINE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x26F*/ { "MSG_LIST_STABLED_PETS", STATUS_LOGGEDIN, &WorldSession::HandleListStabledPetsOpcode },
- /*0x270*/ { "CMSG_STABLE_PET", STATUS_LOGGEDIN, &WorldSession::HandleStablePet },
- /*0x271*/ { "CMSG_UNSTABLE_PET", STATUS_LOGGEDIN, &WorldSession::HandleUnstablePet },
- /*0x272*/ { "CMSG_BUY_STABLE_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyStableSlot },
- /*0x273*/ { "SMSG_STABLE_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x274*/ { "CMSG_STABLE_REVIVE_PET", STATUS_LOGGEDIN, &WorldSession::HandleStableRevivePet },
- /*0x275*/ { "CMSG_STABLE_SWAP_PET", STATUS_LOGGEDIN, &WorldSession::HandleStableSwapPet },
- /*0x276*/ { "MSG_QUEST_PUSH_RESULT", STATUS_LOGGEDIN, &WorldSession::HandleQuestPushResult },
- /*0x277*/ { "SMSG_PLAY_MUSIC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x278*/ { "SMSG_PLAY_OBJECT_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x279*/ { "CMSG_REQUEST_PET_INFO", STATUS_LOGGEDIN, &WorldSession::HandleRequestPetInfoOpcode },
- /*0x27A*/ { "CMSG_FAR_SIGHT", STATUS_LOGGEDIN, &WorldSession::HandleFarSightOpcode },
- /*0x27B*/ { "SMSG_SPELLDISPELLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x27C*/ { "SMSG_DAMAGE_CALC_LOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x27D*/ { "CMSG_ENABLE_DAMAGE_LOG", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x27E*/ { "CMSG_GROUP_CHANGE_SUB_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleGroupChangeSubGroupOpcode },
- /*0x27F*/ { "CMSG_REQUEST_PARTY_MEMBER_STATS", STATUS_LOGGEDIN, &WorldSession::HandleRequestPartyMemberStatsOpcode},
- /*0x280*/ { "CMSG_GROUP_SWAP_SUB_GROUP", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x281*/ { "CMSG_RESET_FACTION_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x282*/ { "CMSG_AUTOSTORE_BANK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBankItemOpcode },
- /*0x283*/ { "CMSG_AUTOBANK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoBankItemOpcode },
- /*0x284*/ { "MSG_QUERY_NEXT_MAIL_TIME", STATUS_LOGGEDIN, &WorldSession::HandleMsgQueryNextMailtime },
- /*0x285*/ { "SMSG_RECEIVED_MAIL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x286*/ { "SMSG_RAID_GROUP_ONLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x287*/ { "CMSG_SET_DURABILITY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x288*/ { "CMSG_SET_PVP_RANK_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x289*/ { "CMSG_ADD_PVP_MEDAL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x28A*/ { "CMSG_DEL_PVP_MEDAL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x28B*/ { "CMSG_SET_PVP_TITLE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x28C*/ { "SMSG_PVP_CREDIT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x28D*/ { "SMSG_AUCTION_REMOVED_NOTIFICATION",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x28E*/ { "CMSG_GROUP_RAID_CONVERT", STATUS_LOGGEDIN, &WorldSession::HandleRaidConvertOpcode },
- /*0x28F*/ { "CMSG_GROUP_ASSISTANT_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGroupAssistantOpcode },
- /*0x290*/ { "CMSG_BUYBACK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuybackItem },
- /*0x291*/ { "SMSG_SERVER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x292*/ { "CMSG_MEETINGSTONE_JOIN", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x293*/ { "CMSG_MEETINGSTONE_LEAVE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x294*/ { "CMSG_MEETINGSTONE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x295*/ { "SMSG_MEETINGSTONE_SETQUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x296*/ { "CMSG_MEETINGSTONE_INFO", STATUS_LOGGEDIN, &WorldSession::HandleMeetingStoneInfo },
- /*0x297*/ { "SMSG_MEETINGSTONE_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x298*/ { "SMSG_MEETINGSTONE_IN_PROGRESS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x299*/ { "SMSG_MEETINGSTONE_MEMBER_ADDED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x29A*/ { "CMSG_GMTICKETSYSTEM_TOGGLE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x29B*/ { "CMSG_CANCEL_GROWTH_AURA", STATUS_LOGGEDIN, &WorldSession::HandleCancelGrowthAuraOpcode },
- /*0x29C*/ { "SMSG_CANCEL_AUTO_REPEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x29D*/ { "SMSG_STANDSTATE_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x29E*/ { "SMSG_LOOT_ALL_PASSED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x29F*/ { "SMSG_LOOT_ROLL_WON", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2A0*/ { "CMSG_LOOT_ROLL", STATUS_LOGGEDIN, &WorldSession::HandleLootRoll },
- /*0x2A1*/ { "SMSG_LOOT_START_ROLL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2A2*/ { "SMSG_LOOT_ROLL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2A3*/ { "CMSG_LOOT_MASTER_GIVE", STATUS_LOGGEDIN, &WorldSession::HandleLootMasterGiveOpcode },
- /*0x2A4*/ { "SMSG_LOOT_MASTER_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2A5*/ { "SMSG_SET_FORCED_REACTIONS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2A6*/ { "SMSG_SPELL_FAILED_OTHER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2A7*/ { "SMSG_GAMEOBJECT_RESET_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2A8*/ { "CMSG_REPAIR_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleRepairItemOpcode },
- /*0x2A9*/ { "SMSG_CHAT_PLAYER_NOT_FOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2AA*/ { "MSG_TALENT_WIPE_CONFIRM", STATUS_LOGGEDIN, &WorldSession::HandleTalentWipeOpcode },
- /*0x2AB*/ { "SMSG_SUMMON_REQUEST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2AC*/ { "CMSG_SUMMON_RESPONSE", STATUS_LOGGEDIN, &WorldSession::HandleSummonResponseOpcode },
- /*0x2AD*/ { "MSG_MOVE_TOGGLE_GRAVITY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2AE*/ { "SMSG_MONSTER_MOVE_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2AF*/ { "SMSG_PET_BROKEN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2B0*/ { "MSG_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2B1*/ { "MSG_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2B2*/ { "CMSG_SERVER_BROADCAST", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2B3*/ { "CMSG_SELF_RES", STATUS_LOGGEDIN, &WorldSession::HandleSelfResOpcode },
- /*0x2B4*/ { "SMSG_FEIGN_DEATH_RESISTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2B5*/ { "CMSG_RUN_SCRIPT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2B6*/ { "SMSG_SCRIPT_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2B7*/ { "SMSG_DUEL_COUNTDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2B8*/ { "SMSG_AREA_TRIGGER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2B9*/ { "CMSG_TOGGLE_HELM", STATUS_LOGGEDIN, &WorldSession::HandleToggleHelmOpcode },
- /*0x2BA*/ { "CMSG_TOGGLE_CLOAK", STATUS_LOGGEDIN, &WorldSession::HandleToggleCloakOpcode },
- /*0x2BB*/ { "SMSG_MEETINGSTONE_JOINFAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2BC*/ { "SMSG_PLAYER_SKINNED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2BD*/ { "SMSG_DURABILITY_DAMAGE_DEATH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2BE*/ { "CMSG_SET_EXPLORATION", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2BF*/ { "CMSG_SET_ACTIONBAR_TOGGLES", STATUS_AUTHED, &WorldSession::HandleSetActionBar },
- /*0x2C0*/ { "UMSG_DELETE_GUILD_CHARTER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2C1*/ { "MSG_PETITION_RENAME", STATUS_LOGGEDIN, &WorldSession::HandlePetitionRenameOpcode },
- /*0x2C2*/ { "SMSG_INIT_WORLD_STATES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2C3*/ { "SMSG_UPDATE_WORLD_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2C4*/ { "CMSG_ITEM_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleItemNameQueryOpcode },
- /*0x2C5*/ { "SMSG_ITEM_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2C6*/ { "SMSG_PET_ACTION_FEEDBACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2C7*/ { "CMSG_CHAR_RENAME", STATUS_AUTHED, &WorldSession::HandleChangePlayerNameOpcode },
- /*0x2C8*/ { "SMSG_CHAR_RENAME", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2C9*/ { "CMSG_MOVE_SPLINE_DONE", STATUS_LOGGEDIN, &WorldSession::HandleTaxiNextDestinationOpcode },
- /*0x2CA*/ { "CMSG_MOVE_FALL_RESET", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x2CB*/ { "SMSG_INSTANCE_SAVE_CREATED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2CC*/ { "SMSG_RAID_INSTANCE_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2CD*/ { "CMSG_REQUEST_RAID_INFO", STATUS_LOGGEDIN, &WorldSession::HandleRequestRaidInfoOpcode },
- /*0x2CE*/ { "CMSG_MOVE_TIME_SKIPPED", STATUS_LOGGEDIN, &WorldSession::HandleMoveTimeSkippedOpcode },
- /*0x2CF*/ { "CMSG_MOVE_FEATHER_FALL_ACK", STATUS_LOGGEDIN, &WorldSession::HandleFeatherFallAck },
- /*0x2D0*/ { "CMSG_MOVE_WATER_WALK_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveWaterWalkAck },
- /*0x2D1*/ { "CMSG_MOVE_NOT_ACTIVE_MOVER", STATUS_LOGGEDIN, &WorldSession::HandleNotActiveMoverOpcode },
- /*0x2D2*/ { "SMSG_PLAY_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2D3*/ { "CMSG_BATTLEFIELD_STATUS", STATUS_LOGGEDIN, &WorldSession::HandleBattlefieldStatusOpcode },
- /*0x2D4*/ { "SMSG_BATTLEFIELD_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2D5*/ { "CMSG_BATTLEFIELD_PORT", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPortOpcode},
- /*0x2D6*/ { "MSG_INSPECT_HONOR_STATS", STATUS_LOGGEDIN, &WorldSession::HandleInspectHonorStatsOpcode },
- /*0x2D7*/ { "CMSG_BATTLEMASTER_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundHelloOpcode },
- /*0x2D8*/ { "CMSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2D9*/ { "CMSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2DA*/ { "SMSG_FORCE_WALK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2DB*/ { "CMSG_FORCE_WALK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
- /*0x2DC*/ { "SMSG_FORCE_SWIM_BACK_SPEED_CHANGE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2DD*/ { "CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck },
- /*0x2DE*/ { "SMSG_FORCE_TURN_RATE_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2DF*/ { "CMSG_FORCE_TURN_RATE_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
- /*0x2E0*/ { "MSG_PVP_LOG_DATA", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPVPlogdataOpcode},
- /*0x2E1*/ { "CMSG_LEAVE_BATTLEFIELD", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundLeaveOpcode },
- /*0x2E2*/ { "CMSG_AREA_SPIRIT_HEALER_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueryOpcode},
- /*0x2E3*/ { "CMSG_AREA_SPIRIT_HEALER_QUEUE", STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueueOpcode},
- /*0x2E4*/ { "SMSG_AREA_SPIRIT_HEALER_TIME", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2E5*/ { "CMSG_GM_UNTEACH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2E6*/ { "SMSG_WARDEN_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2E7*/ { "CMSG_WARDEN_DATA", STATUS_LOGGEDIN, &WorldSession::HandleWardenDataOpcode },
- /*0x2E8*/ { "SMSG_GROUP_JOINED_BATTLEGROUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2E9*/ { "MSG_BATTLEGROUND_PLAYER_POSITIONS",STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPositionsOpcode},
- /*0x2EA*/ { "CMSG_PET_STOP_ATTACK", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2EB*/ { "SMSG_BINDER_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2EC*/ { "SMSG_BATTLEGROUND_PLAYER_JOINED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2ED*/ { "SMSG_BATTLEGROUND_PLAYER_LEFT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2EE*/ { "CMSG_BATTLEMASTER_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundJoinOpcode },
- /*0x2EF*/ { "SMSG_ADDON_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2F0*/ { "CMSG_PET_UNLEARN", STATUS_LOGGEDIN, &WorldSession::HandlePetUnlearnOpcode },
- /*0x2F1*/ { "SMSG_PET_UNLEARN_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2F2*/ { "SMSG_PARTY_MEMBER_STATS_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2F3*/ { "CMSG_PET_SPELL_AUTOCAST", STATUS_LOGGEDIN, &WorldSession::HandlePetSpellAutocastOpcode },
- /*0x2F4*/ { "SMSG_WEATHER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2F5*/ { "SMSG_PLAY_TIME_WARNING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2F6*/ { "SMSG_MINIGAME_SETUP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2F7*/ { "SMSG_MINIGAME_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2F8*/ { "CMSG_MINIGAME_MOVE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2F9*/ { "SMSG_MINIGAME_MOVE_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2FA*/ { "SMSG_RAID_INSTANCE_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2FB*/ { "SMSG_COMPRESSED_MOVES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2FC*/ { "CMSG_GUILD_INFO_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildChangeInfoOpcode },
- /*0x2FD*/ { "SMSG_CHAT_RESTRICTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2FE*/ { "SMSG_SPLINE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2FF*/ { "SMSG_SPLINE_SET_RUN_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x300*/ { "SMSG_SPLINE_SET_SWIM_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x301*/ { "SMSG_SPLINE_SET_WALK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x302*/ { "SMSG_SPLINE_SET_SWIM_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x303*/ { "SMSG_SPLINE_SET_TURN_RATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x304*/ { "SMSG_SPLINE_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x305*/ { "SMSG_SPLINE_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x306*/ { "SMSG_SPLINE_MOVE_NORMAL_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x307*/ { "SMSG_SPLINE_MOVE_SET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x308*/ { "SMSG_SPLINE_MOVE_UNSET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x309*/ { "SMSG_SPLINE_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x30A*/ { "SMSG_SPLINE_MOVE_LAND_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x30B*/ { "SMSG_SPLINE_MOVE_START_SWIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x30C*/ { "SMSG_SPLINE_MOVE_STOP_SWIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x30D*/ { "SMSG_SPLINE_MOVE_SET_RUN_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x30E*/ { "SMSG_SPLINE_MOVE_SET_WALK_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x30F*/ { "CMSG_GM_NUKE_ACCOUNT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x310*/ { "MSG_GM_DESTROY_CORPSE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x311*/ { "CMSG_GM_DESTROY_ONLINE_CORPSE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x312*/ { "CMSG_ACTIVATETAXIEXPRESS", STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiFarOpcode },
- /*0x313*/ { "SMSG_SET_FACTION_ATWAR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x314*/ { "SMSG_GAMETIMEBIAS_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x315*/ { "CMSG_DEBUG_ACTIONS_START", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x316*/ { "CMSG_DEBUG_ACTIONS_STOP", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x317*/ { "CMSG_SET_FACTION_INACTIVE", STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionInactiveOpcode},
- /*0x318*/ { "CMSG_SET_WATCHED_FACTION", STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionIndexOpcode},
- /*0x319*/ { "MSG_MOVE_TIME_SKIPPED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x31A*/ { "SMSG_SPLINE_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x31B*/ { "CMSG_SET_EXPLORATION_ALL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x31C*/ { "SMSG_INVALIDATE_PLAYER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x31D*/ { "CMSG_RESET_INSTANCES", STATUS_LOGGEDIN, &WorldSession::HandleResetInstancesOpcode },
- /*0x31E*/ { "SMSG_INSTANCE_RESET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x31F*/ { "SMSG_INSTANCE_RESET_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x320*/ { "SMSG_UPDATE_LAST_INSTANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x321*/ { "MSG_RAID_TARGET_UPDATE", STATUS_LOGGEDIN, &WorldSession::HandleRaidIconTargetOpcode },
- /*0x322*/ { "MSG_RAID_READY_CHECK", STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckOpcode },
- /*0x323*/ { "CMSG_LUA_USAGE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x324*/ { "SMSG_PET_ACTION_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x325*/ { "SMSG_PET_DISMISS_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x326*/ { "SMSG_GHOSTEE_GONE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x327*/ { "CMSG_GM_UPDATE_TICKET_STATUS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x328*/ { "SMSG_GM_TICKET_STATUS_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x329*/ { "MSG_SET_DUNGEON_DIFFICULTY", STATUS_LOGGEDIN, &WorldSession::HandleDungeonDifficultyOpcode },
- /*0x32A*/ { "CMSG_GMSURVEY_SUBMIT", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },//&WorldSession::HandleGMSurveySubmit
- /*0x32B*/ { "SMSG_UPDATE_INSTANCE_OWNERSHIP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x32C*/ { "CMSG_IGNORE_KNOCKBACK_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x32D*/ { "SMSG_CHAT_PLAYER_AMBIGUOUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x32E*/ { "MSG_DELAY_GHOST_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x32F*/ { "SMSG_SPELLINSTAKILLLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x330*/ { "SMSG_SPELL_UPDATE_CHAIN_TARGETS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x331*/ { "CMSG_CHAT_FILTERED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x332*/ { "SMSG_EXPECTED_SPAM_RECORDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x333*/ { "SMSG_SPELLSTEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x334*/ { "CMSG_LOTTERY_QUERY_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x335*/ { "SMSG_LOTTERY_QUERY_RESULT_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x336*/ { "CMSG_BUY_LOTTERY_TICKET_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x337*/ { "SMSG_LOTTERY_RESULT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x338*/ { "SMSG_CHARACTER_PROFILE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x339*/ { "SMSG_CHARACTER_PROFILE_REALM_CONNECTED",STATUS_NEVER,&WorldSession::Handle_ServerSide },
- /*0x33A*/ { "SMSG_DEFENSE_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x33B*/ { "SMSG_INSTANCE_DIFFICULTY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x33C*/ { "MSG_GM_RESETINSTANCELIMIT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x33D*/ { "SMSG_MOTD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x33E*/ { "SMSG_MOVE_SET_FLIGHT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x33F*/ { "SMSG_MOVE_UNSET_FLIGHT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x340*/ { "CMSG_MOVE_FLIGHT_ACK_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x341*/ { "MSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x342*/ { "MSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x343*/ { "SMSG_MOVE_SET_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x344*/ { "SMSG_MOVE_UNSET_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x345*/ { "CMSG_MOVE_SET_CAN_FLY_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveFlyModeChangeAckOpcode},
- /*0x346*/ { "CMSG_MOVE_SET_FLY", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x347*/ { "CMSG_SOCKET_GEMS", STATUS_LOGGEDIN, &WorldSession::HandleSocketOpcode },
- /*0x348*/ { "CMSG_ARENA_TEAM_CREATE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x349*/ { "SMSG_ARENA_TEAM_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x34A*/ { "UMSG_UPDATE_ARENA_TEAM_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x34B*/ { "CMSG_ARENA_TEAM_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamQueryOpcode },
- /*0x34C*/ { "SMSG_ARENA_TEAM_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x34D*/ { "CMSG_ARENA_TEAM_ROSTER", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRosterOpcode },
- /*0x34E*/ { "SMSG_ARENA_TEAM_ROSTER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x34F*/ { "CMSG_ARENA_TEAM_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamAddMemberOpcode },
- /*0x350*/ { "SMSG_ARENA_TEAM_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x351*/ { "CMSG_ARENA_TEAM_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteAcceptOpcode},
- /*0x352*/ { "CMSG_ARENA_TEAM_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteDeclineOpcode},
- /*0x353*/ { "CMSG_ARENA_TEAM_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamLeaveOpcode },
- /*0x354*/ { "CMSG_ARENA_TEAM_REMOVE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRemoveFromTeamOpcode},
- /*0x355*/ { "CMSG_ARENA_TEAM_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamDisbandOpcode },
- /*0x356*/ { "CMSG_ARENA_TEAM_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamPromoteToCaptainOpcode},
- /*0x357*/ { "SMSG_ARENA_TEAM_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x358*/ { "CMSG_BATTLEMASTER_JOIN_ARENA", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundArenaJoin },
- /*0x359*/ { "MSG_MOVE_START_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x35A*/ { "MSG_MOVE_STOP_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x35B*/ { "SMSG_ARENA_TEAM_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x35C*/ { "CMSG_LFG_SET_AUTOJOIN", STATUS_AUTHED, &WorldSession::HandleLfgAutoJoinOpcode },
- /*0x35D*/ { "CMSG_LFG_CLEAR_AUTOJOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfgCancelAutoJoinOpcode },
- /*0x35E*/ { "CMSG_LFM_SET_AUTOFILL", STATUS_AUTHED, &WorldSession::HandleLfmAutoAddMembersOpcode },
- /*0x35F*/ { "CMSG_LFM_CLEAR_AUTOFILL", STATUS_LOGGEDIN, &WorldSession::HandleLfmCancelAutoAddmembersOpcode},
- /*0x360*/ { "CMSG_ACCEPT_LFG_MATCH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x361*/ { "CMSG_DECLINE_LFG_MATCH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x362*/ { "CMSG_CANCEL_PENDING_LFG", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x363*/ { "CMSG_CLEAR_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleLfgClearOpcode },
- /*0x364*/ { "CMSG_CLEAR_LOOKING_FOR_MORE", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetNoneOpcode },
- /*0x365*/ { "CMSG_SET_LOOKING_FOR_MORE", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetOpcode },
- /*0x366*/ { "CMSG_SET_LFG_COMMENT", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetCommentOpcode },
- /*0x367*/ { "SMSG_LFG_TIMEDOUT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x368*/ { "SMSG_LFG_OTHER_TIMEDOUT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x369*/ { "SMSG_LFG_AUTOJOIN_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36A*/ { "SMSG_LFG_AUTOJOIN_FAILED_NO_PLAYER",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36B*/ { "SMSG_LFG_LEADER_IS_LFM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36C*/ { "SMSG_LFG_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36D*/ { "SMSG_LFG_UPDATE_LFM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36E*/ { "SMSG_LFG_UPDATE_LFG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36F*/ { "SMSG_LFG_UPDATE_QUEUED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x370*/ { "SMSG_LFG_PENDING_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x371*/ { "SMSG_LFG_PENDING_MATCH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x372*/ { "SMSG_LFG_PENDING_MATCH_DONE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x373*/ { "SMSG_TITLE_EARNED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x374*/ { "CMSG_SET_TITLE", STATUS_LOGGEDIN, &WorldSession::HandleChooseTitleOpcode },
- /*0x375*/ { "CMSG_CANCEL_MOUNT_AURA", STATUS_LOGGEDIN, &WorldSession::HandleDismountOpcode },
- /*0x376*/ { "SMSG_ARENA_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x377*/ { "MSG_INSPECT_ARENA_TEAMS", STATUS_LOGGEDIN, &WorldSession::HandleInspectArenaStatsOpcode },
- /*0x378*/ { "SMSG_DEATH_RELEASE_LOC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x379*/ { "CMSG_CANCEL_TEMP_ENCHANTMENT", STATUS_LOGGEDIN, &WorldSession::HandleCancelTempItemEnchantmentOpcode},
- /*0x37A*/ { "SMSG_FORCED_DEATH_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x37B*/ { "CMSG_CHEAT_SET_HONOR_CURRENCY", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x37C*/ { "CMSG_CHEAT_SET_ARENA_CURRENCY", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x37D*/ { "MSG_MOVE_SET_FLIGHT_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x37E*/ { "MSG_MOVE_SET_FLIGHT_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x37F*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT",STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x380*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x381*/ { "SMSG_FORCE_FLIGHT_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x382*/ { "CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck },
- /*0x383*/ { "SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x384*/ { "CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck },
- /*0x385*/ { "SMSG_SPLINE_SET_FLIGHT_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x386*/ { "SMSG_SPLINE_SET_FLIGHT_BACK_SPEED",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x387*/ { "CMSG_MAELSTROM_INVALIDATE_CACHE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x388*/ { "SMSG_FLIGHT_SPLINE_SYNC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x389*/ { "CMSG_SET_TAXI_BENCHMARK_MODE", STATUS_AUTHED, &WorldSession::HandleSetTaxiBenchmarkOpcode },
- /*0x38A*/ { "SMSG_JOINED_BATTLEGROUND_QUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x38B*/ { "SMSG_REALM_SPLIT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x38C*/ { "CMSG_REALM_SPLIT", STATUS_AUTHED, &WorldSession::HandleRealmStateRequestOpcode },
- /*0x38D*/ { "CMSG_MOVE_CHNG_TRANSPORT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x38E*/ { "MSG_PARTY_ASSIGNMENT", STATUS_LOGGEDIN, &WorldSession::HandleGroupPromoteOpcode },
- /*0x38F*/ { "SMSG_OFFER_PETITION_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x390*/ { "SMSG_TIME_SYNC_REQ", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x391*/ { "CMSG_TIME_SYNC_RESP", STATUS_LOGGEDIN, &WorldSession::HandleAllowMoveAckOpcode },
- /*0x392*/ { "CMSG_SEND_LOCAL_EVENT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x393*/ { "CMSG_SEND_GENERAL_TRIGGER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x394*/ { "CMSG_SEND_COMBAT_TRIGGER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x395*/ { "CMSG_MAELSTROM_GM_SENT_MAIL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x396*/ { "SMSG_RESET_FAILED_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x397*/ { "SMSG_REAL_GROUP_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x398*/ { "SMSG_LFG_DISABLED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x399*/ { "CMSG_ACTIVE_PVP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x39A*/ { "CMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x39B*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE",STATUS_NEVER,&WorldSession::Handle_ServerSide },
- /*0x39C*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE_WRITE_FILE",STATUS_NEVER,&WorldSession::Handle_ServerSide},
- /*0x39D*/ { "SMSG_UPDATE_COMBO_POINTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x39E*/ { "SMSG_VOICE_SESSION_ROSTER_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x39F*/ { "SMSG_VOICE_SESSION_LEAVE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3A0*/ { "SMSG_VOICE_SESSION_ADJUST_PRIORITY",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3A1*/ { "CMSG_VOICE_SET_TALKER_MUTED_REQUEST",STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3A2*/ { "SMSG_VOICE_SET_TALKER_MUTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3A3*/ { "SMSG_INIT_EXTRA_AURA_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3A4*/ { "SMSG_SET_EXTRA_AURA_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3A5*/ { "SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3A6*/ { "SMSG_CLEAR_EXTRA_AURA_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3A7*/ { "MSG_MOVE_START_DESCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x3A8*/ { "CMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3A9*/ { "SMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3AA*/ { "SMSG_SPELL_CHANCE_PROC_LOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3AB*/ { "CMSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3AC*/ { "SMSG_DISMOUNT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3AD*/ { "MSG_MOVE_UPDATE_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3AE*/ { "MSG_RAID_READY_CHECK_CONFIRM", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3AF*/ { "CMSG_VOICE_SESSION_ENABLE", STATUS_AUTHED, &WorldSession::HandleVoiceSettingsOpcode },
- /*0x3B0*/ { "SMSG_VOICE_PARENTAL_CONTROLS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3B1*/ { "CMSG_GM_WHISPER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3B2*/ { "SMSG_GM_MESSAGECHAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3B3*/ { "MSG_GM_GEARRATING", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3B4*/ { "CMSG_COMMENTATOR_ENABLE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3B5*/ { "SMSG_COMMENTATOR_STATE_CHANGED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3B6*/ { "CMSG_COMMENTATOR_GET_MAP_INFO", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3B7*/ { "SMSG_COMMENTATOR_MAP_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3B8*/ { "CMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3B9*/ { "SMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3BA*/ { "SMSG_COMMENTATOR_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3BB*/ { "CMSG_COMMENTATOR_ENTER_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3BC*/ { "CMSG_COMMENTATOR_EXIT_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3BD*/ { "CMSG_COMMENTATOR_INSTANCE_COMMAND",STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3BE*/ { "SMSG_CLEAR_TARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3BF*/ { "CMSG_BOT_DETECTED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3C0*/ { "SMSG_CROSSED_INEBRIATION_THRESHOLD",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3C1*/ { "CMSG_CHEAT_PLAYER_LOGIN", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3C2*/ { "CMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3C3*/ { "SMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3C4*/ { "SMSG_KICK_REASON", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3C5*/ { "MSG_RAID_READY_CHECK_FINISHED", STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckFinishOpcode},
- /*0x3C6*/ { "CMSG_COMPLAIN", STATUS_LOGGEDIN, &WorldSession::HandleReportSpamOpcode },
- /*0x3C7*/ { "SMSG_COMPLAIN_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3C8*/ { "SMSG_FEATURE_SYSTEM_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3C9*/ { "CMSG_GM_SHOW_COMPLAINTS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3CA*/ { "CMSG_GM_UNSQUELCH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3CB*/ { "CMSG_CHANNEL_SILENCE_VOICE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3CC*/ { "CMSG_CHANNEL_SILENCE_ALL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3CD*/ { "CMSG_CHANNEL_UNSILENCE_VOICE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3CE*/ { "CMSG_CHANNEL_UNSILENCE_ALL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3CF*/ { "CMSG_TARGET_CAST", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3D0*/ { "CMSG_TARGET_SCRIPT_CAST", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3D1*/ { "CMSG_CHANNEL_DISPLAY_LIST", STATUS_LOGGEDIN, &WorldSession::HandleChannelRosterQuery },
- /*0x3D2*/ { "CMSG_SET_ACTIVE_VOICE_CHANNEL", STATUS_AUTHED, &WorldSession::HandleChannelVoiceChatQuery },
- /*0x3D3*/ { "CMSG_GET_CHANNEL_MEMBER_COUNT", STATUS_LOGGEDIN, &WorldSession::HandleChannelInfoQuery },
- /*0x3D4*/ { "SMSG_CHANNEL_MEMBER_COUNT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3D5*/ { "CMSG_CHANNEL_VOICE_ON", STATUS_LOGGEDIN, &WorldSession::HandleChannelEnableVoiceOpcode },
- /*0x3D6*/ { "CMSG_CHANNEL_VOICE_OFF", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3D7*/ { "CMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3D8*/ { "SMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3D9*/ { "SMSG_AVAILABLE_VOICE_CHANNEL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3DA*/ { "CMSG_ADD_VOICE_IGNORE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3DB*/ { "CMSG_DEL_VOICE_IGNORE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3DC*/ { "CMSG_PARTY_SILENCE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3DD*/ { "CMSG_PARTY_UNSILENCE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3DE*/ { "MSG_NOTIFY_PARTY_SQUELCH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3DF*/ { "SMSG_COMSAT_RECONNECT_TRY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3E0*/ { "SMSG_COMSAT_DISCONNECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3E1*/ { "SMSG_COMSAT_CONNECT_FAIL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3E2*/ { "SMSG_VOICE_CHAT_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3E3*/ { "CMSG_REPORT_PVP_AFK", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundReportAFK },
- /*0x3E4*/ { "CMSG_REPORT_PVP_AFK_RESULT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3E5*/ { "CMSG_GUILD_BANKER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankQuery },
- /*0x3E6*/ { "CMSG_GUILD_BANK_QUERY_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabColon },
- /*0x3E7*/ { "SMSG_GUILD_BANK_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3E8*/ { "CMSG_GUILD_BANK_SWAP_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDepositItem },
- /*0x3E9*/ { "CMSG_GUILD_BANK_BUY_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankBuyTab },
- /*0x3EA*/ { "CMSG_GUILD_BANK_UPDATE_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankModifyTab },
- /*0x3EB*/ { "CMSG_GUILD_BANK_DEPOSIT_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDeposit },
- /*0x3EC*/ { "CMSG_GUILD_BANK_WITHDRAW_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankWithdraw },
- /*0x3ED*/ { "MSG_GUILD_BANK_LOG_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankLog },
- /*0x3EE*/ { "CMSG_SET_CHANNEL_WATCH", STATUS_LOGGEDIN, &WorldSession::HandleChannelJoinNotify },
- /*0x3EF*/ { "SMSG_USERLIST_ADD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3F0*/ { "SMSG_USERLIST_REMOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3F1*/ { "SMSG_USERLIST_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3F2*/ { "CMSG_CLEAR_CHANNEL_WATCH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3F3*/ { "SMSG_INSPECT_TALENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3F4*/ { "SMSG_GOGOGO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3F5*/ { "SMSG_ECHO_PARTY_SQUELCH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3F6*/ { "CMSG_SET_TITLE_SUFFIX", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3F7*/ { "CMSG_SPELLCLICK", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3F8*/ { "SMSG_LOOT_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3F9*/ { "CMSG_GM_CHARACTER_RESTORE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3FA*/ { "CMSG_GM_CHARACTER_SAVE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3FB*/ { "SMSG_VOICESESSION_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3FC*/ { "MSG_GUILD_PERMISSIONS", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetRights },
- /*0x3FD*/ { "MSG_GUILD_BANK_MONEY_WITHDRAWN", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetMoneyAmount },
- /*0x3FE*/ { "MSG_GUILD_EVENT_LOG_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGuildEventLogOpcode },
- /*0x3FF*/ { "CMSG_MAELSTROM_RENAME_GUILD", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x400*/ { "CMSG_GET_MIRRORIMAGE_DATA", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x401*/ { "SMSG_MIRRORIMAGE_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x402*/ { "SMSG_FORCE_DISPLAY_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x403*/ { "SMSG_SPELL_CHANCE_RESIST_PUSHBACK",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x404*/ { "CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT",STATUS_NEVER,&WorldSession::Handle_NULL },
- /*0x405*/ { "SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT",STATUS_NEVER,&WorldSession::Handle_ServerSide },
- /*0x406*/ { "CMSG_KEEP_ALIVE", STATUS_NEVER, &WorldSession::Handle_EarlyProccess },
- /*0x407*/ { "SMSG_RAID_READY_CHECK_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x408*/ { "CMSG_OPT_OUT_OF_LOOT", STATUS_AUTHED, &WorldSession::HandleGroupPassOnLootOpcode },
- /*0x409*/ { "MSG_QUERY_GUILD_BANK_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabText },
- /*0x40A*/ { "CMSG_SET_GUILD_BANK_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankSetTabText },
- /*0x40B*/ { "CMSG_SET_GRANTABLE_LEVELS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x40C*/ { "CMSG_GRANT_LEVEL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x40D*/ { "CMSG_REFER_A_FRIEND", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x40E*/ { "MSG_GM_CHANGE_ARENA_RATING", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x40F*/ { "CMSG_DECLINE_CHANNEL_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleChannelDeclineInvite },
- /*0x410*/ { "CMSG_GROUPACTION_THROTTLED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x411*/ { "SMSG_OVERRIDE_LIGHT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x412*/ { "SMSG_TOTEM_CREATED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x413*/ { "CMSG_TOTEM_DESTROYED", STATUS_LOGGEDIN, &WorldSession::HandleTotemDestroy },
- /*0x414*/ { "CMSG_EXPIRE_RAID_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x415*/ { "CMSG_NO_SPELL_VARIANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x416*/ { "CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY",STATUS_LOGGEDIN,&WorldSession::HandleQuestgiverStatusQueryMultipleOpcode},
- /*0x417*/ { "SMSG_QUESTGIVER_STATUS_MULTIPLE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x418*/ { "CMSG_SET_PLAYER_DECLINED_NAMES", STATUS_AUTHED, &WorldSession::HandleDeclinedPlayerNameOpcode },
- /*0x419*/ { "SMSG_SET_PLAYER_DECLINED_NAMES_RESULT",STATUS_NEVER,&WorldSession::Handle_ServerSide },
- /*0x41A*/ { "CMSG_QUERY_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x41B*/ { "CMSG_CLEAR_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x41C*/ { "SMSG_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x41D*/ { "SMSG_SEND_UNLEARN_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x41E*/ { "SMSG_PROPOSE_LEVEL_GRANT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x41F*/ { "CMSG_ACCEPT_LEVEL_GRANT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x420*/ { "SMSG_REFER_A_FRIEND_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x421*/ { "SMSG_SPLINE_MOVE_SET_FLYING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x422*/ { "SMSG_SPLINE_MOVE_UNSET_FLYING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x423*/ { "SMSG_SUMMON_CANCEL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x000*/ { "MSG_NULL_ACTION", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x001*/ { "CMSG_BOOTME", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x002*/ { "CMSG_DBLOOKUP", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x003*/ { "SMSG_DBLOOKUP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x004*/ { "CMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x005*/ { "SMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x006*/ { "CMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x007*/ { "SMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x008*/ { "CMSG_WORLD_TELEPORT", STATUS_LOGGEDIN, &WorldSession::HandleWorldTeleportOpcode },
+ /*0x009*/ { "CMSG_TELEPORT_TO_UNIT", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
+ /*0x00A*/ { "CMSG_ZONE_MAP", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x00B*/ { "SMSG_ZONE_MAP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x00C*/ { "CMSG_DEBUG_CHANGECELLZONE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x00D*/ { "CMSG_MOVE_CHARACTER_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x00E*/ { "SMSG_MOVE_CHARACTER_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x00F*/ { "CMSG_RECHARGE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x010*/ { "CMSG_LEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x011*/ { "CMSG_CREATEMONSTER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x012*/ { "CMSG_DESTROYMONSTER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x013*/ { "CMSG_CREATEITEM", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x014*/ { "CMSG_CREATEGAMEOBJECT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x015*/ { "SMSG_CHECK_FOR_BOTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x016*/ { "CMSG_MAKEMONSTERATTACKGUID", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x017*/ { "CMSG_BOT_DETECTED2", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x018*/ { "CMSG_FORCEACTION", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x019*/ { "CMSG_FORCEACTIONONOTHER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x01A*/ { "CMSG_FORCEACTIONSHOW", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x01B*/ { "SMSG_FORCEACTIONSHOW", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x01C*/ { "CMSG_PETGODMODE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x01D*/ { "SMSG_PETGODMODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x01E*/ { "SMSG_REFER_A_FRIEND_EXPIRED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x01F*/ { "CMSG_WEATHER_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x020*/ { "CMSG_UNDRESSPLAYER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x021*/ { "CMSG_BEASTMASTER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x022*/ { "CMSG_GODMODE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x023*/ { "SMSG_GODMODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x024*/ { "CMSG_CHEAT_SETMONEY", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x025*/ { "CMSG_LEVEL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x026*/ { "CMSG_PET_LEVEL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x027*/ { "CMSG_SET_WORLDSTATE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x028*/ { "CMSG_COOLDOWN_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x029*/ { "CMSG_USE_SKILL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x02A*/ { "CMSG_FLAG_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x02B*/ { "CMSG_FLAG_QUEST_FINISH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x02C*/ { "CMSG_CLEAR_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x02D*/ { "CMSG_SEND_EVENT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x02E*/ { "CMSG_DEBUG_AISTATE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x02F*/ { "SMSG_DEBUG_AISTATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x030*/ { "CMSG_DISABLE_PVP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x031*/ { "CMSG_ADVANCE_SPAWN_TIME", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x032*/ { "SMSG_DESTRUCTIBLE_BUILDING_DAMAGE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x033*/ { "CMSG_AUTH_SRP6_BEGIN", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x034*/ { "CMSG_AUTH_SRP6_PROOF", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x035*/ { "CMSG_AUTH_SRP6_RECODE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x036*/ { "CMSG_CHAR_CREATE", STATUS_AUTHED, &WorldSession::HandleCharCreateOpcode },
+ /*0x037*/ { "CMSG_CHAR_ENUM", STATUS_AUTHED, &WorldSession::HandleCharEnumOpcode },
+ /*0x038*/ { "CMSG_CHAR_DELETE", STATUS_AUTHED, &WorldSession::HandleCharDeleteOpcode },
+ /*0x039*/ { "SMSG_AUTH_SRP6_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x03A*/ { "SMSG_CHAR_CREATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x03B*/ { "SMSG_CHAR_ENUM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x03C*/ { "SMSG_CHAR_DELETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x03D*/ { "CMSG_PLAYER_LOGIN", STATUS_AUTHED, &WorldSession::HandlePlayerLoginOpcode },
+ /*0x03E*/ { "SMSG_NEW_WORLD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x03F*/ { "SMSG_TRANSFER_PENDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x040*/ { "SMSG_TRANSFER_ABORTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x041*/ { "SMSG_CHARACTER_LOGIN_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x042*/ { "SMSG_LOGIN_SETTIMESPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x043*/ { "SMSG_GAMETIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x044*/ { "CMSG_GAMETIME_SET", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x045*/ { "SMSG_GAMETIME_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x046*/ { "CMSG_GAMESPEED_SET", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x047*/ { "SMSG_GAMESPEED_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x048*/ { "CMSG_SERVERTIME", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x049*/ { "SMSG_SERVERTIME", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x04A*/ { "CMSG_PLAYER_LOGOUT", STATUS_LOGGEDIN, &WorldSession::HandlePlayerLogoutOpcode },
+ /*0x04B*/ { "CMSG_LOGOUT_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleLogoutRequestOpcode },
+ /*0x04C*/ { "SMSG_LOGOUT_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x04D*/ { "SMSG_LOGOUT_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x04E*/ { "CMSG_LOGOUT_CANCEL", STATUS_LOGGEDIN, &WorldSession::HandleLogoutCancelOpcode },
+ /*0x04F*/ { "SMSG_LOGOUT_CANCEL_ACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x050*/ { "CMSG_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleNameQueryOpcode },
+ /*0x051*/ { "SMSG_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x052*/ { "CMSG_PET_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePetNameQuery },
+ /*0x053*/ { "SMSG_PET_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x054*/ { "CMSG_GUILD_QUERY", STATUS_AUTHED, &WorldSession::HandleGuildQueryOpcode },
+ /*0x055*/ { "SMSG_GUILD_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x056*/ { "CMSG_ITEM_QUERY_SINGLE", STATUS_LOGGEDIN, &WorldSession::HandleItemQuerySingleOpcode },
+ /*0x057*/ { "CMSG_ITEM_QUERY_MULTIPLE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x058*/ { "SMSG_ITEM_QUERY_SINGLE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x059*/ { "SMSG_ITEM_QUERY_MULTIPLE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x05A*/ { "CMSG_PAGE_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePageQueryOpcode },
+ /*0x05B*/ { "SMSG_PAGE_TEXT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x05C*/ { "CMSG_QUEST_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestQueryOpcode },
+ /*0x05D*/ { "SMSG_QUEST_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x05E*/ { "CMSG_GAMEOBJECT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGameObjectQueryOpcode },
+ /*0x05F*/ { "SMSG_GAMEOBJECT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x060*/ { "CMSG_CREATURE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCreatureQueryOpcode },
+ /*0x061*/ { "SMSG_CREATURE_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x062*/ { "CMSG_WHO", STATUS_LOGGEDIN, &WorldSession::HandleWhoOpcode },
+ /*0x063*/ { "SMSG_WHO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x064*/ { "CMSG_WHOIS", STATUS_LOGGEDIN, &WorldSession::HandleWhoisOpcode },
+ /*0x065*/ { "SMSG_WHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x066*/ { "CMSG_CONTACT_LIST", STATUS_LOGGEDIN, &WorldSession::HandleFriendListOpcode },
+ /*0x067*/ { "SMSG_CONTACT_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x068*/ { "SMSG_FRIEND_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x069*/ { "CMSG_ADD_FRIEND", STATUS_LOGGEDIN, &WorldSession::HandleAddFriendOpcode },
+ /*0x06A*/ { "CMSG_DEL_FRIEND", STATUS_LOGGEDIN, &WorldSession::HandleDelFriendOpcode },
+ /*0x06B*/ { "CMSG_SET_CONTACT_NOTES", STATUS_LOGGEDIN, &WorldSession::HandleSetFriendNoteOpcode },
+ /*0x06C*/ { "CMSG_ADD_IGNORE", STATUS_LOGGEDIN, &WorldSession::HandleAddIgnoreOpcode },
+ /*0x06D*/ { "CMSG_DEL_IGNORE", STATUS_LOGGEDIN, &WorldSession::HandleDelIgnoreOpcode },
+ /*0x06E*/ { "CMSG_GROUP_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleGroupInviteOpcode },
+ /*0x06F*/ { "SMSG_GROUP_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x070*/ { "CMSG_GROUP_CANCEL", STATUS_LOGGEDIN, &WorldSession::Handle_Deprecated },
+ /*0x071*/ { "SMSG_GROUP_CANCEL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x072*/ { "CMSG_GROUP_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleGroupAcceptOpcode },
+ /*0x073*/ { "CMSG_GROUP_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleGroupDeclineOpcode },
+ /*0x074*/ { "SMSG_GROUP_DECLINE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x075*/ { "CMSG_GROUP_UNINVITE", STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteNameOpcode },
+ /*0x076*/ { "CMSG_GROUP_UNINVITE_GUID", STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteGuidOpcode },
+ /*0x077*/ { "SMSG_GROUP_UNINVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x078*/ { "CMSG_GROUP_SET_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGroupSetLeaderOpcode },
+ /*0x079*/ { "SMSG_GROUP_SET_LEADER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x07A*/ { "CMSG_LOOT_METHOD", STATUS_LOGGEDIN, &WorldSession::HandleLootMethodOpcode },
+ /*0x07B*/ { "CMSG_GROUP_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleGroupLeaveOpcode },
+ /*0x07C*/ { "SMSG_GROUP_DESTROYED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x07D*/ { "SMSG_GROUP_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x07E*/ { "SMSG_PARTY_MEMBER_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x07F*/ { "SMSG_PARTY_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x080*/ { "UMSG_UPDATE_GROUP_MEMBERS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x081*/ { "CMSG_GUILD_CREATE", STATUS_LOGGEDIN, &WorldSession::HandleGuildCreateOpcode },
+ /*0x082*/ { "CMSG_GUILD_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleGuildInviteOpcode },
+ /*0x083*/ { "SMSG_GUILD_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x084*/ { "CMSG_GUILD_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleGuildAcceptOpcode },
+ /*0x085*/ { "CMSG_GUILD_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleGuildDeclineOpcode },
+ /*0x086*/ { "SMSG_GUILD_DECLINE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x087*/ { "CMSG_GUILD_INFO", STATUS_LOGGEDIN, &WorldSession::HandleGuildInfoOpcode },
+ /*0x088*/ { "SMSG_GUILD_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x089*/ { "CMSG_GUILD_ROSTER", STATUS_LOGGEDIN, &WorldSession::HandleGuildRosterOpcode },
+ /*0x08A*/ { "SMSG_GUILD_ROSTER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x08B*/ { "CMSG_GUILD_PROMOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildPromoteOpcode },
+ /*0x08C*/ { "CMSG_GUILD_DEMOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildDemoteOpcode },
+ /*0x08D*/ { "CMSG_GUILD_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaveOpcode },
+ /*0x08E*/ { "CMSG_GUILD_REMOVE", STATUS_LOGGEDIN, &WorldSession::HandleGuildRemoveOpcode },
+ /*0x08F*/ { "CMSG_GUILD_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleGuildDisbandOpcode },
+ /*0x090*/ { "CMSG_GUILD_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaderOpcode },
+ /*0x091*/ { "CMSG_GUILD_MOTD", STATUS_LOGGEDIN, &WorldSession::HandleGuildMOTDOpcode },
+ /*0x092*/ { "SMSG_GUILD_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x093*/ { "SMSG_GUILD_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x094*/ { "UMSG_UPDATE_GUILD", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x095*/ { "CMSG_MESSAGECHAT", STATUS_LOGGEDIN, &WorldSession::HandleMessagechatOpcode },
+ /*0x096*/ { "SMSG_MESSAGECHAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x097*/ { "CMSG_JOIN_CHANNEL", STATUS_LOGGEDIN, &WorldSession::HandleChannelJoin },
+ /*0x098*/ { "CMSG_LEAVE_CHANNEL", STATUS_LOGGEDIN, &WorldSession::HandleChannelLeave },
+ /*0x099*/ { "SMSG_CHANNEL_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x09A*/ { "CMSG_CHANNEL_LIST", STATUS_LOGGEDIN, &WorldSession::HandleChannelList },
+ /*0x09B*/ { "SMSG_CHANNEL_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x09C*/ { "CMSG_CHANNEL_PASSWORD", STATUS_LOGGEDIN, &WorldSession::HandleChannelPassword },
+ /*0x09D*/ { "CMSG_CHANNEL_SET_OWNER", STATUS_LOGGEDIN, &WorldSession::HandleChannelSetOwner },
+ /*0x09E*/ { "CMSG_CHANNEL_OWNER", STATUS_LOGGEDIN, &WorldSession::HandleChannelOwner },
+ /*0x09F*/ { "CMSG_CHANNEL_MODERATOR", STATUS_LOGGEDIN, &WorldSession::HandleChannelModerator },
+ /*0x0A0*/ { "CMSG_CHANNEL_UNMODERATOR", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmoderator },
+ /*0x0A1*/ { "CMSG_CHANNEL_MUTE", STATUS_LOGGEDIN, &WorldSession::HandleChannelMute },
+ /*0x0A2*/ { "CMSG_CHANNEL_UNMUTE", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmute },
+ /*0x0A3*/ { "CMSG_CHANNEL_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleChannelInvite },
+ /*0x0A4*/ { "CMSG_CHANNEL_KICK", STATUS_LOGGEDIN, &WorldSession::HandleChannelKick },
+ /*0x0A5*/ { "CMSG_CHANNEL_BAN", STATUS_LOGGEDIN, &WorldSession::HandleChannelBan },
+ /*0x0A6*/ { "CMSG_CHANNEL_UNBAN", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnban },
+ /*0x0A7*/ { "CMSG_CHANNEL_ANNOUNCEMENTS", STATUS_LOGGEDIN, &WorldSession::HandleChannelAnnounce },
+ /*0x0A8*/ { "CMSG_CHANNEL_MODERATE", STATUS_LOGGEDIN, &WorldSession::HandleChannelModerate },
+ /*0x0A9*/ { "SMSG_UPDATE_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0AA*/ { "SMSG_DESTROY_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0AB*/ { "CMSG_USE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleUseItemOpcode },
+ /*0x0AC*/ { "CMSG_OPEN_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleOpenItemOpcode },
+ /*0x0AD*/ { "CMSG_READ_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleReadItem },
+ /*0x0AE*/ { "SMSG_READ_ITEM_OK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0AF*/ { "SMSG_READ_ITEM_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0B0*/ { "SMSG_ITEM_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0B1*/ { "CMSG_GAMEOBJ_USE", STATUS_LOGGEDIN, &WorldSession::HandleGameObjectUseOpcode },
+ /*0x0B2*/ { "CMSG_DESTROY_ITEMS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0B3*/ { "SMSG_GAMEOBJECT_CUSTOM_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0B4*/ { "CMSG_AREATRIGGER", STATUS_LOGGEDIN, &WorldSession::HandleAreaTriggerOpcode },
+ /*0x0B5*/ { "MSG_MOVE_START_FORWARD", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0B6*/ { "MSG_MOVE_START_BACKWARD", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0B7*/ { "MSG_MOVE_STOP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0B8*/ { "MSG_MOVE_START_STRAFE_LEFT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0B9*/ { "MSG_MOVE_START_STRAFE_RIGHT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0BA*/ { "MSG_MOVE_STOP_STRAFE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0BB*/ { "MSG_MOVE_JUMP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0BC*/ { "MSG_MOVE_START_TURN_LEFT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0BD*/ { "MSG_MOVE_START_TURN_RIGHT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0BE*/ { "MSG_MOVE_STOP_TURN", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0BF*/ { "MSG_MOVE_START_PITCH_UP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0C0*/ { "MSG_MOVE_START_PITCH_DOWN", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0C1*/ { "MSG_MOVE_STOP_PITCH", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0C2*/ { "MSG_MOVE_SET_RUN_MODE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0C3*/ { "MSG_MOVE_SET_WALK_MODE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0C4*/ { "MSG_MOVE_TOGGLE_LOGGING", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0C5*/ { "MSG_MOVE_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0C6*/ { "MSG_MOVE_TELEPORT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0C7*/ { "MSG_MOVE_TELEPORT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveTeleportAck },
+ /*0x0C8*/ { "MSG_MOVE_TOGGLE_FALL_LOGGING", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0C9*/ { "MSG_MOVE_FALL_LAND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0CA*/ { "MSG_MOVE_START_SWIM", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0CB*/ { "MSG_MOVE_STOP_SWIM", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0CC*/ { "MSG_MOVE_SET_RUN_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0CD*/ { "MSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0CE*/ { "MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0CF*/ { "MSG_MOVE_SET_RUN_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D0*/ { "MSG_MOVE_SET_WALK_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D1*/ { "MSG_MOVE_SET_WALK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D2*/ { "MSG_MOVE_SET_SWIM_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D3*/ { "MSG_MOVE_SET_SWIM_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D4*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D5*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D6*/ { "MSG_MOVE_SET_ALL_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D7*/ { "MSG_MOVE_SET_TURN_RATE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D8*/ { "MSG_MOVE_SET_TURN_RATE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D9*/ { "MSG_MOVE_TOGGLE_COLLISION_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0DA*/ { "MSG_MOVE_SET_FACING", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0DB*/ { "MSG_MOVE_SET_PITCH", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0DC*/ { "MSG_MOVE_WORLDPORT_ACK", STATUS_TRANSFER_PENDING,&WorldSession::HandleMoveWorldportAckOpcode},
+ /*0x0DD*/ { "SMSG_MONSTER_MOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0DE*/ { "SMSG_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0DF*/ { "SMSG_MOVE_LAND_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0E0*/ { "MSG_MOVE_SET_RAW_POSITION_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0E1*/ { "CMSG_MOVE_SET_RAW_POSITION", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0E2*/ { "SMSG_FORCE_RUN_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0E3*/ { "CMSG_FORCE_RUN_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
+ /*0x0E4*/ { "SMSG_FORCE_RUN_BACK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0E5*/ { "CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
+ /*0x0E6*/ { "SMSG_FORCE_SWIM_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0E7*/ { "CMSG_FORCE_SWIM_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
+ /*0x0E8*/ { "SMSG_FORCE_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0E9*/ { "CMSG_FORCE_MOVE_ROOT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveRootAck },
+ /*0x0EA*/ { "SMSG_FORCE_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0EB*/ { "CMSG_FORCE_MOVE_UNROOT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveUnRootAck },
+ /*0x0EC*/ { "MSG_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0ED*/ { "MSG_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0EE*/ { "MSG_MOVE_HEARTBEAT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0EF*/ { "SMSG_MOVE_KNOCK_BACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0F0*/ { "CMSG_MOVE_KNOCK_BACK_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveKnockBackAck },
+ /*0x0F1*/ { "MSG_MOVE_KNOCK_BACK", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0F2*/ { "SMSG_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0F3*/ { "SMSG_MOVE_NORMAL_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0F4*/ { "SMSG_MOVE_SET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0F5*/ { "SMSG_MOVE_UNSET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0F6*/ { "CMSG_MOVE_HOVER_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveHoverAck },
+ /*0x0F7*/ { "MSG_MOVE_HOVER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0F8*/ { "CMSG_TRIGGER_CINEMATIC_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0F9*/ { "CMSG_OPENING_CINEMATIC", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0FA*/ { "SMSG_TRIGGER_CINEMATIC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0FB*/ { "CMSG_NEXT_CINEMATIC_CAMERA", STATUS_LOGGEDIN, &WorldSession::HandleNextCinematicCamera },
+ /*0x0FC*/ { "CMSG_COMPLETE_CINEMATIC", STATUS_LOGGEDIN, &WorldSession::HandleCompleteCinema },
+ /*0x0FD*/ { "SMSG_TUTORIAL_FLAGS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0FE*/ { "CMSG_TUTORIAL_FLAG", STATUS_LOGGEDIN, &WorldSession::HandleTutorialFlag },
+ /*0x0FF*/ { "CMSG_TUTORIAL_CLEAR", STATUS_LOGGEDIN, &WorldSession::HandleTutorialClear },
+ /*0x100*/ { "CMSG_TUTORIAL_RESET", STATUS_LOGGEDIN, &WorldSession::HandleTutorialReset },
+ /*0x101*/ { "CMSG_STANDSTATECHANGE", STATUS_LOGGEDIN, &WorldSession::HandleStandStateChangeOpcode },
+ /*0x102*/ { "CMSG_EMOTE", STATUS_LOGGEDIN, &WorldSession::HandleEmoteOpcode },
+ /*0x103*/ { "SMSG_EMOTE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x104*/ { "CMSG_TEXT_EMOTE", STATUS_LOGGEDIN, &WorldSession::HandleTextEmoteOpcode },
+ /*0x105*/ { "SMSG_TEXT_EMOTE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x106*/ { "CMSG_AUTOEQUIP_GROUND_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x107*/ { "CMSG_AUTOSTORE_GROUND_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x108*/ { "CMSG_AUTOSTORE_LOOT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutostoreLootItemOpcode },
+ /*0x109*/ { "CMSG_STORE_LOOT_IN_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x10A*/ { "CMSG_AUTOEQUIP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemOpcode },
+ /*0x10B*/ { "CMSG_AUTOSTORE_BAG_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBagItemOpcode },
+ /*0x10C*/ { "CMSG_SWAP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSwapItem },
+ /*0x10D*/ { "CMSG_SWAP_INV_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSwapInvItemOpcode },
+ /*0x10E*/ { "CMSG_SPLIT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSplitItemOpcode },
+ /*0x10F*/ { "CMSG_AUTOEQUIP_ITEM_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemSlotOpcode },
+ /*0x110*/ { "OBSOLETE_DROP_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x111*/ { "CMSG_DESTROYITEM", STATUS_LOGGEDIN, &WorldSession::HandleDestroyItemOpcode },
+ /*0x112*/ { "SMSG_INVENTORY_CHANGE_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x113*/ { "SMSG_OPEN_CONTAINER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x114*/ { "CMSG_INSPECT", STATUS_LOGGEDIN, &WorldSession::HandleInspectOpcode },
+ /*0x115*/ { "SMSG_INSPECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x116*/ { "CMSG_INITIATE_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleInitiateTradeOpcode },
+ /*0x117*/ { "CMSG_BEGIN_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleBeginTradeOpcode },
+ /*0x118*/ { "CMSG_BUSY_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleBusyTradeOpcode },
+ /*0x119*/ { "CMSG_IGNORE_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleIgnoreTradeOpcode },
+ /*0x11A*/ { "CMSG_ACCEPT_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleAcceptTradeOpcode },
+ /*0x11B*/ { "CMSG_UNACCEPT_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleUnacceptTradeOpcode },
+ /*0x11C*/ { "CMSG_CANCEL_TRADE", STATUS_AUTHED, &WorldSession::HandleCancelTradeOpcode },
+ /*0x11D*/ { "CMSG_SET_TRADE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSetTradeItemOpcode },
+ /*0x11E*/ { "CMSG_CLEAR_TRADE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleClearTradeItemOpcode },
+ /*0x11F*/ { "CMSG_SET_TRADE_GOLD", STATUS_LOGGEDIN, &WorldSession::HandleSetTradeGoldOpcode },
+ /*0x120*/ { "SMSG_TRADE_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x121*/ { "SMSG_TRADE_STATUS_EXTENDED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x122*/ { "SMSG_INITIALIZE_FACTIONS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x123*/ { "SMSG_SET_FACTION_VISIBLE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x124*/ { "SMSG_SET_FACTION_STANDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x125*/ { "CMSG_SET_FACTION_ATWAR", STATUS_LOGGEDIN, &WorldSession::HandleSetFactionAtWar },
+ /*0x126*/ { "CMSG_SET_FACTION_CHEAT", STATUS_LOGGEDIN, &WorldSession::HandleSetFactionCheat },
+ /*0x127*/ { "SMSG_SET_PROFICIENCY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x128*/ { "CMSG_SET_ACTION_BUTTON", STATUS_LOGGEDIN, &WorldSession::HandleSetActionButtonOpcode },
+ /*0x129*/ { "SMSG_ACTION_BUTTONS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x12A*/ { "SMSG_INITIAL_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x12B*/ { "SMSG_LEARNED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x12C*/ { "SMSG_SUPERCEDED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x12D*/ { "CMSG_NEW_SPELL_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x12E*/ { "CMSG_CAST_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleCastSpellOpcode },
+ /*0x12F*/ { "CMSG_CANCEL_CAST", STATUS_LOGGEDIN, &WorldSession::HandleCancelCastOpcode },
+ /*0x130*/ { "SMSG_CAST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x131*/ { "SMSG_SPELL_START", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x132*/ { "SMSG_SPELL_GO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x133*/ { "SMSG_SPELL_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x134*/ { "SMSG_SPELL_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x135*/ { "SMSG_COOLDOWN_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x136*/ { "CMSG_CANCEL_AURA", STATUS_LOGGEDIN, &WorldSession::HandleCancelAuraOpcode },
+ /*0x137*/ { "SMSG_UPDATE_AURA_DURATION_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x138*/ { "SMSG_PET_CAST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x139*/ { "MSG_CHANNEL_START", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x13A*/ { "MSG_CHANNEL_UPDATE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x13B*/ { "CMSG_CANCEL_CHANNELLING", STATUS_LOGGEDIN, &WorldSession::HandleCancelChanneling },
+ /*0x13C*/ { "SMSG_AI_REACTION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x13D*/ { "CMSG_SET_SELECTION", STATUS_LOGGEDIN, &WorldSession::HandleSetSelectionOpcode },
+ /*0x13E*/ { "CMSG_SET_TARGET_OBSOLETE", STATUS_LOGGEDIN, &WorldSession::HandleSetTargetOpcode },
+ /*0x13F*/ { "CMSG_UNUSED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x140*/ { "CMSG_UNUSED2", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x141*/ { "CMSG_ATTACKSWING", STATUS_LOGGEDIN, &WorldSession::HandleAttackSwingOpcode },
+ /*0x142*/ { "CMSG_ATTACKSTOP", STATUS_LOGGEDIN, &WorldSession::HandleAttackStopOpcode },
+ /*0x143*/ { "SMSG_ATTACKSTART", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x144*/ { "SMSG_ATTACKSTOP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x145*/ { "SMSG_ATTACKSWING_NOTINRANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x146*/ { "SMSG_ATTACKSWING_BADFACING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x147*/ { "SMSG_ATTACKSWING_NOTSTANDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x148*/ { "SMSG_ATTACKSWING_DEADTARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x149*/ { "SMSG_ATTACKSWING_CANT_ATTACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x14B*/ { "SMSG_VICTIMSTATEUPDATE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x14C*/ { "SMSG_DAMAGE_DONE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x14D*/ { "SMSG_DAMAGE_TAKEN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x14E*/ { "SMSG_CANCEL_COMBAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x14F*/ { "SMSG_SPELLBREAKLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x150*/ { "SMSG_SPELLHEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x151*/ { "SMSG_SPELLENERGIZELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x152*/ { "SMSG_BREAK_TARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x153*/ { "CMSG_SAVE_PLAYER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x154*/ { "CMSG_SETDEATHBINDPOINT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x155*/ { "SMSG_BINDPOINTUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x156*/ { "CMSG_GETDEATHBINDZONE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x157*/ { "SMSG_BINDZONEREPLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x158*/ { "SMSG_PLAYERBOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x159*/ { "SMSG_CLIENT_CONTROL_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x15A*/ { "CMSG_REPOP_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleRepopRequestOpcode },
+ /*0x15B*/ { "SMSG_RESURRECT_REQUEST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x15C*/ { "CMSG_RESURRECT_RESPONSE", STATUS_LOGGEDIN, &WorldSession::HandleResurrectResponseOpcode },
+ /*0x15D*/ { "CMSG_LOOT", STATUS_LOGGEDIN, &WorldSession::HandleLootOpcode },
+ /*0x15E*/ { "CMSG_LOOT_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleLootMoneyOpcode },
+ /*0x15F*/ { "CMSG_LOOT_RELEASE", STATUS_LOGGEDIN, &WorldSession::HandleLootReleaseOpcode },
+ /*0x160*/ { "SMSG_LOOT_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x161*/ { "SMSG_LOOT_RELEASE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x162*/ { "SMSG_LOOT_REMOVED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x163*/ { "SMSG_LOOT_MONEY_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x164*/ { "SMSG_LOOT_ITEM_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x165*/ { "SMSG_LOOT_CLEAR_MONEY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x166*/ { "SMSG_ITEM_PUSH_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x167*/ { "SMSG_DUEL_REQUESTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x168*/ { "SMSG_DUEL_OUTOFBOUNDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x169*/ { "SMSG_DUEL_INBOUNDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x16A*/ { "SMSG_DUEL_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x16B*/ { "SMSG_DUEL_WINNER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x16C*/ { "CMSG_DUEL_ACCEPTED", STATUS_LOGGEDIN, &WorldSession::HandleDuelAcceptedOpcode },
+ /*0x16D*/ { "CMSG_DUEL_CANCELLED", STATUS_LOGGEDIN, &WorldSession::HandleDuelCancelledOpcode },
+ /*0x16E*/ { "SMSG_MOUNTRESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x16F*/ { "SMSG_DISMOUNTRESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x170*/ { "SMSG_PUREMOUNT_CANCELLED_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x171*/ { "CMSG_MOUNTSPECIAL_ANIM", STATUS_LOGGEDIN, &WorldSession::HandleMountSpecialAnimOpcode },
+ /*0x172*/ { "SMSG_MOUNTSPECIAL_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x173*/ { "SMSG_PET_TAME_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x174*/ { "CMSG_PET_SET_ACTION", STATUS_LOGGEDIN, &WorldSession::HandlePetSetAction },
+ /*0x175*/ { "CMSG_PET_ACTION", STATUS_LOGGEDIN, &WorldSession::HandlePetAction },
+ /*0x176*/ { "CMSG_PET_ABANDON", STATUS_LOGGEDIN, &WorldSession::HandlePetAbandon },
+ /*0x177*/ { "CMSG_PET_RENAME", STATUS_LOGGEDIN, &WorldSession::HandlePetRename },
+ /*0x178*/ { "SMSG_PET_NAME_INVALID", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x179*/ { "SMSG_PET_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x17A*/ { "SMSG_PET_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x17B*/ { "CMSG_GOSSIP_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleGossipHelloOpcode },
+ /*0x17C*/ { "CMSG_GOSSIP_SELECT_OPTION", STATUS_LOGGEDIN, &WorldSession::HandleGossipSelectOptionOpcode },
+ /*0x17D*/ { "SMSG_GOSSIP_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x17E*/ { "SMSG_GOSSIP_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x17F*/ { "CMSG_NPC_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleNpcTextQueryOpcode },
+ /*0x180*/ { "SMSG_NPC_TEXT_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x181*/ { "SMSG_NPC_WONT_TALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x182*/ { "CMSG_QUESTGIVER_STATUS_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverStatusQueryOpcode},
+ /*0x183*/ { "SMSG_QUESTGIVER_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x184*/ { "CMSG_QUESTGIVER_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverHelloOpcode },
+ /*0x185*/ { "SMSG_QUESTGIVER_QUEST_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x186*/ { "CMSG_QUESTGIVER_QUERY_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverQuestQueryOpcode},
+ /*0x187*/ { "CMSG_QUESTGIVER_QUEST_AUTOLAUNCH", STATUS_LOGGEDIN, &WorldSession::HandleQuestAutoLaunch },
+ /*0x188*/ { "SMSG_QUESTGIVER_QUEST_DETAILS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x189*/ { "CMSG_QUESTGIVER_ACCEPT_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverAcceptQuestOpcode},
+ /*0x18A*/ { "CMSG_QUESTGIVER_COMPLETE_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestComplete },
+ /*0x18B*/ { "SMSG_QUESTGIVER_REQUEST_ITEMS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x18C*/ { "CMSG_QUESTGIVER_REQUEST_REWARD", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverRequestRewardOpcode},
+ /*0x18D*/ { "SMSG_QUESTGIVER_OFFER_REWARD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x18E*/ { "CMSG_QUESTGIVER_CHOOSE_REWARD", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverChooseRewardOpcode},
+ /*0x18F*/ { "SMSG_QUESTGIVER_QUEST_INVALID", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x190*/ { "CMSG_QUESTGIVER_CANCEL", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverCancel },
+ /*0x191*/ { "SMSG_QUESTGIVER_QUEST_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x192*/ { "SMSG_QUESTGIVER_QUEST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x193*/ { "CMSG_QUESTLOG_SWAP_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestLogSwapQuest },
+ /*0x194*/ { "CMSG_QUESTLOG_REMOVE_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestLogRemoveQuest },
+ /*0x195*/ { "SMSG_QUESTLOG_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x196*/ { "SMSG_QUESTUPDATE_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x197*/ { "SMSG_QUESTUPDATE_FAILEDTIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x198*/ { "SMSG_QUESTUPDATE_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x199*/ { "SMSG_QUESTUPDATE_ADD_KILL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x19A*/ { "SMSG_QUESTUPDATE_ADD_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x19B*/ { "CMSG_QUEST_CONFIRM_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleQuestConfirmAccept },
+ /*0x19C*/ { "SMSG_QUEST_CONFIRM_ACCEPT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x19D*/ { "CMSG_PUSHQUESTTOPARTY", STATUS_LOGGEDIN, &WorldSession::HandleQuestPushToParty },
+ /*0x19E*/ { "CMSG_LIST_INVENTORY", STATUS_LOGGEDIN, &WorldSession::HandleListInventoryOpcode },
+ /*0x19F*/ { "SMSG_LIST_INVENTORY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1A0*/ { "CMSG_SELL_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSellItemOpcode },
+ /*0x1A1*/ { "SMSG_SELL_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1A2*/ { "CMSG_BUY_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuyItemOpcode },
+ /*0x1A3*/ { "CMSG_BUY_ITEM_IN_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyItemInSlotOpcode },
+ /*0x1A4*/ { "SMSG_BUY_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1A5*/ { "SMSG_BUY_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1A6*/ { "CMSG_TAXICLEARALLNODES", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1A7*/ { "CMSG_TAXIENABLEALLNODES", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1A8*/ { "CMSG_TAXISHOWNODES", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1A9*/ { "SMSG_SHOWTAXINODES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1AA*/ { "CMSG_TAXINODE_STATUS_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleTaxiNodeStatusQueryOpcode },
+ /*0x1AB*/ { "SMSG_TAXINODE_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1AC*/ { "CMSG_TAXIQUERYAVAILABLENODES", STATUS_LOGGEDIN, &WorldSession::HandleTaxiQueryAvailableNodes },
+ /*0x1AD*/ { "CMSG_ACTIVATETAXI", STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiOpcode },
+ /*0x1AE*/ { "SMSG_ACTIVATETAXIREPLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1AF*/ { "SMSG_NEW_TAXI_PATH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1B0*/ { "CMSG_TRAINER_LIST", STATUS_LOGGEDIN, &WorldSession::HandleTrainerListOpcode },
+ /*0x1B1*/ { "SMSG_TRAINER_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1B2*/ { "CMSG_TRAINER_BUY_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleTrainerBuySpellOpcode },
+ /*0x1B3*/ { "SMSG_TRAINER_BUY_SUCCEEDED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1B4*/ { "SMSG_TRAINER_BUY_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1B5*/ { "CMSG_BINDER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleBinderActivateOpcode },
+ /*0x1B6*/ { "SMSG_PLAYERBINDERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1B7*/ { "CMSG_BANKER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleBankerActivateOpcode },
+ /*0x1B8*/ { "SMSG_SHOW_BANK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1B9*/ { "CMSG_BUY_BANK_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyBankSlotOpcode },
+ /*0x1BA*/ { "SMSG_BUY_BANK_SLOT_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1BB*/ { "CMSG_PETITION_SHOWLIST", STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowListOpcode },
+ /*0x1BC*/ { "SMSG_PETITION_SHOWLIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1BD*/ { "CMSG_PETITION_BUY", STATUS_LOGGEDIN, &WorldSession::HandlePetitionBuyOpcode },
+ /*0x1BE*/ { "CMSG_PETITION_SHOW_SIGNATURES", STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowSignOpcode },
+ /*0x1BF*/ { "SMSG_PETITION_SHOW_SIGNATURES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1C0*/ { "CMSG_PETITION_SIGN", STATUS_LOGGEDIN, &WorldSession::HandlePetitionSignOpcode },
+ /*0x1C1*/ { "SMSG_PETITION_SIGN_RESULTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1C2*/ { "MSG_PETITION_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandlePetitionDeclineOpcode },
+ /*0x1C3*/ { "CMSG_OFFER_PETITION", STATUS_LOGGEDIN, &WorldSession::HandleOfferPetitionOpcode },
+ /*0x1C4*/ { "CMSG_TURN_IN_PETITION", STATUS_LOGGEDIN, &WorldSession::HandleTurnInPetitionOpcode },
+ /*0x1C5*/ { "SMSG_TURN_IN_PETITION_RESULTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1C6*/ { "CMSG_PETITION_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePetitionQueryOpcode },
+ /*0x1C7*/ { "SMSG_PETITION_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1C8*/ { "SMSG_FISH_NOT_HOOKED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1C9*/ { "SMSG_FISH_ESCAPED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1CA*/ { "CMSG_BUG", STATUS_LOGGEDIN, &WorldSession::HandleBugOpcode },
+ /*0x1CB*/ { "SMSG_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1CC*/ { "CMSG_PLAYED_TIME", STATUS_LOGGEDIN, &WorldSession::HandlePlayedTime },
+ /*0x1CD*/ { "SMSG_PLAYED_TIME", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1CE*/ { "CMSG_QUERY_TIME", STATUS_LOGGEDIN, &WorldSession::HandleQueryTimeOpcode },
+ /*0x1CF*/ { "SMSG_QUERY_TIME_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1D0*/ { "SMSG_LOG_XPGAIN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1D1*/ { "SMSG_AURACASTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1D2*/ { "CMSG_RECLAIM_CORPSE", STATUS_LOGGEDIN, &WorldSession::HandleCorpseReclaimOpcode },
+ /*0x1D3*/ { "CMSG_WRAP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleWrapItemOpcode },
+ /*0x1D4*/ { "SMSG_LEVELUP_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1D5*/ { "MSG_MINIMAP_PING", STATUS_LOGGEDIN, &WorldSession::HandleMinimapPingOpcode },
+ /*0x1D6*/ { "SMSG_RESISTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1D7*/ { "SMSG_ENCHANTMENTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1D8*/ { "CMSG_SET_SKILL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1D9*/ { "SMSG_START_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1DA*/ { "SMSG_PAUSE_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1DB*/ { "SMSG_STOP_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1DC*/ { "CMSG_PING", STATUS_NEVER, &WorldSession::Handle_EarlyProccess },
+ /*0x1DD*/ { "SMSG_PONG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1DE*/ { "SMSG_CLEAR_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1DF*/ { "SMSG_GAMEOBJECT_PAGETEXT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1E0*/ { "CMSG_SETSHEATHED", STATUS_LOGGEDIN, &WorldSession::HandleSetSheathedOpcode },
+ /*0x1E1*/ { "SMSG_COOLDOWN_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1E2*/ { "SMSG_SPELL_DELAYED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1E3*/ { "CMSG_PLAYER_MACRO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1E4*/ { "SMSG_PLAYER_MACRO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1E5*/ { "CMSG_GHOST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1E6*/ { "CMSG_GM_INVIS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1E7*/ { "SMSG_INVALID_PROMOTION_CODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1E8*/ { "MSG_GM_BIND_OTHER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1E9*/ { "MSG_GM_SUMMON", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1EA*/ { "SMSG_ITEM_TIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1EB*/ { "SMSG_ITEM_ENCHANT_TIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1EC*/ { "SMSG_AUTH_CHALLENGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1ED*/ { "CMSG_AUTH_SESSION", STATUS_NEVER, &WorldSession::Handle_EarlyProccess },
+ /*0x1EE*/ { "SMSG_AUTH_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1EF*/ { "MSG_GM_SHOWLABEL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1F0*/ { "CMSG_PET_CAST_SPELL", STATUS_LOGGEDIN, &WorldSession::HandlePetCastSpellOpcode },
+ /*0x1F1*/ { "MSG_SAVE_GUILD_EMBLEM", STATUS_LOGGEDIN, &WorldSession::HandleGuildSaveEmblemOpcode },
+ /*0x1F2*/ { "MSG_TABARDVENDOR_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleTabardVendorActivateOpcode},
+ /*0x1F3*/ { "SMSG_PLAY_SPELL_VISUAL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1F4*/ { "CMSG_ZONEUPDATE", STATUS_LOGGEDIN, &WorldSession::HandleZoneUpdateOpcode },
+ /*0x1F5*/ { "SMSG_PARTYKILLLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1F6*/ { "SMSG_COMPRESSED_UPDATE_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1F7*/ { "SMSG_PLAY_SPELL_IMPACT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1F8*/ { "SMSG_EXPLORATION_EXPERIENCE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1F9*/ { "CMSG_GM_SET_SECURITY_GROUP", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1FA*/ { "CMSG_GM_NUKE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1FB*/ { "MSG_RANDOM_ROLL", STATUS_LOGGEDIN, &WorldSession::HandleRandomRollOpcode },
+ /*0x1FC*/ { "SMSG_ENVIRONMENTALDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1FD*/ { "CMSG_RWHOIS_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1FE*/ { "SMSG_RWHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1FF*/ { "MSG_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleLookingForGroup },
+ /*0x200*/ { "CMSG_SET_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleSetLfgOpcode },
+ /*0x201*/ { "CMSG_UNLEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x202*/ { "CMSG_UNLEARN_SKILL", STATUS_LOGGEDIN, &WorldSession::HandleUnlearnSkillOpcode },
+ /*0x203*/ { "SMSG_REMOVED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x204*/ { "CMSG_DECHARGE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x205*/ { "CMSG_GMTICKET_CREATE", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketCreateOpcode },
+ /*0x206*/ { "SMSG_GMTICKET_CREATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x207*/ { "CMSG_GMTICKET_UPDATETEXT", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketUpdateOpcode },
+ /*0x208*/ { "SMSG_GMTICKET_UPDATETEXT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x209*/ { "SMSG_ACCOUNT_DATA_TIMES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x20A*/ { "CMSG_REQUEST_ACCOUNT_DATA", STATUS_LOGGEDIN, &WorldSession::HandleRequestAccountData },
+ /*0x20B*/ { "CMSG_UPDATE_ACCOUNT_DATA", STATUS_AUTHED, &WorldSession::HandleUpdateAccountData },
+ /*0x20C*/ { "SMSG_UPDATE_ACCOUNT_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x20D*/ { "SMSG_CLEAR_FAR_SIGHT_IMMEDIATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x20E*/ { "SMSG_POWERGAINLOG_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x20F*/ { "CMSG_GM_TEACH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x210*/ { "CMSG_GM_CREATE_ITEM_TARGET", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x211*/ { "CMSG_GMTICKET_GETTICKET", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketGetTicketOpcode },
+ /*0x212*/ { "SMSG_GMTICKET_GETTICKET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x213*/ { "CMSG_UNLEARN_TALENTS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x214*/ { "SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x215*/ { "SMSG_GAMEOBJECT_DESPAWN_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x216*/ { "MSG_CORPSE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCorpseQueryOpcode },
+ /*0x217*/ { "CMSG_GMTICKET_DELETETICKET", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketDeleteOpcode },
+ /*0x218*/ { "SMSG_GMTICKET_DELETETICKET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x219*/ { "SMSG_CHAT_WRONG_FACTION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x21A*/ { "CMSG_GMTICKET_SYSTEMSTATUS", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketSystemStatusOpcode},
+ /*0x21B*/ { "SMSG_GMTICKET_SYSTEMSTATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x21C*/ { "CMSG_SPIRIT_HEALER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleSpiritHealerActivateOpcode},
+ /*0x21D*/ { "CMSG_SET_STAT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x21E*/ { "SMSG_SET_REST_START_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x21F*/ { "CMSG_SKILL_BUY_STEP", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x220*/ { "CMSG_SKILL_BUY_RANK", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x221*/ { "CMSG_XP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x222*/ { "SMSG_SPIRIT_HEALER_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x223*/ { "CMSG_CHARACTER_POINT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x224*/ { "SMSG_GOSSIP_POI", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x225*/ { "CMSG_CHAT_IGNORED", STATUS_LOGGEDIN, &WorldSession::HandleChatIgnoredOpcode },
+ /*0x226*/ { "CMSG_GM_VISION", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x227*/ { "CMSG_SERVER_COMMAND", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x228*/ { "CMSG_GM_SILENCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x229*/ { "CMSG_GM_REVEALTO", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x22A*/ { "CMSG_GM_RESURRECT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x22B*/ { "CMSG_GM_SUMMONMOB", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x22C*/ { "CMSG_GM_MOVECORPSE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x22D*/ { "CMSG_GM_FREEZE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x22E*/ { "CMSG_GM_UBERINVIS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x22F*/ { "CMSG_GM_REQUEST_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x230*/ { "SMSG_GM_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x231*/ { "CMSG_GUILD_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildRankOpcode },
+ /*0x232*/ { "CMSG_GUILD_ADD_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildAddRankOpcode },
+ /*0x233*/ { "CMSG_GUILD_DEL_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildDelRankOpcode },
+ /*0x234*/ { "CMSG_GUILD_SET_PUBLIC_NOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildSetPublicNoteOpcode },
+ /*0x235*/ { "CMSG_GUILD_SET_OFFICER_NOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildSetOfficerNoteOpcode },
+ /*0x236*/ { "SMSG_LOGIN_VERIFY_WORLD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x237*/ { "CMSG_CLEAR_EXPLORATION", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x238*/ { "CMSG_SEND_MAIL", STATUS_LOGGEDIN, &WorldSession::HandleSendMail },
+ /*0x239*/ { "SMSG_SEND_MAIL_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x23A*/ { "CMSG_GET_MAIL_LIST", STATUS_LOGGEDIN, &WorldSession::HandleGetMail },
+ /*0x23B*/ { "SMSG_MAIL_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x23C*/ { "CMSG_BATTLEFIELD_LIST", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundListOpcode },
+ /*0x23D*/ { "SMSG_BATTLEFIELD_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x23E*/ { "CMSG_BATTLEFIELD_JOIN", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x23F*/ { "SMSG_BATTLEFIELD_WIN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x240*/ { "SMSG_BATTLEFIELD_LOSE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x241*/ { "CMSG_TAXICLEARNODE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x242*/ { "CMSG_TAXIENABLENODE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x243*/ { "CMSG_ITEM_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleItemTextQuery },
+ /*0x244*/ { "SMSG_ITEM_TEXT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x245*/ { "CMSG_MAIL_TAKE_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleTakeMoney },
+ /*0x246*/ { "CMSG_MAIL_TAKE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleTakeItem },
+ /*0x247*/ { "CMSG_MAIL_MARK_AS_READ", STATUS_LOGGEDIN, &WorldSession::HandleMarkAsRead },
+ /*0x248*/ { "CMSG_MAIL_RETURN_TO_SENDER", STATUS_LOGGEDIN, &WorldSession::HandleReturnToSender },
+ /*0x249*/ { "CMSG_MAIL_DELETE", STATUS_LOGGEDIN, &WorldSession::HandleMailDelete },
+ /*0x24A*/ { "CMSG_MAIL_CREATE_TEXT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleMailCreateTextItem },
+ /*0x24B*/ { "SMSG_SPELLLOGMISS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x24C*/ { "SMSG_SPELLLOGEXECUTE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x24D*/ { "SMSG_DEBUGAURAPROC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x24E*/ { "SMSG_PERIODICAURALOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x24F*/ { "SMSG_SPELLDAMAGESHIELD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x250*/ { "SMSG_SPELLNONMELEEDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x251*/ { "CMSG_LEARN_TALENT", STATUS_LOGGEDIN, &WorldSession::HandleLearnTalentOpcode },
+ /*0x252*/ { "SMSG_RESURRECT_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x253*/ { "CMSG_TOGGLE_PVP", STATUS_LOGGEDIN, &WorldSession::HandleTogglePvP },
+ /*0x254*/ { "SMSG_ZONE_UNDER_ATTACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x255*/ { "MSG_AUCTION_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleAuctionHelloOpcode },
+ /*0x256*/ { "CMSG_AUCTION_SELL_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAuctionSellItem },
+ /*0x257*/ { "CMSG_AUCTION_REMOVE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAuctionRemoveItem },
+ /*0x258*/ { "CMSG_AUCTION_LIST_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListItems },
+ /*0x259*/ { "CMSG_AUCTION_LIST_OWNER_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListOwnerItems },
+ /*0x25A*/ { "CMSG_AUCTION_PLACE_BID", STATUS_LOGGEDIN, &WorldSession::HandleAuctionPlaceBid },
+ /*0x25B*/ { "SMSG_AUCTION_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x25C*/ { "SMSG_AUCTION_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x25D*/ { "SMSG_AUCTION_OWNER_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x25E*/ { "SMSG_AUCTION_BIDDER_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x25F*/ { "SMSG_AUCTION_OWNER_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x260*/ { "SMSG_PROCRESIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x261*/ { "SMSG_STANDSTATE_CHANGE_FAILURE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x262*/ { "SMSG_DISPEL_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x263*/ { "SMSG_SPELLORDAMAGE_IMMUNE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x264*/ { "CMSG_AUCTION_LIST_BIDDER_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListBidderItems },
+ /*0x265*/ { "SMSG_AUCTION_BIDDER_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x266*/ { "SMSG_SET_FLAT_SPELL_MODIFIER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x267*/ { "SMSG_SET_PCT_SPELL_MODIFIER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x268*/ { "CMSG_SET_AMMO", STATUS_LOGGEDIN, &WorldSession::HandleSetAmmoOpcode },
+ /*0x269*/ { "SMSG_CORPSE_RECLAIM_DELAY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x26A*/ { "CMSG_SET_ACTIVE_MOVER", STATUS_LOGGEDIN, &WorldSession::HandleSetActiveMoverOpcode },
+ /*0x26B*/ { "CMSG_PET_CANCEL_AURA", STATUS_LOGGEDIN, &WorldSession::HandlePetCancelAuraOpcode },
+ /*0x26C*/ { "CMSG_PLAYER_AI_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x26D*/ { "CMSG_CANCEL_AUTO_REPEAT_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleCancelAutoRepeatSpellOpcode},
+ /*0x26E*/ { "MSG_GM_ACCOUNT_ONLINE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x26F*/ { "MSG_LIST_STABLED_PETS", STATUS_LOGGEDIN, &WorldSession::HandleListStabledPetsOpcode },
+ /*0x270*/ { "CMSG_STABLE_PET", STATUS_LOGGEDIN, &WorldSession::HandleStablePet },
+ /*0x271*/ { "CMSG_UNSTABLE_PET", STATUS_LOGGEDIN, &WorldSession::HandleUnstablePet },
+ /*0x272*/ { "CMSG_BUY_STABLE_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyStableSlot },
+ /*0x273*/ { "SMSG_STABLE_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x274*/ { "CMSG_STABLE_REVIVE_PET", STATUS_LOGGEDIN, &WorldSession::HandleStableRevivePet },
+ /*0x275*/ { "CMSG_STABLE_SWAP_PET", STATUS_LOGGEDIN, &WorldSession::HandleStableSwapPet },
+ /*0x276*/ { "MSG_QUEST_PUSH_RESULT", STATUS_LOGGEDIN, &WorldSession::HandleQuestPushResult },
+ /*0x277*/ { "SMSG_PLAY_MUSIC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x278*/ { "SMSG_PLAY_OBJECT_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x279*/ { "CMSG_REQUEST_PET_INFO", STATUS_LOGGEDIN, &WorldSession::HandleRequestPetInfoOpcode },
+ /*0x27A*/ { "CMSG_FAR_SIGHT", STATUS_LOGGEDIN, &WorldSession::HandleFarSightOpcode },
+ /*0x27B*/ { "SMSG_SPELLDISPELLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x27C*/ { "SMSG_DAMAGE_CALC_LOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x27D*/ { "CMSG_ENABLE_DAMAGE_LOG", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x27E*/ { "CMSG_GROUP_CHANGE_SUB_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleGroupChangeSubGroupOpcode },
+ /*0x27F*/ { "CMSG_REQUEST_PARTY_MEMBER_STATS", STATUS_LOGGEDIN, &WorldSession::HandleRequestPartyMemberStatsOpcode},
+ /*0x280*/ { "CMSG_GROUP_SWAP_SUB_GROUP", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x281*/ { "CMSG_RESET_FACTION_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x282*/ { "CMSG_AUTOSTORE_BANK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBankItemOpcode },
+ /*0x283*/ { "CMSG_AUTOBANK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoBankItemOpcode },
+ /*0x284*/ { "MSG_QUERY_NEXT_MAIL_TIME", STATUS_LOGGEDIN, &WorldSession::HandleMsgQueryNextMailtime },
+ /*0x285*/ { "SMSG_RECEIVED_MAIL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x286*/ { "SMSG_RAID_GROUP_ONLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x287*/ { "CMSG_SET_DURABILITY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x288*/ { "CMSG_SET_PVP_RANK_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x289*/ { "CMSG_ADD_PVP_MEDAL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x28A*/ { "CMSG_DEL_PVP_MEDAL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x28B*/ { "CMSG_SET_PVP_TITLE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x28C*/ { "SMSG_PVP_CREDIT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x28D*/ { "SMSG_AUCTION_REMOVED_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x28E*/ { "CMSG_GROUP_RAID_CONVERT", STATUS_LOGGEDIN, &WorldSession::HandleRaidConvertOpcode },
+ /*0x28F*/ { "CMSG_GROUP_ASSISTANT_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGroupAssistantOpcode },
+ /*0x290*/ { "CMSG_BUYBACK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuybackItem },
+ /*0x291*/ { "SMSG_SERVER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x292*/ { "CMSG_MEETINGSTONE_JOIN", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x293*/ { "CMSG_MEETINGSTONE_LEAVE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x294*/ { "CMSG_MEETINGSTONE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x295*/ { "SMSG_MEETINGSTONE_SETQUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x296*/ { "CMSG_MEETINGSTONE_INFO", STATUS_LOGGEDIN, &WorldSession::HandleMeetingStoneInfo },
+ /*0x297*/ { "SMSG_MEETINGSTONE_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x298*/ { "SMSG_MEETINGSTONE_IN_PROGRESS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x299*/ { "SMSG_MEETINGSTONE_MEMBER_ADDED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x29A*/ { "CMSG_GMTICKETSYSTEM_TOGGLE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x29B*/ { "CMSG_CANCEL_GROWTH_AURA", STATUS_LOGGEDIN, &WorldSession::HandleCancelGrowthAuraOpcode },
+ /*0x29C*/ { "SMSG_CANCEL_AUTO_REPEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x29D*/ { "SMSG_STANDSTATE_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x29E*/ { "SMSG_LOOT_ALL_PASSED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x29F*/ { "SMSG_LOOT_ROLL_WON", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2A0*/ { "CMSG_LOOT_ROLL", STATUS_LOGGEDIN, &WorldSession::HandleLootRoll },
+ /*0x2A1*/ { "SMSG_LOOT_START_ROLL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2A2*/ { "SMSG_LOOT_ROLL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2A3*/ { "CMSG_LOOT_MASTER_GIVE", STATUS_LOGGEDIN, &WorldSession::HandleLootMasterGiveOpcode },
+ /*0x2A4*/ { "SMSG_LOOT_MASTER_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2A5*/ { "SMSG_SET_FORCED_REACTIONS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2A6*/ { "SMSG_SPELL_FAILED_OTHER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2A7*/ { "SMSG_GAMEOBJECT_RESET_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2A8*/ { "CMSG_REPAIR_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleRepairItemOpcode },
+ /*0x2A9*/ { "SMSG_CHAT_PLAYER_NOT_FOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2AA*/ { "MSG_TALENT_WIPE_CONFIRM", STATUS_LOGGEDIN, &WorldSession::HandleTalentWipeOpcode },
+ /*0x2AB*/ { "SMSG_SUMMON_REQUEST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2AC*/ { "CMSG_SUMMON_RESPONSE", STATUS_LOGGEDIN, &WorldSession::HandleSummonResponseOpcode },
+ /*0x2AD*/ { "MSG_MOVE_TOGGLE_GRAVITY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2AE*/ { "SMSG_MONSTER_MOVE_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2AF*/ { "SMSG_PET_BROKEN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2B0*/ { "MSG_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2B1*/ { "MSG_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2B2*/ { "CMSG_SERVER_BROADCAST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2B3*/ { "CMSG_SELF_RES", STATUS_LOGGEDIN, &WorldSession::HandleSelfResOpcode },
+ /*0x2B4*/ { "SMSG_FEIGN_DEATH_RESISTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2B5*/ { "CMSG_RUN_SCRIPT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2B6*/ { "SMSG_SCRIPT_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2B7*/ { "SMSG_DUEL_COUNTDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2B8*/ { "SMSG_AREA_TRIGGER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2B9*/ { "CMSG_SHOWING_HELM", STATUS_LOGGEDIN, &WorldSession::HandleToggleHelmOpcode },
+ /*0x2BA*/ { "CMSG_SHOWING_CLOAK", STATUS_LOGGEDIN, &WorldSession::HandleToggleCloakOpcode },
+ /*0x2BB*/ { "SMSG_MEETINGSTONE_JOINFAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2BC*/ { "SMSG_PLAYER_SKINNED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2BD*/ { "SMSG_DURABILITY_DAMAGE_DEATH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2BE*/ { "CMSG_SET_EXPLORATION", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2BF*/ { "CMSG_SET_ACTIONBAR_TOGGLES", STATUS_AUTHED, &WorldSession::HandleSetActionBar },
+ /*0x2C0*/ { "UMSG_DELETE_GUILD_CHARTER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2C1*/ { "MSG_PETITION_RENAME", STATUS_LOGGEDIN, &WorldSession::HandlePetitionRenameOpcode },
+ /*0x2C2*/ { "SMSG_INIT_WORLD_STATES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2C3*/ { "SMSG_UPDATE_WORLD_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2C4*/ { "CMSG_ITEM_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleItemNameQueryOpcode },
+ /*0x2C5*/ { "SMSG_ITEM_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2C6*/ { "SMSG_PET_ACTION_FEEDBACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2C7*/ { "CMSG_CHAR_RENAME", STATUS_AUTHED, &WorldSession::HandleChangePlayerNameOpcode },
+ /*0x2C8*/ { "SMSG_CHAR_RENAME", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2C9*/ { "CMSG_MOVE_SPLINE_DONE", STATUS_LOGGEDIN, &WorldSession::HandleTaxiNextDestinationOpcode },
+ /*0x2CA*/ { "CMSG_MOVE_FALL_RESET", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x2CB*/ { "SMSG_INSTANCE_SAVE_CREATED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2CC*/ { "SMSG_RAID_INSTANCE_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2CD*/ { "CMSG_REQUEST_RAID_INFO", STATUS_LOGGEDIN, &WorldSession::HandleRequestRaidInfoOpcode },
+ /*0x2CE*/ { "CMSG_MOVE_TIME_SKIPPED", STATUS_LOGGEDIN, &WorldSession::HandleMoveTimeSkippedOpcode },
+ /*0x2CF*/ { "CMSG_MOVE_FEATHER_FALL_ACK", STATUS_LOGGEDIN, &WorldSession::HandleFeatherFallAck },
+ /*0x2D0*/ { "CMSG_MOVE_WATER_WALK_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveWaterWalkAck },
+ /*0x2D1*/ { "CMSG_MOVE_NOT_ACTIVE_MOVER", STATUS_LOGGEDIN, &WorldSession::HandleMoveNotActiveMover },
+ /*0x2D2*/ { "SMSG_PLAY_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2D3*/ { "CMSG_BATTLEFIELD_STATUS", STATUS_LOGGEDIN, &WorldSession::HandleBattlefieldStatusOpcode },
+ /*0x2D4*/ { "SMSG_BATTLEFIELD_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2D5*/ { "CMSG_BATTLEFIELD_PORT", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPortOpcode},
+ /*0x2D6*/ { "MSG_INSPECT_HONOR_STATS", STATUS_LOGGEDIN, &WorldSession::HandleInspectHonorStatsOpcode },
+ /*0x2D7*/ { "CMSG_BATTLEMASTER_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundHelloOpcode },
+ /*0x2D8*/ { "CMSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2D9*/ { "CMSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2DA*/ { "SMSG_FORCE_WALK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2DB*/ { "CMSG_FORCE_WALK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
+ /*0x2DC*/ { "SMSG_FORCE_SWIM_BACK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2DD*/ { "CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
+ /*0x2DE*/ { "SMSG_FORCE_TURN_RATE_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2DF*/ { "CMSG_FORCE_TURN_RATE_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
+ /*0x2E0*/ { "MSG_PVP_LOG_DATA", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPVPlogdataOpcode},
+ /*0x2E1*/ { "CMSG_LEAVE_BATTLEFIELD", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundLeaveOpcode },
+ /*0x2E2*/ { "CMSG_AREA_SPIRIT_HEALER_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueryOpcode},
+ /*0x2E3*/ { "CMSG_AREA_SPIRIT_HEALER_QUEUE", STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueueOpcode},
+ /*0x2E4*/ { "SMSG_AREA_SPIRIT_HEALER_TIME", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2E5*/ { "CMSG_GM_UNTEACH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2E6*/ { "SMSG_WARDEN_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2E7*/ { "CMSG_WARDEN_DATA", STATUS_LOGGEDIN, &WorldSession::HandleWardenDataOpcode },
+ /*0x2E8*/ { "SMSG_GROUP_JOINED_BATTLEGROUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2E9*/ { "MSG_BATTLEGROUND_PLAYER_POSITIONS", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPositionsOpcode},
+ /*0x2EA*/ { "CMSG_PET_STOP_ATTACK", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2EB*/ { "SMSG_BINDER_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2EC*/ { "SMSG_BATTLEGROUND_PLAYER_JOINED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2ED*/ { "SMSG_BATTLEGROUND_PLAYER_LEFT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2EE*/ { "CMSG_BATTLEMASTER_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundJoinOpcode },
+ /*0x2EF*/ { "SMSG_ADDON_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2F0*/ { "CMSG_PET_UNLEARN", STATUS_LOGGEDIN, &WorldSession::HandlePetUnlearnOpcode },
+ /*0x2F1*/ { "SMSG_PET_UNLEARN_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2F2*/ { "SMSG_PARTY_MEMBER_STATS_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2F3*/ { "CMSG_PET_SPELL_AUTOCAST", STATUS_LOGGEDIN, &WorldSession::HandlePetSpellAutocastOpcode },
+ /*0x2F4*/ { "SMSG_WEATHER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2F5*/ { "SMSG_PLAY_TIME_WARNING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2F6*/ { "SMSG_MINIGAME_SETUP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2F7*/ { "SMSG_MINIGAME_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2F8*/ { "CMSG_MINIGAME_MOVE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2F9*/ { "SMSG_MINIGAME_MOVE_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2FA*/ { "SMSG_RAID_INSTANCE_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2FB*/ { "SMSG_COMPRESSED_MOVES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2FC*/ { "CMSG_GUILD_INFO_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildChangeInfoOpcode },
+ /*0x2FD*/ { "SMSG_CHAT_RESTRICTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2FE*/ { "SMSG_SPLINE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2FF*/ { "SMSG_SPLINE_SET_RUN_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x300*/ { "SMSG_SPLINE_SET_SWIM_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x301*/ { "SMSG_SPLINE_SET_WALK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x302*/ { "SMSG_SPLINE_SET_SWIM_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x303*/ { "SMSG_SPLINE_SET_TURN_RATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x304*/ { "SMSG_SPLINE_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x305*/ { "SMSG_SPLINE_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x306*/ { "SMSG_SPLINE_MOVE_NORMAL_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x307*/ { "SMSG_SPLINE_MOVE_SET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x308*/ { "SMSG_SPLINE_MOVE_UNSET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x309*/ { "SMSG_SPLINE_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x30A*/ { "SMSG_SPLINE_MOVE_LAND_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x30B*/ { "SMSG_SPLINE_MOVE_START_SWIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x30C*/ { "SMSG_SPLINE_MOVE_STOP_SWIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x30D*/ { "SMSG_SPLINE_MOVE_SET_RUN_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x30E*/ { "SMSG_SPLINE_MOVE_SET_WALK_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x30F*/ { "CMSG_GM_NUKE_ACCOUNT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x310*/ { "MSG_GM_DESTROY_CORPSE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x311*/ { "CMSG_GM_DESTROY_ONLINE_CORPSE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x312*/ { "CMSG_ACTIVATETAXIEXPRESS", STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiFarOpcode },
+ /*0x313*/ { "SMSG_SET_FACTION_ATWAR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x314*/ { "SMSG_GAMETIMEBIAS_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x315*/ { "CMSG_DEBUG_ACTIONS_START", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x316*/ { "CMSG_DEBUG_ACTIONS_STOP", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x317*/ { "CMSG_SET_FACTION_INACTIVE", STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionInactiveOpcode},
+ /*0x318*/ { "CMSG_SET_WATCHED_FACTION", STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionIndexOpcode},
+ /*0x319*/ { "MSG_MOVE_TIME_SKIPPED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x31A*/ { "SMSG_SPLINE_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x31B*/ { "CMSG_SET_EXPLORATION_ALL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x31C*/ { "SMSG_INVALIDATE_PLAYER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x31D*/ { "CMSG_RESET_INSTANCES", STATUS_LOGGEDIN, &WorldSession::HandleResetInstancesOpcode },
+ /*0x31E*/ { "SMSG_INSTANCE_RESET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x31F*/ { "SMSG_INSTANCE_RESET_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x320*/ { "SMSG_UPDATE_LAST_INSTANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x321*/ { "MSG_RAID_TARGET_UPDATE", STATUS_LOGGEDIN, &WorldSession::HandleRaidIconTargetOpcode },
+ /*0x322*/ { "MSG_RAID_READY_CHECK", STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckOpcode },
+ /*0x323*/ { "CMSG_LUA_USAGE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x324*/ { "SMSG_PET_ACTION_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x325*/ { "SMSG_PET_DISMISS_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x326*/ { "SMSG_GHOSTEE_GONE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x327*/ { "CMSG_GM_UPDATE_TICKET_STATUS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x328*/ { "SMSG_GM_TICKET_STATUS_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x329*/ { "MSG_SET_DUNGEON_DIFFICULTY", STATUS_LOGGEDIN, &WorldSession::HandleDungeonDifficultyOpcode },
+ /*0x32A*/ { "CMSG_GMSURVEY_SUBMIT", STATUS_NEVER, &WorldSession::Handle_NULL },//LOGGEDIN, &WorldSession::HandleGMSurveySubmit },
+ /*0x32B*/ { "SMSG_UPDATE_INSTANCE_OWNERSHIP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x32C*/ { "CMSG_IGNORE_KNOCKBACK_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x32D*/ { "SMSG_CHAT_PLAYER_AMBIGUOUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x32E*/ { "MSG_DELAY_GHOST_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x32F*/ { "SMSG_SPELLINSTAKILLLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x330*/ { "SMSG_SPELL_UPDATE_CHAIN_TARGETS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x331*/ { "CMSG_CHAT_FILTERED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x332*/ { "SMSG_EXPECTED_SPAM_RECORDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x333*/ { "SMSG_SPELLSTEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x334*/ { "CMSG_LOTTERY_QUERY_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x335*/ { "SMSG_LOTTERY_QUERY_RESULT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x336*/ { "CMSG_BUY_LOTTERY_TICKET_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x337*/ { "SMSG_LOTTERY_RESULT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x338*/ { "SMSG_CHARACTER_PROFILE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x339*/ { "SMSG_CHARACTER_PROFILE_REALM_CONNECTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x33A*/ { "SMSG_DEFENSE_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x33B*/ { "SMSG_INSTANCE_DIFFICULTY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x33C*/ { "MSG_GM_RESETINSTANCELIMIT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x33D*/ { "SMSG_MOTD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x33E*/ { "SMSG_MOVE_SET_FLIGHT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x33F*/ { "SMSG_MOVE_UNSET_FLIGHT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x340*/ { "CMSG_MOVE_FLIGHT_ACK_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x341*/ { "MSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x342*/ { "MSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x343*/ { "SMSG_MOVE_SET_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x344*/ { "SMSG_MOVE_UNSET_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x345*/ { "CMSG_MOVE_SET_CAN_FLY_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveFlyModeChangeAckOpcode},
+ /*0x346*/ { "CMSG_MOVE_SET_FLY", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x347*/ { "CMSG_SOCKET_GEMS", STATUS_LOGGEDIN, &WorldSession::HandleSocketOpcode },
+ /*0x348*/ { "CMSG_ARENA_TEAM_CREATE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x349*/ { "SMSG_ARENA_TEAM_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x34A*/ { "UMSG_UPDATE_ARENA_TEAM_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x34B*/ { "CMSG_ARENA_TEAM_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamQueryOpcode },
+ /*0x34C*/ { "SMSG_ARENA_TEAM_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x34D*/ { "CMSG_ARENA_TEAM_ROSTER", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRosterOpcode },
+ /*0x34E*/ { "SMSG_ARENA_TEAM_ROSTER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x34F*/ { "CMSG_ARENA_TEAM_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamAddMemberOpcode },
+ /*0x350*/ { "SMSG_ARENA_TEAM_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x351*/ { "CMSG_ARENA_TEAM_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteAcceptOpcode},
+ /*0x352*/ { "CMSG_ARENA_TEAM_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteDeclineOpcode},
+ /*0x353*/ { "CMSG_ARENA_TEAM_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamLeaveOpcode },
+ /*0x354*/ { "CMSG_ARENA_TEAM_REMOVE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRemoveFromTeamOpcode},
+ /*0x355*/ { "CMSG_ARENA_TEAM_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamDisbandOpcode },
+ /*0x356*/ { "CMSG_ARENA_TEAM_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamPromoteToCaptainOpcode},
+ /*0x357*/ { "SMSG_ARENA_TEAM_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x358*/ { "CMSG_BATTLEMASTER_JOIN_ARENA", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundArenaJoin },
+ /*0x359*/ { "MSG_MOVE_START_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x35A*/ { "MSG_MOVE_STOP_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x35B*/ { "SMSG_ARENA_TEAM_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x35C*/ { "CMSG_LFG_SET_AUTOJOIN", STATUS_AUTHED, &WorldSession::HandleLfgAutoJoinOpcode },
+ /*0x35D*/ { "CMSG_LFG_CLEAR_AUTOJOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfgCancelAutoJoinOpcode },
+ /*0x35E*/ { "CMSG_LFM_SET_AUTOFILL", STATUS_AUTHED, &WorldSession::HandleLfmAutoAddMembersOpcode },
+ /*0x35F*/ { "CMSG_LFM_CLEAR_AUTOFILL", STATUS_LOGGEDIN, &WorldSession::HandleLfmCancelAutoAddmembersOpcode},
+ /*0x360*/ { "CMSG_ACCEPT_LFG_MATCH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x361*/ { "CMSG_DECLINE_LFG_MATCH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x362*/ { "CMSG_CANCEL_PENDING_LFG", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x363*/ { "CMSG_CLEAR_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleLfgClearOpcode },
+ /*0x364*/ { "CMSG_CLEAR_LOOKING_FOR_MORE", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetNoneOpcode },
+ /*0x365*/ { "CMSG_SET_LOOKING_FOR_MORE", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetOpcode },
+ /*0x366*/ { "CMSG_SET_LFG_COMMENT", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetCommentOpcode },
+ /*0x367*/ { "SMSG_LFG_TIMEDOUT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x368*/ { "SMSG_LFG_OTHER_TIMEDOUT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x369*/ { "SMSG_LFG_AUTOJOIN_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x36A*/ { "SMSG_LFG_AUTOJOIN_FAILED_NO_PLAYER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x36B*/ { "SMSG_LFG_LEADER_IS_LFM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x36C*/ { "SMSG_LFG_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x36D*/ { "SMSG_LFG_UPDATE_LFM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x36E*/ { "SMSG_LFG_UPDATE_LFG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x36F*/ { "SMSG_LFG_UPDATE_QUEUED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x370*/ { "SMSG_LFG_PENDING_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x371*/ { "SMSG_LFG_PENDING_MATCH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x372*/ { "SMSG_LFG_PENDING_MATCH_DONE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x373*/ { "SMSG_TITLE_EARNED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x374*/ { "CMSG_SET_TITLE", STATUS_LOGGEDIN, &WorldSession::HandleChooseTitleOpcode },
+ /*0x375*/ { "CMSG_CANCEL_MOUNT_AURA", STATUS_LOGGEDIN, &WorldSession::HandleDismountOpcode },
+ /*0x376*/ { "SMSG_ARENA_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x377*/ { "MSG_INSPECT_ARENA_TEAMS", STATUS_LOGGEDIN, &WorldSession::HandleInspectArenaStatsOpcode },
+ /*0x378*/ { "SMSG_DEATH_RELEASE_LOC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x379*/ { "CMSG_CANCEL_TEMP_ENCHANTMENT", STATUS_LOGGEDIN, &WorldSession::HandleCancelTempItemEnchantmentOpcode},
+ /*0x37A*/ { "SMSG_FORCED_DEATH_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x37B*/ { "CMSG_CHEAT_SET_HONOR_CURRENCY", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x37C*/ { "CMSG_CHEAT_SET_ARENA_CURRENCY", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x37D*/ { "MSG_MOVE_SET_FLIGHT_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x37E*/ { "MSG_MOVE_SET_FLIGHT_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x37F*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x380*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x381*/ { "SMSG_FORCE_FLIGHT_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x382*/ { "CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
+ /*0x383*/ { "SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x384*/ { "CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
+ /*0x385*/ { "SMSG_SPLINE_SET_FLIGHT_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x386*/ { "SMSG_SPLINE_SET_FLIGHT_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x387*/ { "CMSG_MAELSTROM_INVALIDATE_CACHE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x388*/ { "SMSG_FLIGHT_SPLINE_SYNC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x389*/ { "CMSG_SET_TAXI_BENCHMARK_MODE", STATUS_AUTHED, &WorldSession::HandleSetTaxiBenchmarkOpcode },
+ /*0x38A*/ { "SMSG_JOINED_BATTLEGROUND_QUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x38B*/ { "SMSG_REALM_SPLIT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x38C*/ { "CMSG_REALM_SPLIT", STATUS_AUTHED, &WorldSession::HandleRealmStateRequestOpcode },
+ /*0x38D*/ { "CMSG_MOVE_CHNG_TRANSPORT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x38E*/ { "MSG_PARTY_ASSIGNMENT", STATUS_LOGGEDIN, &WorldSession::HandleGroupPromoteOpcode },
+ /*0x38F*/ { "SMSG_OFFER_PETITION_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x390*/ { "SMSG_TIME_SYNC_REQ", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x391*/ { "CMSG_TIME_SYNC_RESP", STATUS_LOGGEDIN, &WorldSession::HandleTimeSyncResp },
+ /*0x392*/ { "CMSG_SEND_LOCAL_EVENT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x393*/ { "CMSG_SEND_GENERAL_TRIGGER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x394*/ { "CMSG_SEND_COMBAT_TRIGGER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x395*/ { "CMSG_MAELSTROM_GM_SENT_MAIL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x396*/ { "SMSG_RESET_FAILED_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x397*/ { "SMSG_REAL_GROUP_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x398*/ { "SMSG_LFG_DISABLED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x399*/ { "CMSG_ACTIVE_PVP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x39A*/ { "CMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x39B*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x39C*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE_WRITE_FILE",STATUS_NEVER,&WorldSession::Handle_ServerSide },
+ /*0x39D*/ { "SMSG_UPDATE_COMBO_POINTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x39E*/ { "SMSG_VOICE_SESSION_ROSTER_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x39F*/ { "SMSG_VOICE_SESSION_LEAVE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3A0*/ { "SMSG_VOICE_SESSION_ADJUST_PRIORITY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3A1*/ { "CMSG_VOICE_SET_TALKER_MUTED_REQUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3A2*/ { "SMSG_VOICE_SET_TALKER_MUTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3A3*/ { "SMSG_INIT_EXTRA_AURA_INFO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3A4*/ { "SMSG_SET_EXTRA_AURA_INFO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3A5*/ { "SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3A6*/ { "SMSG_CLEAR_EXTRA_AURA_INFO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3A7*/ { "MSG_MOVE_START_DESCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x3A8*/ { "CMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3A9*/ { "SMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3AA*/ { "SMSG_SPELL_CHANCE_PROC_LOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3AB*/ { "CMSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3AC*/ { "SMSG_DISMOUNT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3AD*/ { "MSG_MOVE_UPDATE_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3AE*/ { "MSG_RAID_READY_CHECK_CONFIRM", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3AF*/ { "CMSG_VOICE_SESSION_ENABLE", STATUS_AUTHED, &WorldSession::HandleVoiceSettingsOpcode },
+ /*0x3B0*/ { "SMSG_VOICE_SESSION_ENABLE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3B1*/ { "SMSG_VOICE_PARENTAL_CONTROLS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3B2*/ { "CMSG_GM_WHISPER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3B3*/ { "SMSG_GM_MESSAGECHAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3B4*/ { "MSG_GM_GEARRATING", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3B5*/ { "CMSG_COMMENTATOR_ENABLE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3B6*/ { "SMSG_COMMENTATOR_STATE_CHANGED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3B7*/ { "CMSG_COMMENTATOR_GET_MAP_INFO", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3B8*/ { "SMSG_COMMENTATOR_MAP_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3B9*/ { "CMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3BA*/ { "SMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3BB*/ { "SMSG_COMMENTATOR_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3BC*/ { "CMSG_COMMENTATOR_ENTER_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3BD*/ { "CMSG_COMMENTATOR_EXIT_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3BE*/ { "CMSG_COMMENTATOR_INSTANCE_COMMAND", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3BF*/ { "SMSG_CLEAR_TARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3C0*/ { "CMSG_BOT_DETECTED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3C1*/ { "SMSG_CROSSED_INEBRIATION_THRESHOLD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3C2*/ { "CMSG_CHEAT_PLAYER_LOGIN", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3C3*/ { "CMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3C4*/ { "SMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3C5*/ { "SMSG_KICK_REASON", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3C6*/ { "MSG_RAID_READY_CHECK_FINISHED", STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckFinishOpcode},
+ /*0x3C7*/ { "CMSG_COMPLAIN", STATUS_LOGGEDIN, &WorldSession::HandleReportSpamOpcode },
+ /*0x3C8*/ { "SMSG_COMPLAIN_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3C9*/ { "SMSG_FEATURE_SYSTEM_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3CA*/ { "CMSG_GM_SHOW_COMPLAINTS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3CB*/ { "CMSG_GM_UNSQUELCH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3CC*/ { "CMSG_CHANNEL_SILENCE_VOICE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3CD*/ { "CMSG_CHANNEL_SILENCE_ALL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3CE*/ { "CMSG_CHANNEL_UNSILENCE_VOICE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3CF*/ { "CMSG_CHANNEL_UNSILENCE_ALL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3D0*/ { "CMSG_TARGET_CAST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3D1*/ { "CMSG_TARGET_SCRIPT_CAST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3D2*/ { "CMSG_CHANNEL_DISPLAY_LIST", STATUS_LOGGEDIN, &WorldSession::HandleChannelRosterQuery },
+ /*0x3D3*/ { "CMSG_SET_ACTIVE_VOICE_CHANNEL", STATUS_AUTHED, &WorldSession::HandleChannelVoiceChatQuery },
+ /*0x3D4*/ { "CMSG_GET_CHANNEL_MEMBER_COUNT", STATUS_LOGGEDIN, &WorldSession::HandleChannelInfoQuery },
+ /*0x3D5*/ { "SMSG_CHANNEL_MEMBER_COUNT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3D6*/ { "CMSG_CHANNEL_VOICE_ON", STATUS_LOGGEDIN, &WorldSession::HandleChannelEnableVoiceOpcode },
+ /*0x3D7*/ { "CMSG_CHANNEL_VOICE_OFF", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3D8*/ { "CMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3D9*/ { "SMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3DA*/ { "SMSG_AVAILABLE_VOICE_CHANNEL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3DB*/ { "CMSG_ADD_VOICE_IGNORE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3DC*/ { "CMSG_DEL_VOICE_IGNORE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3DD*/ { "CMSG_PARTY_SILENCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3DE*/ { "CMSG_PARTY_UNSILENCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3DF*/ { "MSG_NOTIFY_PARTY_SQUELCH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3E0*/ { "SMSG_COMSAT_RECONNECT_TRY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3E1*/ { "SMSG_COMSAT_DISCONNECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3E2*/ { "SMSG_COMSAT_CONNECT_FAIL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3E3*/ { "SMSG_VOICE_CHAT_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3E4*/ { "CMSG_REPORT_PVP_AFK", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundReportAFK },
+ /*0x3E5*/ { "CMSG_REPORT_PVP_AFK_RESULT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3E6*/ { "CMSG_GUILD_BANKER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankQuery },
+ /*0x3E7*/ { "CMSG_GUILD_BANK_QUERY_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabColon },
+ /*0x3E8*/ { "SMSG_GUILD_BANK_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3E9*/ { "CMSG_GUILD_BANK_SWAP_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDepositItem },
+ /*0x3EA*/ { "CMSG_GUILD_BANK_BUY_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankBuyTab },
+ /*0x3EB*/ { "CMSG_GUILD_BANK_UPDATE_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankModifyTab },
+ /*0x3EC*/ { "CMSG_GUILD_BANK_DEPOSIT_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDeposit },
+ /*0x3ED*/ { "CMSG_GUILD_BANK_WITHDRAW_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankWithdraw },
+ /*0x3EE*/ { "MSG_GUILD_BANK_LOG_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankLog },
+ /*0x3EF*/ { "CMSG_SET_CHANNEL_WATCH", STATUS_LOGGEDIN, &WorldSession::HandleChannelJoinNotify },
+ /*0x3F0*/ { "SMSG_USERLIST_ADD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3F1*/ { "SMSG_USERLIST_REMOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3F2*/ { "SMSG_USERLIST_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3F3*/ { "CMSG_CLEAR_CHANNEL_WATCH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3F4*/ { "SMSG_INSPECT_TALENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3F5*/ { "SMSG_GOGOGO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3F6*/ { "SMSG_ECHO_PARTY_SQUELCH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3F7*/ { "CMSG_SET_TITLE_SUFFIX", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3F8*/ { "CMSG_SPELLCLICK", STATUS_LOGGEDIN, &WorldSession::HandleSpellClick },
+ /*0x3F9*/ { "SMSG_LOOT_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3FA*/ { "CMSG_GM_CHARACTER_RESTORE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3FB*/ { "CMSG_GM_CHARACTER_SAVE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3FC*/ { "SMSG_VOICESESSION_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3FD*/ { "MSG_GUILD_PERMISSIONS", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetRights },
+ /*0x3FE*/ { "MSG_GUILD_BANK_MONEY_WITHDRAWN", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetMoneyAmount },
+ /*0x3FF*/ { "MSG_GUILD_EVENT_LOG_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGuildEventLogOpcode },
+ /*0x400*/ { "CMSG_MAELSTROM_RENAME_GUILD", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x401*/ { "CMSG_GET_MIRRORIMAGE_DATA", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x402*/ { "SMSG_MIRRORIMAGE_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x403*/ { "SMSG_FORCE_DISPLAY_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x404*/ { "SMSG_SPELL_CHANCE_RESIST_PUSHBACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x405*/ { "CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x406*/ { "SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x407*/ { "CMSG_KEEP_ALIVE", STATUS_NEVER, &WorldSession::Handle_EarlyProccess },
+ /*0x408*/ { "SMSG_RAID_READY_CHECK_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x409*/ { "CMSG_OPT_OUT_OF_LOOT", STATUS_AUTHED, &WorldSession::HandleGroupPassOnLootOpcode },
+ /*0x40A*/ { "MSG_QUERY_GUILD_BANK_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabText },
+ /*0x40B*/ { "CMSG_SET_GUILD_BANK_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankSetTabText },
+ /*0x40C*/ { "CMSG_SET_GRANTABLE_LEVELS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x40D*/ { "CMSG_GRANT_LEVEL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x40E*/ { "CMSG_REFER_A_FRIEND", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x40F*/ { "CMSG_DECLINE_CHANNEL_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleChannelDeclineInvite },
+ /*0x410*/ { "CMSG_DECLINE_CHANNEL_INVITE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x411*/ { "CMSG_GROUPACTION_THROTTLED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x412*/ { "SMSG_OVERRIDE_LIGHT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x413*/ { "SMSG_TOTEM_CREATED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x414*/ { "CMSG_TOTEM_DESTROYED", STATUS_LOGGEDIN, &WorldSession::HandleTotemDestroy },
+ /*0x415*/ { "CMSG_EXPIRE_RAID_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x416*/ { "CMSG_NO_SPELL_VARIANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x417*/ { "CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverStatusQueryMultipleOpcode},
+ /*0x418*/ { "SMSG_QUESTGIVER_STATUS_MULTIPLE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x419*/ { "CMSG_SET_PLAYER_DECLINED_NAMES", STATUS_AUTHED, &WorldSession::HandleDeclinedPlayerNameOpcode },
+ /*0x41A*/ { "SMSG_SET_PLAYER_DECLINED_NAMES_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x41B*/ { "CMSG_QUERY_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x41C*/ { "CMSG_CLEAR_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x41D*/ { "SMSG_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x41E*/ { "SMSG_SEND_UNLEARN_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x41F*/ { "SMSG_PROPOSE_LEVEL_GRANT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x420*/ { "CMSG_ACCEPT_LEVEL_GRANT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x421*/ { "SMSG_REFER_A_FRIEND_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x422*/ { "SMSG_SPLINE_MOVE_SET_FLYING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x423*/ { "SMSG_SPLINE_MOVE_UNSET_FLYING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x424*/ { "SMSG_SUMMON_CANCEL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x425*/ { "CMSG_CHANGE_PERSONAL_ARENA_RATING", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x426*/ { "CMSG_ALTER_APPEARANCE", STATUS_LOGGEDIN, &WorldSession::HandleAlterAppearance },
+ /*0x427*/ { "SMSG_ENABLE_BARBER_SHOP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x428*/ { "SMSG_BARBER_SHOP_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x429*/ { "CMSG_CALENDAR_GET_CALENDAR", STATUS_LOGGEDIN, &WorldSession::HandleCalendarGetCalendar },
+ /*0x42A*/ { "CMSG_CALENDAR_GET_EVENT", STATUS_LOGGEDIN, &WorldSession::HandleCalendarGetEvent },
+ /*0x42B*/ { "CMSG_CALENDAR_GUILD_FILTER", STATUS_LOGGEDIN, &WorldSession::HandleCalendarGuildFilter },
+ /*0x42C*/ { "CMSG_CALENDAR_ARENA_TEAM", STATUS_LOGGEDIN, &WorldSession::HandleCalendarArenaTeam },
+ /*0x42D*/ { "CMSG_CALENDAR_ADD_EVENT", STATUS_LOGGEDIN, &WorldSession::HandleCalendarAddEvent },
+ /*0x42E*/ { "CMSG_CALENDAR_UPDATE_EVENT", STATUS_LOGGEDIN, &WorldSession::HandleCalendarUpdateEvent },
+ /*0x42F*/ { "CMSG_CALENDAR_REMOVE_EVENT", STATUS_LOGGEDIN, &WorldSession::HandleCalendarRemoveEvent },
+ /*0x430*/ { "CMSG_CALENDAR_COPY_EVENT", STATUS_LOGGEDIN, &WorldSession::HandleCalendarCopyEvent },
+ /*0x431*/ { "CMSG_CALENDAR_EVENT_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventInvite },
+ /*0x432*/ { "CMSG_CALENDAR_EVENT_RSVP", STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventRsvp },
+ /*0x433*/ { "CMSG_CALENDAR_EVENT_REMOVE_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventRemoveInvite },
+ /*0x434*/ { "CMSG_CALENDAR_EVENT_STATUS", STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventStatus },
+ /*0x435*/ { "CMSG_CALENDAR_EVENT_MODERATOR_STATUS", STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventModeratorStatus},
+ /*0x436*/ { "SMSG_CALENDAR_SEND_CALENDAR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x437*/ { "SMSG_CALENDAR_SEND_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x438*/ { "SMSG_CALENDAR_FILTER_GUILD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x439*/ { "SMSG_CALENDAR_ARENA_TEAM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x43A*/ { "SMSG_CALENDAR_EVENT_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x43B*/ { "SMSG_CALENDAR_EVENT_INVITE_REMOVED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x43C*/ { "SMSG_CALENDAR_EVENT_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x43D*/ { "SMSG_CALENDAR_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x43E*/ { "SMSG_CALENDAR_RAID_LOCKOUT_ADDED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x43F*/ { "SMSG_CALENDAR_RAID_LOCKOUT_REMOVED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x440*/ { "SMSG_CALENDAR_EVENT_INVITE_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x441*/ { "SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x442*/ { "SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x443*/ { "SMSG_CALENDAR_EVENT_REMOVED_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x444*/ { "SMSG_CALENDAR_EVENT_UPDATED_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x445*/ { "SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x446*/ { "CMSG_CALENDAR_COMPLAIN", STATUS_LOGGEDIN, &WorldSession::HandleCalendarComplain },
+ /*0x447*/ { "CMSG_CALENDAR_GET_NUM_PENDING", STATUS_LOGGEDIN, &WorldSession::HandleCalendarGetNumPending },
+ /*0x448*/ { "SMSG_CALENDAR_SEND_NUM_PENDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x449*/ { "CMSG_SAVE_DANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x44A*/ { "SMSG_NOTIFY_DANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x44B*/ { "CMSG_PLAY_DANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x44C*/ { "SMSG_PLAY_DANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x44D*/ { "CMSG_LOAD_DANCES", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x44E*/ { "CMSG_STOP_DANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x44F*/ { "SMSG_STOP_DANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x450*/ { "CMSG_SYNC_DANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x451*/ { "CMSG_DANCE_QUERY", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x452*/ { "SMSG_DANCE_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x453*/ { "SMSG_INVALIDATE_DANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x454*/ { "CMSG_DELETE_DANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x455*/ { "SMSG_LEARNED_DANCE_MOVES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x456*/ { "CMSG_LEARN_DANCE_MOVE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x457*/ { "CMSG_UNLEARN_DANCE_MOVE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x458*/ { "CMSG_SET_RUNE_COUNT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x459*/ { "CMSG_SET_RUNE_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x45A*/ { "MSG_MOVE_SET_PITCH_RATE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x45B*/ { "MSG_MOVE_SET_PITCH_RATE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x45C*/ { "SMSG_FORCE_PITCH_RATE_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x45D*/ { "CMSG_FORCE_PITCH_RATE_CHANGE_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x45E*/ { "SMSG_SPLINE_SET_PITCH_RATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x45F*/ { "SMSG_MOVE_ABANDON_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x460*/ { "MSG_MOVE_ABANDON_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x461*/ { "CMSG_MOVE_ABANDON_TRANSPORT_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x462*/ { "CMSG_UPDATE_MISSILE_TRAJECTORY", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x463*/ { "SMSG_UPDATE_ACCOUNT_DATA_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x464*/ { "SMSG_TRIGGER_MOVIE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x465*/ { "CMSG_COMPLETE_MOVIE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x466*/ { "CMSG_SET_GLYPH_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x467*/ { "CMSG_SET_GLYPH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x468*/ { "SMSG_ACHIEVEMENT_EARNED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x469*/ { "SMSG_DYNAMIC_DROP_ROLL_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x46A*/ { "SMSG_CRITERIA_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x46B*/ { "CMSG_QUERY_INSPECT_ACHIEVEMENTS", STATUS_LOGGEDIN, &WorldSession::HandleInspectAchievements },
+ /*0x46C*/ { "SMSG_RESPOND_INSPECT_ACHIEVEMENTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x46D*/ { "CMSG_DISMISS_CONTROLLED_VEHICLE", STATUS_LOGGEDIN, &WorldSession::HandleDismissControlledVehicle },
+ /*0x46E*/ { "CMSG_COMPLETE_ACHIEVEMENT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x46F*/ { "SMSG_QUESTUPDATE_ADD_PVP_KILL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x470*/ { "CMSG_SET_CRITERIA_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x471*/ { "SMSG_GROUP_SWAP_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x472*/ { "CMSG_UNITANIMTIER_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x473*/ { "CMSG_CHAR_CUSTOMIZE", STATUS_AUTHED, &WorldSession::HandleCharCustomize },
+ /*0x474*/ { "SMSG_CHAR_CUSTOMIZE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x475*/ { "SMSG_PET_RENAMEABLE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x476*/ { "CMSG_REQUEST_VEHICLE_EXIT", STATUS_LOGGEDIN, &WorldSession::HandleRequestVehicleExit },
+ /*0x477*/ { "CMSG_REQUEST_VEHICLE_PREV_SEAT", STATUS_LOGGEDIN, &WorldSession::HandleChangeSeatsOnControlledVehicle},
+ /*0x478*/ { "CMSG_REQUEST_VEHICLE_NEXT_SEAT", STATUS_LOGGEDIN, &WorldSession::HandleChangeSeatsOnControlledVehicle},
+ /*0x479*/ { "CMSG_REQUEST_VEHICLE_SWITCH_SEAT", STATUS_LOGGEDIN, &WorldSession::HandleChangeSeatsOnControlledVehicle},
+ /*0x47A*/ { "CMSG_PET_LEARN_TALENT", STATUS_LOGGEDIN, &WorldSession::HandlePetLearnTalent },
+ /*0x47B*/ { "CMSG_PET_UNLEARN_TALENTS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x47C*/ { "SMSG_SET_PHASE_SHIFT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x47D*/ { "SMSG_ALL_ACHIEVEMENT_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x47E*/ { "CMSG_FORCE_SAY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x47F*/ { "SMSG_HEALTH_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x480*/ { "SMSG_POWER_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x481*/ { "CMSG_GAMEOBJ_REPORT_USE", STATUS_LOGGEDIN, &WorldSession::HandleGameobjectReportUse },
+ /*0x482*/ { "SMSG_HIGHEST_THREAT_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x483*/ { "SMSG_THREAT_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x484*/ { "SMSG_THREAT_REMOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x485*/ { "SMSG_THREAT_CLEAR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x486*/ { "SMSG_CONVERT_RUNE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x487*/ { "SMSG_RESYNC_RUNES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x488*/ { "SMSG_ADD_RUNE_POWER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x489*/ { "CMSG_START_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x48A*/ { "CMSG_REMOVE_GLYPH", STATUS_LOGGEDIN, &WorldSession::HandleRemoveGlyph },
+ /*0x48B*/ { "CMSG_DUMP_OBJECTS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x48C*/ { "SMSG_DUMP_OBJECTS_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x48D*/ { "CMSG_DISMISS_CRITTER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x48E*/ { "SMSG_NOTIFY_DEST_LOC_SPELL_CAST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x48F*/ { "CMSG_AUCTION_LIST_PENDING_SALES", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListPendingSales },
+ /*0x490*/ { "SMSG_AUCTION_LIST_PENDING_SALES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x491*/ { "SMSG_MODIFY_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x492*/ { "SMSG_PET_UPDATE_COMBO_POINTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x493*/ { "CMSG_ENABLETAXI", STATUS_LOGGEDIN, &WorldSession::HandleTaxiQueryAvailableNodes },
+ /*0x494*/ { "SMSG_PRE_RESURRECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x495*/ { "SMSG_AURA_UPDATE_ALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x496*/ { "SMSG_AURA_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x497*/ { "CMSG_FLOOD_GRACE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x498*/ { "SMSG_SERVER_FIRST_ACHIEVEMENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x499*/ { "SMSG_PET_LEARNED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x49A*/ { "SMSG_PET_REMOVED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x49B*/ { "CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE", STATUS_LOGGEDIN, &WorldSession::HandleChangeSeatsOnControlledVehicle},
+ /*0x49C*/ { "CMSG_HEARTH_AND_RESURRECT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x49D*/ { "SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x49E*/ { "SMSG_CRITERIA_DELETED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x49F*/ { "SMSG_ACHIEVEMENT_DELETED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4A0*/ { "CMSG_SERVER_INFO_QUERY", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4A1*/ { "SMSG_SERVER_INFO_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4A2*/ { "CMSG_CHECK_LOGIN_CRITERIA", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4A3*/ { "SMSG_SERVER_BUCK_DATA_START", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4A4*/ { "CMSG_QUERY_VEHICLE_STATUS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4A5*/ { "SMSG_PET_GUIDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4A6*/ { "SMSG_CLIENTCACHE_VERSION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4A7*/ { "UMSG_UNKNOWN_1191", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4A8*/ { "UMSG_UNKNOWN_1192", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4A9*/ { "UMSG_UNKNOWN_1193", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4AA*/ { "UMSG_UNKNOWN_1194", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4AB*/ { "UMSG_UNKNOWN_1195", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4AC*/ { "UMSG_UNKNOWN_1196", STATUS_NEVER, &WorldSession::Handle_NULL },
};
diff --git a/src/game/Opcodes.h b/src/game/Opcodes.h
index 12f9c9459fa..d57cfd62852 100644
--- a/src/game/Opcodes.h
+++ b/src/game/Opcodes.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -49,8 +49,8 @@ enum Opcodes
CMSG_ZONE_MAP = 0x00A,
SMSG_ZONE_MAP = 0x00B,
CMSG_DEBUG_CHANGECELLZONE = 0x00C,
- CMSG_EMBLAZON_TABARD_OBSOLETE = 0x00D,
- CMSG_UNEMBLAZON_TABARD_OBSOLETE = 0x00E,
+ CMSG_MOVE_CHARACTER_CHEAT = 0x00D,
+ SMSG_MOVE_CHARACTER_CHEAT = 0x00E,
CMSG_RECHARGE = 0x00F,
CMSG_LEARN_SPELL = 0x010,
CMSG_CREATEMONSTER = 0x011,
@@ -66,7 +66,7 @@ enum Opcodes
SMSG_FORCEACTIONSHOW = 0x01B,
CMSG_PETGODMODE = 0x01C,
SMSG_PETGODMODE = 0x01D,
- SMSG_DEBUGINFOSPELLMISS_OBSOLETE = 0x01E,
+ SMSG_REFER_A_FRIEND_EXPIRED = 0x01E,
CMSG_WEATHER_SPEED_CHEAT = 0x01F,
CMSG_UNDRESSPLAYER = 0x020,
CMSG_BEASTMASTER = 0x021,
@@ -86,7 +86,7 @@ enum Opcodes
SMSG_DEBUG_AISTATE = 0x02F,
CMSG_DISABLE_PVP_CHEAT = 0x030,
CMSG_ADVANCE_SPAWN_TIME = 0x031,
- CMSG_PVP_PORT_OBSOLETE = 0x032,
+ SMSG_DESTRUCTIBLE_BUILDING_DAMAGE = 0x032,
CMSG_AUTH_SRP6_BEGIN = 0x033,
CMSG_AUTH_SRP6_PROOF = 0x034,
CMSG_AUTH_SRP6_RECODE = 0x035,
@@ -214,7 +214,7 @@ enum Opcodes
SMSG_READ_ITEM_FAILED = 0x0AF,
SMSG_ITEM_COOLDOWN = 0x0B0,
CMSG_GAMEOBJ_USE = 0x0B1,
- CMSG_GAMEOBJ_CHAIR_USE_OBSOLETE = 0x0B2,
+ CMSG_DESTROY_ITEMS = 0x0B2,
SMSG_GAMEOBJECT_CUSTOM_ANIM = 0x0B3,
CMSG_AREATRIGGER = 0x0B4,
MSG_MOVE_START_FORWARD = 0x0B5,
@@ -347,7 +347,7 @@ enum Opcodes
SMSG_SPELL_COOLDOWN = 0x134,
SMSG_COOLDOWN_EVENT = 0x135,
CMSG_CANCEL_AURA = 0x136,
- SMSG_UPDATE_AURA_DURATION = 0x137,
+ SMSG_UPDATE_AURA_DURATION_OBSOLETE = 0x137,
SMSG_PET_CAST_FAILED = 0x138,
MSG_CHANNEL_START = 0x139,
MSG_CHANNEL_UPDATE = 0x13A,
@@ -371,10 +371,10 @@ enum Opcodes
SMSG_DAMAGE_DONE_OBSOLETE = 0x14C,
SMSG_DAMAGE_TAKEN_OBSOLETE = 0x14D,
SMSG_CANCEL_COMBAT = 0x14E,
- SMSG_PLAYER_COMBAT_XP_GAIN_OBSOLETE = 0x14F,
+ SMSG_SPELLBREAKLOG = 0x14F,
SMSG_SPELLHEALLOG = 0x150,
SMSG_SPELLENERGIZELOG = 0x151,
- CMSG_SHEATHE_OBSOLETE = 0x152,
+ SMSG_BREAK_TARGET = 0x152,
CMSG_SAVE_PLAYER = 0x153,
CMSG_SETDEATHBINDPOINT = 0x154,
SMSG_BINDPOINTUPDATE = 0x155,
@@ -578,7 +578,7 @@ enum Opcodes
SMSG_GMTICKET_SYSTEMSTATUS = 0x21B,
CMSG_SPIRIT_HEALER_ACTIVATE = 0x21C,
CMSG_SET_STAT_CHEAT = 0x21D,
- SMSG_SET_REST_START = 0x21E,
+ SMSG_SET_REST_START_OBSOLETE = 0x21E,
CMSG_SKILL_BUY_STEP = 0x21F,
CMSG_SKILL_BUY_RANK = 0x220,
CMSG_XP_CHEAT = 0x221,
@@ -733,8 +733,8 @@ enum Opcodes
SMSG_SCRIPT_MESSAGE = 0x2B6,
SMSG_DUEL_COUNTDOWN = 0x2B7,
SMSG_AREA_TRIGGER_MESSAGE = 0x2B8,
- CMSG_TOGGLE_HELM = 0x2B9,
- CMSG_TOGGLE_CLOAK = 0x2BA,
+ CMSG_SHOWING_HELM = 0x2B9,
+ CMSG_SHOWING_CLOAK = 0x2BA,
SMSG_MEETINGSTONE_JOINFAILED = 0x2BB,
SMSG_PLAYER_SKINNED = 0x2BC,
SMSG_DURABILITY_DAMAGE_DEATH = 0x2BD,
@@ -967,10 +967,10 @@ enum Opcodes
SMSG_VOICE_SESSION_ADJUST_PRIORITY = 0x3A0,
CMSG_VOICE_SET_TALKER_MUTED_REQUEST = 0x3A1,
SMSG_VOICE_SET_TALKER_MUTED = 0x3A2,
- SMSG_INIT_EXTRA_AURA_INFO = 0x3A3,
- SMSG_SET_EXTRA_AURA_INFO = 0x3A4,
- SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE = 0x3A5,
- SMSG_CLEAR_EXTRA_AURA_INFO = 0x3A6,
+ SMSG_INIT_EXTRA_AURA_INFO_OBSOLETE = 0x3A3,
+ SMSG_SET_EXTRA_AURA_INFO_OBSOLETE = 0x3A4,
+ SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE = 0x3A5,
+ SMSG_CLEAR_EXTRA_AURA_INFO_OBSOLETE = 0x3A6,
MSG_MOVE_START_DESCEND = 0x3A7,
CMSG_IGNORE_REQUIREMENTS_CHEAT = 0x3A8,
SMSG_IGNORE_REQUIREMENTS_CHEAT = 0x3A9,
@@ -980,127 +980,262 @@ enum Opcodes
MSG_MOVE_UPDATE_CAN_FLY = 0x3AD,
MSG_RAID_READY_CHECK_CONFIRM = 0x3AE,
CMSG_VOICE_SESSION_ENABLE = 0x3AF,
- SMSG_VOICE_PARENTAL_CONTROLS = 0x3B0,
- CMSG_GM_WHISPER = 0x3B1,
- SMSG_GM_MESSAGECHAT = 0x3B2,
- MSG_GM_GEARRATING = 0x3B3,
- CMSG_COMMENTATOR_ENABLE = 0x3B4,
- SMSG_COMMENTATOR_STATE_CHANGED = 0x3B5,
- CMSG_COMMENTATOR_GET_MAP_INFO = 0x3B6,
- SMSG_COMMENTATOR_MAP_INFO = 0x3B7,
- CMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3B8,
- SMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3B9,
- SMSG_COMMENTATOR_PLAYER_INFO = 0x3BA,
- CMSG_COMMENTATOR_ENTER_INSTANCE = 0x3BB,
- CMSG_COMMENTATOR_EXIT_INSTANCE = 0x3BC,
- CMSG_COMMENTATOR_INSTANCE_COMMAND = 0x3BD,
- SMSG_CLEAR_TARGET = 0x3BE,
- CMSG_BOT_DETECTED = 0x3BF,
- SMSG_CROSSED_INEBRIATION_THRESHOLD = 0x3C0,
- CMSG_CHEAT_PLAYER_LOGIN = 0x3C1,
- CMSG_CHEAT_PLAYER_LOOKUP = 0x3C2,
- SMSG_CHEAT_PLAYER_LOOKUP = 0x3C3,
- SMSG_KICK_REASON = 0x3C4,
- MSG_RAID_READY_CHECK_FINISHED = 0x3C5,
- CMSG_COMPLAIN = 0x3C6,
- SMSG_COMPLAIN_RESULT = 0x3C7,
- SMSG_FEATURE_SYSTEM_STATUS = 0x3C8,
- CMSG_GM_SHOW_COMPLAINTS = 0x3C9,
- CMSG_GM_UNSQUELCH = 0x3CA,
- CMSG_CHANNEL_SILENCE_VOICE = 0x3CB,
- CMSG_CHANNEL_SILENCE_ALL = 0x3CC,
- CMSG_CHANNEL_UNSILENCE_VOICE = 0x3CD,
- CMSG_CHANNEL_UNSILENCE_ALL = 0x3CE,
- CMSG_TARGET_CAST = 0x3CF,
- CMSG_TARGET_SCRIPT_CAST = 0x3D0,
- CMSG_CHANNEL_DISPLAY_LIST = 0x3D1,
- CMSG_SET_ACTIVE_VOICE_CHANNEL = 0x3D2,
- CMSG_GET_CHANNEL_MEMBER_COUNT = 0x3D3,
- SMSG_CHANNEL_MEMBER_COUNT = 0x3D4,
- CMSG_CHANNEL_VOICE_ON = 0x3D5,
- CMSG_CHANNEL_VOICE_OFF = 0x3D6,
- CMSG_DEBUG_LIST_TARGETS = 0x3D7,
- SMSG_DEBUG_LIST_TARGETS = 0x3D8,
- SMSG_AVAILABLE_VOICE_CHANNEL = 0x3D9,
- CMSG_ADD_VOICE_IGNORE = 0x3DA,
- CMSG_DEL_VOICE_IGNORE = 0x3DB,
- CMSG_PARTY_SILENCE = 0x3DC,
- CMSG_PARTY_UNSILENCE = 0x3DD,
- MSG_NOTIFY_PARTY_SQUELCH = 0x3DE,
- SMSG_COMSAT_RECONNECT_TRY = 0x3DF,
- SMSG_COMSAT_DISCONNECT = 0x3E0,
- SMSG_COMSAT_CONNECT_FAIL = 0x3E1,
- SMSG_VOICE_CHAT_STATUS = 0x3E2,
- CMSG_REPORT_PVP_AFK = 0x3E3,
- CMSG_REPORT_PVP_AFK_RESULT = 0x3E4,
- CMSG_GUILD_BANKER_ACTIVATE = 0x3E5,
- CMSG_GUILD_BANK_QUERY_TAB = 0x3E6,
- SMSG_GUILD_BANK_LIST = 0x3E7,
- CMSG_GUILD_BANK_SWAP_ITEMS = 0x3E8,
- CMSG_GUILD_BANK_BUY_TAB = 0x3E9,
- CMSG_GUILD_BANK_UPDATE_TAB = 0x3EA,
- CMSG_GUILD_BANK_DEPOSIT_MONEY = 0x3EB,
- CMSG_GUILD_BANK_WITHDRAW_MONEY = 0x3EC,
- MSG_GUILD_BANK_LOG_QUERY = 0x3ED,
- CMSG_SET_CHANNEL_WATCH = 0x3EE,
- SMSG_USERLIST_ADD = 0x3EF,
- SMSG_USERLIST_REMOVE = 0x3F0,
- SMSG_USERLIST_UPDATE = 0x3F1,
- CMSG_CLEAR_CHANNEL_WATCH = 0x3F2,
- SMSG_INSPECT_TALENT = 0x3F3,
- SMSG_GOGOGO_OBSOLETE = 0x3F4,
- SMSG_ECHO_PARTY_SQUELCH = 0x3F5,
- CMSG_SET_TITLE_SUFFIX = 0x3F6,
- CMSG_SPELLCLICK = 0x3F7,
- SMSG_LOOT_LIST = 0x3F8,
- CMSG_GM_CHARACTER_RESTORE = 0x3F9,
- CMSG_GM_CHARACTER_SAVE = 0x3FA,
- SMSG_VOICESESSION_FULL = 0x3FB,
- MSG_GUILD_PERMISSIONS = 0x3FC,
- MSG_GUILD_BANK_MONEY_WITHDRAWN = 0x3FD,
- MSG_GUILD_EVENT_LOG_QUERY = 0x3FE,
- CMSG_MAELSTROM_RENAME_GUILD = 0x3FF,
- CMSG_GET_MIRRORIMAGE_DATA = 0x400,
- SMSG_MIRRORIMAGE_DATA = 0x401,
- SMSG_FORCE_DISPLAY_UPDATE = 0x402,
- SMSG_SPELL_CHANCE_RESIST_PUSHBACK = 0x403,
- CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x404,
- SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x405,
- CMSG_KEEP_ALIVE = 0x406,
- SMSG_RAID_READY_CHECK_ERROR = 0x407,
- CMSG_OPT_OUT_OF_LOOT = 0x408,
- MSG_QUERY_GUILD_BANK_TEXT = 0x409,
- CMSG_SET_GUILD_BANK_TEXT = 0x40A,
- CMSG_SET_GRANTABLE_LEVELS = 0x40B,
- CMSG_GRANT_LEVEL = 0x40C,
- CMSG_REFER_A_FRIEND = 0x40D,
- MSG_GM_CHANGE_ARENA_RATING = 0x40E,
- CMSG_DECLINE_CHANNEL_INVITE = 0x40F,
- CMSG_GROUPACTION_THROTTLED = 0x410,
- SMSG_OVERRIDE_LIGHT = 0x411,
- SMSG_TOTEM_CREATED = 0x412,
- CMSG_TOTEM_DESTROYED = 0x413,
- CMSG_EXPIRE_RAID_INSTANCE = 0x414,
- CMSG_NO_SPELL_VARIANCE = 0x415,
- CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x416,
- SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x417,
- CMSG_SET_PLAYER_DECLINED_NAMES = 0x418,
- SMSG_SET_PLAYER_DECLINED_NAMES_RESULT = 0x419,
- CMSG_QUERY_SERVER_BUCK_DATA = 0x41A,
- CMSG_CLEAR_SERVER_BUCK_DATA = 0x41B,
- SMSG_SERVER_BUCK_DATA = 0x41C,
- SMSG_SEND_UNLEARN_SPELLS = 0x41D,
- SMSG_PROPOSE_LEVEL_GRANT = 0x41E,
- CMSG_ACCEPT_LEVEL_GRANT = 0x41F,
- SMSG_REFER_A_FRIEND_FAILURE = 0x420,
- SMSG_SPLINE_MOVE_SET_FLYING = 0x421,
- SMSG_SPLINE_MOVE_UNSET_FLYING = 0x422,
- SMSG_SUMMON_CANCEL = 0x423
+ SMSG_VOICE_SESSION_ENABLE = 0x3B0,
+ SMSG_VOICE_PARENTAL_CONTROLS = 0x3B1,
+ CMSG_GM_WHISPER = 0x3B2,
+ SMSG_GM_MESSAGECHAT = 0x3B3,
+ MSG_GM_GEARRATING = 0x3B4,
+ CMSG_COMMENTATOR_ENABLE = 0x3B5,
+ SMSG_COMMENTATOR_STATE_CHANGED = 0x3B6,
+ CMSG_COMMENTATOR_GET_MAP_INFO = 0x3B7,
+ SMSG_COMMENTATOR_MAP_INFO = 0x3B8,
+ CMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3B9,
+ SMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3BA,
+ SMSG_COMMENTATOR_PLAYER_INFO = 0x3BB,
+ CMSG_COMMENTATOR_ENTER_INSTANCE = 0x3BC,
+ CMSG_COMMENTATOR_EXIT_INSTANCE = 0x3BD,
+ CMSG_COMMENTATOR_INSTANCE_COMMAND = 0x3BE,
+ SMSG_CLEAR_TARGET = 0x3BF,
+ CMSG_BOT_DETECTED = 0x3C0,
+ SMSG_CROSSED_INEBRIATION_THRESHOLD = 0x3C1,
+ CMSG_CHEAT_PLAYER_LOGIN = 0x3C2,
+ CMSG_CHEAT_PLAYER_LOOKUP = 0x3C3,
+ SMSG_CHEAT_PLAYER_LOOKUP = 0x3C4,
+ SMSG_KICK_REASON = 0x3C5,
+ MSG_RAID_READY_CHECK_FINISHED = 0x3C6,
+ CMSG_COMPLAIN = 0x3C7,
+ SMSG_COMPLAIN_RESULT = 0x3C8,
+ SMSG_FEATURE_SYSTEM_STATUS = 0x3C9,
+ CMSG_GM_SHOW_COMPLAINTS = 0x3CA,
+ CMSG_GM_UNSQUELCH = 0x3CB,
+ CMSG_CHANNEL_SILENCE_VOICE = 0x3CC,
+ CMSG_CHANNEL_SILENCE_ALL = 0x3CD,
+ CMSG_CHANNEL_UNSILENCE_VOICE = 0x3CE,
+ CMSG_CHANNEL_UNSILENCE_ALL = 0x3CF,
+ CMSG_TARGET_CAST = 0x3D0,
+ CMSG_TARGET_SCRIPT_CAST = 0x3D1,
+ CMSG_CHANNEL_DISPLAY_LIST = 0x3D2,
+ CMSG_SET_ACTIVE_VOICE_CHANNEL = 0x3D3,
+ CMSG_GET_CHANNEL_MEMBER_COUNT = 0x3D4,
+ SMSG_CHANNEL_MEMBER_COUNT = 0x3D5,
+ CMSG_CHANNEL_VOICE_ON = 0x3D6,
+ CMSG_CHANNEL_VOICE_OFF = 0x3D7,
+ CMSG_DEBUG_LIST_TARGETS = 0x3D8,
+ SMSG_DEBUG_LIST_TARGETS = 0x3D9,
+ SMSG_AVAILABLE_VOICE_CHANNEL = 0x3DA,
+ CMSG_ADD_VOICE_IGNORE = 0x3DB,
+ CMSG_DEL_VOICE_IGNORE = 0x3DC,
+ CMSG_PARTY_SILENCE = 0x3DD,
+ CMSG_PARTY_UNSILENCE = 0x3DE,
+ MSG_NOTIFY_PARTY_SQUELCH = 0x3DF,
+ SMSG_COMSAT_RECONNECT_TRY = 0x3E0,
+ SMSG_COMSAT_DISCONNECT = 0x3E1,
+ SMSG_COMSAT_CONNECT_FAIL = 0x3E2,
+ SMSG_VOICE_CHAT_STATUS = 0x3E3,
+ CMSG_REPORT_PVP_AFK = 0x3E4,
+ CMSG_REPORT_PVP_AFK_RESULT = 0x3E5,
+ CMSG_GUILD_BANKER_ACTIVATE = 0x3E6,
+ CMSG_GUILD_BANK_QUERY_TAB = 0x3E7,
+ SMSG_GUILD_BANK_LIST = 0x3E8,
+ CMSG_GUILD_BANK_SWAP_ITEMS = 0x3E9,
+ CMSG_GUILD_BANK_BUY_TAB = 0x3EA,
+ CMSG_GUILD_BANK_UPDATE_TAB = 0x3EB,
+ CMSG_GUILD_BANK_DEPOSIT_MONEY = 0x3EC,
+ CMSG_GUILD_BANK_WITHDRAW_MONEY = 0x3ED,
+ MSG_GUILD_BANK_LOG_QUERY = 0x3EE,
+ CMSG_SET_CHANNEL_WATCH = 0x3EF,
+ SMSG_USERLIST_ADD = 0x3F0,
+ SMSG_USERLIST_REMOVE = 0x3F1,
+ SMSG_USERLIST_UPDATE = 0x3F2,
+ CMSG_CLEAR_CHANNEL_WATCH = 0x3F3,
+ SMSG_INSPECT_TALENT = 0x3F4,
+ SMSG_GOGOGO_OBSOLETE = 0x3F5,
+ SMSG_ECHO_PARTY_SQUELCH = 0x3F6,
+ CMSG_SET_TITLE_SUFFIX = 0x3F7,
+ CMSG_SPELLCLICK = 0x3F8,
+ SMSG_LOOT_LIST = 0x3F9,
+ CMSG_GM_CHARACTER_RESTORE = 0x3FA,
+ CMSG_GM_CHARACTER_SAVE = 0x3FB,
+ SMSG_VOICESESSION_FULL = 0x3FC,
+ MSG_GUILD_PERMISSIONS = 0x3FD,
+ MSG_GUILD_BANK_MONEY_WITHDRAWN = 0x3FE,
+ MSG_GUILD_EVENT_LOG_QUERY = 0x3FF,
+ CMSG_MAELSTROM_RENAME_GUILD = 0x400,
+ CMSG_GET_MIRRORIMAGE_DATA = 0x401,
+ SMSG_MIRRORIMAGE_DATA = 0x402,
+ SMSG_FORCE_DISPLAY_UPDATE = 0x403,
+ SMSG_SPELL_CHANCE_RESIST_PUSHBACK = 0x404,
+ CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x405,
+ SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x406,
+ CMSG_KEEP_ALIVE = 0x407,
+ SMSG_RAID_READY_CHECK_ERROR = 0x408,
+ CMSG_OPT_OUT_OF_LOOT = 0x409,
+ MSG_QUERY_GUILD_BANK_TEXT = 0x40A,
+ CMSG_SET_GUILD_BANK_TEXT = 0x40B,
+ CMSG_SET_GRANTABLE_LEVELS = 0x40C,
+ CMSG_GRANT_LEVEL = 0x40D,
+ CMSG_REFER_A_FRIEND = 0x40E,
+ MSG_GM_CHANGE_ARENA_RATING = 0x40F,
+ CMSG_DECLINE_CHANNEL_INVITE = 0x410,
+ CMSG_GROUPACTION_THROTTLED = 0x411,
+ SMSG_OVERRIDE_LIGHT = 0x412,
+ SMSG_TOTEM_CREATED = 0x413,
+ CMSG_TOTEM_DESTROYED = 0x414,
+ CMSG_EXPIRE_RAID_INSTANCE = 0x415,
+ CMSG_NO_SPELL_VARIANCE = 0x416,
+ CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x417,
+ SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x418,
+ CMSG_SET_PLAYER_DECLINED_NAMES = 0x419,
+ SMSG_SET_PLAYER_DECLINED_NAMES_RESULT = 0x41A,
+ CMSG_QUERY_SERVER_BUCK_DATA = 0x41B,
+ CMSG_CLEAR_SERVER_BUCK_DATA = 0x41C,
+ SMSG_SERVER_BUCK_DATA = 0x41D,
+ SMSG_SEND_UNLEARN_SPELLS = 0x41E,
+ SMSG_PROPOSE_LEVEL_GRANT = 0x41F,
+ CMSG_ACCEPT_LEVEL_GRANT = 0x420,
+ SMSG_REFER_A_FRIEND_FAILURE = 0x421,
+ SMSG_SPLINE_MOVE_SET_FLYING = 0x422,
+ SMSG_SPLINE_MOVE_UNSET_FLYING = 0x423,
+ SMSG_SUMMON_CANCEL = 0x424,
+ CMSG_CHANGE_PERSONAL_ARENA_RATING = 0x425,
+ CMSG_ALTER_APPEARANCE = 0x426,
+ SMSG_ENABLE_BARBER_SHOP = 0x427,
+ SMSG_BARBER_SHOP_RESULT = 0x428,
+ CMSG_CALENDAR_GET_CALENDAR = 0x429,
+ CMSG_CALENDAR_GET_EVENT = 0x42A,
+ CMSG_CALENDAR_GUILD_FILTER = 0x42B,
+ CMSG_CALENDAR_ARENA_TEAM = 0x42C,
+ CMSG_CALENDAR_ADD_EVENT = 0x42D,
+ CMSG_CALENDAR_UPDATE_EVENT = 0x42E,
+ CMSG_CALENDAR_REMOVE_EVENT = 0x42F,
+ CMSG_CALENDAR_COPY_EVENT = 0x430,
+ CMSG_CALENDAR_EVENT_INVITE = 0x431,
+ CMSG_CALENDAR_EVENT_RSVP = 0x432,
+ CMSG_CALENDAR_EVENT_REMOVE_INVITE = 0x433,
+ CMSG_CALENDAR_EVENT_STATUS = 0x434,
+ CMSG_CALENDAR_EVENT_MODERATOR_STATUS = 0x435,
+ SMSG_CALENDAR_SEND_CALENDAR = 0x436,
+ SMSG_CALENDAR_SEND_EVENT = 0x437,
+ SMSG_CALENDAR_FILTER_GUILD = 0x438,
+ SMSG_CALENDAR_ARENA_TEAM = 0x439,
+ SMSG_CALENDAR_EVENT_INVITE = 0x43A,
+ SMSG_CALENDAR_EVENT_INVITE_REMOVED = 0x43B,
+ SMSG_CALENDAR_EVENT_STATUS = 0x43C,
+ SMSG_CALENDAR_COMMAND_RESULT = 0x43D,
+ SMSG_CALENDAR_RAID_LOCKOUT_ADDED = 0x43E,
+ SMSG_CALENDAR_RAID_LOCKOUT_REMOVED = 0x43F,
+ SMSG_CALENDAR_EVENT_INVITE_ALERT = 0x440,
+ SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT = 0x441,
+ SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT = 0x442,
+ SMSG_CALENDAR_EVENT_REMOVED_ALERT = 0x443,
+ SMSG_CALENDAR_EVENT_UPDATED_ALERT = 0x444,
+ SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT = 0x445,
+ CMSG_CALENDAR_COMPLAIN = 0x446,
+ CMSG_CALENDAR_GET_NUM_PENDING = 0x447,
+ SMSG_CALENDAR_SEND_NUM_PENDING = 0x448,
+ CMSG_SAVE_DANCE = 0x449,
+ SMSG_NOTIFY_DANCE = 0x44A,
+ CMSG_PLAY_DANCE = 0x44B,
+ SMSG_PLAY_DANCE = 0x44C,
+ CMSG_LOAD_DANCES = 0x44D,
+ CMSG_STOP_DANCE = 0x44E,
+ SMSG_STOP_DANCE = 0x44F,
+ CMSG_SYNC_DANCE = 0x450,
+ CMSG_DANCE_QUERY = 0x451,
+ SMSG_DANCE_QUERY_RESPONSE = 0x452,
+ SMSG_INVALIDATE_DANCE = 0x453,
+ CMSG_DELETE_DANCE = 0x454,
+ SMSG_LEARNED_DANCE_MOVES = 0x455,
+ CMSG_LEARN_DANCE_MOVE = 0x456,
+ CMSG_UNLEARN_DANCE_MOVE = 0x457,
+ CMSG_SET_RUNE_COUNT = 0x458,
+ CMSG_SET_RUNE_COOLDOWN = 0x459,
+ MSG_MOVE_SET_PITCH_RATE_CHEAT = 0x45A,
+ MSG_MOVE_SET_PITCH_RATE = 0x45B,
+ SMSG_FORCE_PITCH_RATE_CHANGE = 0x45C,
+ CMSG_FORCE_PITCH_RATE_CHANGE_ACK = 0x45D,
+ SMSG_SPLINE_SET_PITCH_RATE = 0x45E,
+ SMSG_MOVE_ABANDON_TRANSPORT = 0x45F,
+ MSG_MOVE_ABANDON_TRANSPORT = 0x460,
+ CMSG_MOVE_ABANDON_TRANSPORT_ACK = 0x461,
+ CMSG_UPDATE_MISSILE_TRAJECTORY = 0x462,
+ SMSG_UPDATE_ACCOUNT_DATA_COMPLETE = 0x463,
+ SMSG_TRIGGER_MOVIE = 0x464,
+ CMSG_COMPLETE_MOVIE = 0x465,
+ CMSG_SET_GLYPH_SLOT = 0x466,
+ CMSG_SET_GLYPH = 0x467,
+ SMSG_ACHIEVEMENT_EARNED = 0x468,
+ SMSG_DYNAMIC_DROP_ROLL_RESULT = 0x469,
+ SMSG_CRITERIA_UPDATE = 0x46A,
+ CMSG_QUERY_INSPECT_ACHIEVEMENTS = 0x46B,
+ SMSG_RESPOND_INSPECT_ACHIEVEMENTS = 0x46C,
+ CMSG_DISMISS_CONTROLLED_VEHICLE = 0x46D,
+ CMSG_COMPLETE_ACHIEVEMENT_CHEAT = 0x46E,
+ SMSG_QUESTUPDATE_ADD_PVP_KILL = 0x46F,
+ CMSG_SET_CRITERIA_CHEAT = 0x470,
+ SMSG_GROUP_SWAP_FAILED = 0x471,
+ CMSG_UNITANIMTIER_CHEAT = 0x472,
+ CMSG_CHAR_CUSTOMIZE = 0x473,
+ SMSG_CHAR_CUSTOMIZE = 0x474,
+ SMSG_PET_RENAMEABLE = 0x475,
+ CMSG_REQUEST_VEHICLE_EXIT = 0x476,
+ CMSG_REQUEST_VEHICLE_PREV_SEAT = 0x477,
+ CMSG_REQUEST_VEHICLE_NEXT_SEAT = 0x478,
+ CMSG_REQUEST_VEHICLE_SWITCH_SEAT = 0x479,
+ CMSG_PET_LEARN_TALENT = 0x47A,
+ CMSG_PET_UNLEARN_TALENTS = 0x47B,
+ SMSG_SET_PHASE_SHIFT = 0x47C,
+ SMSG_ALL_ACHIEVEMENT_DATA = 0x47D,
+ CMSG_FORCE_SAY_CHEAT = 0x47E,
+ SMSG_HEALTH_UPDATE = 0x47F,
+ SMSG_POWER_UPDATE = 0x480,
+ CMSG_GAMEOBJ_REPORT_USE = 0x481,
+ SMSG_HIGHEST_THREAT_UPDATE = 0x482,
+ SMSG_THREAT_UPDATE = 0x483,
+ SMSG_THREAT_REMOVE = 0x484,
+ SMSG_THREAT_CLEAR = 0x485,
+ SMSG_CONVERT_RUNE = 0x486,
+ SMSG_RESYNC_RUNES = 0x487,
+ SMSG_ADD_RUNE_POWER = 0x488,
+ CMSG_START_QUEST = 0x489,
+ CMSG_REMOVE_GLYPH = 0x48A,
+ CMSG_DUMP_OBJECTS = 0x48B,
+ SMSG_DUMP_OBJECTS_DATA = 0x48C,
+ CMSG_DISMISS_CRITTER = 0x48D,
+ SMSG_NOTIFY_DEST_LOC_SPELL_CAST = 0x48E,
+ CMSG_AUCTION_LIST_PENDING_SALES = 0x48F,
+ SMSG_AUCTION_LIST_PENDING_SALES = 0x490,
+ SMSG_MODIFY_COOLDOWN = 0x491,
+ SMSG_PET_UPDATE_COMBO_POINTS = 0x492,
+ CMSG_ENABLETAXI = 0x493,
+ SMSG_PRE_RESURRECT = 0x494,
+ SMSG_AURA_UPDATE_ALL = 0x495,
+ SMSG_AURA_UPDATE = 0x496,
+ CMSG_FLOOD_GRACE_CHEAT = 0x497,
+ SMSG_SERVER_FIRST_ACHIEVEMENT = 0x498,
+ SMSG_PET_LEARNED_SPELL = 0x499,
+ SMSG_PET_REMOVED_SPELL = 0x49A,
+ CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE = 0x49B,
+ CMSG_HEARTH_AND_RESURRECT = 0x49C,
+ SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA = 0x49D,
+ SMSG_CRITERIA_DELETED = 0x49E,
+ SMSG_ACHIEVEMENT_DELETED = 0x49F,
+ CMSG_SERVER_INFO_QUERY = 0x4A0,
+ SMSG_SERVER_INFO_RESPONSE = 0x4A1,
+ CMSG_CHECK_LOGIN_CRITERIA = 0x4A2,
+ SMSG_SERVER_BUCK_DATA_START = 0x4A3,
+ CMSG_QUERY_VEHICLE_STATUS = 0x4A4,
+ SMSG_PET_GUIDS = 0x4A5,
+ SMSG_CLIENTCACHE_VERSION = 0x4A6,
+ UMSG_UNKNOWN_1191 = 0x4A7,
+ UMSG_UNKNOWN_1192 = 0x4A8,
+ UMSG_UNKNOWN_1193 = 0x4A9,
+ UMSG_UNKNOWN_1194 = 0x4AA,
+ UMSG_UNKNOWN_1195 = 0x4AB,
+ UMSG_UNKNOWN_1196 = 0x4AC,
+ NUM_MSG_TYPES = 0x4AD
};
-// Don't forget to change this value and add opcode name to Opcodes.cpp when you add new opcode!
-#define NUM_MSG_TYPES 0x424
-
/// Player state
enum SessionStatus
{
diff --git a/src/game/OutdoorPvP.cpp b/src/game/OutdoorPvP.cpp
index 99b1c9a55f0..97acf08ce8c 100644
--- a/src/game/OutdoorPvP.cpp
+++ b/src/game/OutdoorPvP.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -83,7 +83,7 @@ bool OutdoorPvPObjective::AddObject(uint32 type, uint32 entry, uint32 map, float
data.spawntimesecs = 0;
data.animprogress = 100;
data.spawnMask = 1;
- data.go_state = 1;
+ data.go_state = GO_STATE_READY;
objmgr.AddGameobjectToGrid(guid, &data);
@@ -95,7 +95,7 @@ bool OutdoorPvPObjective::AddObject(uint32 type, uint32 entry, uint32 map, float
if(!pMap)
return true;
GameObject * go = new GameObject;
- if(!go->Create(guid,entry, pMap,x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1))
+ if(!go->Create(guid,entry, pMap,PHASEMASK_NORMAL,x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,GO_STATE_READY))
{
sLog.outError("Gameobject template %u not found in database.", entry);
delete go;
@@ -156,20 +156,19 @@ bool OutdoorPvPObjective::AddCreature(uint32 type, uint32 entry, uint32 teamval,
if(!pMap)
return true;
Creature* pCreature = new Creature;
- if (!pCreature->Create(guid, pMap, entry, teamval))
+ if (!pCreature->Create(guid, pMap, PHASEMASK_NORMAL, entry, teamval))
{
sLog.outError("Can't create creature entry: %u",entry);
delete pCreature;
- return true;
+ return false;
}
- pCreature->AIM_Initialize();
-
pCreature->Relocate(x, y, z, o);
if(!pCreature->IsPositionValid())
{
sLog.outError("ERROR: Creature (guidlow %d, entry %d) not added to opvp. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
+ delete pCreature;
return false;
}
@@ -239,7 +238,7 @@ bool OutdoorPvPObjective::AddCapturePoint(uint32 entry, uint32 map, float x, flo
data.spawntimesecs = 1;
data.animprogress = 100;
data.spawnMask = 1;
- data.go_state = 1;
+ data.go_state = GO_STATE_READY;
objmgr.AddGameobjectToGrid(guid, &data);
@@ -256,7 +255,7 @@ bool OutdoorPvPObjective::AddCapturePoint(uint32 entry, uint32 map, float x, flo
return true;
// add GO...
GameObject * go = new GameObject;
- if(!go->Create(guid,entry, pMap,x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1))
+ if(!go->Create(guid,entry, pMap,PHASEMASK_NORMAL,x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,GO_STATE_READY))
{
sLog.outError("Gameobject template %u not found in database.", entry);
delete go;
@@ -269,20 +268,20 @@ bool OutdoorPvPObjective::AddCapturePoint(uint32 entry, uint32 map, float x, flo
}
// add creature...
Creature* pCreature = new Creature;
- if (!pCreature->Create(creature_guid, pMap, OPVP_TRIGGER_CREATURE_ENTRY, 0))
+ if (!pCreature->Create(creature_guid, pMap, PHASEMASK_NORMAL, OPVP_TRIGGER_CREATURE_ENTRY, 0))
{
sLog.outError("Can't create creature entry: %u",entry);
delete pCreature;
+ return false;
}
else
{
- pCreature->AIM_Initialize();
-
pCreature->Relocate(x, y, z, o);
if(!pCreature->IsPositionValid())
{
sLog.outError("ERROR: Creature (guidlow %d, entry %d) not added to opvp. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
+ delete pCreature;
return false;
}
@@ -315,8 +314,8 @@ bool OutdoorPvPObjective::DelCreature(uint32 type)
// explicit removal from map
// beats me why this is needed, but with the recent removal "cleanup" some creatures stay in the map if "properly" deleted
// so this is a big fat workaround, if AddObjectToRemoveList and DoDelayedMovesAndRemoves worked correctly, this wouldn't be needed
- if(Map * map = MapManager::Instance().FindMap(cr->GetMapId()))
- map->Remove(cr,false);
+ //if(Map * map = MapManager::Instance().FindMap(cr->GetMapId()))
+ // map->Remove(cr,false);
// delete respawn time for this creature
WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE guid = '%u'", guid);
cr->AddObjectToRemoveList();
@@ -373,8 +372,8 @@ bool OutdoorPvPObjective::DelCapturePoint()
// explicit removal from map
// beats me why this is needed, but with the recent removal "cleanup" some creatures stay in the map if "properly" deleted
// so this is a big fat workaround, if AddObjectToRemoveList and DoDelayedMovesAndRemoves worked correctly, this wouldn't be needed
- if(Map * map = MapManager::Instance().FindMap(cr->GetMapId()))
- map->Remove(cr,false);
+ //if(Map * map = MapManager::Instance().FindMap(cr->GetMapId()))
+ // map->Remove(cr,false);
// delete respawn time for this creature
WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE guid = '%u'", guid);
cr->AddObjectToRemoveList();
diff --git a/src/game/OutdoorPvP.h b/src/game/OutdoorPvP.h
index e7bd21059a7..c1c39c1ff65 100644
--- a/src/game/OutdoorPvP.h
+++ b/src/game/OutdoorPvP.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/OutdoorPvPEP.cpp b/src/game/OutdoorPvPEP.cpp
index 41747dba100..f0ff85574c0 100644
--- a/src/game/OutdoorPvPEP.cpp
+++ b/src/game/OutdoorPvPEP.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/OutdoorPvPEP.h b/src/game/OutdoorPvPEP.h
index ae242a1da16..08d31de5cf5 100644
--- a/src/game/OutdoorPvPEP.h
+++ b/src/game/OutdoorPvPEP.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,7 +21,7 @@
#include "OutdoorPvP.h"
-#include "Database/DBCStructure.h"
+#include "DBCStructure.h"
const uint32 EP_AllianceBuffs[4] = {11413, 11414, 11415, 1386};
diff --git a/src/game/OutdoorPvPHP.cpp b/src/game/OutdoorPvPHP.cpp
index b31f79a6288..6058b82c102 100644
--- a/src/game/OutdoorPvPHP.cpp
+++ b/src/game/OutdoorPvPHP.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/OutdoorPvPHP.h b/src/game/OutdoorPvPHP.h
index da41761d572..a538f82b216 100644
--- a/src/game/OutdoorPvPHP.h
+++ b/src/game/OutdoorPvPHP.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/OutdoorPvPMgr.cpp b/src/game/OutdoorPvPMgr.cpp
index 5c53bf4eaba..2050a6c11f7 100644
--- a/src/game/OutdoorPvPMgr.cpp
+++ b/src/game/OutdoorPvPMgr.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -143,7 +143,6 @@ void OutdoorPvPMgr::HandlePlayerEnterZone(Player *plr, uint32 zoneid)
}
// add possibly beneficial buffs to plr for zone
itr->second->HandlePlayerEnterZone(plr, zoneid);
- plr->SendInitWorldStates();
sLog.outDebug("Player %u entered outdoorpvp id %u",plr->GetGUIDLow(), itr->second->GetTypeId());
}
diff --git a/src/game/OutdoorPvPMgr.h b/src/game/OutdoorPvPMgr.h
index 7426876b42b..28b01c586b7 100644
--- a/src/game/OutdoorPvPMgr.h
+++ b/src/game/OutdoorPvPMgr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/OutdoorPvPNA.cpp b/src/game/OutdoorPvPNA.cpp
index 9b59347dd2d..9030337f2cd 100644
--- a/src/game/OutdoorPvPNA.cpp
+++ b/src/game/OutdoorPvPNA.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/OutdoorPvPNA.h b/src/game/OutdoorPvPNA.h
index b6be2270cda..92e0b9dcbbb 100644
--- a/src/game/OutdoorPvPNA.h
+++ b/src/game/OutdoorPvPNA.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/OutdoorPvPObjectiveAI.cpp b/src/game/OutdoorPvPObjectiveAI.cpp
index 7c4fd5e6de8..233fffd6b2f 100644
--- a/src/game/OutdoorPvPObjectiveAI.cpp
+++ b/src/game/OutdoorPvPObjectiveAI.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/OutdoorPvPObjectiveAI.h b/src/game/OutdoorPvPObjectiveAI.h
index d21655795e9..dffd8885243 100644
--- a/src/game/OutdoorPvPObjectiveAI.h
+++ b/src/game/OutdoorPvPObjectiveAI.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -26,7 +26,7 @@ class Creature;
class TRINITY_DLL_DECL OutdoorPvPObjectiveAI : public NullCreatureAI
{
public:
- OutdoorPvPObjectiveAI(Creature *c);
+ explicit OutdoorPvPObjectiveAI(Creature *c);
void MoveInLineOfSight(Unit *);
diff --git a/src/game/OutdoorPvPSI.cpp b/src/game/OutdoorPvPSI.cpp
index 378543da48e..bb4cd22edfa 100644
--- a/src/game/OutdoorPvPSI.cpp
+++ b/src/game/OutdoorPvPSI.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -129,7 +129,7 @@ bool OutdoorPvPSI::HandleAreaTrigger(Player *plr, uint32 trigger)
switch(trigger)
{
case SI_AREATRIGGER_A:
- if(plr->GetTeam() == ALLIANCE && plr->HasAura(SI_SILITHYST_FLAG,0))
+ if(plr->GetTeam() == ALLIANCE && plr->HasAura(SI_SILITHYST_FLAG))
{
// remove aura
plr->RemoveAurasDueToSpell(SI_SILITHYST_FLAG);
@@ -148,13 +148,13 @@ bool OutdoorPvPSI::HandleAreaTrigger(Player *plr, uint32 trigger)
// add 19 honor
plr->RewardHonor(NULL,1,19);
// add 20 cenarion circle repu
- plr->ModifyFactionReputation(609,20);
+ plr->GetReputationMgr().ModifyReputation(sFactionStore.LookupEntry(609),20);
// complete quest
plr->KilledMonster(SI_TURNIN_QUEST_CM_A,0);
}
return true;
case SI_AREATRIGGER_H:
- if(plr->GetTeam() == HORDE && plr->HasAura(SI_SILITHYST_FLAG,0))
+ if(plr->GetTeam() == HORDE && plr->HasAura(SI_SILITHYST_FLAG))
{
// remove aura
plr->RemoveAurasDueToSpell(SI_SILITHYST_FLAG);
@@ -173,7 +173,7 @@ bool OutdoorPvPSI::HandleAreaTrigger(Player *plr, uint32 trigger)
// add 19 honor
plr->RewardHonor(NULL,1,19);
// add 20 cenarion circle repu
- plr->ModifyFactionReputation(609,20);
+ plr->GetReputationMgr().ModifyReputation(sFactionStore.LookupEntry(609),20);
// complete quest
plr->KilledMonster(SI_TURNIN_QUEST_CM_H,0);
}
@@ -202,7 +202,7 @@ bool OutdoorPvPSI::HandleDropFlag(Player *plr, uint32 spellId)
Map * map = MapManager::Instance().GetMap(plr->GetMapId(), plr);
if(!map)
return true;
- if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),SI_SILITHYST_MOUND, map,plr->GetPositionX(),plr->GetPositionY(),plr->GetPositionZ(),plr->GetOrientation(),0,0,0,0,100,1))
+ if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),SI_SILITHYST_MOUND, map, plr->GetPhaseMask(), plr->GetPositionX(),plr->GetPositionY(),plr->GetPositionZ(),plr->GetOrientation(),0,0,0,0,100,GO_STATE_READY))
{
delete go;
}
@@ -228,7 +228,7 @@ bool OutdoorPvPSI::HandleDropFlag(Player *plr, uint32 spellId)
Map * map = MapManager::Instance().GetMap(plr->GetMapId(), plr);
if(!map)
return true;
- if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),SI_SILITHYST_MOUND, map ,plr->GetPositionX(),plr->GetPositionY(),plr->GetPositionZ(),plr->GetOrientation(),0,0,0,0,100,1))
+ if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),SI_SILITHYST_MOUND, map, plr->GetPhaseMask() ,plr->GetPositionX(),plr->GetPositionY(),plr->GetPositionZ(),plr->GetOrientation(),0,0,0,0,100,GO_STATE_READY))
{
delete go;
}
diff --git a/src/game/OutdoorPvPSI.h b/src/game/OutdoorPvPSI.h
index 4b0b5da357e..1f2331b4251 100644
--- a/src/game/OutdoorPvPSI.h
+++ b/src/game/OutdoorPvPSI.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/OutdoorPvPTF.cpp b/src/game/OutdoorPvPTF.cpp
index b94bc9246ee..01b224cffa9 100644
--- a/src/game/OutdoorPvPTF.cpp
+++ b/src/game/OutdoorPvPTF.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/OutdoorPvPZM.cpp b/src/game/OutdoorPvPZM.cpp
index b220f6a778f..6077a0ba66f 100644
--- a/src/game/OutdoorPvPZM.cpp
+++ b/src/game/OutdoorPvPZM.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -279,7 +279,7 @@ int32 OutdoorPvPObjectiveZM_GraveYard::HandleOpenGo(Player *plr, uint64 guid)
uint32 retval = OutdoorPvPObjective::HandleOpenGo(plr, guid);
if(retval>=0)
{
- if(plr->HasAura(ZM_BATTLE_STANDARD_A,0) && m_GraveYardState != ZM_GRAVEYARD_A)
+ if(plr->HasAura(ZM_BATTLE_STANDARD_A) && m_GraveYardState != ZM_GRAVEYARD_A)
{
if(m_GraveYardState == ZM_GRAVEYARD_H)
sWorld.SendZoneText(ZM_GRAVEYARD_ZONE,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_ZM_LOOSE_GY_H));
@@ -292,7 +292,7 @@ int32 OutdoorPvPObjectiveZM_GraveYard::HandleOpenGo(Player *plr, uint64 guid)
plr->RemoveAurasDueToSpell(ZM_BATTLE_STANDARD_A);
sWorld.SendZoneText(ZM_GRAVEYARD_ZONE,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_ZM_CAPTURE_GY_A));
}
- else if(plr->HasAura(ZM_BATTLE_STANDARD_H,0) && m_GraveYardState != ZM_GRAVEYARD_H)
+ else if(plr->HasAura(ZM_BATTLE_STANDARD_H) && m_GraveYardState != ZM_GRAVEYARD_H)
{
if(m_GraveYardState == ZM_GRAVEYARD_A)
sWorld.SendZoneText(ZM_GRAVEYARD_ZONE,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_ZM_LOOSE_GY_A));
diff --git a/src/game/OutdoorPvPZM.h b/src/game/OutdoorPvPZM.h
index b9d5ae7bc2e..405c0133b5c 100644
--- a/src/game/OutdoorPvPZM.h
+++ b/src/game/OutdoorPvPZM.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/Path.h b/src/game/Path.h
index 2b793aed892..2fd6723b01c 100644
--- a/src/game/Path.h
+++ b/src/game/Path.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
index 6b5ff6c1543..070de6e5899 100644
--- a/src/game/Pet.cpp
+++ b/src/game/Pet.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,12 +21,10 @@
#include "Common.h"
#include "Database/DatabaseEnv.h"
#include "Log.h"
-#include "WorldSession.h"
#include "WorldPacket.h"
#include "ObjectMgr.h"
#include "SpellMgr.h"
#include "Pet.h"
-#include "MapManager.h"
#include "Formulas.h"
#include "SpellAuras.h"
#include "CreatureAI.h"
@@ -41,71 +39,32 @@ char const* petTypeSuffix[MAX_PET_TYPE] =
"'s Companion" // MINI_PET
};
-//numbers represent minutes * 100 while happy (you get 100 loyalty points per min while happy)
-uint32 const LevelUpLoyalty[6] =
-{
- 5500,
- 11500,
- 17000,
- 23500,
- 31000,
- 39500,
-};
-
-uint32 const LevelStartLoyalty[6] =
-{
- 2000,
- 4500,
- 7000,
- 10000,
- 13500,
- 17500,
-};
+#define PET_XP_FACTOR 0.1f
-Pet::Pet(PetType type) : Creature()
+Pet::Pet(Player *owner, PetType type) : Guardian(NULL, owner),
+m_petType(type), m_removed(false), m_happinessTimer(7500), m_duration(0),
+m_resetTalentsCost(0), m_resetTalentsTime(0), m_usedTalentCount(0), m_auraRaidUpdateMask(0), m_loading(false),
+m_declinedname(NULL), m_owner(owner)
{
- m_isPet = true;
+ m_summonMask |= SUMMON_MASK_PET;
m_name = "Pet";
- m_petType = type;
-
- m_removed = false;
m_regenTimer = 4000;
- m_happinessTimer = 7500;
- m_loyaltyTimer = 12000;
- m_duration = 0;
- m_bonusdamage = 0;
-
- m_loyaltyPoints = 0;
- m_TrainingPoints = 0;
- m_resetTalentsCost = 0;
- m_resetTalentsTime = 0;
- m_auraUpdateMask = 0;
+ owner->SetPetAtLoginFlag(0);
- // pets always have a charminfo, even if they are not actually charmed
- CharmInfo* charmInfo = InitCharmInfo();
-
- if(type == MINI_PET || type == POSSESSED_PET) // always passive
+ if(type == POSSESSED_PET) // always passive
SetReactState(REACT_PASSIVE);
- else if(type == GUARDIAN_PET) // always aggressive
- SetReactState(REACT_AGGRESSIVE);
-
- m_spells.clear();
- m_Auras.clear();
- m_CreatureSpellCooldowns.clear();
- m_CreatureCategoryCooldowns.clear();
- m_autospells.clear();
- m_declinedname = NULL;
- //m_isActive = true;
}
Pet::~Pet()
{
if(m_uint32Values) // only for fully created Object
{
- for (PetSpellMap::iterator i = m_spells.begin(); i != m_spells.end(); ++i)
+ if(GetOwnerGUID())
+ sLog.outCrash("Pet %u is deconstructed but it still has owner guid", GetEntry());
+
+ for (PetSpellMap::const_iterator i = m_spells.begin(); i != m_spells.end(); ++i)
delete i->second;
- ObjectAccessor::Instance().RemoveObject(this);
}
delete m_declinedname;
@@ -115,9 +74,11 @@ void Pet::AddToWorld()
{
///- Register the pet for guid lookup
if(!IsInWorld())
- {
+ {
+ ///- Register the pet for guid lookup
ObjectAccessor::Instance().AddObject(this);
Unit::AddToWorld();
+ AIM_Initialize();
}
}
@@ -126,32 +87,42 @@ void Pet::RemoveFromWorld()
///- Remove the pet from the accessor
if(IsInWorld())
{
- ObjectAccessor::Instance().RemoveObject(this);
///- Don't call the function for Creature, normal mobs + totems go in a different storage
Unit::RemoveFromWorld();
+ ObjectAccessor::Instance().RemoveObject(this);
}
}
-bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool current )
+bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool current )
{
+ m_loading = true;
+
uint32 ownerid = owner->GetGUIDLow();
QueryResult *result;
- if(petnumber)
- // known petnumber entry 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
- result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND id = '%u'",ownerid, petnumber);
- else if(current)
- // current pet (slot 0) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
- result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND slot = '0'",ownerid );
- else if(petentry)
+ if (petnumber)
+ // known petnumber entry 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
+ result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType , load_flags "
+ "FROM character_pet WHERE owner = '%u' AND id = '%u'",
+ ownerid, petnumber);
+ else if (current)
+ // current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
+ result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType , load_flags "
+ "FROM character_pet WHERE owner = '%u' AND slot = '%u'",
+ ownerid, PET_SAVE_AS_CURRENT );
+ else if (petentry)
// known petentry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets)
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
- result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '0' OR slot = '3') ",ownerid, petentry );
+ // 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
+ result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType , load_flags "
+ "FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '%u' OR slot > '%u') ",
+ ownerid, petentry,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
else
// any current or other non-stabled pet (for hunter "call pet")
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
- result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3') ",ownerid);
+ // 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
+ result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType , load_flags "
+ "FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u') ",
+ ownerid,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
if(!result)
return false;
@@ -160,28 +131,36 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
// update for case of current pet "slot = 0"
petentry = fields[1].GetUInt32();
- if(!petentry)
+ if (!petentry)
{
delete result;
return false;
}
- uint32 summon_spell_id = fields[21].GetUInt32();
+ uint32 summon_spell_id = fields[19].GetUInt32();
SpellEntry const* spellInfo = sSpellStore.LookupEntry(summon_spell_id);
bool is_temporary_summoned = spellInfo && GetSpellDuration(spellInfo) > 0;
// check temporary summoned pets like mage water elemental
- if(current && is_temporary_summoned)
+ if (current && is_temporary_summoned)
{
delete result;
return false;
}
+ uint32 pet_number = fields[0].GetUInt32();
+
+ if (current && owner->IsPetNeedBeTemporaryUnsummoned())
+ {
+ owner->SetTemporaryUnsummonedPetNumber(pet_number);
+ delete result;
+ return false;
+ }
+
Map *map = owner->GetMap();
uint32 guid = objmgr.GenerateLowGuid(HIGHGUID_PET);
- uint32 pet_number = fields[0].GetUInt32();
- if(!Create(guid, map, petentry, pet_number))
+ if (!Create(guid, map, owner->GetPhaseMask(), petentry, pet_number))
{
delete result;
return false;
@@ -189,181 +168,186 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
float px, py, pz;
owner->GetClosePoint(px, py, pz, GetObjectSize(), PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
-
Relocate(px, py, pz, owner->GetOrientation());
- if(!IsPositionValid())
+ if (!IsPositionValid())
{
- sLog.outError("ERROR: Pet (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)",
+ sLog.outError("Pet (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)",
GetGUIDLow(), GetEntry(), GetPositionX(), GetPositionY());
delete result;
return false;
}
- setPetType(PetType(fields[22].GetUInt8()));
- SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,owner->getFaction());
+ setPetType(PetType(fields[20].GetUInt8()));
+ SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, owner->getFaction());
SetUInt32Value(UNIT_CREATED_BY_SPELL, summon_spell_id);
CreatureInfo const *cinfo = GetCreatureInfo();
- if(cinfo->type == CREATURE_TYPE_CRITTER)
+ if (cinfo->type == CREATURE_TYPE_CRITTER)
{
- AIM_Initialize();
map->Add((Creature*)this);
delete result;
return true;
}
- if(getPetType()==HUNTER_PET || (getPetType()==SUMMON_PET && cinfo->type == CREATURE_TYPE_DEMON && owner->getClass() == CLASS_WARLOCK))
+
+ if (getPetType() == HUNTER_PET || (getPetType() == SUMMON_PET && cinfo->type == CREATURE_TYPE_DEMON && owner->getClass() == CLASS_WARLOCK))
m_charmInfo->SetPetNumber(pet_number, true);
else
m_charmInfo->SetPetNumber(pet_number, false);
- SetUInt64Value(UNIT_FIELD_SUMMONEDBY, owner->GetGUID());
+
+ // set current pet as current
+ // 0=current
+ // 1..MAX_PET_STABLES in stable slot
+ // PET_SAVE_NOT_IN_SLOT(100) = not stable slot (summoning))
+ if(fields[8].GetUInt32() != 0)
+ {
+ CharacterDatabase.BeginTransaction();
+ CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u' AND id <> '%u'",
+ PET_SAVE_NOT_IN_SLOT, ownerid, PET_SAVE_AS_CURRENT, m_charmInfo->GetPetNumber());
+ CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND id = '%u'",
+ PET_SAVE_AS_CURRENT, ownerid, m_charmInfo->GetPetNumber());
+ CharacterDatabase.CommitTransaction();
+ }
+
SetDisplayId(fields[3].GetUInt32());
SetNativeDisplayId(fields[3].GetUInt32());
- uint32 petlevel=fields[4].GetUInt32();
- SetUInt32Value(UNIT_NPC_FLAGS , 0);
- SetName(fields[11].GetString());
+ uint32 petlevel = fields[4].GetUInt32();
+ SetUInt32Value(UNIT_NPC_FLAGS, 0);
+ SetName(fields[9].GetString());
- switch(getPetType())
+ switch (getPetType())
{
-
case SUMMON_PET:
petlevel=owner->getLevel();
- SetUInt32Value(UNIT_FIELD_BYTES_0,2048);
+ SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
// this enables popup window (pet dismiss, cancel)
break;
case HUNTER_PET:
SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100);
- SetByteValue(UNIT_FIELD_BYTES_1, 1, fields[8].GetUInt32());
- SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
- SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 );
-
- if(fields[12].GetBool())
- SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_NOT_ALLOWED);
- else
- SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED);
+ SetByteValue(UNIT_FIELD_BYTES_1, 1, fields[7].GetUInt32());
+ SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
+ SetByteValue(UNIT_FIELD_BYTES_2, 2, fields[10].GetBool() ? UNIT_RENAME_NOT_ALLOWED : UNIT_RENAME_ALLOWED);
SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
// this enables popup window (pet abandon, cancel)
- SetTP(fields[9].GetInt32());
- SetMaxPower(POWER_HAPPINESS,GetCreatePowers(POWER_HAPPINESS));
- SetPower( POWER_HAPPINESS,fields[15].GetUInt32());
+ SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS));
+ SetPower(POWER_HAPPINESS, fields[13].GetUInt32());
setPowerType(POWER_FOCUS);
break;
default:
- sLog.outError("Pet have incorrect type (%u) for pet loading.",getPetType());
+ sLog.outError("Pet have incorrect type (%u) for pet loading.", getPetType());
}
- InitStatsForLevel( petlevel);
+
SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, fields[5].GetUInt32());
- SetUInt64Value(UNIT_FIELD_CREATEDBY, owner->GetGUID());
+ SetCreatorGUID(owner->GetGUID());
SetReactState( ReactStates( fields[6].GetUInt8() ));
- m_loyaltyPoints = fields[7].GetInt32();
-
- uint32 savedhealth = fields[13].GetUInt32();
- uint32 savedmana = fields[14].GetUInt32();
- // set current pet as current
- if(fields[10].GetUInt32() != 0)
+ SetCanModifyStats(true);
+ InitStatsForLevel(petlevel);
+ uint32 savedhealth = fields[11].GetUInt32();
+ uint32 savedmana = fields[12].GetUInt32();
+ if(getPetType() == SUMMON_PET && !current) //all (?) summon pets come with full health when called, but not when they are current
{
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("UPDATE character_pet SET slot = '3' WHERE owner = '%u' AND slot = '0' AND id <> '%u'",ownerid, m_charmInfo->GetPetNumber());
- CharacterDatabase.PExecute("UPDATE character_pet SET slot = '0' WHERE owner = '%u' AND id = '%u'",ownerid, m_charmInfo->GetPetNumber());
- CharacterDatabase.CommitTransaction();
+ SetHealth(GetMaxHealth());
+ SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
}
-
- if(!is_temporary_summoned)
+ else
{
- // permanent controlled pets store state in DB
- Tokens tokens = StrSplit(fields[16].GetString(), " ");
+ SetHealth(savedhealth > GetMaxHealth() ? GetMaxHealth() : savedhealth);
+ SetPower(POWER_MANA, savedmana > GetMaxPower(POWER_MANA) ? GetMaxPower(POWER_MANA) : savedmana);
+ }
- if(tokens.size() != 20)
- {
- delete result;
- return false;
- }
+ map->Add((Creature*)this);
+ owner->SetGuardian(this, true);
- int index;
- Tokens::iterator iter;
- for(iter = tokens.begin(), index = 0; index < 10; ++iter, ++index )
- {
- m_charmInfo->GetActionBarEntry(index)->Type = atol((*iter).c_str());
- ++iter;
- m_charmInfo->GetActionBarEntry(index)->SpellOrAction = atol((*iter).c_str());
-
- // patch for old data where some spells have ACT_DECIDE but should have ACT_CAST
- // so overwrite old state
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_charmInfo->GetActionBarEntry(index)->SpellOrAction);
- if (spellInfo && spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET) m_charmInfo->GetActionBarEntry(index)->Type = ACT_CAST;
- }
+ m_resetTalentsCost = fields[17].GetUInt32();
+ m_resetTalentsTime = fields[18].GetUInt64();
+ uint8 loadFlags = fields[21].GetUInt8();
+ if (loadFlags & AT_LOAD_RESET_SPELLS)
+ {
+ CharacterDatabase.PExecute("UPDATE character_pet SET load_flags = load_flags & ~ %u WHERE id = '%u'",uint32(AT_LOAD_RESET_SPELLS),pet_number);
+ loadFlags &= ~uint8(AT_LOAD_RESET_SPELLS);
+ CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u'",pet_number);
+ InitPetCreateSpells();
+ resetTalents(true);
+ learnLevelupSpells();
+ }
+ else
+ {
+ learnLevelupSpells();
+ LearnPetPassives();
+ _LoadSpells();
+ _LoadSpellCooldowns();
- //init teach spells
- tokens = StrSplit(fields[17].GetString(), " ");
- for (iter = tokens.begin(), index = 0; index < 4; ++iter, ++index)
+ // Load action bar data
+ if (!is_temporary_summoned)
{
- uint32 tmp = atol((*iter).c_str());
+ // permanent controlled pets store state in DB
+ Tokens tokens = StrSplit(fields[14].GetString(), " ");
- ++iter;
+ if (tokens.size() != 20)
+ {
+ delete result;
+ return false;
+ }
- if(tmp)
- AddTeachSpell(tmp, atol((*iter).c_str()));
- else
- break;
- }
- }
+ int index;
+ Tokens::iterator iter;
+ for(iter = tokens.begin(), index = 0; index < 10; ++iter, ++index )
+ {
+ m_charmInfo->GetActionBarEntry(index)->Type = atol((*iter).c_str());
+ ++iter;
+ m_charmInfo->GetActionBarEntry(index)->SpellOrAction = atol((*iter).c_str());
- // since last save (in seconds)
- uint32 timediff = (time(NULL) - fields[18].GetUInt32());
+ // patch for old data where some spells have ACT_DECIDE but should have ACT_CAST
+ // so overwrite old state
+ if(SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_charmInfo->GetActionBarEntry(index)->SpellOrAction))
+ {
+ if (spellInfo && spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET)
+ m_charmInfo->GetActionBarEntry(index)->Type = ACT_DISABLED;
- delete result;
+ if(m_charmInfo->GetActionBarEntry(index)->Type == ACT_ENABLED)
+ ToggleAutocast(spellInfo->Id, true);
+ }
+ }
- //load spells/cooldowns/auras
- SetCanModifyStats(true);
- _LoadAuras(timediff);
+ //init teach spells
+ tokens = StrSplit(fields[15].GetString(), " ");
+ for (iter = tokens.begin(), index = 0; index < 4; ++iter, ++index)
+ {
+ uint32 tmp = atol((*iter).c_str());
- //init AB
- if(is_temporary_summoned)
- {
- // Temporary summoned pets always have initial spell list at load
- InitPetCreateSpells();
- }
- else
- {
- LearnPetPassives();
- CastPetAuras(current);
- }
+ ++iter;
- if(getPetType() == SUMMON_PET && !current) //all (?) summon pets come with full health when called, but not when they are current
- {
- SetHealth(GetMaxHealth());
- SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
- }
- else
- {
- SetHealth(savedhealth > GetMaxHealth() ? GetMaxHealth() : savedhealth);
- SetPower(POWER_MANA, savedmana > GetMaxPower(POWER_MANA) ? GetMaxPower(POWER_MANA) : savedmana);
+ if(tmp)
+ AddTeachSpell(tmp, atol((*iter).c_str()));
+ else
+ break;
+ }
+ }
}
+ owner->SetPetAtLoginFlag(loadFlags);
- AIM_Initialize();
- map->Add((Creature*)this);
-
- // Spells should be loaded after pet is added to map, because in CanCast is check on it
- _LoadSpells();
- _LoadSpellCooldowns();
+ //load spells/cooldowns/auras
+ // Spells should be loaded after pet is added to map, because in CheckCast is check on it
+ // since last save (in seconds)
+ uint32 timediff = (time(NULL) - fields[16].GetUInt32());
+ _LoadAuras(timediff);
+ CastPetAuras(current);
- owner->SetPet(this); // in DB stored only full controlled creature
+ delete result;
sLog.outDebug("New Pet has guid %u", GetGUIDLow());
- if(owner->GetTypeId() == TYPEID_PLAYER)
- {
- ((Player*)owner)->PetSpellInitialize();
- if(((Player*)owner)->GetGroup())
- ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_PET);
- }
+ owner->PetSpellInitialize();
+
+ if(owner->GetGroup())
+ owner->SetGroupUpdateFlag(GROUP_UPDATE_PET);
- if(owner->GetTypeId() == TYPEID_PLAYER && getPetType() == HUNTER_PET)
+ if(getPetType() == HUNTER_PET)
{
result = CharacterDatabase.PQuery("SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE owner = '%u' AND id = '%u'", owner->GetGUIDLow(), GetCharmInfo()->GetPetNumber());
@@ -373,129 +357,129 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
delete m_declinedname;
m_declinedname = new DeclinedName;
- Field *fields = result->Fetch();
+ Field *fields2 = result->Fetch();
for(int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
{
- m_declinedname->name[i] = fields[i].GetCppString();
+ m_declinedname->name[i] = fields2[i].GetCppString();
}
}
}
+ m_loading = false;
return true;
}
void Pet::SavePetToDB(PetSaveMode mode)
{
- if(!GetEntry())
+ if (!GetEntry())
return;
// save only fully controlled creature
- if(!isControlled())
+ if (!isControlled())
+ return;
+
+ // not save not player pets
+ if(!IS_PLAYER_GUID(GetOwnerGUID()))
+ return;
+
+ Player* pOwner = (Player*)GetOwner();
+ if (!pOwner)
return;
+ // not save pet as current if another pet temporary unsummoned
+ if (mode == PET_SAVE_AS_CURRENT && pOwner->GetTemporaryUnsummonedPetNumber() &&
+ pOwner->GetTemporaryUnsummonedPetNumber() != m_charmInfo->GetPetNumber())
+ {
+ // pet will lost anyway at restore temporary unsummoned
+ if(getPetType()==HUNTER_PET)
+ return;
+
+ // for warlock case
+ mode = PET_SAVE_NOT_IN_SLOT;
+ }
+
uint32 curhealth = GetHealth();
uint32 curmana = GetPower(POWER_MANA);
- switch(mode)
+ // stable and not in slot saves
+ if(mode > PET_SAVE_AS_CURRENT)
{
- case PET_SAVE_IN_STABLE_SLOT_1:
- case PET_SAVE_IN_STABLE_SLOT_2:
- case PET_SAVE_NOT_IN_SLOT:
- {
- RemoveAllAuras();
-
- //only alive hunter pets get auras saved, the others don't
- if(!(getPetType() == HUNTER_PET && isAlive()))
- m_Auras.clear();
- }
- default:
- break;
+ RemoveAllAuras();
}
_SaveSpells();
_SaveSpellCooldowns();
_SaveAuras();
- switch(mode)
+ // current/stable/not_in_slot
+ if(mode >= PET_SAVE_AS_CURRENT)
{
- case PET_SAVE_AS_CURRENT:
- case PET_SAVE_IN_STABLE_SLOT_1:
- case PET_SAVE_IN_STABLE_SLOT_2:
- case PET_SAVE_NOT_IN_SLOT:
+ uint32 owner = GUID_LOPART(GetOwnerGUID());
+ std::string name = m_name;
+ CharacterDatabase.escape_string(name);
+ CharacterDatabase.BeginTransaction();
+ // remove current data
+ CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND id = '%u'", owner,m_charmInfo->GetPetNumber() );
+
+ // prevent duplicate using slot (except PET_SAVE_NOT_IN_SLOT)
+ if(mode <= PET_SAVE_LAST_STABLE_SLOT)
+ CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u'",
+ PET_SAVE_NOT_IN_SLOT, owner, uint32(mode) );
+
+ // prevent existence another hunter pet in PET_SAVE_AS_CURRENT and PET_SAVE_NOT_IN_SLOT
+ if(getPetType()==HUNTER_PET && (mode==PET_SAVE_AS_CURRENT||mode > PET_SAVE_LAST_STABLE_SLOT))
+ CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u')",
+ owner,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
+ // save pet
+ std::ostringstream ss;
+ ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType, load_flags) "
+ << "VALUES ("
+ << m_charmInfo->GetPetNumber() << ", "
+ << GetEntry() << ", "
+ << owner << ", "
+ << GetNativeDisplayId() << ", "
+ << getLevel() << ", "
+ << GetUInt32Value(UNIT_FIELD_PETEXPERIENCE) << ", "
+ << uint32(GetReactState()) << ", "
+ << uint32(GetFreeTalentPoints()) << ", "
+ << uint32(mode) << ", '"
+ << name.c_str() << "', "
+ << uint32((GetByteValue(UNIT_FIELD_BYTES_2, 2) == UNIT_RENAME_ALLOWED)?0:1) << ", "
+ << (curhealth<1?1:curhealth) << ", "
+ << curmana << ", "
+ << GetPower(POWER_HAPPINESS) << ", '";
+
+ for(uint32 i = 0; i < 10; ++i)
+ ss << uint32(m_charmInfo->GetActionBarEntry(i)->Type) << " " << uint32(m_charmInfo->GetActionBarEntry(i)->SpellOrAction) << " ";
+ ss << "', '";
+
+ //save spells the pet can teach to it's Master
{
- uint32 loyalty =1;
- if(getPetType()!=HUNTER_PET)
- loyalty = GetLoyaltyLevel();
-
- uint32 owner = GUID_LOPART(GetOwnerGUID());
- std::string name = m_name;
- CharacterDatabase.escape_string(name);
- CharacterDatabase.BeginTransaction();
- // remove current data
- CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND id = '%u'", owner,m_charmInfo->GetPetNumber() );
-
- // prevent duplicate using slot (except PET_SAVE_NOT_IN_SLOT)
- if(mode!=PET_SAVE_NOT_IN_SLOT)
- CharacterDatabase.PExecute("UPDATE character_pet SET slot = 3 WHERE owner = '%u' AND slot = '%u'", owner, uint32(mode) );
-
- // prevent existence another hunter pet in PET_SAVE_AS_CURRENT and PET_SAVE_NOT_IN_SLOT
- if(getPetType()==HUNTER_PET && (mode==PET_SAVE_AS_CURRENT||mode==PET_SAVE_NOT_IN_SLOT))
- CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3')", owner );
- // save pet
- std::ostringstream ss;
- ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata,TeachSpelldata,savetime,resettalents_cost,resettalents_time,CreatedBySpell,PetType) "
- << "VALUES ("
- << m_charmInfo->GetPetNumber() << ", "
- << GetEntry() << ", "
- << owner << ", "
- << GetNativeDisplayId() << ", "
- << getLevel() << ", "
- << GetUInt32Value(UNIT_FIELD_PETEXPERIENCE) << ", "
- << uint32(GetReactState()) << ", "
- << m_loyaltyPoints << ", "
- << GetLoyaltyLevel() << ", "
- << m_TrainingPoints << ", "
- << uint32(mode) << ", '"
- << name.c_str() << "', "
- << uint32((GetByteValue(UNIT_FIELD_BYTES_2, 2) == UNIT_RENAME_ALLOWED)?0:1) << ", "
- << (curhealth<1?1:curhealth) << ", "
- << curmana << ", "
- << GetPower(POWER_HAPPINESS) << ", '";
-
- for(uint32 i = 0; i < 10; i++)
- ss << uint32(m_charmInfo->GetActionBarEntry(i)->Type) << " " << uint32(m_charmInfo->GetActionBarEntry(i)->SpellOrAction) << " ";
- ss << "', '";
-
- //save spells the pet can teach to it's Master
- {
- int i = 0;
- for(TeachSpellMap::iterator itr = m_teachspells.begin(); i < 4 && itr != m_teachspells.end(); ++i, ++itr)
- ss << itr->first << " " << itr->second << " ";
- for(; i < 4; ++i)
- ss << uint32(0) << " " << uint32(0) << " ";
- }
-
- ss << "', "
- << time(NULL) << ", "
- << uint32(m_resetTalentsCost) << ", "
- << uint64(m_resetTalentsTime) << ", "
- << GetUInt32Value(UNIT_CREATED_BY_SPELL) << ", "
- << uint32(getPetType()) << ")";
+ int i = 0;
+ for(TeachSpellMap::const_iterator itr = m_teachspells.begin(); i < 4 && itr != m_teachspells.end(); ++i, ++itr)
+ ss << itr->first << " " << itr->second << " ";
+ for(; i < 4; ++i)
+ ss << uint32(0) << " " << uint32(0) << " ";
+ }
- CharacterDatabase.Execute( ss.str().c_str() );
+ ss << "', "
+ << time(NULL) << ", "
+ << uint32(m_resetTalentsCost) << ", "
+ << uint64(m_resetTalentsTime) << ", "
+ << GetUInt32Value(UNIT_CREATED_BY_SPELL) << ", "
+ << uint32(getPetType()) << ", "
+ << (pOwner->GetAtLoginFlag()>>AT_LOAD_PET_FLAGS) << ")";
- CharacterDatabase.CommitTransaction();
- break;
- }
- case PET_SAVE_AS_DELETED:
- {
- RemoveAllAuras();
- DeleteFromDB(m_charmInfo->GetPetNumber());
- break;
- }
- default:
- sLog.outError("Unknown pet save/remove mode: %d",mode);
+ CharacterDatabase.Execute( ss.str().c_str() );
+ CharacterDatabase.CommitTransaction();
}
+ // delete
+ else
+ {
+ RemoveAllAuras();
+ DeleteFromDB(m_charmInfo->GetPetNumber());
+ }
+ pOwner->SetPetAtLoginFlag(0);
}
void Pet::DeleteFromDB(uint32 guidlow)
@@ -512,11 +496,7 @@ void Pet::setDeathState(DeathState s) // overwrite virtual
Creature::setDeathState(s);
if(getDeathState()==CORPSE)
{
- //remove summoned pet (no corpse)
- if(getPetType()==SUMMON_PET)
- Remove(PET_SAVE_NOT_IN_SLOT);
- // other will despawn at corpse desppawning (Pet::Update code)
- else
+ if(getPetType() == HUNTER_PET)
{
// pet corpse non lootable and non skinnable
SetUInt32Value( UNIT_DYNAMIC_FLAGS, 0x00 );
@@ -527,12 +507,12 @@ void Pet::setDeathState(DeathState s) // overwrite virtual
if(!mapEntry || (mapEntry->map_type != MAP_ARENA && mapEntry->map_type != MAP_BATTLEGROUND))
ModifyPower(POWER_HAPPINESS, -HAPPINESS_LEVEL_SIZE);
- SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
+ SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
}
}
else if(getDeathState()==ALIVE)
{
- RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
+ RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
CastPetAuras(true);
}
}
@@ -546,9 +526,8 @@ void Pet::Update(uint32 diff)
{
case CORPSE:
{
- if( m_deathTimer <= diff )
+ if(getPetType() != HUNTER_PET || m_deathTimer <= diff )
{
- assert(getPetType()!=SUMMON_PET && "Must be already removed.");
Remove(PET_SAVE_NOT_IN_SLOT); //hunters' pets never get removed because of death, NEVER!
return;
}
@@ -557,8 +536,9 @@ void Pet::Update(uint32 diff)
case ALIVE:
{
// unsummon pet that lost owner
- Unit* owner = GetOwner();
+ Player* owner = GetOwner();
if(!owner || (!IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) && !isPossessed()) || isControlled() && !owner->GetPetGUID())
+ //if(!owner || (!IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) && (owner->GetCharmGUID() && (owner->GetCharmGUID() != GetGUID()))) || (isControlled() && !owner->GetPetGUID()))
{
Remove(PET_SAVE_NOT_IN_SLOT, true);
return;
@@ -568,6 +548,7 @@ void Pet::Update(uint32 diff)
{
if( owner->GetPetGUID() != GetGUID() )
{
+ sLog.outError("Pet %u is not pet of owner %u, removed", GetEntry(), m_owner->GetName());
Remove(getPetType()==HUNTER_PET?PET_SAVE_AS_DELETED:PET_SAVE_NOT_IN_SLOT);
return;
}
@@ -604,14 +585,6 @@ void Pet::Update(uint32 diff)
else
m_happinessTimer -= diff;
- if(m_loyaltyTimer <= diff)
- {
- TickLoyaltyChange();
- m_loyaltyTimer = 12000;
- }
- else
- m_loyaltyTimer -= diff;
-
break;
}
default:
@@ -630,10 +603,10 @@ void Pet::RegenerateFocus()
float addvalue = 24 * sWorld.getRate(RATE_POWER_FOCUS);
- AuraList const& ModPowerRegenPCTAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
- for(AuraList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
- if ((*i)->GetModifier()->m_miscvalue == POWER_FOCUS)
- addvalue *= ((*i)->GetModifierValue() + 100) / 100.0f;
+ AuraEffectList const& ModPowerRegenPCTAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
+ for(AuraEffectList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
+ if ((*i)->GetMiscValue() == POWER_FOCUS)
+ addvalue *= ((*i)->GetAmount() + 100) / 100.0f;
ModifyPower(POWER_FOCUS, (int32)addvalue);
}
@@ -643,83 +616,12 @@ void Pet::LooseHappiness()
uint32 curValue = GetPower(POWER_HAPPINESS);
if (curValue <= 0)
return;
- int32 addvalue = (140 >> GetLoyaltyLevel()) * 125; //value is 70/35/17/8/4 (per min) * 1000 / 8 (timer 7.5 secs)
+ int32 addvalue = 670; //value is 70/35/17/8/4 (per min) * 1000 / 8 (timer 7.5 secs)
if(isInCombat()) //we know in combat happiness fades faster, multiplier guess
addvalue = int32(addvalue * 1.5);
ModifyPower(POWER_HAPPINESS, -addvalue);
}
-void Pet::ModifyLoyalty(int32 addvalue)
-{
- uint32 loyaltylevel = GetLoyaltyLevel();
-
- if(addvalue > 0) //only gain influenced, not loss
- addvalue = int32((float)addvalue * sWorld.getRate(RATE_LOYALTY));
-
- if(loyaltylevel >= BEST_FRIEND && (addvalue + m_loyaltyPoints) > int32(GetMaxLoyaltyPoints(loyaltylevel)))
- return;
-
- m_loyaltyPoints += addvalue;
-
- if(m_loyaltyPoints < 0)
- {
- if(loyaltylevel > REBELLIOUS)
- {
- //level down
- --loyaltylevel;
- SetLoyaltyLevel(LoyaltyLevel(loyaltylevel));
- m_loyaltyPoints = GetStartLoyaltyPoints(loyaltylevel);
- SetTP(m_TrainingPoints - int32(getLevel()));
- }
- else
- {
- m_loyaltyPoints = 0;
- Unit* owner = GetOwner();
- if(owner && owner->GetTypeId() == TYPEID_PLAYER)
- {
- WorldPacket data(SMSG_PET_BROKEN, 0);
- ((Player*)owner)->GetSession()->SendPacket(&data);
-
- //run away
- ((Player*)owner)->RemovePet(this,PET_SAVE_AS_DELETED);
- }
- }
- }
- //level up
- else if(m_loyaltyPoints > int32(GetMaxLoyaltyPoints(loyaltylevel)))
- {
- ++loyaltylevel;
- SetLoyaltyLevel(LoyaltyLevel(loyaltylevel));
- m_loyaltyPoints = GetStartLoyaltyPoints(loyaltylevel);
- SetTP(m_TrainingPoints + getLevel());
- }
-}
-
-void Pet::TickLoyaltyChange()
-{
- int32 addvalue;
-
- switch(GetHappinessState())
- {
- case HAPPY: addvalue = 20; break;
- case CONTENT: addvalue = 10; break;
- case UNHAPPY: addvalue = -20; break;
- default:
- return;
- }
- ModifyLoyalty(addvalue);
-}
-
-void Pet::KillLoyaltyBonus(uint32 level)
-{
- if(level > 100)
- return;
-
- //at lower levels gain is faster | the lower loyalty the more loyalty is gained
- uint32 bonus = uint32(((100 - level) / 10) + (6 - GetLoyaltyLevel()));
- ModifyLoyalty(bonus);
-}
-
HappinessState Pet::GetHappinessState()
{
if(GetPower(POWER_HAPPINESS) < HAPPINESS_LEVEL_SIZE)
@@ -730,11 +632,6 @@ HappinessState Pet::GetHappinessState()
return CONTENT;
}
-void Pet::SetLoyaltyLevel(LoyaltyLevel level)
-{
- SetByteValue(UNIT_FIELD_BYTES_1, 1, level);
-}
-
bool Pet::CanTakeMoreActiveSpells(uint32 spellid)
{
uint8 activecount = 1;
@@ -745,7 +642,7 @@ bool Pet::CanTakeMoreActiveSpells(uint32 spellid)
chainstartstore[0] = spellmgr.GetFirstSpellInChain(spellid);
- for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
+ for (PetSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
{
if(IsPassiveSpell(itr->first))
continue;
@@ -771,102 +668,9 @@ bool Pet::CanTakeMoreActiveSpells(uint32 spellid)
return true;
}
-bool Pet::HasTPForSpell(uint32 spellid)
-{
- int32 neededtrainp = GetTPForSpell(spellid);
- if((m_TrainingPoints - neededtrainp < 0 || neededtrainp < 0) && neededtrainp != 0)
- return false;
- return true;
-}
-
-int32 Pet::GetTPForSpell(uint32 spellid)
-{
- uint32 basetrainp = 0;
-
- SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spellid);
- SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spellid);
- for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
- {
- if(!_spell_idx->second->reqtrainpoints)
- return 0;
-
- basetrainp = _spell_idx->second->reqtrainpoints;
- break;
- }
-
- uint32 spenttrainp = 0;
- uint32 chainstart = spellmgr.GetFirstSpellInChain(spellid);
-
- for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
- {
- if(itr->second->state == PETSPELL_REMOVED)
- continue;
-
- if(spellmgr.GetFirstSpellInChain(itr->first) == chainstart)
- {
- SkillLineAbilityMap::const_iterator _lower = spellmgr.GetBeginSkillLineAbilityMap(itr->first);
- SkillLineAbilityMap::const_iterator _upper = spellmgr.GetEndSkillLineAbilityMap(itr->first);
-
- for(SkillLineAbilityMap::const_iterator _spell_idx2 = _lower; _spell_idx2 != _upper; ++_spell_idx2)
- {
- if(_spell_idx2->second->reqtrainpoints > spenttrainp)
- {
- spenttrainp = _spell_idx2->second->reqtrainpoints;
- break;
- }
- }
- }
- }
-
- return int32(basetrainp) - int32(spenttrainp);
-}
-
-uint32 Pet::GetMaxLoyaltyPoints(uint32 level)
-{
- return LevelUpLoyalty[level - 1];
-}
-
-uint32 Pet::GetStartLoyaltyPoints(uint32 level)
-{
- return LevelStartLoyalty[level - 1];
-}
-
-void Pet::SetTP(int32 TP)
-{
- m_TrainingPoints = TP;
- SetUInt32Value(UNIT_TRAINING_POINTS, (uint32)GetDispTP());
-}
-
-int32 Pet::GetDispTP()
-{
- if(getPetType()!= HUNTER_PET)
- return(0);
- if(m_TrainingPoints < 0)
- return -m_TrainingPoints;
- else
- return -(m_TrainingPoints + 1);
-}
-
void Pet::Remove(PetSaveMode mode, bool returnreagent)
{
- Unit* owner = GetOwner();
-
- if(owner)
- {
- if(owner->GetTypeId()==TYPEID_PLAYER)
- {
- ((Player*)owner)->RemovePet(this,mode,returnreagent);
- return;
- }
-
- // only if current pet in slot
- if(owner->GetPetGUID()==GetGUID())
- owner->SetPet(0);
- }
-
- CleanupsBeforeDelete();
- AddObjectToRemoveList();
- m_removed = true;
+ m_owner->RemovePet(this,mode,returnreagent);
}
void Pet::GivePetXP(uint32 xp)
@@ -901,7 +705,7 @@ void Pet::GivePetXP(uint32 xp)
newXP -= nextLvlXP;
SetLevel( level + 1 );
- SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((Trinity::XP::xp_to_level(level+1))/4));
+ SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(level+1)*PET_XP_FACTOR);
level = getLevel();
nextLvlXP = GetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP);
@@ -909,9 +713,6 @@ void Pet::GivePetXP(uint32 xp)
}
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, newXP);
-
- if(getPetType() == HUNTER_PET)
- KillLoyaltyBonus(level);
}
void Pet::GivePetLevel(uint32 level)
@@ -919,16 +720,15 @@ void Pet::GivePetLevel(uint32 level)
if(!level)
return;
- InitStatsForLevel( level);
-
- SetTP(m_TrainingPoints + (GetLoyaltyLevel() - 1));
+ InitStatsForLevel(level);
+ InitTalentForLevel();
}
bool Pet::CreateBaseAtCreature(Creature* creature)
{
if(!creature)
{
- sLog.outError("CRITICAL ERROR: NULL pointer parsed into CreateBaseAtCreature()");
+ sLog.outError("CRITICAL: NULL pointer parsed into CreateBaseAtCreature()");
return false;
}
uint32 guid=objmgr.GenerateLowGuid(HIGHGUID_PET);
@@ -938,14 +738,14 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
sLog.outDebug("Create pet");
uint32 pet_number = objmgr.GeneratePetNumber();
- if(!Create(guid, creature->GetMap(), creature->GetEntry(), pet_number))
+ if(!Create(guid, creature->GetMap(), creature->GetPhaseMask(), creature->GetEntry(), pet_number))
return false;
Relocate(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation());
if(!IsPositionValid())
{
- sLog.outError("ERROR: Pet (guidlow %d, entry %d) not created base at creature. Suggested coordinates isn't valid (X: %f Y: %f)",
+ sLog.outError("Pet (guidlow %d, entry %d) not created base at creature. Suggested coordinates isn't valid (X: %f Y: %f)",
GetGUIDLow(), GetEntry(), GetPositionX(), GetPositionY());
return false;
}
@@ -953,15 +753,10 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
CreatureInfo const *cinfo = GetCreatureInfo();
if(!cinfo)
{
- sLog.outError("ERROR: CreateBaseAtCreature() failed, creatureInfo is missing!");
+ sLog.outError("CreateBaseAtCreature() failed, creatureInfo is missing!");
return false;
}
- if(cinfo->type == CREATURE_TYPE_CRITTER)
- {
- setPetType(MINI_PET);
- return true;
- }
SetDisplayId(creature->GetDisplayId());
SetNativeDisplayId(creature->GetNativeDisplayId());
SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS));
@@ -969,45 +764,44 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
setPowerType(POWER_FOCUS);
SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0);
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
- SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((Trinity::XP::xp_to_level(creature->getLevel()))/4));
- SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+ SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(creature->getLevel())*PET_XP_FACTOR);
SetUInt32Value(UNIT_NPC_FLAGS, 0);
- CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(creature->GetCreatureInfo()->family);
- if( char* familyname = cFamily->Name[sWorld.GetDefaultDbcLocale()] )
- SetName(familyname);
+ if(CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family))
+ SetName(cFamily->Name[sWorld.GetDefaultDbcLocale()]);
else
- SetName(creature->GetName());
+ SetName(creature->GetNameForLocaleIdx(objmgr.GetDBCLocaleIndex()));
- m_loyaltyPoints = 1000;
if(cinfo->type == CREATURE_TYPE_BEAST)
{
SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100);
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
- SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 );
SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED);
-
- SetUInt32Value(UNIT_MOD_CAST_SPEED, creature->GetUInt32Value(UNIT_MOD_CAST_SPEED) );
- SetLoyaltyLevel(REBELLIOUS);
+ SetUInt32Value(UNIT_MOD_CAST_SPEED, creature->GetUInt32Value(UNIT_MOD_CAST_SPEED));
}
return true;
}
-bool Pet::InitStatsForLevel(uint32 petlevel)
+bool Guardian::InitStatsForLevel(uint32 petlevel)
{
CreatureInfo const *cinfo = GetCreatureInfo();
assert(cinfo);
- Unit* owner = GetOwner();
- if(!owner)
+ SetLevel(petlevel);
+
+ //Determine pet type
+ PetType petType = MAX_PET_TYPE;
+ if(HasSummonMask(SUMMON_MASK_PET) && m_owner->GetTypeId() == TYPEID_PLAYER)
{
- sLog.outError("ERROR: attempt to summon pet (Entry %u) without owner! Attempt terminated.", cinfo->Entry);
- return false;
+ if(m_owner->getClass() == CLASS_WARLOCK)
+ petType = SUMMON_PET;
+ else if(m_owner->getClass() == CLASS_HUNTER)
+ petType = HUNTER_PET;
+ else
+ sLog.outError("Unknown type pet %u is summoned by player class %u", GetEntry(), m_owner->getClass());
}
- uint32 creature_ID = (getPetType() == HUNTER_PET) ? 1 : cinfo->Entry;
-
- SetLevel(petlevel);
+ uint32 creature_ID = (petType == HUNTER_PET) ? 1 : cinfo->Entry;
SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool));
@@ -1019,8 +813,9 @@ bool Pet::InitStatsForLevel(uint32 petlevel)
SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0);
+ //scale
CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family);
- if(cFamily && cFamily->minScale > 0.0f && getPetType()==HUNTER_PET)
+ if(cFamily && cFamily->minScale > 0.0f && petType==HUNTER_PET)
{
float scale;
if (getLevel() >= cFamily->maxScaleLevel)
@@ -1032,11 +827,10 @@ bool Pet::InitStatsForLevel(uint32 petlevel)
SetFloatValue(OBJECT_FIELD_SCALE_X, scale);
}
- m_bonusdamage = 0;
+ //resistance
int32 createResistance[MAX_SPELL_SCHOOL] = {0,0,0,0,0,0,0};
-
- if(cinfo && getPetType() != HUNTER_PET)
+ if(cinfo && petType != HUNTER_PET)
{
createResistance[SPELL_SCHOOL_HOLY] = cinfo->resistance1;
createResistance[SPELL_SCHOOL_FIRE] = cinfo->resistance2;
@@ -1045,158 +839,125 @@ bool Pet::InitStatsForLevel(uint32 petlevel)
createResistance[SPELL_SCHOOL_SHADOW] = cinfo->resistance5;
createResistance[SPELL_SCHOOL_ARCANE] = cinfo->resistance6;
}
+ for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
+ SetModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(createResistance[i]));
- switch(getPetType())
+ //health, mana, armor and resistance
+ PetLevelInfo const* pInfo = objmgr.GetPetLevelInfo(creature_ID, petlevel);
+ if(pInfo) // exist in DB
{
- case SUMMON_PET:
- {
- if(owner->GetTypeId() == TYPEID_PLAYER)
- {
- switch(owner->getClass())
- {
- case CLASS_WARLOCK:
- {
+ SetCreateHealth(pInfo->health);
+ if(petType != HUNTER_PET) //hunter pet use focus
+ SetCreateMana(pInfo->mana);
- //the damage bonus used for pets is either fire or shadow damage, whatever is higher
- uint32 fire = owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE);
- uint32 shadow = owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW);
- uint32 val = (fire > shadow) ? fire : shadow;
+ if(pInfo->armor > 0)
+ SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(pInfo->armor));
- SetBonusDamage(int32 (val * 0.15f));
- //bonusAP += val * 0.57;
- break;
- }
- case CLASS_MAGE:
- {
- //40% damage bonus of mage's frost damage
- float val = owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FROST) * 0.4;
- if(val < 0)
- val = 0;
- SetBonusDamage( int32(val));
- break;
- }
- default:
- break;
- }
- }
+ for(int stat = 0; stat < MAX_STATS; ++stat)
+ SetCreateStat(Stats(stat), float(pInfo->stats[stat]));
+ }
+ else // not exist in DB, use some default fake data
+ {
+ // remove elite bonuses included in DB values
+ //SetCreateHealth(uint32(((float(cinfo->maxhealth) / cinfo->maxlevel) / (1 + 2 * cinfo->rank)) * petlevel) );
+ //SetCreateMana( uint32(((float(cinfo->maxmana) / cinfo->maxlevel) / (1 + 2 * cinfo->rank)) * petlevel) );
+
+ SetCreateStat(STAT_STRENGTH, 22);
+ SetCreateStat(STAT_AGILITY, 22);
+ SetCreateStat(STAT_STAMINA, 25);
+ SetCreateStat(STAT_INTELLECT, 28);
+ SetCreateStat(STAT_SPIRIT, 27);
+ }
+
+ m_bonusdamage = 0;
+ switch(petType)
+ {
+ case SUMMON_PET:
+ {
+ //the damage bonus used for pets is either fire or shadow damage, whatever is higher
+ uint32 fire = m_owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE);
+ uint32 shadow = m_owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW);
+ uint32 val = (fire > shadow) ? fire : shadow;
+ SetBonusDamage(int32 (val * 0.15f));
+ //bonusAP += val * 0.57;
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)) );
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)) );
//SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, float(cinfo->attackpower));
-
- PetLevelInfo const* pInfo = objmgr.GetPetLevelInfo(creature_ID, petlevel);
- if(pInfo) // exist in DB
- {
- SetCreateHealth(pInfo->health);
- SetCreateMana(pInfo->mana);
-
- if(pInfo->armor > 0)
- SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(pInfo->armor));
-
- for(int stat = 0; stat < MAX_STATS; ++stat)
- {
- SetCreateStat(Stats(stat), float(pInfo->stats[stat]));
- }
- }
- else // not exist in DB, use some default fake data
- {
- sLog.outErrorDb("Summoned pet (Entry: %u) not have pet stats data in DB",cinfo->Entry);
-
- // remove elite bonuses included in DB values
- SetCreateHealth(uint32(((float(cinfo->maxhealth) / cinfo->maxlevel) / (1 + 2 * cinfo->rank)) * petlevel) );
- SetCreateMana( uint32(((float(cinfo->maxmana) / cinfo->maxlevel) / (1 + 2 * cinfo->rank)) * petlevel) );
-
- SetCreateStat(STAT_STRENGTH, 22);
- SetCreateStat(STAT_AGILITY, 22);
- SetCreateStat(STAT_STAMINA, 25);
- SetCreateStat(STAT_INTELLECT, 28);
- SetCreateStat(STAT_SPIRIT, 27);
- }
break;
}
case HUNTER_PET:
{
- SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((Trinity::XP::xp_to_level(petlevel))/4));
-
+ SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(petlevel)*PET_XP_FACTOR);
//these formula may not be correct; however, it is designed to be close to what it should be
//this makes dps 0.5 of pets level
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)) );
//damage range is then petlevel / 2
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)) );
//damage is increased afterwards as strength and pet scaling modify attack power
-
- //stored standard pet stats are entry 1 in pet_levelinfo
- PetLevelInfo const* pInfo = objmgr.GetPetLevelInfo(creature_ID, petlevel);
- if(pInfo) // exist in DB
- {
- SetCreateHealth(pInfo->health);
- SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(pInfo->armor));
- //SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, float(cinfo->attackpower));
-
- for( int i = STAT_STRENGTH; i < MAX_STATS; i++)
- {
- SetCreateStat(Stats(i), float(pInfo->stats[i]));
- }
- }
- else // not exist in DB, use some default fake data
- {
- sLog.outErrorDb("Hunter pet levelstats missing in DB");
-
- // remove elite bonuses included in DB values
- SetCreateHealth( uint32(((float(cinfo->maxhealth) / cinfo->maxlevel) / (1 + 2 * cinfo->rank)) * petlevel) );
-
- SetCreateStat(STAT_STRENGTH, 22);
- SetCreateStat(STAT_AGILITY, 22);
- SetCreateStat(STAT_STAMINA, 25);
- SetCreateStat(STAT_INTELLECT, 28);
- SetCreateStat(STAT_SPIRIT, 27);
- }
break;
}
- case GUARDIAN_PET:
- SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
- SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000);
-
+ default:
+ {
switch(GetEntry())
{
+ case 510: // mage Water Elemental
+ {
+ //40% damage bonus of mage's frost damage
+ float val = m_owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FROST) * 0.4;
+ if(val < 0)
+ val = 0;
+ SetBonusDamage( int32(val));
+ break;
+ }
case 1964: //force of nature
- SetCreateHealth(30 + 30*petlevel);
+ {
+ if(!pInfo)
+ SetCreateHealth(30 + 30*petlevel);
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 2.5f - (petlevel / 2)));
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 2.5f + (petlevel / 2)));
break;
+ }
case 15352: //earth elemental 36213
- SetCreateHealth(100 + 120*petlevel);
+ {
+ if(!pInfo)
+ SetCreateHealth(100 + 120*petlevel);
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)));
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)));
break;
+ }
case 15438: //fire elemental
- SetCreateHealth(40*petlevel);
- SetCreateMana(28 + 10*petlevel);
+ {
+ if(!pInfo)
+ {
+ SetCreateHealth(40*petlevel);
+ SetCreateMana(28 + 10*petlevel);
+ }
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 4 - petlevel));
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 4 + petlevel));
break;
+ }
default:
- SetCreateMana(28 + 10*petlevel);
- SetCreateHealth(28 + 30*petlevel);
-
- // FIXME: this is wrong formula, possible each guardian pet have own damage formula
- //these formula may not be correct; however, it is designed to be close to what it should be
- //this makes dps 0.5 of pets level
- SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)));
- //damage range is then petlevel / 2
- SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)));
+ {
+ if(!pInfo)
+ {
+ SetCreateMana(28 + 10*petlevel);
+ SetCreateHealth(28 + 30*petlevel);
+ }
+ // FIXME: this is wrong formula, possible each guardian pet have own damage formula
+ //these formula may not be correct; however, it is designed to be close to what it should be
+ //this makes dps 0.5 of pets level
+ SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)));
+ //damage range is then petlevel / 2
+ SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)));
break;
+ }
}
break;
- default:
- sLog.outError("Pet have incorrect type (%u) for levelup.", getPetType());
- break;
+ }
}
- for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
- SetModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(createResistance[i]));
-
UpdateAllStats();
SetHealth(GetMaxHealth());
@@ -1272,7 +1033,7 @@ void Pet::_LoadSpellCooldowns()
continue;
data << uint32(spell_id);
- data << uint32(uint32(db_time-curTime)*1000); // in m.secs
+ data << uint32(uint32(db_time-curTime)*IN_MILISECONDS);
_AddCreatureSpellCooldown(spell_id,db_time);
@@ -1310,7 +1071,7 @@ void Pet::_SaveSpellCooldowns()
void Pet::_LoadSpells()
{
- QueryResult *result = CharacterDatabase.PQuery("SELECT spell,slot,active FROM pet_spell WHERE guid = '%u'",m_charmInfo->GetPetNumber());
+ QueryResult *result = CharacterDatabase.PQuery("SELECT spell,active FROM pet_spell WHERE guid = '%u'",m_charmInfo->GetPetNumber());
if(result)
{
@@ -1318,7 +1079,7 @@ void Pet::_LoadSpells()
{
Field *fields = result->Fetch();
- addSpell(fields[0].GetUInt16(), fields[2].GetUInt16(), PETSPELL_UNCHANGED, fields[1].GetUInt16());
+ addSpell(fields[0].GetUInt32(), fields[1].GetUInt16(), PETSPELL_UNCHANGED);
}
while( result->NextRow() );
@@ -1335,7 +1096,7 @@ void Pet::_SaveSpells()
if (itr->second->state == PETSPELL_REMOVED || itr->second->state == PETSPELL_CHANGED)
CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u' and spell = '%u'", m_charmInfo->GetPetNumber(), itr->first);
if (itr->second->state == PETSPELL_NEW || itr->second->state == PETSPELL_CHANGED)
- CharacterDatabase.PExecute("INSERT INTO pet_spell (guid,spell,slot,active) VALUES ('%u', '%u', '%u','%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second->slotId,itr->second->active);
+ CharacterDatabase.PExecute("INSERT INTO pet_spell (guid,spell,active) VALUES ('%u', '%u', '%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second->active);
if (itr->second->state == PETSPELL_REMOVED)
_removeSpell(itr->first);
@@ -1346,45 +1107,36 @@ void Pet::_SaveSpells()
void Pet::_LoadAuras(uint32 timediff)
{
- m_Auras.clear();
- for (int i = 0; i < TOTAL_AURAS; i++)
- m_modAuras[i].clear();
+ sLog.outDebug("Loading auras for pet %u",GetGUIDLow());
- // all aura related fields
- for(int i = UNIT_FIELD_AURA; i <= UNIT_FIELD_AURASTATE; ++i)
- SetUInt32Value(i, 0);
-
- QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber());
+ QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_mask,stackcount,amount0, amount1, amount2 ,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber());
if(result)
{
do
{
+ int32 damage[3];
Field *fields = result->Fetch();
uint64 caster_guid = fields[0].GetUInt64();
uint32 spellid = fields[1].GetUInt32();
- uint32 effindex = fields[2].GetUInt32();
- uint32 stackcount= fields[3].GetUInt32();
- int32 damage = (int32)fields[4].GetUInt32();
- int32 maxduration = (int32)fields[5].GetUInt32();
- int32 remaintime = (int32)fields[6].GetUInt32();
- int32 remaincharges = (int32)fields[7].GetUInt32();
+ uint32 effmask = fields[2].GetUInt32();
+ uint32 stackcount = fields[3].GetUInt32();
+ damage[0] = int32(fields[4].GetUInt32());
+ damage[1] = int32(fields[5].GetUInt32());
+ damage[2] = int32(fields[6].GetUInt32());
+ int32 maxduration = (int32)fields[7].GetUInt32();
+ int32 remaintime = (int32)fields[8].GetUInt32();
+ int32 remaincharges = (int32)fields[9].GetUInt32();
SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid);
if(!spellproto)
{
- sLog.outError("Unknown aura (spellid %u, effindex %u), ignore.",spellid,effindex);
- continue;
- }
-
- if(effindex >= 3)
- {
- sLog.outError("Invalid effect index (spellid %u, effindex %u), ignore.",spellid,effindex);
+ sLog.outError("Unknown aura (spellid %u), ignore.",spellid);
continue;
}
// negative effects should continue counting down after logout
- if (remaintime != -1 && !IsPositiveEffect(spellid, effindex))
+ if (remaintime != -1 && !IsPositiveSpell(spellid))
{
if(remaintime <= int32(timediff))
continue;
@@ -1399,21 +1151,12 @@ void Pet::_LoadAuras(uint32 timediff)
remaincharges = spellproto->procCharges;
}
else
- remaincharges = -1;
-
- /// do not load single target auras (unless they were cast by the player)
- if (caster_guid != GetGUID() && IsSingleTargetSpell(spellproto))
- continue;
+ remaincharges = 0;
- for(uint32 i=0; i<stackcount; i++)
- {
- Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL);
-
- if(!damage)
- damage = aura->GetModifier()->m_amount;
- aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges);
- AddAura(aura);
- }
+ Aura* aura = new Aura(spellproto, effmask, NULL, this, NULL, NULL);
+ aura->SetLoadedState(caster_guid,maxduration,remaintime,remaincharges, stackcount, &damage[0]);
+ AddAura(aura);
+ sLog.outDetail("Added aura spellid %u, effectmask %u", spellproto->Id, effmask);
}
while( result->NextRow() );
@@ -1426,56 +1169,36 @@ void Pet::_SaveAuras()
CharacterDatabase.PExecute("DELETE FROM pet_aura WHERE guid = '%u'", m_charmInfo->GetPetNumber());
AuraMap const& auras = GetAuras();
- if (auras.empty())
- return;
-
- spellEffectPair lastEffectPair = auras.begin()->first;
- uint32 stackCounter = 1;
-
- for(AuraMap::const_iterator itr = auras.begin(); ; ++itr)
+ for(AuraMap::const_iterator itr = auras.begin(); itr !=auras.end() ; ++itr)
{
- if(itr == auras.end() || lastEffectPair != itr->first)
- {
- AuraMap::const_iterator itr2 = itr;
- // save previous spellEffectPair to db
- itr2--;
- SpellEntry const *spellInfo = itr2->second->GetSpellProto();
- /// do not save single target auras (unless they were cast by the player)
- if (!(itr2->second->GetCasterGUID() != GetGUID() && IsSingleTargetSpell(spellInfo)))
- {
- if(!itr2->second->IsPassive())
- {
- // skip all auras from spell that apply at cast SPELL_AURA_MOD_SHAPESHIFT or pet area auras.
- uint8 i;
- for (i = 0; i < 3; i++)
- if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH ||
- spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_OWNER ||
- spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PET )
- break;
-
- if (i == 3)
- {
- CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges) "
- "VALUES ('%u', '" I64FMTD "', '%u', '%u', '%u', '%d', '%d', '%d', '%d')",
- m_charmInfo->GetPetNumber(), itr2->second->GetCasterGUID(),(uint32)itr2->second->GetId(), (uint32)itr2->second->GetEffIndex(), (uint32)itr2->second->GetStackAmount(), itr2->second->GetModifier()->m_amount,int(itr2->second->GetAuraMaxDuration()),int(itr2->second->GetAuraDuration()),int(itr2->second->m_procCharges));
- }
- }
- }
- if(itr == auras.end())
- break;
- }
+ // skip all auras from spell that apply at cast SPELL_AURA_MOD_SHAPESHIFT or pet area auras.
+ // do not save single target auras (unless they were cast by the player)
+ if (itr->second->IsPassive() || itr->second->IsAuraType(SPELL_AURA_MOD_STEALTH))
+ continue;
+ bool isCaster = itr->second->GetCasterGUID() == GetGUID();
+ if (!isCaster)
+ if (itr->second->IsSingleTarget()
+ || itr->second->IsAreaAura())
+ continue;
- if (lastEffectPair == itr->first)
- stackCounter++;
- else
+ uint32 amounts[MAX_SPELL_EFFECTS];
+ for (uint8 i=0;i<MAX_SPELL_EFFECTS;++i)
{
- lastEffectPair = itr->first;
- stackCounter = 1;
+ if (AuraEffect * partAura = itr->second->GetPartAura(i))
+ amounts[i]=partAura->GetAmount();
+ else
+ amounts[i]=0;
}
+
+ CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_mask,stackcount,amount0, amount1, amount2,maxduration,remaintime,remaincharges) "
+ "VALUES ('%u', '" I64FMTD "', '%u', '%u', '%u', '%u', '%u', '%d', '%d', '%d', '%d')",
+ m_charmInfo->GetPetNumber(), itr->second->GetCasterGUID(),(uint32)itr->second->GetId(), (uint32)itr->second->GetEffectMask(),
+ (uint32)itr->second->GetStackAmount(), amounts[0], amounts[1], amounts[2]
+ ,int(itr->second->GetAuraMaxDuration()),int(itr->second->GetAuraDuration()),int(itr->second->GetAuraCharges()));
}
}
-bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 slot_id, PetSpellType type)
+bool Pet::addSpell(uint32 spell_id, uint16 active, PetSpellState state, PetSpellType type)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
if (!spellInfo)
@@ -1494,7 +1217,7 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s
// same spells don't have autocast option
if (spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET)
- active = ACT_CAST;
+ active = ACT_DISABLED;
PetSpellMap::iterator itr = m_spells.find(spell_id);
if (itr != m_spells.end())
@@ -1531,40 +1254,45 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s
else
newspell->active = active;
- uint32 chainstart = spellmgr.GetFirstSpellInChain(spell_id);
-
- for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
+ // talent: unlearn all other talent ranks (high and low)
+ if(TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id))
{
- if(itr->second->state == PETSPELL_REMOVED) continue;
-
- if(spellmgr.GetFirstSpellInChain(itr->first) == chainstart)
+ if(TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentPos->talent_id ))
{
- slot_id = itr->second->slotId;
- newspell->active = itr->second->active;
-
- if(newspell->active == ACT_ENABLED)
- ToggleAutocast(itr->first, false);
+ for(int i=0; i < MAX_TALENT_RANK; ++i)
+ {
+ // skip learning spell and no rank spell case
+ uint32 rankSpellId = talentInfo->RankID[i];
+ if(!rankSpellId || rankSpellId==spell_id)
+ continue;
- oldspell_id = itr->first;
- removeSpell(itr->first);
+ // skip unknown ranks
+ if(!HasSpell(rankSpellId))
+ continue;
+ removeSpell(rankSpellId);
+ }
}
}
-
- uint16 tmpslot=slot_id;
-
- if (tmpslot == 0xffff)
+ else if(uint32 chainstart = spellmgr.GetFirstSpellInChain(spell_id))
{
- uint16 maxid = 0;
- PetSpellMap::iterator itr;
- for (itr = m_spells.begin(); itr != m_spells.end(); ++itr)
+ for (PetSpellMap::const_iterator itr2 = m_spells.begin(); itr2 != m_spells.end(); ++itr2)
{
- if(itr->second->state == PETSPELL_REMOVED) continue;
- if (itr->second->slotId > maxid) maxid = itr->second->slotId;
+ if(itr2->second->state == PETSPELL_REMOVED) continue;
+
+ if(spellmgr.GetFirstSpellInChain(itr2->first) == chainstart)
+ {
+ newspell->active = itr2->second->active;
+
+ if(newspell->active == ACT_ENABLED)
+ ToggleAutocast(itr2->first, false);
+
+ oldspell_id = itr2->first;
+ unlearnSpell(itr2->first);
+ break;
+ }
}
- tmpslot = maxid + 1;
}
- newspell->slotId = tmpslot;
m_spells[spell_id] = newspell;
if (IsPassiveSpell(spell_id))
@@ -1575,29 +1303,70 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s
if(newspell->active == ACT_ENABLED)
ToggleAutocast(spell_id, true);
+ uint32 talentCost = GetTalentSpellCost(spell_id);
+ if (talentCost)
+ {
+ int32 free_points = GetMaxTalentPointsForLevel(getLevel());
+ m_usedTalentCount+=talentCost;
+ // update free talent points
+ free_points-=m_usedTalentCount;
+ SetFreeTalentPoints(free_points > 0 ? free_points : 0);
+ }
return true;
}
-bool Pet::learnSpell(uint16 spell_id)
+bool Pet::learnSpell(uint32 spell_id)
{
// prevent duplicated entires in spell book
if (!addSpell(spell_id))
return false;
- Unit* owner = GetOwner();
- if(owner->GetTypeId()==TYPEID_PLAYER)
- ((Player*)owner)->PetSpellInitialize();
+ if(!m_loading)
+ {
+ WorldPacket data(SMSG_PET_LEARNED_SPELL, 2);
+ data << uint16(spell_id);
+ m_owner->GetSession()->SendPacket(&data);
+ m_owner->PetSpellInitialize();
+ }
return true;
}
-void Pet::removeSpell(uint16 spell_id)
+void Pet::learnLevelupSpells()
+{
+ PetLevelupSpellMap const * spell_map = spellmgr.GetPetLevelupSpellMap();
+ int8 level = getLevel();
+ for(PetLevelupSpellMap::const_iterator itr = spell_map->lower_bound(GetCreatureInfo()->family); itr != spell_map->upper_bound(GetCreatureInfo()->family); ++itr)
+ {
+ if(itr->second.first <= level)
+ learnSpell(itr->second.second);
+ else
+ unlearnSpell(itr->second.second);
+ }
+}
+
+bool Pet::unlearnSpell(uint32 spell_id)
+{
+ if(removeSpell(spell_id))
+ {
+ if(!m_loading)
+ {
+ WorldPacket data(SMSG_PET_REMOVED_SPELL, 2);
+ data << uint16(spell_id);
+ m_owner->GetSession()->SendPacket(&data);
+ }
+ return true;
+ }
+ return false;
+}
+
+bool Pet::removeSpell(uint32 spell_id)
{
PetSpellMap::iterator itr = m_spells.find(spell_id);
if (itr == m_spells.end())
- return;
+ return false;
if(itr->second->state == PETSPELL_REMOVED)
- return;
+ return false;
if(itr->second->state == PETSPELL_NEW)
{
@@ -1608,9 +1377,23 @@ void Pet::removeSpell(uint16 spell_id)
itr->second->state = PETSPELL_REMOVED;
RemoveAurasDueToSpell(spell_id);
+
+ uint32 talentCost = GetTalentSpellCost(spell_id);
+ if (talentCost > 0)
+ {
+ if (m_usedTalentCount > talentCost)
+ m_usedTalentCount-=talentCost;
+ else
+ m_usedTalentCount = 0;
+ // update free talent points
+ int32 free_points = GetMaxTalentPointsForLevel(getLevel()) - m_usedTalentCount;
+ SetFreeTalentPoints(free_points > 0 ? free_points : 0);
+ }
+
+ return true;
}
-bool Pet::_removeSpell(uint16 spell_id)
+bool Pet::_removeSpell(uint32 spell_id)
{
PetSpellMap::iterator itr = m_spells.find(spell_id);
if (itr != m_spells.end())
@@ -1626,12 +1409,15 @@ void Pet::InitPetCreateSpells()
{
m_charmInfo->InitPetActionBar();
+ for (PetSpellMap::const_iterator i = m_spells.begin(); i != m_spells.end(); ++i)
+ delete i->second;
m_spells.clear();
- int32 usedtrainpoints = 0, petspellid;
+
+ uint32 petspellid;
PetCreateSpellEntry const* CreateSpells = objmgr.GetPetCreateSpellEntry(GetEntry());
if(CreateSpells)
{
- for(uint8 i = 0; i < 4; i++)
+ for(uint8 i = 0; i < 4; ++i)
{
if(!CreateSpells->spellid[i])
break;
@@ -1647,7 +1433,7 @@ void Pet::InitPetCreateSpells()
if(owner->GetTypeId() == TYPEID_PLAYER && !((Player*)owner)->HasSpell(learn_spellproto->Id))
{
if(IsPassiveSpell(petspellid)) //learn passive skills when tamed, not sure if thats right
- ((Player*)owner)->learnSpell(learn_spellproto->Id);
+ ((Player*)owner)->learnSpell(learn_spellproto->Id,false);
else
AddTeachSpell(learn_spellproto->EffectTriggerSpell[0], learn_spellproto->Id);
}
@@ -1656,23 +1442,12 @@ void Pet::InitPetCreateSpells()
petspellid = learn_spellproto->Id;
addSpell(petspellid);
-
- SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(learn_spellproto->EffectTriggerSpell[0]);
- SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(learn_spellproto->EffectTriggerSpell[0]);
-
- for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
- {
- usedtrainpoints += _spell_idx->second->reqtrainpoints;
- break;
- }
}
}
LearnPetPassives();
CastPetAuras(false);
-
- SetTP(-usedtrainpoints);
}
void Pet::CheckLearning(uint32 spellid)
@@ -1692,11 +1467,116 @@ void Pet::CheckLearning(uint32 spellid)
if(urand(0, 100) < 10)
{
- ((Player*)owner)->learnSpell(itr->second);
+ ((Player*)owner)->learnSpell(itr->second,false);
m_teachspells.erase(itr);
}
}
+bool Pet::resetTalents(bool no_cost)
+{
+ Unit *owner = GetOwner();
+ if (!owner || owner->GetTypeId()!=TYPEID_PLAYER)
+ return false;
+
+ CreatureInfo const * ci = GetCreatureInfo();
+ if(!ci)
+ return false;
+ // Check pet talent type
+ CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
+ if(!pet_family || pet_family->petTalentType < 0)
+ return false;
+
+ Player *player = (Player *)owner;
+
+ uint32 level = getLevel();
+ uint32 talentPointsForLevel = GetMaxTalentPointsForLevel(level);
+
+ if (m_usedTalentCount == 0)
+ {
+ SetFreeTalentPoints(talentPointsForLevel);
+ return false;
+ }
+
+ uint32 cost = 0;
+
+ if(!no_cost)
+ {
+ cost = resetTalentsCost();
+
+ if (player->GetMoney() < cost)
+ {
+ player->SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
+ return false;
+ }
+ }
+
+ for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i)
+ {
+ TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
+
+ if (!talentInfo) continue;
+
+ TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
+
+ if(!talentTabInfo)
+ continue;
+
+ // unlearn only talents for pets family talent type
+ if(!((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask))
+ continue;
+
+ for (int j = 0; j < MAX_TALENT_RANK; j++)
+ {
+ for(PetSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end();)
+ {
+ if(itr->second->state == PETSPELL_REMOVED)
+ {
+ ++itr;
+ continue;
+ }
+ // remove learned spells (all ranks)
+ uint32 itrFirstId = spellmgr.GetFirstSpellInChain(itr->first);
+
+ // unlearn if first rank is talent or learned by talent
+ if (itrFirstId == talentInfo->RankID[j] || spellmgr.IsSpellLearnToSpell(talentInfo->RankID[j],itrFirstId))
+ {
+ removeSpell(itr->first);
+ itr = m_spells.begin();
+ continue;
+ }
+ else
+ ++itr;
+ }
+ }
+ }
+
+ SetFreeTalentPoints(talentPointsForLevel);
+
+ if(!no_cost)
+ {
+ player->ModifyMoney(-(int32)cost);
+
+ m_resetTalentsCost = cost;
+ m_resetTalentsTime = time(NULL);
+ }
+ if(!m_loading)
+ player->PetSpellInitialize();
+ return true;
+}
+
+void Pet::InitTalentForLevel()
+{
+ uint32 level = getLevel();
+ uint32 talentPointsForLevel = GetMaxTalentPointsForLevel(level);
+ // Reset talents in case low level (on level down) or wrong points for level (hunter can unlearn TP increase talent)
+ if(talentPointsForLevel == 0 || m_usedTalentCount > talentPointsForLevel)
+ {
+ // Remove all talent points
+ resetTalents(true);
+ }
+ SetFreeTalentPoints(talentPointsForLevel - m_usedTalentCount);
+}
+
uint32 Pet::resetTalentsCost() const
{
uint32 days = (sWorld.GetGameTime() - m_resetTalentsTime)/DAY;
@@ -1715,23 +1595,31 @@ uint32 Pet::resetTalentsCost() const
return (m_resetTalentsCost + 1*GOLD > 10*GOLD ? 10*GOLD : m_resetTalentsCost + 1*GOLD);
}
+uint8 Pet::GetMaxTalentPointsForLevel(uint32 level)
+{
+ uint8 points = (level >= 20) ? ((level - 16) / 4) : 0;
+ // Mod points from owner SPELL_AURA_MOD_PET_TALENT_POINTS
+ if (Unit *owner = GetOwner())
+ points+=owner->GetTotalAuraModifier(SPELL_AURA_MOD_PET_TALENT_POINTS);
+ return points;
+}
+
void Pet::ToggleAutocast(uint32 spellid, bool apply)
{
if(IsPassiveSpell(spellid))
return;
- //if(const SpellEntry *tempSpell = GetSpellStore()->LookupEntry(spellid))
- // if(tempSpell->EffectImplicitTargetA[0] != TARGET_ALL_AROUND_CASTER
- // && tempSpell->EffectImplicitTargetA[0] != TARGET_CHAIN_DAMAGE)
- // return;
-
- PetSpellMap::const_iterator itr = m_spells.find((uint16)spellid);
+ PetSpellMap::const_iterator itr = m_spells.find(spellid);
+ if(itr == m_spells.end())
+ return;
int i;
if(apply)
{
- for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++);
+ for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; ++i)
+ ; // just search
+
if (i == m_autospells.size())
{
m_autospells.push_back(spellid);
@@ -1742,7 +1630,9 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply)
else
{
AutoSpellList::iterator itr2 = m_autospells.begin();
- for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++, itr2++);
+ for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; ++i, itr2++)
+ ; // just search
+
if (i < m_autospells.size())
{
m_autospells.erase(itr2);
@@ -1752,10 +1642,11 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply)
}
}
-bool Pet::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number)
+bool Pet::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number)
{
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
+ SetPhaseMask(phaseMask,false);
Object::_Create(guidlow, pet_number, HIGHGUID_PET);
@@ -1765,18 +1656,15 @@ bool Pet::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number)
if(!InitEntry(Entry))
return false;
- SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
- SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 );
-
- if(getPetType() == MINI_PET) // always non-attackable
- SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
return true;
}
bool Pet::HasSpell(uint32 spell) const
{
- return (m_spells.find(spell) != m_spells.end());
+ PetSpellMap::const_iterator itr = m_spells.find(spell);
+ return (itr != m_spells.end() && itr->second->state != PETSPELL_REMOVED );
}
// Get all passive spells in our skill line
@@ -1797,7 +1685,7 @@ void Pet::LearnPetPassives()
// Passive 01~10, Passive 00 (20782, not used), Ferocious Inspiration (34457)
// Scale 01~03 (34902~34904, bonus from owner, not used)
for(PetFamilySpellsSet::const_iterator petSet = petStore->second.begin(); petSet != petStore->second.end(); ++petSet)
- addSpell(*petSet, ACT_DECIDE, PETSPELL_NEW, 0xffff, PETSPELL_FAMILY);
+ addSpell(*petSet, ACT_DECIDE, PETSPELL_NEW, PETSPELL_FAMILY);
}
}
@@ -1810,7 +1698,7 @@ void Pet::CastPetAuras(bool current)
if(getPetType() != HUNTER_PET && (getPetType() != SUMMON_PET || owner->getClass() != CLASS_WARLOCK))
return;
- for(PetAuraSet::iterator itr = owner->m_petAuras.begin(); itr != owner->m_petAuras.end();)
+ for(PetAuraSet::const_iterator itr = owner->m_petAuras.begin(); itr != owner->m_petAuras.end();)
{
PetAura const* pa = *itr;
++itr;
@@ -1837,3 +1725,10 @@ void Pet::CastPetAura(PetAura const* aura)
CastSpell(this, auraId, true);
}
+void Pet::learnSpellHighRank(uint32 spellid)
+{
+ learnSpell(spellid);
+
+ if(uint32 next = spellmgr.GetNextSpellInChain(spellid))
+ learnSpellHighRank(next);
+}
diff --git a/src/game/Pet.h b/src/game/Pet.h
index d55c467826a..9d7a42e57a0 100644
--- a/src/game/Pet.h
+++ b/src/game/Pet.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,28 +22,29 @@
#define TRINITYCORE_PET_H
#include "ObjectDefines.h"
-#include "Creature.h"
#include "Unit.h"
+#include "TemporarySummon.h"
enum PetType
{
SUMMON_PET = 0,
HUNTER_PET = 1,
- GUARDIAN_PET = 2,
- MINI_PET = 3,
- POSSESSED_PET = 4,
- MAX_PET_TYPE = 5
+ POSSESSED_PET = 2,
+ MAX_PET_TYPE = 4,
};
extern char const* petTypeSuffix[MAX_PET_TYPE];
+#define MAX_PET_STABLES 4
+
+// stored in character_pet.slot
enum PetSaveMode
{
- PET_SAVE_AS_DELETED =-1,
- PET_SAVE_AS_CURRENT = 0,
- PET_SAVE_IN_STABLE_SLOT_1 = 1,
- PET_SAVE_IN_STABLE_SLOT_2 = 2,
- PET_SAVE_NOT_IN_SLOT = 3
+ PET_SAVE_AS_DELETED = -1, // not saved in fact
+ PET_SAVE_AS_CURRENT = 0, // in current slot (with player)
+ PET_SAVE_FIRST_STABLE_SLOT = 1,
+ PET_SAVE_LAST_STABLE_SLOT = MAX_PET_STABLES, // last in DB stable slot index (including), all higher have same meaning as PET_SAVE_NOT_IN_SLOT
+ PET_SAVE_NOT_IN_SLOT = 100 // for avoid conflict with stable size grow will use 100
};
enum HappinessState
@@ -53,16 +54,6 @@ enum HappinessState
HAPPY = 3
};
-enum LoyaltyLevel
-{
- REBELLIOUS = 1,
- UNRULY = 2,
- SUBMISSIVE = 3,
- DEPENDABLE = 4,
- FAITHFUL = 5,
- BEST_FRIEND = 6
-};
-
enum PetSpellState
{
PETSPELL_UNCHANGED = 0,
@@ -79,7 +70,6 @@ enum PetSpellType
struct PetSpell
{
- uint16 slotId;
uint16 active;
PetSpellState state : 16;
@@ -100,6 +90,12 @@ enum PetTalk
PET_TALK_ATTACK = 1
};
+enum AtLoadFlags
+{
+ AT_LOAD_NONE = 0,
+ AT_LOAD_RESET_SPELLS = 1,
+};
+
enum PetNameInvalidReason
{
PET_NAME_INVALID = 1,
@@ -117,15 +113,12 @@ enum PetNameInvalidReason
PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 16
};
-typedef UNORDERED_MAP<uint16, PetSpell*> PetSpellMap;
+typedef UNORDERED_MAP<uint32, PetSpell*> PetSpellMap;
typedef std::map<uint32,uint32> TeachSpellMap;
typedef std::vector<uint32> AutoSpellList;
#define HAPPINESS_LEVEL_SIZE 333000
-extern const uint32 LevelUpLoyalty[6];
-extern const uint32 LevelStartLoyalty[6];
-
#define ACTIVE_SPELLS_MAX 4
#define OWNER_MAX_DISTANCE 100
@@ -133,10 +126,10 @@ extern const uint32 LevelStartLoyalty[6];
#define PET_FOLLOW_DIST 1
#define PET_FOLLOW_ANGLE (M_PI/2)
-class Pet : public Creature
+class Pet : public Guardian
{
public:
- explicit Pet(PetType type = MAX_PET_TYPE);
+ explicit Pet(Player *owner, PetType type = MAX_PET_TYPE);
virtual ~Pet();
void AddToWorld();
@@ -147,9 +140,9 @@ class Pet : public Creature
bool isControlled() const { return getPetType()==SUMMON_PET || getPetType()==HUNTER_PET; }
bool isTemporarySummoned() const { return m_duration > 0; }
- bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number);
+ bool Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number);
bool CreateBaseAtCreature(Creature* creature);
- bool LoadPetFromDB( Unit* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false );
+ bool LoadPetFromDB( Player* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false );
void SavePetToDB(PetSaveMode mode);
void Remove(PetSaveMode mode, bool returnreagent = false);
static void DeleteFromDB(uint32 guidlow);
@@ -168,24 +161,13 @@ class Pet : public Creature
void RegenerateFocus();
void LooseHappiness();
- void TickLoyaltyChange();
- void ModifyLoyalty(int32 addvalue);
HappinessState GetHappinessState();
- uint32 GetMaxLoyaltyPoints(uint32 level);
- uint32 GetStartLoyaltyPoints(uint32 level);
- void KillLoyaltyBonus(uint32 level);
- uint32 GetLoyaltyLevel() { return GetByteValue(UNIT_FIELD_BYTES_1, 1); }
- void SetLoyaltyLevel(LoyaltyLevel level);
void GivePetXP(uint32 xp);
void GivePetLevel(uint32 level);
- bool InitStatsForLevel(uint32 level);
bool HaveInDiet(ItemPrototype const* item) const;
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel);
void SetDuration(int32 dur) { m_duration = dur; }
- int32 GetBonusDamage() { return m_bonusdamage; }
- void SetBonusDamage(int32 damage) { m_bonusdamage = damage; }
-
bool UpdateStats(Stats stat);
bool UpdateAllStats();
void UpdateResistances(uint32 school);
@@ -195,10 +177,8 @@ class Pet : public Creature
void UpdateAttackPowerAndDamage(bool ranged = false);
void UpdateDamagePhysical(WeaponAttackType attType);
- bool CanTakeMoreActiveSpells(uint32 SpellIconID);
- void ToggleAutocast(uint32 spellid, bool apply);
- bool HasTPForSpell(uint32 spellid);
- int32 GetTPForSpell(uint32 spellid);
+ bool CanTakeMoreActiveSpells(uint32 SpellIconID);
+ void ToggleAutocast(uint32 spellid, bool apply);
bool HasSpell(uint32 spell) const;
void AddTeachSpell(uint32 learned_id, uint32 source_id) { m_teachspells[learned_id] = source_id; }
@@ -214,10 +194,14 @@ class Pet : public Creature
void _LoadSpells();
void _SaveSpells();
- bool addSpell(uint16 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, uint16 slot_id=0xffff, PetSpellType type = PETSPELL_NORMAL);
- bool learnSpell(uint16 spell_id);
- void removeSpell(uint16 spell_id);
- bool _removeSpell(uint16 spell_id);
+ bool addSpell(uint32 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
+ bool learnSpell(uint32 spell_id);
+ void learnSpellHighRank(uint32 spellid);
+ void learnLevelupSpells();
+ bool unlearnSpell(uint32 spell_id);
+ bool removeSpell(uint32 spell_id);
+ bool _removeSpell(uint32 spell_id);
+ void _resetSpells();
PetSpellMap m_spells;
TeachSpellMap m_teachspells;
@@ -225,32 +209,36 @@ class Pet : public Creature
void InitPetCreateSpells();
void CheckLearning(uint32 spellid);
+
+ bool resetTalents(bool no_cost = false);
uint32 resetTalentsCost() const;
+ void InitTalentForLevel();
- void SetTP(int32 TP);
- int32 GetDispTP();
+ uint8 GetMaxTalentPointsForLevel(uint32 level);
+ uint8 GetFreeTalentPoints() { return GetByteValue(UNIT_FIELD_BYTES_1, 1); }
+ void SetFreeTalentPoints(uint8 points) { SetByteValue(UNIT_FIELD_BYTES_1, 1, points); }
- int32 m_TrainingPoints;
uint32 m_resetTalentsCost;
time_t m_resetTalentsTime;
+ uint32 m_usedTalentCount;
- uint64 GetAuraUpdateMask() { return m_auraUpdateMask; }
- void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
- void UnsetAuraUpdateMask(uint8 slot) { m_auraUpdateMask &= ~(uint64(1) << slot); }
- void ResetAuraUpdateMask() { m_auraUpdateMask = 0; }
+ const uint64& GetAuraUpdateMaskForRaid() const { return m_auraRaidUpdateMask; }
+ void SetAuraUpdateMaskForRaid(uint8 slot) { m_auraRaidUpdateMask |= (uint64(1) << slot); }
+ void ResetAuraUpdateMaskForRaid() { m_auraRaidUpdateMask = 0; }
DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
bool m_removed; // prevent overwrite pet state in DB at next Pet::Update if pet already removed(saved)
+
+ Player *GetOwner() { return m_owner; }
protected:
- uint32 m_regenTimer;
+ Player *m_owner;
uint32 m_happinessTimer;
- uint32 m_loyaltyTimer;
PetType m_petType;
int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets)
- int32 m_loyaltyPoints;
- int32 m_bonusdamage;
- uint64 m_auraUpdateMask;
+ uint64 m_auraRaidUpdateMask;
+ bool m_loading;
+ uint32 m_regenTimer;
DeclinedName *m_declinedname;
diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp
index 75c1aa06c20..ae4441d7c6d 100644
--- a/src/game/PetAI.cpp
+++ b/src/game/PetAI.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,7 +22,7 @@
#include "Errors.h"
#include "Pet.h"
#include "Player.h"
-#include "Database/DBCStores.h"
+#include "DBCStores.h"
#include "Spell.h"
#include "ObjectAccessor.h"
#include "SpellMgr.h"
@@ -38,7 +38,7 @@ int PetAI::Permissible(const Creature *creature)
return PERMIT_BASE_NO;
}
-PetAI::PetAI(Creature *c) : CreatureAI(c), i_pet(*c), i_tracker(TIME_INTERVAL_LOOK)
+PetAI::PetAI(Creature *c) : CreatureAI(c), i_tracker(TIME_INTERVAL_LOOK)
{
m_AllySet.clear();
UpdateAllies();
@@ -51,46 +51,46 @@ void PetAI::EnterEvadeMode()
bool PetAI::_needToStop() const
{
// This is needed for charmed creatures, as once their target was reset other effects can trigger threat
- if(i_pet.isCharmed() && i_pet.getVictim() == i_pet.GetCharmer())
+ if(m_creature->isCharmed() && m_creature->getVictim() == m_creature->GetCharmer())
return true;
- return !i_pet.canAttack(i_pet.getVictim());
+ return !m_creature->canAttack(m_creature->getVictim());
}
void PetAI::_stopAttack()
{
- if( !i_pet.isAlive() )
+ if( !m_creature->isAlive() )
{
- DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", i_pet.GetGUIDLow());
- i_pet.GetMotionMaster()->Clear();
- i_pet.GetMotionMaster()->MoveIdle();
- i_pet.CombatStop();
- i_pet.getHostilRefManager().deleteReferences();
+ DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow());
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveIdle();
+ m_creature->CombatStop();
+ m_creature->getHostilRefManager().deleteReferences();
return;
}
- Unit* owner = i_pet.GetCharmerOrOwner();
+ Unit* owner = m_creature->GetCharmerOrOwner();
- if(owner && i_pet.GetCharmInfo() && i_pet.GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
+ if(owner && m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
{
- i_pet.GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
+ m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
}
else
{
- i_pet.clearUnitState(UNIT_STAT_FOLLOW);
- i_pet.GetMotionMaster()->Clear();
- i_pet.GetMotionMaster()->MoveIdle();
+ m_creature->clearUnitState(UNIT_STAT_FOLLOW);
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveIdle();
}
- i_pet.AttackStop();
+ m_creature->AttackStop();
}
void PetAI::UpdateAI(const uint32 diff)
{
- if (!i_pet.isAlive())
+ if (!m_creature->isAlive())
return;
- Unit* owner = i_pet.GetCharmerOrOwner();
+ Unit* owner = m_creature->GetCharmerOrOwner();
if(m_updateAlliesTimer <= diff)
// UpdateAllies self set update timer
@@ -98,12 +98,12 @@ void PetAI::UpdateAI(const uint32 diff)
else
m_updateAlliesTimer -= diff;
- // i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
- if( i_pet.getVictim() )
+ // m_creature->getVictim() can't be used for check in case stop fighting, m_creature->getVictim() clear at Unit death etc.
+ if( m_creature->getVictim() )
{
if( _needToStop() )
{
- DEBUG_LOG("Pet AI stoped attacking [guid=%u]", i_pet.GetGUIDLow());
+ DEBUG_LOG("Pet AI stoped attacking [guid=%u]", m_creature->GetGUIDLow());
_stopAttack();
return;
}
@@ -114,26 +114,26 @@ void PetAI::UpdateAI(const uint32 diff)
{
if(me->isInCombat())
_stopAttack();
- else if(owner && i_pet.GetCharmInfo()) //no victim
+ else if(owner && m_creature->GetCharmInfo()) //no victim
{
- if(owner->isInCombat() && !(i_pet.HasReactState(REACT_PASSIVE) || i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY)))
+ if(owner->isInCombat() && !(m_creature->HasReactState(REACT_PASSIVE) || m_creature->GetCharmInfo()->HasCommandState(COMMAND_STAY)))
AttackStart(owner->getAttackerForHelper());
- else if(i_pet.GetCharmInfo()->HasCommandState(COMMAND_FOLLOW) && !i_pet.hasUnitState(UNIT_STAT_FOLLOW))
- i_pet.GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
+ else if(m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW) && !m_creature->hasUnitState(UNIT_STAT_FOLLOW))
+ m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
}
}
if(!me->GetCharmInfo())
return;
- if (i_pet.GetGlobalCooldown() == 0 && !i_pet.hasUnitState(UNIT_STAT_CASTING))
+ if (m_creature->GetGlobalCooldown() == 0 && !m_creature->hasUnitState(UNIT_STAT_CASTING))
{
bool inCombat = me->getVictim();
//Autocast
- for (uint8 i = 0; i < i_pet.GetPetAutoSpellSize(); i++)
+ for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); ++i)
{
- uint32 spellID = i_pet.GetPetAutoSpellOnPos(i);
+ uint32 spellID = m_creature->GetPetAutoSpellOnPos(i);
if (!spellID)
continue;
@@ -153,19 +153,19 @@ void PetAI::UpdateAI(const uint32 diff)
continue;
}
- Spell *spell = new Spell(&i_pet, spellInfo, false, 0);
+ Spell *spell = new Spell(m_creature, spellInfo, false, 0);
- if(inCombat && !i_pet.hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(i_pet.getVictim()))
+ if(inCombat && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(m_creature->getVictim()))
{
- m_targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(i_pet.getVictim(), spell));
+ m_targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(m_creature->getVictim(), spell));
continue;
}
else
{
bool spellUsed = false;
- for(std::set<uint64>::iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
+ for(std::set<uint64>::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
{
- Unit* Target = ObjectAccessor::GetUnit(i_pet,*tar);
+ Unit* Target = ObjectAccessor::GetUnit(*m_creature,*tar);
//only buff targets that are in combat, unless the spell can only be cast while out of combat
if(!Target)
@@ -196,19 +196,19 @@ void PetAI::UpdateAI(const uint32 diff)
SpellCastTargets targets;
targets.setUnitTarget( target );
- if( !i_pet.HasInArc(M_PI, target) )
+ if( !m_creature->HasInArc(M_PI, target) )
{
- i_pet.SetInFront(target);
+ m_creature->SetInFront(target);
if( target->GetTypeId() == TYPEID_PLAYER )
- i_pet.SendUpdateToPlayer( (Player*)target );
+ m_creature->SendUpdateToPlayer( (Player*)target );
if(owner && owner->GetTypeId() == TYPEID_PLAYER)
- i_pet.SendUpdateToPlayer( (Player*)owner );
+ m_creature->SendUpdateToPlayer( (Player*)owner );
}
- i_pet.AddCreatureSpellCooldown(spell->m_spellInfo->Id);
- if(i_pet.isPet())
- ((Pet*)&i_pet)->CheckLearning(spell->m_spellInfo->Id);
+ m_creature->AddCreatureSpellCooldown(spell->m_spellInfo->Id);
+ if(m_creature->isPet())
+ ((Pet*)m_creature)->CheckLearning(spell->m_spellInfo->Id);
spell->prepare(&targets);
}
@@ -222,10 +222,10 @@ void PetAI::UpdateAI(const uint32 diff)
void PetAI::UpdateAllies()
{
- Unit* owner = i_pet.GetCharmerOrOwner();
+ Unit* owner = m_creature->GetCharmerOrOwner();
Group *pGroup = NULL;
- m_updateAlliesTimer = 10000; //update friendly targets every 10 seconds, lesser checks increase performance
+ m_updateAlliesTimer = 10*IN_MILISECONDS; //update friendly targets every 10 seconds, lesser checks increase performance
if(!owner)
return;
@@ -240,7 +240,7 @@ void PetAI::UpdateAllies()
return;
m_AllySet.clear();
- m_AllySet.insert(i_pet.GetGUID());
+ m_AllySet.insert(m_creature->GetGUID());
if(pGroup) //add group
{
for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
diff --git a/src/game/PetAI.h b/src/game/PetAI.h
index 864195701c2..a346908ee0e 100644
--- a/src/game/PetAI.h
+++ b/src/game/PetAI.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -31,7 +31,7 @@ class TRINITY_DLL_DECL PetAI : public CreatureAI
{
public:
- PetAI(Creature *c);
+ explicit PetAI(Creature *c);
void EnterEvadeMode();
void JustDied(Unit* who) { _stopAttack(); }
@@ -46,7 +46,6 @@ class TRINITY_DLL_DECL PetAI : public CreatureAI
void UpdateAllies();
- Creature &i_pet;
TimeTracker i_tracker;
std::set<uint64> m_AllySet;
uint32 m_updateAlliesTimer;
diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp
index 932eb593ff8..6576a2a7622 100644
--- a/src/game/PetHandler.cpp
+++ b/src/game/PetHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,18 +21,15 @@
#include "Common.h"
#include "WorldPacket.h"
#include "WorldSession.h"
-#include "World.h"
#include "ObjectMgr.h"
#include "SpellMgr.h"
#include "Log.h"
#include "Opcodes.h"
#include "Spell.h"
#include "ObjectAccessor.h"
-#include "MapManager.h"
#include "CreatureAI.h"
#include "Util.h"
#include "Pet.h"
-#include "Language.h"
void WorldSession::HandlePetAction( WorldPacket & recv_data )
{
@@ -49,25 +46,39 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
// used also for charmed creature
Unit* pet= ObjectAccessor::GetUnit(*_player, guid1);
- sLog.outDetail("HandlePetAction.Pet %u flag is %u, spellid is %u, target %u.\n", uint32(GUID_LOPART(guid1)), flag, spellid, uint32(GUID_LOPART(guid2)) );
+ sLog.outDetail("HandlePetAction.Pet %u flag is %u, spellid is %u, target %u.", uint32(GUID_LOPART(guid1)), flag, spellid, uint32(GUID_LOPART(guid2)) );
if(!pet)
{
- sLog.outError( "Pet %u not exist.\n", uint32(GUID_LOPART(guid1)) );
+ sLog.outError( "Pet %u not exist.", uint32(GUID_LOPART(guid1)) );
return;
}
- if(pet != GetPlayer()->GetPet() && pet != GetPlayer()->GetCharm())
+ if(pet != GetPlayer()->GetFirstControlled())
{
- sLog.outError("HandlePetAction.Pet %u isn't pet of player %s.\n", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName() );
+ sLog.outError("HandlePetAction.Pet %u isn't pet of player %s.", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName() );
return;
}
- if(!pet->isAlive())
- return;
-
+ //TODO: allow control charmed player?
if(pet->GetTypeId() == TYPEID_PLAYER && !(flag == ACT_COMMAND && spellid == COMMAND_ATTACK))
return;
+ if(GetPlayer()->m_Controlled.size() == 1)
+ HandlePetActionHelper(pet, guid1, spellid, flag, guid2);
+ else
+ {
+ //If a pet is dismissed, m_Controlled will change
+ std::vector<Unit*> controlled;
+ for(Unit::ControlList::iterator itr = GetPlayer()->m_Controlled.begin(); itr != GetPlayer()->m_Controlled.end(); ++itr)
+ if((*itr)->GetEntry() == pet->GetEntry() && (*itr)->isAlive())
+ controlled.push_back(*itr);
+ for(std::vector<Unit*>::iterator itr = controlled.begin(); itr != controlled.end(); ++itr)
+ HandlePetActionHelper(*itr, guid1, spellid, flag, guid2);
+ }
+}
+
+void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid, uint16 flag, uint64 guid2)
+{
CharmInfo *charmInfo = pet->GetCharmInfo();
if(!charmInfo)
{
@@ -119,27 +130,33 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
// return;
pet->clearUnitState(UNIT_STAT_FOLLOW);
-
- if(pet->GetTypeId() != TYPEID_PLAYER && ((Creature*)pet)->IsAIEnabled)
+ // This is true if pet has no target or has target but targets differs.
+ if(pet->getVictim() != TargetUnit)
{
- ((Creature*)pet)->AI()->AttackStart(TargetUnit);
+ if (pet->getVictim())
+ pet->AttackStop();
- //10% chance to play special pet attack talk, else growl
- if(((Creature*)pet)->isPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10)
- pet->SendPetTalk((uint32)PET_TALK_ATTACK);
- else
+ if(pet->GetTypeId() != TYPEID_PLAYER && ((Creature*)pet)->IsAIEnabled)
{
- // 90% chance for pet and 100% chance for charmed creature
- pet->SendPetAIReaction(guid1);
+ ((Creature*)pet)->AI()->AttackStart(TargetUnit);
+
+ //10% chance to play special pet attack talk, else growl
+ if(((Creature*)pet)->isPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10)
+ pet->SendPetTalk((uint32)PET_TALK_ATTACK);
+ else
+ {
+ // 90% chance for pet and 100% chance for charmed creature
+ pet->SendPetAIReaction(guid1);
+ }
}
- }
- else // charmed player
- {
- if(pet->getVictim() && pet->getVictim() != TargetUnit)
- pet->AttackStop();
+ else // charmed player
+ {
+ if(pet->getVictim() && pet->getVictim() != TargetUnit)
+ pet->AttackStop();
- pet->Attack(TargetUnit,true);
- pet->SendPetAIReaction(guid1);
+ pet->Attack(TargetUnit,true);
+ pet->SendPetAIReaction(guid1);
+ }
}
break;
}
@@ -154,10 +171,10 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
p->setDeathState(CORPSE);
}
else // charmed or possessed
- _player->Uncharm();
+ _player->StopCastingCharm();
break;
default:
- sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.\n", flag, spellid);
+ sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", flag, spellid);
}
break;
case ACT_REACTION: // 0x600
@@ -171,28 +188,26 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
break;
}
break;
- case ACT_DISABLED: //0x8100 spell (disabled), ignore
- case ACT_CAST: //0x0100
- case ACT_ENABLED: //0xc100 spell
+ case ACT_DISABLED: // 0x8100 spell (disabled), ignore
+ case ACT_PASSIVE: // 0x0100
+ case ACT_ENABLED: // 0xC100 spell
{
- Unit* unit_target;
- if(guid2)
- unit_target = ObjectAccessor::GetUnit(*_player,guid2);
- else
- unit_target = NULL;
-
+ Unit* unit_target = NULL;
if (((Creature*)pet)->GetGlobalCooldown() > 0)
return;
+ if(guid2)
+ unit_target = ObjectAccessor::GetUnit(*_player,guid2);
+
// do not cast unknown spells
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid );
if(!spellInfo)
{
- sLog.outError("WORLD: unknown PET spell id %i\n", spellid);
+ sLog.outError("WORLD: unknown PET spell id %i", spellid);
return;
}
- for(uint32 i = 0; i < 3;i++)
+ for(uint32 i = 0; i < 3;++i)
{
if(spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_INSTANT || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED)
return;
@@ -206,21 +221,30 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
Spell *spell = new Spell(pet, spellInfo, false);
- int16 result = spell->PetCanCast(unit_target);
+ SpellCastResult result = spell->CheckPetCast(unit_target);
- //auto turn to target unless possessed
+ //auto turn to target unless possessed
if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->isPossessed())
{
- pet->SetInFront(unit_target);
- if( unit_target->GetTypeId() == TYPEID_PLAYER )
- pet->SendUpdateToPlayer( (Player*)unit_target );
- if(Unit* powner = pet->GetCharmerOrOwner())
+ if(unit_target)
+ {
+ pet->SetInFront(unit_target);
+ if (unit_target->GetTypeId() == TYPEID_PLAYER)
+ pet->SendUpdateToPlayer( (Player*)unit_target );
+ }
+ else if(Unit *unit_target2 = spell->m_targets.getUnitTarget())
+ {
+ pet->SetInFront(unit_target2);
+ if (unit_target2->GetTypeId() == TYPEID_PLAYER)
+ pet->SendUpdateToPlayer( (Player*)unit_target2 );
+ }
+ if (Unit* powner = pet->GetCharmerOrOwner())
if(powner->GetTypeId() == TYPEID_PLAYER)
pet->SendUpdateToPlayer((Player*)powner);
- result = -1;
+ result = SPELL_CAST_OK;
}
- if(result == -1)
+ if(result == SPELL_CAST_OK)
{
((Creature*)pet)->AddCreatureSpellCooldown(spellid);
if (((Creature*)pet)->isPet())
@@ -239,12 +263,15 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->isPossessed())
{
- pet->clearUnitState(UNIT_STAT_FOLLOW);
- if(pet->getVictim())
- pet->AttackStop();
- pet->GetMotionMaster()->Clear();
- if (((Creature*)pet)->IsAIEnabled)
- ((Creature*)pet)->AI()->AttackStart(unit_target);
+ // This is true if pet has no target or has target but targets differs.
+ if (pet->getVictim() != unit_target)
+ {
+ if (pet->getVictim())
+ pet->AttackStop();
+ pet->GetMotionMaster()->Clear();
+ if (((Creature*)pet)->IsAIEnabled)
+ ((Creature*)pet)->AI()->AttackStart(unit_target);
+ }
}
spell->prepare(&(spell->m_targets));
@@ -254,14 +281,13 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
if(pet->isPossessed())
{
WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
- data << uint32(spellid) << uint8(2) << uint8(result);
+ data << uint8(0) << uint32(spellid) << uint8(result);
switch (result)
{
case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
data << uint32(spellInfo->RequiresSpellFocus);
break;
- case SPELL_FAILED_REQUIRES_AREA:
- data << uint32(spellInfo->AreaId);
+ default:
break;
}
SendPacket(&data);
@@ -278,7 +304,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
break;
}
default:
- sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.\n", flag, spellid);
+ sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", flag, spellid);
}
}
@@ -286,7 +312,7 @@ void WorldSession::HandlePetNameQuery( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data,4+8);
- sLog.outDetail( "HandlePetNameQuery. CMSG_PET_NAME_QUERY\n" );
+ sLog.outDetail( "HandlePetNameQuery. CMSG_PET_NAME_QUERY" );
uint32 petnumber;
uint64 petguid;
@@ -299,7 +325,7 @@ void WorldSession::HandlePetNameQuery( WorldPacket & recv_data )
void WorldSession::SendPetNameQuery( uint64 petguid, uint32 petnumber)
{
- Creature* pet = ObjectAccessor::GetCreatureOrPet(*_player, petguid);
+ Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, petguid);
if(!pet || !pet->GetCharmInfo() || pet->GetCharmInfo()->GetPetNumber() != petnumber)
return;
@@ -326,7 +352,7 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data, 8+4+2+2);
- sLog.outDetail( "HandlePetSetAction. CMSG_PET_SET_ACTION\n" );
+ sLog.outDetail( "HandlePetSetAction. CMSG_PET_SET_ACTION" );
uint64 petguid;
uint32 position;
@@ -336,16 +362,11 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
recv_data >> petguid;
- // FIXME: charmed case
- //Pet* pet = ObjectAccessor::Instance().GetPet(petguid);
- if(ObjectAccessor::FindPlayer(petguid))
- return;
-
- Creature* pet = ObjectAccessor::GetCreatureOrPet(*_player, petguid);
+ Unit* pet = ObjectAccessor::GetUnit(*_player, petguid);
- if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm()))
+ if(!pet || pet != _player->GetFirstControlled())
{
- sLog.outError( "HandlePetSetAction: Unknown pet or pet owner.\n" );
+ sLog.outError( "HandlePetSetAction: Unknown pet or pet owner." );
return;
}
@@ -357,32 +378,33 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
}
count = (recv_data.size() == 24) ? 2 : 1;
- for(uint8 i = 0; i < count; i++)
+ for(uint8 i = 0; i < count; ++i)
{
recv_data >> position;
recv_data >> spell_id;
recv_data >> act_state;
- sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X\n", _player->GetName(), position, spell_id, act_state);
+ sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X", _player->GetName(), position, spell_id, act_state);
//if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add
- if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_CAST) && spell_id && !pet->HasSpell(spell_id)))
+ if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id)))
{
//sign for autocast
if(act_state == ACT_ENABLED && spell_id)
{
- if(pet->isCharmed())
- charmInfo->ToggleCreatureAutocast(spell_id, true);
- else
+ if(pet->GetTypeId() == TYPEID_UNIT && ((Creature*)pet)->isPet())
((Pet*)pet)->ToggleAutocast(spell_id, true);
+ else
+ charmInfo->ToggleCreatureAutocast(spell_id, true);
}
//sign for no/turn off autocast
else if(act_state == ACT_DISABLED && spell_id)
{
- if(pet->isCharmed())
- charmInfo->ToggleCreatureAutocast(spell_id, false);
- else
+ if(pet->GetTypeId() == TYPEID_UNIT && ((Creature*)pet)->isPet())
((Pet*)pet)->ToggleAutocast(spell_id, false);
+ else
+ charmInfo->ToggleCreatureAutocast(spell_id, false);
+
}
charmInfo->GetActionBarEntry(position)->Type = act_state;
@@ -395,7 +417,7 @@ void WorldSession::HandlePetRename( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data, 8+1);
- sLog.outDetail( "HandlePetRename. CMSG_PET_RENAME\n" );
+ sLog.outDetail( "HandlePetRename. CMSG_PET_RENAME" );
uint64 petguid;
uint8 isdeclined;
@@ -478,7 +500,7 @@ void WorldSession::HandlePetAbandon( WorldPacket & recv_data )
sLog.outDetail( "HandlePetAbandon. CMSG_PET_ABANDON pet guid is %u", GUID_LOPART(guid) );
// pet/charmed
- Creature* pet = ObjectAccessor::GetCreatureOrPet(*_player, guid);
+ Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid);
if(pet)
{
if(pet->isPet())
@@ -492,7 +514,7 @@ void WorldSession::HandlePetAbandon( WorldPacket & recv_data )
_player->RemovePet((Pet*)pet,PET_SAVE_AS_DELETED);
}
else if(pet->GetGUID() == _player->GetCharmGUID())
- _player->Uncharm();
+ _player->StopCastingCharm();
}
}
@@ -502,16 +524,16 @@ void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket)
sLog.outDetail("CMSG_PET_UNLEARN");
uint64 guid;
- recvPacket >> guid;
+ recvPacket >> guid; // Pet guid
Pet* pet = _player->GetPet();
- if(!pet || pet->getPetType() != HUNTER_PET || pet->m_spells.size() <= 1)
+ if(!pet || pet->getPetType() != HUNTER_PET || pet->m_usedTalentCount == 0)
return;
if(guid != pet->GetGUID())
{
- sLog.outError( "HandlePetUnlearnOpcode.Pet %u isn't pet of player %s .\n", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
+ sLog.outError( "HandlePetUnlearnOpcode.Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
return;
}
@@ -521,38 +543,7 @@ void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket)
sLog.outError("WorldSession::HandlePetUnlearnOpcode: object "I64FMTD" is considered pet-like but doesn't have a charminfo!", pet->GetGUID());
return;
}
-
- uint32 cost = pet->resetTalentsCost();
-
- if (GetPlayer()->GetMoney() < cost)
- {
- GetPlayer()->SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
- return;
- }
-
- for(PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end();)
- {
- uint32 spell_id = itr->first; // Pet::removeSpell can invalidate iterator at erase NEW spell
- ++itr;
- pet->removeSpell(spell_id);
- }
-
- pet->SetTP(pet->getLevel() * (pet->GetLoyaltyLevel() - 1));
-
- for(uint8 i = 0; i < 10; i++)
- {
- if(charmInfo->GetActionBarEntry(i)->SpellOrAction && charmInfo->GetActionBarEntry(i)->Type == ACT_ENABLED || charmInfo->GetActionBarEntry(i)->Type == ACT_DISABLED)
- charmInfo->GetActionBarEntry(i)->SpellOrAction = 0;
- }
-
- // relearn pet passives
- pet->LearnPetPassives();
-
- pet->m_resetTalentsTime = time(NULL);
- pet->m_resetTalentsCost = cost;
- GetPlayer()->ModifyMoney(-(int32)cost);
-
- GetPlayer()->PetSpellInitialize();
+ pet->resetTalents();
}
void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
@@ -566,22 +557,22 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
uint8 state; //1 for on, 0 for off
recvPacket >> guid >> spellid >> spellid2 >> state;
- if(!_player->GetPet() && !_player->GetCharm())
+ if(!_player->GetGuardianPet() && !_player->GetCharm())
return;
if(ObjectAccessor::FindPlayer(guid))
return;
- Creature* pet=ObjectAccessor::GetCreatureOrPet(*_player,guid);
+ Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid);
- if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm()))
+ if(!pet || (pet != _player->GetGuardianPet() && pet != _player->GetCharm()))
{
- sLog.outError( "HandlePetSpellAutocastOpcode.Pet %u isn't pet of player %s .\n", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
+ sLog.outError( "HandlePetSpellAutocastOpcode.Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
return;
}
// do not add not learned spells/ passive spells
- if(!pet->HasSpell(spellid) || IsPassiveSpell(spellid))
+ if(!pet->HasSpell(spellid) || IsAutocastableSpell(spellid))
return;
CharmInfo *charmInfo = pet->GetCharmInfo();
@@ -591,11 +582,10 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
return;
}
- if(pet->isCharmed())
- //state can be used as boolean
- pet->GetCharmInfo()->ToggleCreatureAutocast(spellid, state);
- else
+ if(pet->isPet())
((Pet*)pet)->ToggleAutocast(spellid, state);
+ else
+ pet->GetCharmInfo()->ToggleCreatureAutocast(spellid, state);
for(uint8 i = 0; i < 10; ++i)
{
@@ -608,21 +598,25 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
{
sLog.outDetail("WORLD: CMSG_PET_CAST_SPELL");
- CHECK_PACKET_SIZE(recvPacket,8+4);
+ CHECK_PACKET_SIZE(recvPacket,8+1+4+1);
uint64 guid;
uint32 spellid;
+ uint8 cast_count;
+ uint8 unk_flags; // flags (if 0x02 - some additional data are received)
+
+ recvPacket >> guid >> cast_count >> spellid >> unk_flags;
- recvPacket >> guid >> spellid;
+ sLog.outDebug("WORLD: CMSG_PET_CAST_SPELL, cast_count: %u, spellid %u, unk_flags %u", cast_count, spellid, unk_flags);
// This opcode is also sent from charmed and possessed units (players and creatures)
- if(!_player->GetPet() && !_player->GetCharm())
+ if(!_player->GetGuardianPet() && !_player->GetCharm())
return;
Unit* caster = ObjectAccessor::GetUnit(*_player, guid);
- if(!caster || (caster != _player->GetPet() && caster != _player->GetCharm()))
+ if(!caster || (caster != _player->GetGuardianPet() && caster != _player->GetCharm()))
{
- sLog.outError( "HandlePetCastSpellOpcode: Pet %u isn't pet of player %s .\n", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
+ sLog.outError( "HandlePetCastSpellOpcode: Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
return;
}
@@ -632,7 +626,7 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid);
if(!spellInfo)
{
- sLog.outError("WORLD: unknown PET spell id %i\n", spellid);
+ sLog.outError("WORLD: unknown PET spell id %i", spellid);
return;
}
@@ -647,10 +641,11 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
caster->clearUnitState(UNIT_STAT_FOLLOW);
Spell *spell = new Spell(caster, spellInfo, false);
+ spell->m_cast_count = cast_count; // probably pending spell cast
spell->m_targets = targets;
- int16 result = spell->PetCanCast(NULL);
- if(result == -1)
+ SpellCastResult result = spell->CheckPetCast(NULL);
+ if(result == SPELL_CAST_OK)
{
if(caster->GetTypeId() == TYPEID_UNIT)
{
@@ -706,3 +701,15 @@ void WorldSession::SendPetNameInvalid(uint32 error, const std::string& name, Dec
SendPacket(&data);
}
+void WorldSession::HandlePetLearnTalent( WorldPacket & recv_data )
+{
+ sLog.outDebug("WORLD: CMSG_PET_LEARN_TALENT");
+
+ CHECK_PACKET_SIZE(recv_data, 8+4+4);
+
+ uint64 guid;
+ uint32 talent_id, requested_rank;
+ recv_data >> guid >> talent_id >> requested_rank;
+
+ _player->LearnPetTalent(guid, talent_id, requested_rank);
+}
diff --git a/src/game/PetitionsHandler.cpp b/src/game/PetitionsHandler.cpp
index 7ae368140c7..19457caa048 100644
--- a/src/game/PetitionsHandler.cpp
+++ b/src/game/PetitionsHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -28,7 +28,6 @@
#include "Opcodes.h"
#include "Guild.h"
#include "ArenaTeam.h"
-#include "MapManager.h"
#include "GossipDef.h"
#include "SocialMgr.h"
@@ -83,7 +82,7 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data)
sLog.outDebug("Petitioner with GUID %u tried sell petition: name %s", GUID_LOPART(guidNPC), name.c_str());
// prevent cheating
- Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guidNPC,UNIT_NPC_FLAG_PETITIONER);
+ Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guidNPC,UNIT_NPC_FLAG_PETITIONER);
if (!pCreature)
{
sLog.outDebug("WORLD: HandlePetitionBuyOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(guidNPC));
@@ -92,7 +91,7 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data)
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
uint32 charterid = 0;
uint32 cost = 0;
@@ -199,9 +198,9 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data)
if(!charter)
return;
- charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT, charter->GetGUIDLow());
- // ITEM_FIELD_ENCHANTMENT is guild/arenateam id
- // ITEM_FIELD_ENCHANTMENT+1 is current signatures count (showed on item)
+ charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1, charter->GetGUIDLow());
+ // ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id
+ // ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item)
charter->SetState(ITEM_CHANGED, _player);
_player->SendNewItem(charter, 1, true, false);
@@ -255,7 +254,7 @@ void WorldSession::HandlePetitionShowSignOpcode(WorldPacket & recv_data)
QueryResult *result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", petitionguid_low);
if(!result)
{
- sLog.outError("any petition on server...");
+ sLog.outError("Petition %u is not found for player %u %s", GUID_LOPART(petitionguid), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName());
return;
}
Field *fields = result->Fetch();
@@ -280,10 +279,10 @@ void WorldSession::HandlePetitionShowSignOpcode(WorldPacket & recv_data)
data << petitionguid_low; // guild guid (in Trinity always same as GUID_LOPART(petitionguid)
data << signs; // sign's count
- for(uint8 i = 1; i <= signs; i++)
+ for(uint8 i = 1; i <= signs; ++i)
{
- Field *fields = result->Fetch();
- uint64 plguid = fields[0].GetUInt64();
+ Field *fields2 = result->Fetch();
+ uint64 plguid = fields2[0].GetUInt64();
data << plguid; // Player GUID
data << (uint32)0; // there 0 ...
@@ -463,7 +462,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)
if(!result)
{
- sLog.outError("any petition on server...");
+ sLog.outError("Petition %u is not found for player %u %s", GUID_LOPART(petitionguid), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName());
return;
}
@@ -565,7 +564,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)
// update signs count on charter, required testing...
//Item *item = _player->GetItemByGuid(petitionguid));
//if(item)
- // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT+1, signs);
+ // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs);
// update for owner if online
if(Player *owner = objmgr.GetPlayer(ownerguid))
@@ -691,10 +690,10 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recv_data)
data << GUID_LOPART(petitionguid); // guild guid (in Trinity always same as GUID_LOPART(petition guid)
data << signs; // sign's count
- for(uint8 i = 1; i <= signs; i++)
+ for(uint8 i = 1; i <= signs; ++i)
{
- Field *fields = result->Fetch();
- uint64 plguid = fields[0].GetUInt64();
+ Field *fields2 = result->Fetch();
+ plguid = fields2[0].GetUInt64();
data << plguid; // Player GUID
data << (uint32)0; // there 0 ...
@@ -827,7 +826,7 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data)
if(type == 9) // create guild
{
Guild* guild = new Guild;
- if(!guild->create(_player->GetGUID(), name))
+ if(!guild->create(_player, name))
{
delete guild;
delete result;
@@ -907,7 +906,7 @@ void WorldSession::HandlePetitionShowListOpcode(WorldPacket & recv_data)
void WorldSession::SendPetitionShowList(uint64 guid)
{
- Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_PETITIONER);
+ Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_PETITIONER);
if (!pCreature)
{
sLog.outDebug("WORLD: HandlePetitionShowListOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
@@ -916,7 +915,7 @@ void WorldSession::SendPetitionShowList(uint64 guid)
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
uint8 count = 0;
if(pCreature->isTabardDesigner())
@@ -960,7 +959,7 @@ void WorldSession::SendPetitionShowList(uint64 guid)
data << uint32(5); // unknown
data << uint32(5); // required signs?
}
- //for(uint8 i = 0; i < count; i++)
+ //for(uint8 i = 0; i < count; ++i)
//{
// data << uint32(i); // index
// data << uint32(GUILD_CHARTER); // charter entry
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 387ea279969..c5325de71ab 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -23,13 +23,13 @@
#include "Database/DatabaseEnv.h"
#include "Log.h"
#include "Opcodes.h"
-#include "ObjectMgr.h"
#include "SpellMgr.h"
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "UpdateMask.h"
#include "Player.h"
+#include "Vehicle.h"
#include "SkillDiscovery.h"
#include "QuestDef.h"
#include "GossipDef.h"
@@ -49,7 +49,6 @@
#include "Group.h"
#include "Guild.h"
#include "Pet.h"
-#include "SpellAuras.h"
#include "Util.h"
#include "Transports.h"
#include "Weather.h"
@@ -63,11 +62,13 @@
#include "Database/DatabaseImpl.h"
#include "Spell.h"
#include "SocialMgr.h"
-#include "GameEvent.h"
+#include "GameEventMgr.h"
+#include "AchievementMgr.h"
+#include "SpellAuras.h"
#include <cmath>
-#define ZONE_UPDATE_INTERVAL 1000
+#define ZONE_UPDATE_INTERVAL (1*IN_MILISECONDS)
#define PLAYER_SKILL_INDEX(x) (PLAYER_SKILL_INFO_1_1 + ((x)*3))
#define PLAYER_SKILL_VALUE_INDEX(x) (PLAYER_SKILL_INDEX(x)+1)
@@ -132,9 +133,20 @@ PlayerTaxi::PlayerTaxi()
memset(m_taximask, 0, sizeof(m_taximask));
}
-void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 level)
+void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint32 level)
{
- // capital and taxi hub masks
+ // class specific initial known nodes
+ switch(chrClass)
+ {
+ case CLASS_DEATH_KNIGHT:
+ {
+ for(int i = 0; i < TaxiMaskSize; ++i)
+ m_taximask[i] |= sOldContinentsNodesMask[i];
+ break;
+ }
+ }
+
+ // race specific initial known nodes: capital and taxi hub masks
switch(race)
{
case RACE_HUMAN: SetTaximaskNode(2); break; // Human
@@ -149,6 +161,7 @@ void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 level)
case RACE_BLOODELF: SetTaximaskNode(82); break; // Blood Elf
case RACE_DRAENEI: SetTaximaskNode(94); break; // Draenei
}
+
// new continent starting masks (It will be accessible only at new map)
switch(Player::TeamForRace(race))
{
@@ -188,7 +201,7 @@ void PlayerTaxi::AppendTaximaskTo( ByteBuffer& data, bool all )
}
}
-bool PlayerTaxi::LoadTaxiDestinationsFromString( const std::string& values )
+bool PlayerTaxi::LoadTaxiDestinationsFromString( const std::string& values, uint32 team )
{
ClearTaxiDestinations();
@@ -216,6 +229,10 @@ bool PlayerTaxi::LoadTaxiDestinationsFromString( const std::string& values )
return false;
}
+ // can't load taxi path without mount set (quest taxi path?)
+ if(!objmgr.GetTaxiMount(GetTaxiSource(),team))
+ return false;
+
return true;
}
@@ -245,13 +262,20 @@ uint32 PlayerTaxi::GetCurrentTaxiPath() const
return path;
}
-//== Player ====================================================
+std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi)
+{
+ ss << "'";
+ for(int i = 0; i < TaxiMaskSize; ++i)
+ ss << taxi.m_taximask[i] << " ";
+ ss << "'";
+ return ss;
+}
-const int32 Player::ReputationRank_Length[MAX_REPUTATION_RANK] = {36000, 3000, 3000, 3000, 6000, 12000, 21000, 1000};
+//== Player ====================================================
UpdateMask Player::updateVisualBits;
-Player::Player (WorldSession *session): Unit()
+Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputationMgr(this)
{
m_transport = 0;
@@ -280,6 +304,7 @@ Player::Player (WorldSession *session): Unit()
m_comboPoints = 0;
m_usedTalentCount = 0;
+ m_questRewardTalentCount = 0;
m_regenTimer = 0;
m_weaponChangeTimer = 0;
@@ -306,7 +331,7 @@ Player::Player (WorldSession *session): Unit()
// group is initialized in the reference constructor
SetGroupInvite(NULL);
m_groupUpdateMask = 0;
- m_auraUpdateMask = 0;
+ m_auraRaidUpdateMask = 0;
duel = NULL;
@@ -315,7 +340,8 @@ Player::Player (WorldSession *session): Unit()
m_atLoginFlags = AT_LOGIN_NONE;
- m_dontMove = false;
+ mSemaphoreTeleport_Near = false;
+ mSemaphoreTeleport_Far = false;
pTrader = 0;
ClearTrade();
@@ -332,10 +358,11 @@ Player::Player (WorldSession *session): Unit()
m_DailyQuestChanged = false;
m_lastDailyQuestTime = 0;
- m_regenTimer = 0;
- m_weaponChangeTimer = 0;
- m_breathTimer = 0;
- m_isunderwater = 0;
+ for (int i=0; i<MAX_TIMERS; i++)
+ m_MirrorTimer[i] = DISABLED_MIRROR_TIMER;
+
+ m_MirrorTimerFlags = UNDERWATER_NONE;
+ m_MirrorTimerFlagsLast = UNDERWATER_NONE;
m_isInWater = false;
m_drunkTimer = 0;
m_drunk = 0;
@@ -345,12 +372,13 @@ Player::Player (WorldSession *session): Unit()
m_swingErrorMsg = 0;
- m_DetectInvTimer = 1000;
+ m_DetectInvTimer = 1*IN_MILISECONDS;
m_bgBattleGroundID = 0;
+ m_bgTypeID = BATTLEGROUND_TYPE_NONE;
for (int j=0; j < PLAYER_MAX_BATTLEGROUND_QUEUES; j++)
{
- m_bgBattleGroundQueueID[j].bgQueueType = 0;
+ m_bgBattleGroundQueueID[j].bgQueueTypeId = BATTLEGROUND_QUEUE_NONE;
m_bgBattleGroundQueueID[j].invitedToInstance = 0;
}
m_bgTeam = 0;
@@ -362,6 +390,7 @@ Player::Player (WorldSession *session): Unit()
m_canParry = false;
m_canBlock = false;
m_canDualWield = false;
+ m_canTitanGrip = false;
m_ammoDPS = 0.0f;
m_temporaryUnsummonedPetNumber = 0;
@@ -400,12 +429,22 @@ Player::Player (WorldSession *session): Unit()
m_InstanceValid = true;
m_dungeonDifficulty = DIFFICULTY_NORMAL;
+ m_lastPotionId = 0;
+
for (int i = 0; i < BASEMOD_END; i++)
{
m_auraBaseMod[i][FLAT_MOD] = 0.0f;
m_auraBaseMod[i][PCT_MOD] = 1.0f;
}
+ for (int i = 0; i < MAX_COMBAT_RATING; i++)
+ m_baseRatingValue[i] = 0;
+
+ m_baseSpellDamage = 0;
+ m_baseSpellHealing = 0;
+ m_baseFeralAP = 0;
+ m_baseManaRegen = 0;
+
// Honor System
m_lastHonorUpdateTime = time(NULL);
@@ -419,7 +458,9 @@ Player::Player (WorldSession *session): Unit()
//Default movement to run mode
m_unit_movement_flags = 0;
- m_miniPet = 0;
+ m_mover = this;
+ m_seer = this;
+
m_bgAfkReportedTimer = 0;
m_contestedPvPTimer = 0;
@@ -427,13 +468,16 @@ Player::Player (WorldSession *session): Unit()
m_isActive = true;
- m_farsightVision = false;
+ m_runes = NULL;
+
+ m_lastFallTime = 0;
+ m_lastFallZ = 0;
+
+ m_ControlledByPlayer = true;
}
Player::~Player ()
{
- CleanupsBeforeDelete();
-
// it must be unloaded already in PlayerLogout and accessed only for loggined player
//m_social = NULL;
@@ -443,7 +487,6 @@ Player::~Player ()
if(m_items[i])
delete m_items[i];
}
- CleanupChannels();
for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
delete itr->second;
@@ -457,31 +500,28 @@ Player::~Player ()
delete PlayerTalkClass;
- if (m_transport)
- {
- m_transport->RemovePassenger(this);
- }
-
for(size_t x = 0; x < ItemSetEff.size(); x++)
if(ItemSetEff[x])
delete ItemSetEff[x];
- // clean up player-instance binds, may unload some instance saves
- for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
- for(BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
- itr->second.save->RemovePlayer(this);
-
delete m_declinedname;
+ delete m_runes;
}
void Player::CleanupsBeforeDelete()
{
- if(m_uint32Values) // only for fully created Object
- {
- TradeCancel(false);
- DuelComplete(DUEL_INTERUPTED);
- }
+ TradeCancel(false);
+ DuelComplete(DUEL_INTERUPTED);
+
Unit::CleanupsBeforeDelete();
+
+ if (m_transport)
+ m_transport->RemovePassenger(this);
+
+ // clean up player-instance binds, may unload some instance saves
+ for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i)
+ for(BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
+ itr->second.save->RemovePlayer(this);
}
bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 class_, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair, uint8 outfitId )
@@ -517,24 +557,8 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
uint8 powertype = cEntry->powerType;
- uint32 unitfield;
-
- switch(powertype)
- {
- case POWER_ENERGY:
- case POWER_MANA:
- unitfield = 0x00000000;
- break;
- case POWER_RAGE:
- unitfield = 0x00110000;
- break;
- default:
- sLog.outError("Invalid default powertype %u for player (class %u)",powertype,class_);
- return false;
- }
-
- SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE );
- SetFloatValue(UNIT_FIELD_COMBATREACH, DEFAULT_COMBAT_REACH );
+ SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE);
+ SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f);
switch(gender)
{
@@ -557,12 +581,13 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
uint32 RaceClassGender = ( race ) | ( class_ << 8 ) | ( gender << 16 );
SetUInt32Value(UNIT_FIELD_BYTES_0, ( RaceClassGender | ( powertype << 24 ) ) );
- SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield);
- SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY | UNIT_BYTE2_FLAG_UNK5 );
- SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE );
+ SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP );
+ SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE );
+ SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_REGENERATE_POWER);
SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); // fix cast time showed in spell tooltip on client
+ SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f); // default for players in 3.0.3
- //-1 is default value
+ // -1 is default value
SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
SetUInt32Value(PLAYER_BYTES, (skin | (face << 8) | (hairStyle << 16) | (hairColor << 24)));
@@ -574,6 +599,7 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
SetUInt32Value( PLAYER_GUILD_TIMESTAMP, 0 );
SetUInt64Value( PLAYER__FIELD_KNOWN_TITLES, 0 ); // 0=disabled
+ SetUInt64Value( PLAYER__FIELD_KNOWN_TITLES1, 0 ); // 0=disabled
SetUInt32Value( PLAYER_CHOSEN_TITLE, 0 );
SetUInt32Value( PLAYER_FIELD_KILLS, 0 );
SetUInt32Value( PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0 );
@@ -581,10 +607,20 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
SetUInt32Value( PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0 );
// set starting level
+ uint32 start_level = getClass() != CLASS_DEATH_KNIGHT
+ ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL)
+ : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
+
if (GetSession()->GetSecurity() >= SEC_MODERATOR)
- SetUInt32Value (UNIT_FIELD_LEVEL, sWorld.getConfig(CONFIG_START_GM_LEVEL));
- else
- SetUInt32Value (UNIT_FIELD_LEVEL, sWorld.getConfig(CONFIG_START_PLAYER_LEVEL));
+ {
+ uint32 gm_level = sWorld.getConfig(CONFIG_START_GM_LEVEL);
+ if(gm_level > start_level)
+ start_level = gm_level;
+ }
+
+ SetUInt32Value(UNIT_FIELD_LEVEL, start_level);
+
+ InitRunes();
SetUInt32Value (PLAYER_FIELD_COINAGE, sWorld.getConfig(CONFIG_START_PLAYER_MONEY));
SetUInt32Value (PLAYER_FIELD_HONOR_CURRENCY, sWorld.getConfig(CONFIG_START_HONOR_POINTS));
@@ -600,40 +636,40 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
//Reputations if "StartAllReputation" is enabled, -- TODO: Fix this in a better way
if(sWorld.getConfig(CONFIG_START_ALL_REP))
{
- SetFactionReputation(sFactionStore.LookupEntry(942),42999);
- SetFactionReputation(sFactionStore.LookupEntry(935),42999);
- SetFactionReputation(sFactionStore.LookupEntry(936),42999);
- SetFactionReputation(sFactionStore.LookupEntry(1011),42999);
- SetFactionReputation(sFactionStore.LookupEntry(970),42999);
- SetFactionReputation(sFactionStore.LookupEntry(967),42999);
- SetFactionReputation(sFactionStore.LookupEntry(989),42999);
- SetFactionReputation(sFactionStore.LookupEntry(932),42999);
- SetFactionReputation(sFactionStore.LookupEntry(934),42999);
- SetFactionReputation(sFactionStore.LookupEntry(1038),42999);
- SetFactionReputation(sFactionStore.LookupEntry(1077),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(942),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(935),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(936),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(1011),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(970),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(967),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(989),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(932),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(934),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(1038),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(1077),42999);
// Factions depending on team, like cities and some more stuff
switch(GetTeam())
{
case ALLIANCE:
- SetFactionReputation(sFactionStore.LookupEntry(72),42999);
- SetFactionReputation(sFactionStore.LookupEntry(47),42999);
- SetFactionReputation(sFactionStore.LookupEntry(69),42999);
- SetFactionReputation(sFactionStore.LookupEntry(930),42999);
- SetFactionReputation(sFactionStore.LookupEntry(730),42999);
- SetFactionReputation(sFactionStore.LookupEntry(978),42999);
- SetFactionReputation(sFactionStore.LookupEntry(54),42999);
- SetFactionReputation(sFactionStore.LookupEntry(946),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(72),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(47),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(69),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(930),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(730),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(978),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(54),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(946),42999);
break;
case HORDE:
- SetFactionReputation(sFactionStore.LookupEntry(76),42999);
- SetFactionReputation(sFactionStore.LookupEntry(68),42999);
- SetFactionReputation(sFactionStore.LookupEntry(81),42999);
- SetFactionReputation(sFactionStore.LookupEntry(911),42999);
- SetFactionReputation(sFactionStore.LookupEntry(729),42999);
- SetFactionReputation(sFactionStore.LookupEntry(941),42999);
- SetFactionReputation(sFactionStore.LookupEntry(530),42999);
- SetFactionReputation(sFactionStore.LookupEntry(947),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(76),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(68),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(81),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(911),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(729),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(941),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(530),42999);
+ GetReputationMgr().SetReputation(sFactionStore.LookupEntry(947),42999);
break;
default:
break;
@@ -648,6 +684,7 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
// base stats and related field values
InitStatsForLevel();
InitTaxiNodesForLevel();
+ InitGlyphsForLevel();
InitTalentForLevel();
InitPrimaryProffesions(); // to max set before any spell added
@@ -660,8 +697,16 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
SetPower(POWER_MANA,GetMaxPower(POWER_MANA));
}
+ if(getPowerType() == POWER_RUNIC_POWER)
+ {
+ SetPower(POWER_RUNE, 8);
+ SetMaxPower(POWER_RUNE, 8);
+ SetPower(POWER_RUNIC_POWER, 0);
+ SetMaxPower(POWER_RUNIC_POWER, 1000);
+ }
+
// original spells
- learnDefaultSpells(true);
+ learnDefaultSpells();
// original action bar
std::list<uint16>::const_iterator action_itr[4];
@@ -703,6 +748,11 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
uint32 item_id = oEntry->ItemId[j];
+
+ // Hack for not existed item id in dbc 3.0.3
+ if(item_id==40582)
+ continue;
+
ItemPrototype const* iProto = objmgr.GetItemPrototype(item_id);
if(!iProto)
{
@@ -710,7 +760,9 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
continue;
}
- uint32 count = iProto->Stackable; // max stack by default (mostly 1)
+ // max stack by default (mostly 1), 1 for infinity stackable
+ uint32 count = iProto->Stackable > 0 ? uint32(iProto->Stackable) : 1;
+
if(iProto->Class==ITEM_CLASS_CONSUMABLE && iProto->SubClass==ITEM_SUBCLASS_FOOD)
{
switch(iProto->Spells[0].SpellCategory)
@@ -760,9 +812,9 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
}
// if this is ammo then use it
- uint8 msg = CanUseAmmo( pItem->GetProto()->ItemId );
+ msg = CanUseAmmo( pItem->GetEntry() );
if( msg == EQUIP_ERR_OK )
- SetAmmo( pItem->GetProto()->ItemId );
+ SetAmmo( pItem->GetEntry() );
}
}
}
@@ -806,25 +858,14 @@ bool Player::StoreNewItemInBestSlots(uint32 titem_id, uint32 titem_amount)
return false;
}
-void Player::StartMirrorTimer(MirrorTimerType Type, uint32 MaxValue)
-{
- uint32 BreathRegen = (uint32)-1;
-
- WorldPacket data(SMSG_START_MIRROR_TIMER, (21));
- data << (uint32)Type;
- data << MaxValue;
- data << MaxValue;
- data << BreathRegen;
- data << (uint8)0;
- data << (uint32)0; // spell id
- GetSession()->SendPacket(&data);
-}
-
-void Player::ModifyMirrorTimer(MirrorTimerType Type, uint32 MaxValue, uint32 CurrentValue, uint32 Regen)
+void Player::SendMirrorTimer(MirrorTimerType Type, uint32 MaxValue, uint32 CurrentValue, int32 Regen)
{
- if(Type==BREATH_TIMER)
- m_breathTimer = ((MaxValue + 1000) - CurrentValue) / Regen;
-
+ if (MaxValue == DISABLED_MIRROR_TIMER)
+ {
+ if (CurrentValue!=DISABLED_MIRROR_TIMER)
+ StopMirrorTimer(Type);
+ return;
+ }
WorldPacket data(SMSG_START_MIRROR_TIMER, (21));
data << (uint32)Type;
data << CurrentValue;
@@ -837,150 +878,199 @@ void Player::ModifyMirrorTimer(MirrorTimerType Type, uint32 MaxValue, uint32 Cur
void Player::StopMirrorTimer(MirrorTimerType Type)
{
- if(Type==BREATH_TIMER)
- m_breathTimer = 0;
-
+ m_MirrorTimer[Type] = DISABLED_MIRROR_TIMER;
WorldPacket data(SMSG_STOP_MIRROR_TIMER, 4);
data << (uint32)Type;
GetSession()->SendPacket( &data );
}
-void Player::EnvironmentalDamage(uint64 guid, EnviromentalDamage type, uint32 damage)
+void Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
{
+ if(!isAlive() || isGameMaster())
+ return;
+
+ // Absorb, resist some environmental damage type
+ uint32 absorb = 0;
+ uint32 resist = 0;
+ if (type == DAMAGE_LAVA)
+ CalcAbsorbResist(this, SPELL_SCHOOL_MASK_FIRE, DIRECT_DAMAGE, damage, &absorb, &resist);
+ else if (type == DAMAGE_SLIME)
+ CalcAbsorbResist(this, SPELL_SCHOOL_MASK_NATURE, DIRECT_DAMAGE, damage, &absorb, &resist);
+
+ damage-=absorb+resist;
+
WorldPacket data(SMSG_ENVIRONMENTALDAMAGELOG, (21));
- data << (uint64)guid;
- data << (uint8)(type!=DAMAGE_FALL_TO_VOID ? type : DAMAGE_FALL);
- data << (uint32)damage;
- data << (uint32)0;
- data << (uint32)0;
+ data << uint64(GetGUID());
+ data << uint8(type!=DAMAGE_FALL_TO_VOID ? type : DAMAGE_FALL);
+ data << uint32(damage);
+ data << uint32(absorb);
+ data << uint32(resist);
SendMessageToSet(&data, true);
DealDamage(this, damage, NULL, SELF_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- if(type==DAMAGE_FALL && !isAlive()) // DealDamage not apply item durability loss at self damage
+ if(!isAlive())
{
- DEBUG_LOG("We are fall to death, loosing 10 percents durability");
- DurabilityLossAll(0.10f,false);
- // durability lost message
- WorldPacket data(SMSG_DURABILITY_DAMAGE_DEATH, 0);
- GetSession()->SendPacket(&data);
+ if(type==DAMAGE_FALL) // DealDamage not apply item durability loss at self damage
+ {
+ DEBUG_LOG("We are fall to death, loosing 10 percents durability");
+ DurabilityLossAll(0.10f,false);
+ // durability lost message
+ WorldPacket data2(SMSG_DURABILITY_DAMAGE_DEATH, 0);
+ GetSession()->SendPacket(&data2);
+ }
+
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM, 1, type);
}
}
-void Player::HandleDrowning()
+int32 Player::getMaxTimer(MirrorTimerType timer)
{
- if(!m_isunderwater)
- return;
-
- //if player is GM, have waterbreath, is dead or if breathing is disabled then return
- if(waterbreath || isGameMaster() || !isAlive() || GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_DISABLE_BREATHING))
+ switch (timer)
{
- StopMirrorTimer(BREATH_TIMER);
- m_isunderwater = 0;
- return;
+ case FATIGUE_TIMER:
+ return MINUTE*IN_MILISECONDS;
+ case BREATH_TIMER:
+ {
+ if (!isAlive() || HasAuraType(SPELL_AURA_WATER_BREATHING) || GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_DISABLE_BREATHING))
+ return DISABLED_MIRROR_TIMER;
+ int32 UnderWaterTime = 3*MINUTE*IN_MILISECONDS;
+ AuraEffectList const& mModWaterBreathing = GetAurasByType(SPELL_AURA_MOD_WATER_BREATHING);
+ for(AuraEffectList::const_iterator i = mModWaterBreathing.begin(); i != mModWaterBreathing.end(); ++i)
+ UnderWaterTime = uint32(UnderWaterTime * (100.0f + (*i)->GetAmount()) / 100.0f);
+ return UnderWaterTime;
+ }
+ case FIRE_TIMER:
+ {
+ if (!isAlive())
+ return DISABLED_MIRROR_TIMER;
+ return 1*IN_MILISECONDS;
+ }
+ default:
+ return 0;
}
+ return 0;
+}
- uint32 UnderWaterTime = 1*MINUTE*1000; // default length 1 min
+void Player::UpdateMirrorTimers()
+{
+ // Desync flags for update on next HandleDrowning
+ if (m_MirrorTimerFlags)
+ m_MirrorTimerFlagsLast = ~m_MirrorTimerFlags;
+}
- AuraList const& mModWaterBreathing = GetAurasByType(SPELL_AURA_MOD_WATER_BREATHING);
- for(AuraList::const_iterator i = mModWaterBreathing.begin(); i != mModWaterBreathing.end(); ++i)
- UnderWaterTime = uint32(UnderWaterTime * (100.0f + (*i)->GetModifierValue()) / 100.0f);
+void Player::HandleDrowning(uint32 time_diff)
+{
+ if (!m_MirrorTimerFlags)
+ return;
- if ((m_isunderwater & 0x01) && !(m_isunderwater & 0x80) && isAlive())
+ // In water
+ if (m_MirrorTimerFlags & UNDERWATER_INWATER)
{
- //single trigger timer
- if (!(m_isunderwater & 0x02))
+ // Breath timer not activated - activate it
+ if (m_MirrorTimer[BREATH_TIMER] == DISABLED_MIRROR_TIMER)
{
- m_isunderwater|= 0x02;
- m_breathTimer = UnderWaterTime + 1000;
+ m_MirrorTimer[BREATH_TIMER] = getMaxTimer(BREATH_TIMER);
+ SendMirrorTimer(BREATH_TIMER, m_MirrorTimer[BREATH_TIMER], m_MirrorTimer[BREATH_TIMER], -1);
}
- //single trigger "Breathbar"
- if ( m_breathTimer <= UnderWaterTime && !(m_isunderwater & 0x04))
+ else // If activated - do tick
{
- m_isunderwater|= 0x04;
- StartMirrorTimer(BREATH_TIMER, UnderWaterTime);
- }
- //continuous trigger drowning "Damage"
- if ((m_breathTimer == 0) && (m_isunderwater & 0x01))
- {
- //TODO: Check this formula
- uint64 guid = GetGUID();
- uint32 damage = GetMaxHealth() / 5 + urand(0, getLevel()-1);
-
- EnvironmentalDamage(guid, DAMAGE_DROWNING,damage);
- m_breathTimer = 2000;
+ m_MirrorTimer[BREATH_TIMER]-=time_diff;
+ // Timer limit - need deal damage
+ if (m_MirrorTimer[BREATH_TIMER] < 0)
+ {
+ m_MirrorTimer[BREATH_TIMER]+= 1*IN_MILISECONDS;
+ // Calculate and deal damage
+ // TODO: Check this formula
+ uint32 damage = GetMaxHealth() / 5 + urand(0, getLevel()-1);
+ EnvironmentalDamage(DAMAGE_DROWNING, damage);
+ }
+ else if (!(m_MirrorTimerFlagsLast & UNDERWATER_INWATER)) // Update time in client if need
+ SendMirrorTimer(BREATH_TIMER, getMaxTimer(BREATH_TIMER), m_MirrorTimer[BREATH_TIMER], -1);
}
}
- //single trigger retract bar
- else if (!(m_isunderwater & 0x01) && !(m_isunderwater & 0x08) && (m_isunderwater & 0x02) && (m_breathTimer > 0) && isAlive())
+ else if (m_MirrorTimer[BREATH_TIMER] != DISABLED_MIRROR_TIMER) // Regen timer
{
- m_isunderwater = 0x08;
-
- uint32 BreathRegen = 10;
- ModifyMirrorTimer(BREATH_TIMER, UnderWaterTime, m_breathTimer,BreathRegen);
- m_isunderwater = 0x10;
- }
- //remove bar
- else if ((m_breathTimer < 50) && !(m_isunderwater & 0x01) && (m_isunderwater == 0x10))
- {
- StopMirrorTimer(BREATH_TIMER);
- m_isunderwater = 0;
+ int32 UnderWaterTime = getMaxTimer(BREATH_TIMER);
+ // Need breath regen
+ m_MirrorTimer[BREATH_TIMER]+=10*time_diff;
+ if (m_MirrorTimer[BREATH_TIMER] >= UnderWaterTime || !isAlive())
+ StopMirrorTimer(BREATH_TIMER);
+ else if (m_MirrorTimerFlagsLast & UNDERWATER_INWATER)
+ SendMirrorTimer(BREATH_TIMER, UnderWaterTime, m_MirrorTimer[BREATH_TIMER], 10);
}
-}
-void Player::HandleLava()
-{
- bool ValidArea = false;
-
- if ((m_isunderwater & 0x80) && isAlive())
+ // In dark water
+ if (m_MirrorTimerFlags & UNDERWARER_INDARKWATER)
{
- //Single trigger Set BreathTimer
- if (!(m_isunderwater & 0x80))
+ // Fatigue timer not activated - activate it
+ if (m_MirrorTimer[FATIGUE_TIMER] == DISABLED_MIRROR_TIMER)
{
- m_isunderwater|= 0x04;
- m_breathTimer = 1000;
+ m_MirrorTimer[FATIGUE_TIMER] = getMaxTimer(FATIGUE_TIMER);
+ SendMirrorTimer(FATIGUE_TIMER, m_MirrorTimer[FATIGUE_TIMER], m_MirrorTimer[FATIGUE_TIMER], -1);
}
- //Reset BreathTimer and still in the lava
- if (!m_breathTimer)
+ else
{
- uint64 guid = GetGUID();
- uint32 damage = urand(600, 700); // TODO: Get more detailed information about lava damage
- uint32 dmgZone = GetZoneId(); // TODO: Find correct "lava dealing zone" flag in Area Table
-
- // Deal lava damage only in lava zones.
- switch(dmgZone)
+ m_MirrorTimer[FATIGUE_TIMER]-=time_diff;
+ // Timer limit - need deal damage or teleport ghost to graveyard
+ if (m_MirrorTimer[FATIGUE_TIMER] < 0)
{
- case 0x8D:
- ValidArea = false;
- break;
- case 0x94:
- ValidArea = false;
- break;
- case 0x2CE:
- ValidArea = false;
- break;
- case 0x2CF:
- ValidArea = false;
- break;
- default:
- if (dmgZone / 5 & 0x408)
- ValidArea = true;
+ m_MirrorTimer[FATIGUE_TIMER]+= 1*IN_MILISECONDS;
+ if (isAlive()) // Calculate and deal damage
+ {
+ uint32 damage = GetMaxHealth() / 5 + urand(0, getLevel()-1);
+ EnvironmentalDamage(DAMAGE_EXHAUSTED, damage);
+ }
+ else if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) // Teleport ghost to graveyard
+ RepopAtGraveyard();
}
-
- // if is valid area and is not gamemaster then deal damage
- if ( ValidArea && !isGameMaster() )
- EnvironmentalDamage(guid, DAMAGE_LAVA, damage);
-
- m_breathTimer = 1000;
+ else if (!(m_MirrorTimerFlagsLast & UNDERWARER_INDARKWATER))
+ SendMirrorTimer(FATIGUE_TIMER, getMaxTimer(FATIGUE_TIMER), m_MirrorTimer[FATIGUE_TIMER], -1);
}
-
}
- //Death timer disabled and WaterFlags reset
- else if (m_deathState == DEAD)
+ else if (m_MirrorTimer[FATIGUE_TIMER] != DISABLED_MIRROR_TIMER) // Regen timer
+ {
+ int32 DarkWaterTime = getMaxTimer(FATIGUE_TIMER);
+ m_MirrorTimer[FATIGUE_TIMER]+=10*time_diff;
+ if (m_MirrorTimer[FATIGUE_TIMER] >= DarkWaterTime || !isAlive())
+ StopMirrorTimer(FATIGUE_TIMER);
+ else if (m_MirrorTimerFlagsLast & UNDERWARER_INDARKWATER)
+ SendMirrorTimer(FATIGUE_TIMER, DarkWaterTime, m_MirrorTimer[FATIGUE_TIMER], 10);
+ }
+
+ if (m_MirrorTimerFlags & (UNDERWATER_INLAVA|UNDERWATER_INSLIME))
{
- m_breathTimer = 0;
- m_isunderwater = 0;
+ // Breath timer not activated - activate it
+ if (m_MirrorTimer[FIRE_TIMER] == DISABLED_MIRROR_TIMER)
+ m_MirrorTimer[FIRE_TIMER] = getMaxTimer(FIRE_TIMER);
+ else
+ {
+ m_MirrorTimer[FIRE_TIMER]-=time_diff;
+ if (m_MirrorTimer[FIRE_TIMER] < 0)
+ {
+ m_MirrorTimer[FIRE_TIMER]+= 1*IN_MILISECONDS;
+ // Calculate and deal damage
+ // TODO: Check this formula
+ uint32 damage = urand(600, 700);
+ if (m_MirrorTimerFlags&UNDERWATER_INLAVA)
+ EnvironmentalDamage(DAMAGE_LAVA, damage);
+ else
+ EnvironmentalDamage(DAMAGE_SLIME, damage);
+ }
+ }
}
+ else
+ m_MirrorTimer[FIRE_TIMER] = DISABLED_MIRROR_TIMER;
+
+ // Recheck timers flag
+ m_MirrorTimerFlags&=~UNDERWATER_EXIST_TIMERS;
+ for (int i = 0; i< MAX_TIMERS; ++i)
+ if (m_MirrorTimer[i]!=DISABLED_MIRROR_TIMER)
+ {
+ m_MirrorTimerFlags|=UNDERWATER_EXIST_TIMERS;
+ break;
+ }
+ m_MirrorTimerFlagsLast = m_MirrorTimerFlags;
}
///The player sobers by 256 every 10 seconds
@@ -1058,8 +1148,6 @@ void Player::Update( uint32 p_time )
UpdateAfkReport(now);
- CheckExploreSystem();
-
if(isCharmed())
{
if(Unit *charmer = GetCharmer())
@@ -1203,14 +1291,15 @@ void Player::Update( uint32 p_time )
{
if(p_time >= m_zoneUpdateTimer)
{
- uint32 newzone = GetZoneId();
+ uint32 newzone, newarea;
+ GetZoneAndAreaId(newzone,newarea);
+
if( m_zoneUpdateId != newzone )
- UpdateZone(newzone); // also update area
+ UpdateZone(newzone,newarea); // also update area
else
{
// use area updates as well
// needed for free far all arenas for example
- uint32 newarea = GetAreaId();
if( m_areaUpdateId != newarea )
UpdateArea(newarea);
@@ -1245,21 +1334,8 @@ void Player::Update( uint32 p_time )
}
}
- //Breathtimer
- if(m_breathTimer > 0)
- {
- if(p_time >= m_breathTimer)
- m_breathTimer = 0;
- else
- m_breathTimer -= p_time;
-
- }
-
//Handle Water/drowning
- HandleDrowning();
-
- //Handle lava
- HandleLava();
+ HandleDrowning(p_time);
//Handle detect stealth players
if (m_DetectInvTimer > 0)
@@ -1286,7 +1362,7 @@ void Player::Update( uint32 p_time )
{
m_drunkTimer += p_time;
- if (m_drunkTimer > 10000)
+ if (m_drunkTimer > 10*IN_MILISECONDS)
HandleSobering();
}
@@ -1311,6 +1387,7 @@ void Player::Update( uint32 p_time )
Pet* pet = GetPet();
if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && !pet->isPossessed())
+ //if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && (GetCharmGUID() && (pet->GetGUID() != GetCharmGUID())))
{
RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true);
return;
@@ -1344,16 +1421,15 @@ void Player::setDeathState(DeathState s)
//FIXME: is pet dismissed at dying or releasing spirit? if second, add setDeathState(DEAD) to HandleRepopRequestOpcode and define pet unsummon here with (s == DEAD)
RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
- // remove uncontrolled pets
- RemoveMiniPet();
- RemoveGuardians();
-
// save value before aura remove in Unit::setDeathState
ressSpellId = GetUInt32Value(PLAYER_SELF_RES_SPELL);
// passive spell
if(!ressSpellId)
ressSpellId = GetResurrectionSpellId();
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP, 1);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH, 1);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON, 1);
}
Unit::setDeathState(s);
@@ -1374,13 +1450,15 @@ void Player::setDeathState(DeathState s)
void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
{
- *p_data << GetGUID();
+ Field *fields = result->Fetch();
+
+ *p_data << uint64(GetGUID());
*p_data << m_name;
- *p_data << getRace();
+ *p_data << uint8(getRace());
uint8 pClass = getClass();
- *p_data << pClass;
- *p_data << getGender();
+ *p_data << uint8(pClass);
+ *p_data << uint8(getGender());
uint32 bytes = GetUInt32Value(PLAYER_BYTES);
*p_data << uint8(bytes);
@@ -1393,16 +1471,17 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
*p_data << uint8(getLevel()); // player level
// do not use GetMap! it will spawn a new instance since the bound instances are not loaded
- uint32 zoneId = MapManager::Instance().GetZoneId(GetMapId(), GetPositionX(),GetPositionY());
+ uint32 zoneId = MapManager::Instance().GetZoneId(GetMapId(), GetPositionX(),GetPositionY(),GetPositionZ());
sLog.outDebug("Player::BuildEnumData: m:%u, x:%f, y:%f, z:%f zone:%u", GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), zoneId);
- *p_data << zoneId;
- *p_data << GetMapId();
+ *p_data << uint32(zoneId);
+ *p_data << uint32(GetMapId());
*p_data << GetPositionX();
*p_data << GetPositionY();
*p_data << GetPositionZ();
- *p_data << (result ? result->Fetch()[13].GetUInt32() : 0);
+ // guild id
+ *p_data << (result ? fields[13].GetUInt32() : 0);
uint32 char_flags = 0;
if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM))
@@ -1413,14 +1492,13 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
char_flags |= CHARACTER_FLAG_GHOST;
if(HasAtLoginFlag(AT_LOGIN_RENAME))
char_flags |= CHARACTER_FLAG_RENAME;
- // always send the flag if declined names aren't used
- // to let the client select a default method of declining the name
- if(!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) || (result && result->Fetch()[14].GetCppString() != ""))
+ if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) && (fields[14].GetCppString() != ""))
char_flags |= CHARACTER_FLAG_DECLINED;
- *p_data << (uint32)char_flags; // character flags
-
- *p_data << (uint8)1; // unknown
+ *p_data << uint32(char_flags); // character flags
+ // character customize (flags?)
+ *p_data << uint32(HasAtLoginFlag(AT_LOGIN_CUSTOMIZE) ? 1 : 0);
+ *p_data << uint8(1); // unknown
// Pets info
{
@@ -1431,8 +1509,6 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
// show pet at selection character in character list only for non-ghost character
if(result && isAlive() && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER))
{
- Field* fields = result->Fetch();
-
uint32 entry = fields[10].GetUInt32();
CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(entry);
if(cInfo)
@@ -1443,36 +1519,11 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
}
}
- *p_data << (uint32)petDisplayId;
- *p_data << (uint32)petLevel;
- *p_data << (uint32)petFamily;
+ *p_data << uint32(petDisplayId);
+ *p_data << uint32(petLevel);
+ *p_data << uint32(petFamily);
}
- /*ItemPrototype const *items[EQUIPMENT_SLOT_END];
- for (int i = 0; i < EQUIPMENT_SLOT_END; i++)
- items[i] = NULL;
-
- QueryResult *result = CharacterDatabase.PQuery("SELECT slot,item_template FROM character_inventory WHERE guid = '%u' AND bag = 0",GetGUIDLow());
- if (result)
- {
- do
- {
- Field *fields = result->Fetch();
- uint8 slot = fields[0].GetUInt8() & 255;
- uint32 item_id = fields[1].GetUInt32();
- if( slot >= EQUIPMENT_SLOT_END )
- continue;
-
- items[slot] = objmgr.GetItemPrototype(item_id);
- if(!items[slot])
- {
- sLog.outError( "Player::BuildEnumData: Player %s have unknown item (id: #%u) in inventory, skipped.", GetName(),item_id );
- continue;
- }
- } while (result->NextRow());
- delete result;
- }*/
-
for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; slot++)
{
uint32 visualbase = PLAYER_VISIBLE_ITEM_1_0 + (slot * MAX_VISIBLE_ITEM_OFFSET);
@@ -1489,20 +1540,20 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
if (proto != NULL)
{
- *p_data << (uint32)proto->DisplayInfoID;
- *p_data << (uint8)proto->InventoryType;
- *p_data << (uint32)(enchant?enchant->aura_id:0);
+ *p_data << uint32(proto->DisplayInfoID);
+ *p_data << uint8(proto->InventoryType);
+ *p_data << uint32(enchant ? enchant->aura_id : 0);
}
else
{
- *p_data << (uint32)0;
- *p_data << (uint8)0;
- *p_data << (uint32)0; // enchant?
+ *p_data << uint32(0);
+ *p_data << uint8(0);
+ *p_data << uint32(0); // enchant?
}
}
- *p_data << (uint32)0; // first bag display id
- *p_data << (uint8)0; // first bag inventory type
- *p_data << (uint32)0; // enchant?
+ *p_data << uint32(0); // first bag display id
+ *p_data << uint8(0); // first bag inventory type
+ *p_data << uint32(0); // enchant?
}
bool Player::ToggleAFK()
@@ -1566,19 +1617,6 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
if(!InBattleGround() && mEntry->IsBattleGroundOrArena())
return false;
- // 449 - Champions' Hall (Alliance) // 450 - Hall of Legends (Horde)
- if(mapid == 449 && GetTeam()==HORDE)
- {
- GetSession()->SendNotification(LANG_NO_ENTER_CHAMPIONS_HALL);
- return false;
- }
-
- if(mapid == 450 && GetTeam() == ALLIANCE)
- {
- GetSession()->SendNotification(LANG_NO_ENTER_HALL_OF_LEGENDS);
- return false;
- }
-
// client without expansion support
if(GetSession()->Expansion() < mEntry->Expansion())
{
@@ -1587,106 +1625,69 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
if(GetTransport())
RepopAtGraveyard(); // teleport to near graveyard if on transport, looks blizz like :)
- SendTransferAborted(mapid, TRANSFER_ABORT_INSUF_EXPAN_LVL1);
+ SendTransferAborted(mapid, TRANSFER_ABORT_INSUF_EXPAN_LVL, mEntry->Expansion());
return false; // normal client can't teleport to this map...
}
else
{
- sLog.outDebug("Player %s will teleported to map %u", GetName(), mapid);
+ sLog.outDebug("Player %s is being teleported to map %u", GetName(), mapid);
}
- // if we were on a transport, leave
- if (!(options & TELE_TO_NOT_LEAVE_TRANSPORT) && m_transport)
+ // reset movement flags at teleport, because player will continue move with these flags after teleport
+ SetUnitMovementFlags(0);
+
+ if (m_transport)
{
- m_transport->RemovePassenger(this);
- m_transport = NULL;
- m_movementInfo.t_x = 0.0f;
- m_movementInfo.t_y = 0.0f;
- m_movementInfo.t_z = 0.0f;
- m_movementInfo.t_o = 0.0f;
- m_movementInfo.t_time = 0;
+ if (options & TELE_TO_NOT_LEAVE_TRANSPORT)
+ AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+ else
+ {
+ m_transport->RemovePassenger(this);
+ m_transport = NULL;
+ m_movementInfo.t_x = 0.0f;
+ m_movementInfo.t_y = 0.0f;
+ m_movementInfo.t_z = 0.0f;
+ m_movementInfo.t_o = 0.0f;
+ m_movementInfo.t_time = 0;
+ }
}
- SetSemaphoreTeleport(true);
-
- // The player was ported to another map and looses the duel immediatly.
+ // The player was ported to another map and looses the duel immediately.
// We have to perform this check before the teleport, otherwise the
// ObjectAccessor won't find the flag.
if (duel && GetMapId()!=mapid)
{
- GameObject* obj = ObjectAccessor::GetGameObject(*this, GetUInt64Value(PLAYER_DUEL_ARBITER));
+ GameObject* obj = GetMap()->GetGameObject(GetUInt64Value(PLAYER_DUEL_ARBITER));
if (obj)
DuelComplete(DUEL_FLED);
}
- // reset movement flags at teleport, because player will continue move with these flags after teleport
- SetUnitMovementFlags(0);
-
if ((GetMapId() == mapid) && (!m_transport))
{
- // prepare zone change detect
- uint32 old_zone = GetZoneId();
-
- // near teleport
- if(!GetSession()->PlayerLogout())
- {
- WorldPacket data;
- BuildTeleportAckMsg(&data, x, y, z, orientation);
- GetSession()->SendPacket(&data);
- SetPosition( x, y, z, orientation, true);
- }
- else
- // this will be used instead of the current location in SaveToDB
- m_teleport_dest = WorldLocation(mapid, x, y, z, orientation);
- SetFallInformation(0, z);
-
- //BuildHeartBeatMsg(&data);
- //SendMessageToSet(&data, true);
if (!(options & TELE_TO_NOT_UNSUMMON_PET))
{
- //same map, only remove pet if out of range
- if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE))
- {
- if(pet->isControlled() && !pet->isTemporarySummoned() )
- m_temporaryUnsummonedPetNumber = pet->GetCharmInfo()->GetPetNumber();
- else
- m_temporaryUnsummonedPetNumber = 0;
-
- RemovePet(pet, PET_SAVE_NOT_IN_SLOT);
- }
+ //same map, only remove pet if out of range for new position
+ if(pet && pet->GetDistance(x,y,z) >= OWNER_MAX_DISTANCE)
+ UnsummonPetTemporaryIfAny();
}
if(!(options & TELE_TO_NOT_LEAVE_COMBAT))
CombatStop();
- if (!(options & TELE_TO_NOT_UNSUMMON_PET))
- {
- // resummon pet
- if(pet && m_temporaryUnsummonedPetNumber)
- {
- Pet* NewPet = new Pet;
- if(!NewPet->LoadPetFromDB(this, 0, m_temporaryUnsummonedPetNumber, true))
- delete NewPet;
-
- m_temporaryUnsummonedPetNumber = 0;
- }
- }
+ // this will be used instead of the current location in SaveToDB
+ m_teleport_dest = WorldLocation(mapid, x, y, z, orientation);
+ SetFallInformation(0, z);
+ // code for finish transfer called in WorldSession::HandleMovementOpcodes()
+ // at client packet MSG_MOVE_TELEPORT_ACK
+ SetSemaphoreTeleportNear(true);
+ // near teleport, triggering send MSG_MOVE_TELEPORT_ACK from client at landing
if(!GetSession()->PlayerLogout())
{
- // don't reset teleport semaphore while logging out, otherwise m_teleport_dest won't be used in Player::SaveToDB
- SetSemaphoreTeleport(false);
-
- UpdateZone(GetZoneId());
- }
-
- // new zone
- if(old_zone != GetZoneId())
- {
- // honorless target
- if(pvpInfo.inHostileArea)
- CastSpell(this, 2479, true);
+ WorldPacket data;
+ BuildTeleportAckMsg(&data, x, y, z, orientation);
+ GetSession()->SendPacket(&data);
}
}
else
@@ -1698,10 +1699,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
// Check enter rights before map getting to avoid creating instance copy for player
// this check not dependent from map instance copy and same for all instance copies of selected map
if (!MapManager::Instance().CanPlayerEnter(mapid, this))
- {
- SetSemaphoreTeleport(false);
return false;
- }
// If the map is not created, assume it is possible to enter it.
// It will be created in the WorldPortAck.
@@ -1726,15 +1724,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
// remove pet on map change
if (pet)
- {
- //leaving map -> delete pet right away (doing this later will cause problems)
- if(pet->isControlled() && !pet->isTemporarySummoned())
- m_temporaryUnsummonedPetNumber = pet->GetCharmInfo()->GetPetNumber();
- else
- m_temporaryUnsummonedPetNumber = 0;
-
- RemovePet(pet, PET_SAVE_NOT_IN_SLOT);
- }
+ UnsummonPetTemporaryIfAny();
// remove all dyn objects
RemoveAllDynObjects();
@@ -1791,13 +1781,11 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
// if the player is saved before worldportack (at logout for example)
// this will be used instead of the current location in SaveToDB
- RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP);
+ RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING);
// move packet sent by client always after far teleport
- // SetPosition(final_x, final_y, final_z, final_o, true);
- SetDontMove(true);
-
// code for finish transfer to new map called in WorldSession::HandleMoveWorldportAckOpcode at client packet
+ SetSemaphoreTeleportFar(true);
}
else
return false;
@@ -1827,9 +1815,6 @@ void Player::RemoveFromWorld()
///- Release charmed creatures, unsummon totems and remove pets/guardians
StopCastingCharm();
StopCastingBindSight();
- UnsummonAllTotems();
- RemoveMiniPet();
- RemoveGuardians();
}
for(int i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; i++)
@@ -1842,6 +1827,15 @@ void Player::RemoveFromWorld()
///- It will crash when updating the ObjectAccessor
///- The player should only be removed when logging out
Unit::RemoveFromWorld();
+
+ if(m_uint32Values)
+ {
+ if(WorldObject *viewpoint = GetViewpoint())
+ {
+ sLog.outCrash("Player %s has viewpoint %u %u when removed from world", GetName(), viewpoint->GetEntry(), viewpoint->GetTypeId());
+ SetViewpoint(viewpoint, false);
+ }
+ }
}
void Player::RewardRage( uint32 damage, uint32 weaponSpeedHitFactor, bool attacker )
@@ -1862,7 +1856,7 @@ void Player::RewardRage( uint32 damage, uint32 weaponSpeedHitFactor, bool attack
addRage = damage/rageconversion*2.5;
// Berserker Rage effect
- if(HasAura(18499,0))
+ if(HasAura(18499))
addRage *= 1.3;
}
@@ -1883,13 +1877,20 @@ void Player::RegenerateAll()
{
RegenerateHealth();
if (!isInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN))
+ {
Regenerate(POWER_RAGE);
+ if(getClass() == CLASS_DEATH_KNIGHT)
+ Regenerate(POWER_RUNIC_POWER);
+ }
}
Regenerate( POWER_ENERGY );
Regenerate( POWER_MANA );
+ if(getClass() == CLASS_DEATH_KNIGHT)
+ Regenerate( POWER_RUNE );
+
m_regenTimer = regenDelay;
}
@@ -1909,11 +1910,11 @@ void Player::Regenerate(Powers power)
if (recentCast)
{
// Trinity Updates Mana in intervals of 2s, which is correct
- addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT) * ManaIncreaseRate * 2.00f;
+ addvalue = GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER) * ManaIncreaseRate * 2.00f;
}
else
{
- addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN) * ManaIncreaseRate * 2.00f;
+ addvalue = GetFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER) * ManaIncreaseRate * 2.00f;
}
} break;
case POWER_RAGE: // Regenerate rage
@@ -1924,6 +1925,17 @@ void Player::Regenerate(Powers power)
case POWER_ENERGY: // Regenerate energy (rogue)
addvalue = 20;
break;
+ case POWER_RUNIC_POWER:
+ {
+ float RunicPowerDecreaseRate = sWorld.getRate(RATE_POWER_RUNICPOWER_LOSS);
+ addvalue = 30 * RunicPowerDecreaseRate; // 3 RunicPower by tick
+ } break;
+ case POWER_RUNE:
+ {
+ for(uint32 i = 0; i < MAX_RUNES; ++i)
+ if(uint8 cd = GetRuneCooldown(i)) // if we have cooldown, reduce it...
+ SetRuneCooldown(i, cd - 1); // ... by 2 sec (because update is every 2 sec)
+ } break;
case POWER_FOCUS:
case POWER_HAPPINESS:
break;
@@ -1933,13 +1945,13 @@ void Player::Regenerate(Powers power)
// Exist only for POWER_MANA, POWER_ENERGY, POWER_FOCUS auras
if(power != POWER_MANA)
{
- AuraList const& ModPowerRegenPCTAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
- for(AuraList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
- if ((*i)->GetModifier()->m_miscvalue == power)
- addvalue *= ((*i)->GetModifierValue() + 100) / 100.0f;
+ AuraEffectList const& ModPowerRegenPCTAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
+ for(AuraEffectList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
+ if ((*i)->GetMiscValue() == power)
+ addvalue *= ((*i)->GetAmount() + 100) / 100.0f;
}
- if (power != POWER_RAGE)
+ if (power != POWER_RAGE && power != POWER_RUNIC_POWER)
{
curValue += uint32(addvalue);
if (curValue > maxValue)
@@ -1975,9 +1987,9 @@ void Player::RegenerateHealth()
addvalue = OCTRegenHPPerSpirit()* HealthIncreaseRate;
if (!isInCombat())
{
- AuraList const& mModHealthRegenPct = GetAurasByType(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT);
- for(AuraList::const_iterator i = mModHealthRegenPct.begin(); i != mModHealthRegenPct.end(); ++i)
- addvalue *= (100.0f + (*i)->GetModifierValue()) / 100.0f;
+ AuraEffectList const& mModHealthRegenPct = GetAurasByType(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT);
+ for(AuraEffectList::const_iterator i = mModHealthRegenPct.begin(); i != mModHealthRegenPct.end(); ++i)
+ addvalue *= (100.0f + (*i)->GetAmount()) / 100.0f;
}
else if(HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT))
addvalue *= GetTotalAuraModifier(SPELL_AURA_MOD_REGEN_DURING_COMBAT) / 100.0f;
@@ -2005,6 +2017,88 @@ bool Player::CanInteractWithNPCs(bool alive) const
return true;
}
+Creature*
+Player::GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask)
+{
+ // unit checks
+ if (!guid)
+ return NULL;
+
+ if(!IsInWorld())
+ return NULL;
+
+ // exist
+ Creature *unit = GetMap()->GetCreature(guid);
+ if (!unit)
+ return NULL;
+
+ // player check
+ if(!CanInteractWithNPCs(!unit->isSpiritService()))
+ return NULL;
+
+ // appropriate npc type
+ if(npcflagmask && !unit->HasFlag( UNIT_NPC_FLAGS, npcflagmask ))
+ return NULL;
+
+ // alive or spirit healer
+ if(!unit->isAlive() && (!unit->isSpiritService() || isAlive() ))
+ return NULL;
+
+ // not allow interaction under control
+ if(unit->GetCharmerOrOwnerGUID())
+ return NULL;
+
+ // not enemy
+ if( unit->IsHostileTo(this))
+ return NULL;
+
+ // not unfriendly
+ if(FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(unit->getFaction()))
+ if(factionTemplate->faction)
+ if(FactionEntry const* faction = sFactionStore.LookupEntry(factionTemplate->faction))
+ if(faction->reputationListID >= 0 && GetReputationMgr().GetRank(faction) <= REP_UNFRIENDLY)
+ return NULL;
+
+ // not too far
+ if(!unit->IsWithinDistInMap(this,INTERACTION_DISTANCE))
+ return NULL;
+
+ return unit;
+}
+
+GameObject* Player::GetGameObjectIfCanInteractWith(uint64 guid, GameobjectTypes type) const
+{
+ if(GameObject *go = GetMap()->GetGameObject(guid))
+ {
+ if(go->GetGoType() == type)
+ {
+ float maxdist;
+ switch(type)
+ {
+ // TODO: find out how the client calculates the maximal usage distance to spellless working
+ // gameobjects like guildbanks and mailboxes - 10.0 is a just an abitrary choosen number
+ case GAMEOBJECT_TYPE_GUILD_BANK:
+ case GAMEOBJECT_TYPE_MAILBOX:
+ maxdist = 10.0f;
+ break;
+ case GAMEOBJECT_TYPE_FISHINGHOLE:
+ maxdist = 20.0f+CONTACT_DISTANCE; // max spell range
+ break;
+ default:
+ maxdist = INTERACTION_DISTANCE;
+ break;
+ }
+
+ if (go->IsWithinDistInMap(this, maxdist))
+ return go;
+
+ sLog.outError("IsGameObjectOfTypeInRange: GameObject '%s' [GUID: %u] is too far away from player %s [GUID: %u] to be used by him (distance=%f, maximal 10 is allowed)", go->GetGOInfo()->name,
+ go->GetGUIDLow(), GetName(), GetGUIDLow(), go->GetDistance(this));
+ }
+ }
+ return NULL;
+}
+
bool Player::IsUnderWater() const
{
return IsInWater() &&
@@ -2037,21 +2131,27 @@ void Player::SetGameMaster(bool on)
setFaction(35);
SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM);
- RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
ResetContestedPvP();
getHostilRefManager().setOnlineOfflineState(false);
CombatStop();
+
+ SetPhaseMask(PHASEMASK_ANYWHERE,false); // see and visible in all phases
}
else
{
+ // restore phase
+ AuraEffectList const& phases = GetAurasByType(SPELL_AURA_PHASE);
+ SetPhaseMask(!phases.empty() ? phases.front()->GetMiscValue() : PHASEMASK_NORMAL,false);
+
m_ExtraFlags &= ~ PLAYER_EXTRA_GM_ON;
setFactionForRace(getRace());
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM);
// restore FFA PvP Server state
if(sWorld.IsFFAPvPRealm())
- SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
// restore FFA PvP area state, remove not allowed for GM mounts
UpdateArea(m_areaUpdateId);
@@ -2115,7 +2215,7 @@ void Player::UninviteFromGroup()
group->RemoveInvite(this);
- if(group->GetMembersCount() <= 1) // group has just 1 member => disband
+ if(group->GetMembersCount() <= 1) // group has just 1 member => disband
{
if(group->IsCreated())
{
@@ -2173,9 +2273,9 @@ void Player::GiveXP(uint32 xp, Unit* victim)
return;
// handle SPELL_AURA_MOD_XP_PCT auras
- Unit::AuraList const& ModXPPctAuras = GetAurasByType(SPELL_AURA_MOD_XP_PCT);
- for(Unit::AuraList::const_iterator i = ModXPPctAuras.begin();i != ModXPPctAuras.end(); ++i)
- xp = uint32(xp*(1.0f + (*i)->GetModifierValue() / 100.0f));
+ Unit::AuraEffectList const& ModXPPctAuras = GetAurasByType(SPELL_AURA_MOD_XP_PCT);
+ for(Unit::AuraEffectList::const_iterator i = ModXPPctAuras.begin();i != ModXPPctAuras.end(); ++i)
+ xp = uint32(xp*(1.0f + (*i)->GetAmount() / 100.0f));
// XP resting bonus for kill
uint32 rested_bonus_xp = victim ? GetXPRestBonus(xp) : 0;
@@ -2223,13 +2323,15 @@ void Player::GiveLevel(uint32 level)
data << uint32(0);
data << uint32(0);
data << uint32(0);
+ data << uint32(0);
+ data << uint32(0);
// end for
for(int i = STAT_STRENGTH; i < MAX_STATS; ++i) // Stats loop (0-4)
data << uint32(int32(info.stats[i]) - GetCreateStat(Stats(i)));
GetSession()->SendPacket(&data);
- SetUInt32Value(PLAYER_NEXT_LEVEL_XP, Trinity::XP::xp_to_level(level));
+ SetUInt32Value(PLAYER_NEXT_LEVEL_XP, objmgr.GetXPForLevel(level));
//update level, max level of skills
if(getLevel()!= level)
@@ -2246,6 +2348,7 @@ void Player::GiveLevel(uint32 level)
InitTalentForLevel();
InitTaxiNodesForLevel();
+ InitGlyphsForLevel();
UpdateAllStats();
@@ -2265,6 +2368,7 @@ void Player::GiveLevel(uint32 level)
Pet* pet = GetPet();
if(pet && pet->getPetType()==SUMMON_PET)
pet->GivePetLevel(level);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL);
}
void Player::InitTalentForLevel()
@@ -2282,7 +2386,8 @@ void Player::InitTalentForLevel()
}
else
{
- uint32 talentPointsForLevel = uint32((level-9)*sWorld.getRate(RATE_TALENT));
+ uint32 talentPointsForLevel = CalculateTalentsPoints();
+
// if used more that have then reset
if(m_usedTalentCount > talentPointsForLevel)
{
@@ -2309,7 +2414,7 @@ void Player::InitStatsForLevel(bool reapplyMods)
objmgr.GetPlayerLevelInfo(getRace(),getClass(),getLevel(),&info);
SetUInt32Value(PLAYER_FIELD_MAX_LEVEL, sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) );
- SetUInt32Value(PLAYER_NEXT_LEVEL_XP, Trinity::XP::xp_to_level(getLevel()));
+ SetUInt32Value(PLAYER_NEXT_LEVEL_XP, objmgr.GetXPForLevel(getLevel()));
UpdateSkillsForLevel ();
@@ -2359,11 +2464,11 @@ void Player::InitStatsForLevel(bool reapplyMods)
SetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, 0.0f );
SetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, 0.0f );
- SetUInt32Value(UNIT_FIELD_ATTACK_POWER, 0 );
- SetUInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, 0 );
+ SetInt32Value(UNIT_FIELD_ATTACK_POWER, 0 );
+ SetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, 0 );
SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER,0.0f);
- SetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER, 0 );
- SetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MODS,0 );
+ SetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER, 0 );
+ SetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MODS,0 );
SetFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER,0.0f);
// Base crit values (will be recalculated in UpdateAllStats() at loading and in _ApplyAllStatBonuses() at reset
@@ -2398,9 +2503,12 @@ void Player::InitStatsForLevel(bool reapplyMods)
SetUInt32Value(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE,0);
for(int i = 0; i < MAX_SPELL_SCHOOL; ++i)
{
- SetFloatValue(UNIT_FIELD_POWER_COST_MODIFIER+i,0.0f);
+ SetUInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+i,0);
SetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,0.0f);
}
+ // Reset no reagent cost field
+ for(int i = 0; i < 3; i++)
+ SetUInt32Value(PLAYER_NO_REAGENT_COST_1 + i, 0);
// Init data for form but skip reapply item mods for form
InitDataForForm(reapplyMods);
@@ -2417,15 +2525,18 @@ void Player::InitStatsForLevel(bool reapplyMods)
RemoveFlag( UNIT_FIELD_FLAGS,
UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_ATTACKABLE_1 |
UNIT_FLAG_PET_IN_COMBAT | UNIT_FLAG_SILENCED | UNIT_FLAG_PACIFIED |
- UNIT_FLAG_DISABLE_ROTATE | UNIT_FLAG_IN_COMBAT | UNIT_FLAG_DISARMED |
+ UNIT_FLAG_STUNNED | UNIT_FLAG_IN_COMBAT | UNIT_FLAG_DISARMED |
UNIT_FLAG_CONFUSED | UNIT_FLAG_FLEEING | UNIT_FLAG_NOT_SELECTABLE |
UNIT_FLAG_SKINNABLE | UNIT_FLAG_MOUNT | UNIT_FLAG_TAXI_FLIGHT );
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE ); // must be set
+ SetFlag(UNIT_FIELD_FLAGS_2,UNIT_FLAG2_REGENERATE_POWER);// must be set
+
// cleanup player flags (will be re-applied if need at aura load), to avoid have ghost flag without ghost aura, for example.
- RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK | PLAYER_FLAGS_DND | PLAYER_FLAGS_GM | PLAYER_FLAGS_GHOST | PLAYER_FLAGS_FFA_PVP);
+ RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK | PLAYER_FLAGS_DND | PLAYER_FLAGS_GM | PLAYER_FLAGS_GHOST | PLAYER_ALLOW_ONLY_ABILITY);
- SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x00); // one form stealth modified bytes
+ RemoveStandFlags(UNIT_STAND_FLAGS_ALL); // one form stealth modified bytes
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP | UNIT_BYTE2_FLAG_SANCTUARY);
// restore if need some important flags
SetUInt32Value(PLAYER_FIELD_BYTES2, 0 ); // flags empty by default
@@ -2441,10 +2552,14 @@ void Player::InitStatsForLevel(bool reapplyMods)
SetPower(POWER_RAGE, GetMaxPower(POWER_RAGE));
SetPower(POWER_FOCUS, 0);
SetPower(POWER_HAPPINESS, 0);
+ SetPower(POWER_RUNIC_POWER, 0);
}
void Player::SendInitialSpells()
{
+ time_t curTime = time(NULL);
+ time_t infTime = curTime + MONTH/2;
+
uint16 spellCount = 0;
WorldPacket data(SMSG_INITIAL_SPELLS, (1+2+4*m_spells.size()+2+m_spellCooldowns.size()*(2+2+2+4+4)));
@@ -2477,12 +2592,15 @@ void Player::SendInitialSpells()
if(!sEntry)
continue;
+ // not send infinity cooldown
+ if(itr->second.end > infTime)
+ continue;
+
data << uint16(itr->first);
time_t cooldown = 0;
- time_t curTime = time(NULL);
if(itr->second.end > curTime)
- cooldown = (itr->second.end-curTime)*1000;
+ cooldown = (itr->second.end-curTime)*IN_MILISECONDS;
data << uint16(itr->second.itemid); // cast item id
data << uint16(sEntry->Category); // spell category
@@ -2573,13 +2691,13 @@ void Player::AddNewMailDeliverTime(time_t deliver_time)
}
}
-bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading, uint16 slot_id, bool disabled)
+bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
if (!spellInfo)
{
// do character spell book cleanup (all characters)
- if(loading && !learning) // spell load case
+ if(!IsInWorld() && !learning) // spell load case
{
sLog.outError("Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.",spell_id);
CharacterDatabase.PExecute("DELETE FROM character_spell WHERE spell = '%u'",spell_id);
@@ -2593,7 +2711,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
if(!SpellMgr::IsSpellValid(spellInfo,this,false))
{
// do character spell book cleanup (all characters)
- if(loading && !learning) // spell load case
+ if(!IsInWorld() && !learning) // spell load case
{
sLog.outError("Player::addSpell: Broken spell #%u learning not allowed, deleting for all characters in `character_spell`.",spell_id);
CharacterDatabase.PExecute("DELETE FROM character_spell WHERE spell = '%u'",spell_id);
@@ -2606,29 +2724,80 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
PlayerSpellState state = learning ? PLAYERSPELL_NEW : PLAYERSPELL_UNCHANGED;
+ bool dependent_set = false;
bool disabled_case = false;
bool superceded_old = false;
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
if (itr != m_spells.end())
{
+ uint32 next_active_spell_id = 0;
+ // fix activate state for non-stackable low rank (and find next spell for !active case)
+ if(!SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0)
+ {
+ if(uint32 next = spellmgr.GetNextSpellInChain(spell_id))
+ {
+ if(HasSpell(next))
+ {
+ // high rank already known so this must !active
+ active = false;
+ next_active_spell_id = next;
+ }
+ }
+ }
+
+ // not do anything if already known in expected state
+ if(itr->second->state != PLAYERSPELL_REMOVED && itr->second->active == active &&
+ itr->second->dependent == dependent && itr->second->disabled == disabled)
+ {
+ if(!IsInWorld() && !learning) // explicitly load from DB and then exist in it already and set correctly
+ itr->second->state = PLAYERSPELL_UNCHANGED;
+
+ return false;
+ }
+
+ // dependent spell known as not dependent, overwrite state
+ if (itr->second->state != PLAYERSPELL_REMOVED && !itr->second->dependent && dependent)
+ {
+ itr->second->dependent = dependent;
+ if (itr->second->state != PLAYERSPELL_NEW)
+ itr->second->state = PLAYERSPELL_CHANGED;
+ dependent_set = true;
+ }
+
// update active state for known spell
if(itr->second->active != active && itr->second->state != PLAYERSPELL_REMOVED && !itr->second->disabled)
{
itr->second->active = active;
- // loading && !learning == explicitly load from DB and then exist in it already and set correctly
- if(loading && !learning)
+ if(!IsInWorld() && !learning && !dependent_set) // explicitly load from DB and then exist in it already and set correctly
itr->second->state = PLAYERSPELL_UNCHANGED;
else if(itr->second->state != PLAYERSPELL_NEW)
itr->second->state = PLAYERSPELL_CHANGED;
- if(!active)
+ if(active)
{
- WorldPacket data(SMSG_REMOVED_SPELL, 4);
- data << uint16(spell_id);
- GetSession()->SendPacket(&data);
+ if (IsPassiveSpell(spell_id) && IsNeedCastPassiveSpellAtLearn(spellInfo))
+ CastSpell (this,spell_id,true);
}
+ else if(IsInWorld())
+ {
+ if(next_active_spell_id)
+ {
+ // update spell ranks in spellbook and action bar
+ WorldPacket data(SMSG_SUPERCEDED_SPELL, (4));
+ data << uint16(spell_id);
+ data << uint16(next_active_spell_id);
+ GetSession()->SendPacket( &data );
+ }
+ else
+ {
+ WorldPacket data(SMSG_REMOVED_SPELL, 4);
+ data << uint16(spell_id);
+ GetSession()->SendPacket(&data);
+ }
+ }
+
return active; // learn (show in spell book if active now)
}
@@ -2657,7 +2826,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
default: // known not saved yet spell (new or modified)
{
// can be in case spell loading but learned at some previous spell loading
- if(loading && !learning)
+ if(!IsInWorld() && !learning && !dependent_set)
itr->second->state = PLAYERSPELL_UNCHANGED;
return false;
@@ -2672,17 +2841,13 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
{
if(TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentPos->talent_id ))
{
- for(int i=0; i <5; ++i)
+ for(int i=0; i < MAX_TALENT_RANK; ++i)
{
// skip learning spell and no rank spell case
uint32 rankSpellId = talentInfo->RankID[i];
if(!rankSpellId || rankSpellId==spell_id)
continue;
- // skip unknown ranks
- if(!HasSpell(rankSpellId))
- continue;
-
removeSpell(rankSpellId);
}
}
@@ -2690,52 +2855,54 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
// non talent spell: learn low ranks (recursive call)
else if(uint32 prev_spell = spellmgr.GetPrevSpellInChain(spell_id))
{
- if(loading) // at spells loading, no output, but allow save
- addSpell(prev_spell,active,true,loading,SPELL_WITHOUT_SLOT_ID,disabled);
+ if(!IsInWorld() || disabled) // at spells loading, no output, but allow save
+ addSpell(prev_spell,active,true,true,disabled);
else // at normal learning
- learnSpell(prev_spell);
+ learnSpell(prev_spell,true);
}
PlayerSpell *newspell = new PlayerSpell;
- newspell->active = active;
- newspell->state = state;
- newspell->disabled = disabled;
+ newspell->state = state;
+ newspell->active = active;
+ newspell->dependent = dependent;
+ newspell->disabled = disabled;
// replace spells in action bars and spellbook to bigger rank if only one spell rank must be accessible
if(newspell->active && !newspell->disabled && !SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0)
{
- for( PlayerSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr )
+ for( PlayerSpellMap::iterator itr2 = m_spells.begin(); itr2 != m_spells.end(); ++itr2 )
{
- if(itr->second->state == PLAYERSPELL_REMOVED) continue;
- SpellEntry const *i_spellInfo = sSpellStore.LookupEntry(itr->first);
+ if(itr2->second->state == PLAYERSPELL_REMOVED) continue;
+ SpellEntry const *i_spellInfo = sSpellStore.LookupEntry(itr2->first);
if(!i_spellInfo) continue;
- if( spellmgr.IsRankSpellDueToSpell(spellInfo,itr->first) )
+ if( spellmgr.IsRankSpellDueToSpell(spellInfo,itr2->first) )
{
- if(itr->second->active)
+ if(itr2->second->active)
{
- if(spellmgr.IsHighRankOfSpell(spell_id,itr->first))
+ if(spellmgr.IsHighRankOfSpell(spell_id,itr2->first))
{
- if(!loading) // not send spell (re-/over-)learn packets at loading
+ if(IsInWorld()) // not send spell (re-/over-)learn packets at loading
{
WorldPacket data(SMSG_SUPERCEDED_SPELL, (4));
- data << uint16(itr->first);
+ data << uint16(itr2->first);
data << uint16(spell_id);
GetSession()->SendPacket( &data );
}
// mark old spell as disable (SMSG_SUPERCEDED_SPELL replace it in client by new)
- itr->second->active = false;
- itr->second->state = PLAYERSPELL_CHANGED;
+ itr2->second->active = false;
+ if(itr2->second->state != PLAYERSPELL_NEW)
+ itr2->second->state = PLAYERSPELL_CHANGED;
superceded_old = true; // new spell replace old in action bars and spell book.
}
- else if(spellmgr.IsHighRankOfSpell(itr->first,spell_id))
+ else if(spellmgr.IsHighRankOfSpell(itr2->first,spell_id))
{
- if(!loading) // not send spell (re-/over-)learn packets at loading
+ if(IsInWorld()) // not send spell (re-/over-)learn packets at loading
{
WorldPacket data(SMSG_SUPERCEDED_SPELL, (4));
data << uint16(spell_id);
- data << uint16(itr->first);
+ data << uint16(itr2->first);
GetSession()->SendPacket( &data );
}
@@ -2749,23 +2916,6 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
}
}
- uint16 tmpslot=slot_id;
-
- if (tmpslot == SPELL_WITHOUT_SLOT_ID)
- {
- uint16 maxid = 0;
- PlayerSpellMap::iterator itr;
- for (itr = m_spells.begin(); itr != m_spells.end(); ++itr)
- {
- if(itr->second->state == PLAYERSPELL_REMOVED)
- continue;
- if (itr->second->slotId > maxid)
- maxid = itr->second->slotId;
- }
- tmpslot = maxid + 1;
- }
-
- newspell->slotId = tmpslot;
m_spells[spell_id] = newspell;
// return false if spell disabled
@@ -2785,23 +2935,8 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
// also cast passive spells (including all talents without SPELL_EFFECT_LEARN_SPELL) with additional checks
else if (IsPassiveSpell(spell_id))
{
- // if spell doesn't require a stance or the player is in the required stance
- if( ( !spellInfo->Stances &&
- spell_id != 5420 && spell_id != 5419 && spell_id != 7376 &&
- spell_id != 7381 && spell_id != 21156 && spell_id != 21009 &&
- spell_id != 21178 && spell_id != 33948 && spell_id != 40121 ) ||
- m_form != 0 && (spellInfo->Stances & (1<<(m_form-1))) ||
- (spell_id == 5420 && m_form == FORM_TREE) ||
- (spell_id == 5419 && m_form == FORM_TRAVEL) ||
- (spell_id == 7376 && m_form == FORM_DEFENSIVESTANCE) ||
- (spell_id == 7381 && m_form == FORM_BERSERKERSTANCE) ||
- (spell_id == 21156 && m_form == FORM_BATTLESTANCE)||
- (spell_id == 21178 && (m_form == FORM_BEAR || m_form == FORM_DIREBEAR) ) ||
- (spell_id == 33948 && m_form == FORM_FLIGHT) ||
- (spell_id == 40121 && m_form == FORM_FLIGHT_EPIC) )
- //Check CasterAuraStates
- if (!spellInfo->CasterAuraState || HasAuraState(AuraState(spellInfo->CasterAuraState)))
- CastSpell(this, spell_id, true);
+ if(IsNeedCastPassiveSpellAtLearn(spellInfo))
+ CastSpell(this, spell_id, true);
}
else if( IsSpellHaveEffect(spellInfo,SPELL_EFFECT_SKILL_STEP) )
{
@@ -2824,6 +2959,9 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
SpellLearnSkillNode const* spellLearnSkill = spellmgr.GetSpellLearnSkill(spell_id);
+ SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spell_id);
+ SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spell_id);
+
if(spellLearnSkill)
{
uint32 skill_value = GetPureSkillValue(spellLearnSkill->skill);
@@ -2842,9 +2980,6 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
else
{
// not ranked skills
- SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spell_id);
- SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spell_id);
-
for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
{
SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(_spell_idx->second->skillId);
@@ -2855,10 +2990,8 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
continue;
if(_spell_idx->second->learnOnGetSkill == ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL ||
- // poison special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL
- pSkill->id==SKILL_POISONS && _spell_idx->second->max_value==0 ||
- // lockpicking special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL
- pSkill->id==SKILL_LOCKPICKING && _spell_idx->second->max_value==0 )
+ // lockpicking/runeforging special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL
+ (pSkill->id==SKILL_LOCKPICKING || pSkill->id==SKILL_RUNEFORGING) && _spell_idx->second->max_value==0 )
{
switch(GetSkillRangeType(pSkill,_spell_idx->second->racemask!=0))
{
@@ -2882,41 +3015,81 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
SpellLearnSpellMap::const_iterator spell_begin = spellmgr.GetBeginSpellLearnSpell(spell_id);
SpellLearnSpellMap::const_iterator spell_end = spellmgr.GetEndSpellLearnSpell(spell_id);
- for(SpellLearnSpellMap::const_iterator itr = spell_begin; itr != spell_end; ++itr)
+ for(SpellLearnSpellMap::const_iterator itr2 = spell_begin; itr2 != spell_end; ++itr2)
{
- if(!itr->second.autoLearned)
+ if(!itr2->second.autoLearned)
{
- if(loading) // at spells loading, no output, but allow save
- addSpell(itr->second.spell,true,true,loading);
+ if(!IsInWorld() || !itr2->second.active) // at spells loading, no output, but allow save
+ addSpell(itr2->second.spell,itr2->second.active,true,true,false);
else // at normal learning
- learnSpell(itr->second.spell);
+ learnSpell(itr2->second.spell,true);
+ }
+ }
+
+ if(!GetSession()->PlayerLoading())
+ {
+ // not ranked skills
+ for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
+ {
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE,_spell_idx->second->skillId);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS,_spell_idx->second->skillId);
}
+
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL,spell_id);
}
// return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell
return active && !disabled && !superceded_old;
}
-void Player::learnSpell(uint32 spell_id)
+bool Player::IsNeedCastPassiveSpellAtLearn(SpellEntry const* spellInfo) const
+{
+ bool need_cast = false;
+
+ switch(spellInfo->Id)
+ {
+ // some spells not have stance data expacted cast at form change or present
+ case 5420: need_cast = (m_form == FORM_TREE); break;
+ case 5419: need_cast = (m_form == FORM_TRAVEL); break;
+ case 7376: need_cast = (m_form == FORM_DEFENSIVESTANCE); break;
+ case 7381: need_cast = (m_form == FORM_BERSERKERSTANCE); break;
+ case 21156: need_cast = (m_form == FORM_BATTLESTANCE); break;
+ case 21178: need_cast = (m_form == FORM_BEAR || m_form == FORM_DIREBEAR); break;
+ case 33948: need_cast = (m_form == FORM_FLIGHT); break;
+ case 34764: need_cast = (m_form == FORM_FLIGHT); break;
+ case 40121: need_cast = (m_form == FORM_FLIGHT_EPIC); break;
+ case 40122: need_cast = (m_form == FORM_FLIGHT_EPIC); break;
+ // another spells have proper stance data
+ default: need_cast = !spellInfo->Stances || m_form != 0 && (spellInfo->Stances & (1<<(m_form-1))); break;
+ }
+
+ //Check CasterAuraStates
+ return need_cast && (!spellInfo->CasterAuraState || HasAuraState(AuraState(spellInfo->CasterAuraState)));
+}
+
+void Player::learnSpell(uint32 spell_id, bool dependent)
{
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
bool disabled = (itr != m_spells.end()) ? itr->second->disabled : false;
bool active = disabled ? itr->second->active : true;
- bool learning = addSpell(spell_id,active);
+ bool learning = addSpell(spell_id,active,true,dependent,false);
// learn all disabled higher ranks (recursive)
- SpellChainNode const* node = spellmgr.GetSpellChainNode(spell_id);
- if (node)
+ if(disabled)
{
- PlayerSpellMap::iterator iter = m_spells.find(node->next);
- if (disabled && iter != m_spells.end() && iter->second->disabled )
- learnSpell(node->next);
+ SpellChainNode const* node = spellmgr.GetSpellChainNode(spell_id);
+ if(node)
+ {
+ PlayerSpellMap::iterator iter = m_spells.find(node->next);
+ if (iter != m_spells.end() && iter->second->disabled )
+ learnSpell(node->next,false);
+ }
}
- // prevent duplicated entires in spell book
- if(!learning)
+ // prevent duplicated entires in spell book, also not send if not in world (loading)
+ if(!learning || !IsInWorld ())
return;
WorldPacket data(SMSG_LEARNED_SPELL, 4);
@@ -2924,7 +3097,7 @@ void Player::learnSpell(uint32 spell_id)
GetSession()->SendPacket(&data);
}
-void Player::removeSpell(uint32 spell_id, bool disabled)
+void Player::removeSpell(uint32 spell_id, bool disabled, bool update_action_bar_for_low_rank)
{
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
if (itr == m_spells.end())
@@ -2946,10 +3119,8 @@ void Player::removeSpell(uint32 spell_id, bool disabled)
for (uint32 i=reqMap.count(spell_id);i>0;i--,itr2++)
removeSpell(itr2->second,disabled);
- // removing
- WorldPacket data(SMSG_REMOVED_SPELL, 4);
- data << uint16(spell_id);
- GetSession()->SendPacket(&data);
+ bool cur_active = itr->second->active;
+ bool cur_dependent = itr->second->dependent;
if (disabled)
{
@@ -3042,10 +3213,8 @@ void Player::removeSpell(uint32 spell_id, bool disabled)
continue;
if(_spell_idx->second->learnOnGetSkill == ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL ||
- // poison special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL
- pSkill->id==SKILL_POISONS && _spell_idx->second->max_value==0 ||
- // lockpicking special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL
- pSkill->id==SKILL_LOCKPICKING && _spell_idx->second->max_value==0 )
+ // lockpicking/runeforging special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL
+ (pSkill->id==SKILL_LOCKPICKING || pSkill->id==SKILL_RUNEFORGING) && _spell_idx->second->max_value==0 )
{
// not reset skills for professions and racial abilities
if( (pSkill->categoryId==SKILL_CATEGORY_SECONDARY || pSkill->categoryId==SKILL_CATEGORY_PROFESSION) &&
@@ -3063,6 +3232,60 @@ void Player::removeSpell(uint32 spell_id, bool disabled)
for(SpellLearnSpellMap::const_iterator itr2 = spell_begin; itr2 != spell_end; ++itr2)
removeSpell(itr2->second.spell, disabled);
+
+ // activate lesser rank in spellbook/action bar, and cast it if need
+ bool prev_activate = false;
+
+ if(uint32 prev_id = spellmgr.GetPrevSpellInChain (spell_id))
+ {
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
+
+ // if talent then lesser rank also talent and need learn
+ if(talentCosts)
+ {
+ //learnSpell (prev_id,false);
+ }
+ // if ranked non-stackable spell: need activate lesser rank and update dendence state
+ else if(cur_active && !SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0)
+ {
+ // need manually update dependence state (learn spell ignore like attempts)
+ PlayerSpellMap::iterator prev_itr = m_spells.find(prev_id);
+ if (prev_itr != m_spells.end())
+ {
+ if(prev_itr->second->dependent != cur_dependent)
+ {
+ prev_itr->second->dependent = cur_dependent;
+ if(prev_itr->second->state != PLAYERSPELL_NEW)
+ prev_itr->second->state = PLAYERSPELL_CHANGED;
+ }
+
+ // now re-learn if need re-activate
+ if(cur_active && !prev_itr->second->active)
+ {
+ if(addSpell(prev_id,true,false,prev_itr->second->dependent,prev_itr->second->disabled))
+ {
+ if(update_action_bar_for_low_rank)
+ {
+ // downgrade spell ranks in spellbook and action bar
+ WorldPacket data(SMSG_SUPERCEDED_SPELL, (4));
+ data << uint16(spell_id);
+ data << uint16(prev_id);
+ GetSession()->SendPacket( &data );
+ prev_activate = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // remove from spell book if not replaced by lesser rank
+ if(!prev_activate)
+ {
+ WorldPacket data(SMSG_REMOVED_SPELL, 4);
+ data << uint16(spell_id);
+ GetSession()->SendPacket(&data);
+ }
}
void Player::RemoveArenaSpellCooldowns()
@@ -3077,13 +3300,13 @@ void Player::RemoveArenaSpellCooldowns()
SpellEntry const * entry = sSpellStore.LookupEntry(itr->first);
// check if spellentry is present and if the cooldown is less than 15 mins
if( entry &&
- entry->RecoveryTime <= 15 * MINUTE * 1000 &&
- entry->CategoryRecoveryTime <= 15 * MINUTE * 1000 )
+ entry->RecoveryTime <= 15 * MINUTE * IN_MILISECONDS &&
+ entry->CategoryRecoveryTime <= 15 * MINUTE * IN_MILISECONDS )
{
// notify player
WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8));
data << uint32(itr->first);
- data << GetGUID();
+ data << uint64(GetGUID());
GetSession()->SendPacket(&data);
// remove cooldown
m_spellCooldowns.erase(itr);
@@ -3108,7 +3331,7 @@ void Player::RemoveAllSpellCooldown()
void Player::_LoadSpellCooldowns(QueryResult *result)
{
- m_spellCooldowns.clear();
+ // some cooldowns can be already set at aura loading...
//QueryResult *result = CharacterDatabase.PQuery("SELECT spell,item,time FROM character_spell_cooldown WHERE guid = '%u'",GetGUIDLow());
@@ -3149,17 +3372,20 @@ void Player::_SaveSpellCooldowns()
CharacterDatabase.PExecute("DELETE FROM character_spell_cooldown WHERE guid = '%u'", GetGUIDLow());
time_t curTime = time(NULL);
+ time_t infTime = curTime + MONTH/2;
// remove outdated and save active
for(SpellCooldowns::iterator itr = m_spellCooldowns.begin();itr != m_spellCooldowns.end();)
{
if(itr->second.end <= curTime)
m_spellCooldowns.erase(itr++);
- else
+ else if(itr->second.end <= infTime) // not save locked cooldowns, it will be reset or set at reload
{
CharacterDatabase.PExecute("INSERT INTO character_spell_cooldown (guid,spell,item,time) VALUES ('%u', '%u', '%u', '" I64FMTD "')", GetGUIDLow(), itr->first, itr->second.itemid, uint64(itr->second.end));
++itr;
}
+ else
+ ++itr;
}
}
@@ -3205,8 +3431,7 @@ bool Player::resetTalents(bool no_cost)
CharacterDatabase.PExecute("UPDATE characters set at_login = at_login & ~ %u WHERE guid ='%u'", uint32(AT_LOGIN_RESET_TALENTS), GetGUIDLow());
}
- uint32 level = getLevel();
- uint32 talentPointsForLevel = level < 10 ? 0 : uint32((level-9)*sWorld.getRate(RATE_TALENT));
+ uint32 talentPointsForLevel = CalculateTalentsPoints();
if (m_usedTalentCount == 0)
{
@@ -3244,7 +3469,7 @@ bool Player::resetTalents(bool no_cost)
if( (getClassMask() & talentTabInfo->ClassMask) == 0 )
continue;
- for (int j = 0; j < 5; j++)
+ for (int j = 0; j < MAX_TALENT_RANK; j++)
{
for(PlayerSpellMap::iterator itr = GetSpellMap().begin(); itr != GetSpellMap().end();)
{
@@ -3275,6 +3500,7 @@ bool Player::resetTalents(bool no_cost)
if(!no_cost)
{
ModifyMoney(-(int32)cost);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS, cost);
m_resetTalentsCost = cost;
m_resetTalentsTime = time(NULL);
@@ -3283,19 +3509,14 @@ bool Player::resetTalents(bool no_cost)
//FIXME: remove pet before or after unlearn spells? for now after unlearn to allow removing of talent related, pet affecting auras
RemovePet(NULL,PET_SAVE_NOT_IN_SLOT, true);
- return true;
-}
-
-bool Player::_removeSpell(uint16 spell_id)
-{
- PlayerSpellMap::iterator itr = m_spells.find(spell_id);
- if (itr != m_spells.end())
+ if(m_canTitanGrip)
{
- delete itr->second;
- m_spells.erase(itr);
- return true;
+ m_canTitanGrip = false;
+ if(sWorld.getConfig(CONFIG_OFFHAND_CHECK_AT_TALENTS_RESET))
+ AutoUnequipOffhandIfNeed();
}
- return false;
+
+ return true;
}
Mail* Player::GetMail(uint32 id)
@@ -3343,50 +3564,46 @@ void Player::InitVisibleBits()
{
updateVisualBits.SetCount(PLAYER_END);
- // TODO: really implement OWNER_ONLY and GROUP_ONLY. Flags can be found in UpdateFields.h
-
updateVisualBits.SetBit(OBJECT_FIELD_GUID);
updateVisualBits.SetBit(OBJECT_FIELD_TYPE);
+ updateVisualBits.SetBit(OBJECT_FIELD_ENTRY);
updateVisualBits.SetBit(OBJECT_FIELD_SCALE_X);
-
- updateVisualBits.SetBit(UNIT_FIELD_CHARM);
- updateVisualBits.SetBit(UNIT_FIELD_CHARM+1);
-
- updateVisualBits.SetBit(UNIT_FIELD_SUMMON);
- updateVisualBits.SetBit(UNIT_FIELD_SUMMON+1);
-
- updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY);
- updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY+1);
-
- updateVisualBits.SetBit(UNIT_FIELD_TARGET);
- updateVisualBits.SetBit(UNIT_FIELD_TARGET+1);
-
- updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT);
- updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT+1);
-
+ updateVisualBits.SetBit(UNIT_FIELD_CHARM + 0);
+ updateVisualBits.SetBit(UNIT_FIELD_CHARM + 1);
+ updateVisualBits.SetBit(UNIT_FIELD_SUMMON + 0);
+ updateVisualBits.SetBit(UNIT_FIELD_SUMMON + 1);
+ updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY + 0);
+ updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY + 1);
+ updateVisualBits.SetBit(UNIT_FIELD_TARGET + 0);
+ updateVisualBits.SetBit(UNIT_FIELD_TARGET + 1);
+ updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT + 0);
+ updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT + 1);
+ updateVisualBits.SetBit(UNIT_FIELD_BYTES_0);
updateVisualBits.SetBit(UNIT_FIELD_HEALTH);
updateVisualBits.SetBit(UNIT_FIELD_POWER1);
updateVisualBits.SetBit(UNIT_FIELD_POWER2);
updateVisualBits.SetBit(UNIT_FIELD_POWER3);
updateVisualBits.SetBit(UNIT_FIELD_POWER4);
updateVisualBits.SetBit(UNIT_FIELD_POWER5);
-
+ updateVisualBits.SetBit(UNIT_FIELD_POWER6);
+ updateVisualBits.SetBit(UNIT_FIELD_POWER7);
updateVisualBits.SetBit(UNIT_FIELD_MAXHEALTH);
updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER1);
updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER2);
updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER3);
updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER4);
updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER5);
-
+ updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER6);
+ updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER7);
updateVisualBits.SetBit(UNIT_FIELD_LEVEL);
updateVisualBits.SetBit(UNIT_FIELD_FACTIONTEMPLATE);
- updateVisualBits.SetBit(UNIT_FIELD_BYTES_0);
+ updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_ID + 0);
+ updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_ID + 1);
+ updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_ID + 2);
updateVisualBits.SetBit(UNIT_FIELD_FLAGS);
updateVisualBits.SetBit(UNIT_FIELD_FLAGS_2);
- for(uint16 i = UNIT_FIELD_AURA; i < UNIT_FIELD_AURASTATE; ++i)
- updateVisualBits.SetBit(i);
updateVisualBits.SetBit(UNIT_FIELD_AURASTATE);
- updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME);
+ updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME + 0);
updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME + 1);
updateVisualBits.SetBit(UNIT_FIELD_BOUNDINGRADIUS);
updateVisualBits.SetBit(UNIT_FIELD_COMBATREACH);
@@ -3399,10 +3616,12 @@ void Player::InitVisibleBits()
updateVisualBits.SetBit(UNIT_DYNAMIC_FLAGS);
updateVisualBits.SetBit(UNIT_CHANNEL_SPELL);
updateVisualBits.SetBit(UNIT_MOD_CAST_SPEED);
+ updateVisualBits.SetBit(UNIT_FIELD_BASE_MANA);
updateVisualBits.SetBit(UNIT_FIELD_BYTES_2);
+ updateVisualBits.SetBit(UNIT_FIELD_HOVERHEIGHT);
- updateVisualBits.SetBit(PLAYER_DUEL_ARBITER);
- updateVisualBits.SetBit(PLAYER_DUEL_ARBITER+1);
+ updateVisualBits.SetBit(PLAYER_DUEL_ARBITER + 0);
+ updateVisualBits.SetBit(PLAYER_DUEL_ARBITER + 1);
updateVisualBits.SetBit(PLAYER_FLAGS);
updateVisualBits.SetBit(PLAYER_GUILDID);
updateVisualBits.SetBit(PLAYER_GUILDRANK);
@@ -3413,29 +3632,29 @@ void Player::InitVisibleBits()
updateVisualBits.SetBit(PLAYER_GUILD_TIMESTAMP);
// PLAYER_QUEST_LOG_x also visible bit on official (but only on party/raid)...
- for(uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i+=4)
+ for(uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i += 4)
updateVisualBits.SetBit(i);
- //Players visible items are not inventory stuff
- //431) = 884 (0x374) = main weapon
- for(uint16 i = 0; i < EQUIPMENT_SLOT_END; i++)
+ // Players visible items are not inventory stuff
+ for(uint16 i = 0; i < EQUIPMENT_SLOT_END; ++i)
{
- // item creator
- updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + (i*MAX_VISIBLE_ITEM_OFFSET) + 0);
- updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + (i*MAX_VISIBLE_ITEM_OFFSET) + 1);
+ uint32 offset = i * MAX_VISIBLE_ITEM_OFFSET;
- uint16 visual_base = PLAYER_VISIBLE_ITEM_1_0 + (i*MAX_VISIBLE_ITEM_OFFSET);
+ // item creator
+ updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + 0 + offset);
+ updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + 1 + offset);
// item entry
- updateVisualBits.SetBit(visual_base + 0);
+ updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_0 + 0 + offset);
- // item enchantment IDs
- for(uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j)
- updateVisualBits.SetBit(visual_base + 1 + j);
+ // item enchantments
+ for(uint8 j = 0; j < MAX_ENCHANTMENT_SLOT; ++j)
+ updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_0 + 1 + j + offset);
// random properties
- updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + 0 + (i*MAX_VISIBLE_ITEM_OFFSET));
- updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + 1 + (i*MAX_VISIBLE_ITEM_OFFSET));
+ updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + offset);
+ updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_SEED + offset);
+ updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PAD + offset);
}
updateVisualBits.SetBit(PLAYER_CHOSEN_TITLE);
@@ -3453,7 +3672,6 @@ void Player::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target )
if(target == this)
{
-
for(int i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++)
{
if(m_items[i] == NULL)
@@ -3461,7 +3679,7 @@ void Player::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target )
m_items[i]->BuildCreateUpdateBlockForPlayer( data, target );
}
- for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
+ for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
{
if(m_items[i] == NULL)
continue;
@@ -3494,7 +3712,7 @@ void Player::DestroyForPlayer( Player *target ) const
m_items[i]->DestroyForPlayer( target );
}
- for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
+ for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
{
if(m_items[i] == NULL)
continue;
@@ -3506,8 +3724,16 @@ void Player::DestroyForPlayer( Player *target ) const
bool Player::HasSpell(uint32 spell) const
{
- PlayerSpellMap::const_iterator itr = m_spells.find((uint16)spell);
- return (itr != m_spells.end() && itr->second->state != PLAYERSPELL_REMOVED && !itr->second->disabled);
+ PlayerSpellMap::const_iterator itr = m_spells.find(spell);
+ return (itr != m_spells.end() && itr->second->state != PLAYERSPELL_REMOVED &&
+ !itr->second->disabled);
+}
+
+bool Player::HasActiveSpell(uint32 spell) const
+{
+ PlayerSpellMap::const_iterator itr = m_spells.find(spell);
+ return (itr != m_spells.end() && itr->second->state != PLAYERSPELL_REMOVED &&
+ itr->second->active && !itr->second->disabled);
}
TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell) const
@@ -3515,22 +3741,22 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell
if (!trainer_spell)
return TRAINER_SPELL_RED;
- if (!trainer_spell->spell)
+ if (!trainer_spell->learnedSpell)
return TRAINER_SPELL_RED;
// known spell
- if(HasSpell(trainer_spell->spell))
+ if(HasSpell(trainer_spell->learnedSpell))
return TRAINER_SPELL_GRAY;
// check race/class requirement
- if(!IsSpellFitByClassAndRace(trainer_spell->spell))
+ if(!IsSpellFitByClassAndRace(trainer_spell->learnedSpell))
return TRAINER_SPELL_RED;
// check level requirement
- if(getLevel() < trainer_spell->reqlevel)
+ if(getLevel() < trainer_spell->reqLevel)
return TRAINER_SPELL_RED;
- if(SpellChainNode const* spell_chain = spellmgr.GetSpellChainNode(trainer_spell->spell))
+ if(SpellChainNode const* spell_chain = spellmgr.GetSpellChainNode(trainer_spell->learnedSpell))
{
// check prev.rank requirement
if(spell_chain->prev && !HasSpell(spell_chain->prev))
@@ -3545,11 +3771,11 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell
}
// check skill requirement
- if(trainer_spell->reqskill && GetBaseSkillValue(trainer_spell->reqskill) < trainer_spell->reqskillvalue)
+ if(trainer_spell->reqSkill && GetBaseSkillValue(trainer_spell->reqSkill) < trainer_spell->reqSkillValue)
return TRAINER_SPELL_RED;
// exist, already checked at loading
- SpellEntry const* spell = sSpellStore.LookupEntry(trainer_spell->spell);
+ SpellEntry const* spell = sSpellStore.LookupEntry(trainer_spell->learnedSpell);
// secondary prof. or not prof. spell
uint32 skill = spell->EffectMiscValue[1];
@@ -3582,27 +3808,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
}
// remove from arena teams
- uint32 at_id = GetArenaTeamIdFromDB(playerguid,ARENA_TEAM_2v2);
- if(at_id != 0)
- {
- ArenaTeam * at = objmgr.GetArenaTeamById(at_id);
- if(at)
- at->DelMember(playerguid);
- }
- at_id = GetArenaTeamIdFromDB(playerguid,ARENA_TEAM_3v3);
- if(at_id != 0)
- {
- ArenaTeam * at = objmgr.GetArenaTeamById(at_id);
- if(at)
- at->DelMember(playerguid);
- }
- at_id = GetArenaTeamIdFromDB(playerguid,ARENA_TEAM_5v5);
- if(at_id != 0)
- {
- ArenaTeam * at = objmgr.GetArenaTeamById(at_id);
- if(at)
- at->DelMember(playerguid);
- }
+ LeaveAllArenaTeams(playerguid);
// the player was uninvited already on logout so just remove from group
QueryResult *resultGroup = CharacterDatabase.PQuery("SELECT leaderGuid FROM group_member WHERE memberGuid='%u'", guid);
@@ -3643,15 +3849,16 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
MailItemsInfo mi;
if(has_items)
{
- QueryResult *resultItems = CharacterDatabase.PQuery("SELECT item_guid,item_template FROM mail_items WHERE mail_id='%u'", mail_id);
+ // data needs to be at first place for Item::LoadFromDB
+ QueryResult *resultItems = CharacterDatabase.PQuery("SELECT data,item_guid,item_template FROM mail_items JOIN item_instance ON item_guid = guid WHERE mail_id='%u'", mail_id);
if(resultItems)
{
do
{
Field *fields2 = resultItems->Fetch();
- uint32 item_guidlow = fields2[0].GetUInt32();
- uint32 item_template = fields2[1].GetUInt32();
+ uint32 item_guidlow = fields2[1].GetUInt32();
+ uint32 item_template = fields2[2].GetUInt32();
ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_template);
if(!itemProto)
@@ -3661,7 +3868,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
}
Item *pItem = NewItemOrBag(itemProto);
- if(!pItem->LoadFromDB(item_guidlow, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)))
+ if(!pItem->LoadFromDB(item_guidlow, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER),resultItems))
{
pItem->FSetState(ITEM_REMOVED);
pItem->SaveToDB(); // it also deletes item object !
@@ -3724,6 +3931,8 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE receiver = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE owner = '%u'",guid);
+ CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE guid = '%u'",guid);
+ CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE guid = '%u'",guid);
CharacterDatabase.CommitTransaction();
//LoginDatabase.PExecute("UPDATE realmcharacters SET numchars = numchars - 1 WHERE acctid = %d AND realmid = %d", accountId, realmID);
@@ -3754,6 +3963,10 @@ void Player::SetMovement(PlayerMovementType pType)
*/
void Player::BuildPlayerRepop()
{
+ WorldPacket data(SMSG_PRE_RESURRECT, GetPackGUID().size());
+ data.append(GetPackGUID());
+ GetSession()->SendPacket(&data);
+
if(getRace() == RACE_NIGHTELF)
CastSpell(this, 20584, true); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)
CastSpell(this, 8326, true); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
@@ -3798,7 +4011,8 @@ void Player::BuildPlayerRepop()
SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, (float)1.0); //see radius of death player?
- SetByteValue(UNIT_FIELD_BYTES_1, 3, PLAYER_STATE_FLAG_ALWAYS_STAND);
+ // set and clear other
+ SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND);
}
void Player::SendDelayResponse(const uint32 ml_seconds)
@@ -3843,13 +4057,15 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
SetPower(POWER_ENERGY, uint32(GetMaxPower(POWER_ENERGY)*restore_percent));
}
+ // trigger update zone for alive state zone updates
+ uint32 newzone, newarea;
+ GetZoneAndAreaId(newzone,newarea);
+ UpdateZone(newzone,newarea);
+
// update visibility
//ObjectAccessor::UpdateVisibilityForPlayer(this);
SetToNotify();
- // some items limited to specific map
- DestroyZoneLimitedItem( true, GetZoneId());
-
if(!applySickness)
return;
@@ -3869,13 +4085,9 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
{
int32 delta = (int32(getLevel()) - startLevel + 1)*MINUTE;
- for(int i =0; i < 3; ++i)
+ if(Aura* Aur = GetAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS, GetGUID()))
{
- if(Aura* Aur = GetAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS,i))
- {
- Aur->SetAuraDuration(delta*1000);
- Aur->UpdateAuraDuration();
- }
+ Aur->SetAuraDuration(delta*IN_MILISECONDS);
}
}
}
@@ -3894,7 +4106,7 @@ void Player::KillPlayer()
ApplyModFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTE_RELEASE_TIMER, !sMapStore.LookupEntry(GetMapId())->Instanceable());
// 6 minutes until repop at graveyard
- m_deathTimer = 6*MINUTE*1000;
+ m_deathTimer = 6*MINUTE*IN_MILISECONDS;
UpdateCorpseReclaimDelay(); // dependent at use SetDeathPvP() call before kill
SendCorpseReclaimDelay();
@@ -3915,8 +4127,7 @@ void Player::CreateCorpse()
Corpse *corpse = new Corpse( (m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH) ? CORPSE_RESURRECTABLE_PVP : CORPSE_RESURRECTABLE_PVE );
SetPvPDeath(false);
- if(!corpse->Create(objmgr.GenerateLowGuid(HIGHGUID_CORPSE), this, GetMapId(), GetPositionX(),
- GetPositionY(), GetPositionZ(), GetOrientation()))
+ if(!corpse->Create(objmgr.GenerateLowGuid(HIGHGUID_CORPSE), this))
{
delete corpse;
return;
@@ -3944,7 +4155,7 @@ void Player::CreateCorpse()
flags |= CORPSE_FLAG_HIDE_HELM;
if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_CLOAK))
flags |= CORPSE_FLAG_HIDE_CLOAK;
- if(InBattleGround())
+ if(InBattleGround() && !InArena())
flags |= CORPSE_FLAG_LOOTABLE; // to be able to remove insignia
corpse->SetUInt32Value( CORPSE_FIELD_FLAGS, flags );
@@ -4131,7 +4342,7 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g
DurabilityCostsEntry const *dcost = sDurabilityCostsStore.LookupEntry(ditemProto->ItemLevel);
if(!dcost)
{
- sLog.outError("ERROR: RepairDurability: Wrong item lvl %u", ditemProto->ItemLevel);
+ sLog.outError("RepairDurability: Wrong item lvl %u", ditemProto->ItemLevel);
return TotalCost;
}
@@ -4139,7 +4350,7 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g
DurabilityQualityEntry const *dQualitymodEntry = sDurabilityQualityStore.LookupEntry(dQualitymodEntryId);
if(!dQualitymodEntry)
{
- sLog.outError("ERROR: RepairDurability: Wrong dQualityModEntry %u", dQualitymodEntryId);
+ sLog.outError("RepairDurability: Wrong dQualityModEntry %u", dQualitymodEntryId);
return TotalCost;
}
@@ -4220,10 +4431,8 @@ void Player::RepopAtGraveyard()
WorldSafeLocsEntry const *ClosestGrave = NULL;
// Special handle for battleground maps
- BattleGround *bg = sBattleGroundMgr.GetBattleGround(GetBattleGroundId());
-
- if(bg && (bg->GetTypeID() == BATTLEGROUND_AB || bg->GetTypeID() == BATTLEGROUND_EY || bg->GetTypeID() == BATTLEGROUND_AV))
- ClosestGrave = bg->GetClosestGraveYard(GetPositionX(), GetPositionY(), GetPositionZ(), GetTeam());
+ if( BattleGround *bg = GetBattleGround() )
+ ClosestGrave = bg->GetClosestGraveYard(this);
else
ClosestGrave = objmgr.GetClosestGraveYard( GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeam() );
@@ -4384,7 +4593,7 @@ float Player::GetBaseModValue(BaseModGroup modGroup, BaseModType modType) const
{
if(modGroup >= BASEMOD_END || modType > MOD_END)
{
- sLog.outError("ERROR: trial to access non existed BaseModGroup or wrong BaseModType!");
+ sLog.outError("trial to access non existed BaseModGroup or wrong BaseModType!");
return 0.0f;
}
@@ -4398,7 +4607,7 @@ float Player::GetTotalBaseModValue(BaseModGroup modGroup) const
{
if(modGroup >= BASEMOD_END)
{
- sLog.outError("ERROR: wrong BaseModGroup in GetTotalBaseModValue()!");
+ sLog.outError("wrong BaseModGroup in GetTotalBaseModValue()!");
return 0.0f;
}
@@ -4410,9 +4619,7 @@ float Player::GetTotalBaseModValue(BaseModGroup modGroup) const
uint32 Player::GetShieldBlockValue() const
{
- BaseModGroup modGroup = SHIELD_BLOCK_VALUE;
-
- float value = GetTotalBaseModValue(modGroup) + GetStat(STAT_STRENGTH)/20 - 1;
+ float value = (m_auraBaseMod[SHIELD_BLOCK_VALUE][FLAT_MOD] + GetStat(STAT_STRENGTH) * 0.5f - 10)*m_auraBaseMod[SHIELD_BLOCK_VALUE][PCT_MOD];
value = (value < 0) ? 0 : value;
@@ -4516,24 +4723,24 @@ float Player::GetRatingBonusValue(CombatRating cr) const
uint32 Player::GetMeleeCritDamageReduction(uint32 damage) const
{
- float melee = GetRatingBonusValue(CR_CRIT_TAKEN_MELEE)*2.0f;
- if (melee>25.0f) melee = 25.0f;
+ float melee = GetRatingBonusValue(CR_CRIT_TAKEN_MELEE)*2.2f;
+ if (melee>33.0f) melee = 33.0f;
return uint32 (melee * damage /100.0f);
}
uint32 Player::GetRangedCritDamageReduction(uint32 damage) const
{
- float ranged = GetRatingBonusValue(CR_CRIT_TAKEN_RANGED)*2.0f;
- if (ranged>25.0f) ranged=25.0f;
+ float ranged = GetRatingBonusValue(CR_CRIT_TAKEN_RANGED)*2.2f;
+ if (ranged>33.0f) ranged=33.0f;
return uint32 (ranged * damage /100.0f);
}
uint32 Player::GetSpellCritDamageReduction(uint32 damage) const
{
- float spell = GetRatingBonusValue(CR_CRIT_TAKEN_SPELL)*2.0f;
- // In wow script resilience limited to 25%
- if (spell>25.0f)
- spell = 25.0f;
+ float spell = GetRatingBonusValue(CR_CRIT_TAKEN_SPELL)*2.2f;
+ // In wow script resilience limited to 33%
+ if (spell>33.0f)
+ spell = 33.0f;
return uint32 (spell * damage / 100.0f);
}
@@ -4601,7 +4808,18 @@ float Player::OCTRegenMPPerSpirit()
void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply)
{
- ApplyModUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, value, apply);
+ m_baseRatingValue[cr]+=(apply ? value : -value);
+
+ int32 amount = uint32(m_baseRatingValue[cr]);
+ // Apply bonus from SPELL_AURA_MOD_RATING_FROM_STAT
+ // stat used stored in miscValueB for this aura
+ AuraEffectList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT);
+ for(AuraEffectList::const_iterator i = modRatingFromStat.begin();i != modRatingFromStat.end(); ++i)
+ if ((*i)->GetMiscValue() & (1<<cr))
+ amount += int32(GetStat(Stats((*i)->GetMiscBValue())) * (*i)->GetAmount() / 100.0f);
+ if (amount < 0)
+ amount = 0;
+ SetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, uint32(amount));
float RatingCoeffecient = GetRatingCoefficient(cr);
float RatingChange = 0.0f;
@@ -4624,16 +4842,13 @@ void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply)
UpdateBlockPercentage();
break;
case CR_HIT_MELEE:
- RatingChange = value / RatingCoeffecient;
- m_modMeleeHitChance += apply ? RatingChange : -RatingChange;
+ UpdateMeleeHitChances();
break;
case CR_HIT_RANGED:
- RatingChange = value / RatingCoeffecient;
- m_modRangedHitChance += apply ? RatingChange : -RatingChange;
+ UpdateRangedHitChances();
break;
case CR_HIT_SPELL:
- RatingChange = value / RatingCoeffecient;
- m_modSpellHitChance += apply ? RatingChange : -RatingChange;
+ UpdateSpellHitChances();
break;
case CR_CRIT_MELEE:
if(affectStats)
@@ -4731,6 +4946,7 @@ bool Player::UpdateSkill(uint32 skill_id, uint32 step)
new_value = max;
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(new_value,max));
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL,skill_id);
return true;
}
@@ -4766,7 +4982,7 @@ bool Player::UpdateCraftSkill(uint32 spellid)
if(spellEntry && spellEntry->Mechanic==MECHANIC_DISCOVERY)
{
if(uint32 discoveredSpell = GetSkillDiscoverySpell(_spell_idx->second->skillId, spellid, this))
- learnSpell(discoveredSpell);
+ learnSpell(discoveredSpell,false);
}
uint32 craft_skill_gain = sWorld.getConfig(CONFIG_SKILL_GAIN_CRAFTING);
@@ -4793,6 +5009,7 @@ bool Player::UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLeve
case SKILL_HERBALISM:
case SKILL_LOCKPICKING:
case SKILL_JEWELCRAFTING:
+ case SKILL_INSCRIPTION:
return UpdateSkillPro(SkillId, SkillGainChance(SkillValue, RedLevel+100, RedLevel+50, RedLevel+25)*Multiplicator,gathering_skill_gain);
case SKILL_SKINNING:
if( sWorld.getConfig(CONFIG_SKILL_CHANCE_SKINNING_STEPS)==0)
@@ -4821,6 +5038,11 @@ bool Player::UpdateFishingSkill()
return UpdateSkillPro(SKILL_FISHING,chance*10,gathering_skill_gain);
}
+// levels sync. with spell requirement for skill levels to learn
+// bonus abilities in sSkillLineAbilityStore
+// Used only to avoid scan DBC at each skill grow
+static uint32 bonusSkillLevels[] = {75,150,225,300,375,450};
+
bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
{
sLog.outDebug("UpdateSkillPro(SkillId %d, Chance %3.1f%%)", SkillId, Chance/10.0);
@@ -4855,6 +5077,15 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
new_value = MaxValue;
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(new_value,MaxValue));
+ for(uint32* bsl = &bonusSkillLevels[0]; *bsl; ++bsl)
+ {
+ if((SkillValue < *bsl && new_value >= *bsl))
+ {
+ learnSkillRewardedSpells( SkillId, new_value);
+ break;
+ }
+ }
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL,SkillId);
sLog.outDebug("Player::UpdateSkillPro Chance=%3.1f%% taken", Chance/10.0);
return true;
}
@@ -4902,22 +5133,8 @@ void Player::UpdateWeaponSkill (WeaponAttackType attType)
UpdateAllCritPercentages();
}
-void Player::UpdateCombatSkills(Unit *pVictim, WeaponAttackType attType, MeleeHitOutcome outcome, bool defence)
+void Player::UpdateCombatSkills(Unit *pVictim, WeaponAttackType attType, bool defence)
{
-/* Not need, this checked on call this func from trigger system
- switch(outcome)
- {
- case MELEE_HIT_CRIT:
- case MELEE_HIT_DODGE:
- case MELEE_HIT_PARRY:
- case MELEE_HIT_BLOCK:
- case MELEE_HIT_BLOCK_CRIT:
- return;
-
- default:
- break;
- }
-*/
uint32 plevel = getLevel(); // if defense than pVictim == attacker
uint32 greylevel = Trinity::XP::GetGrayLevel(plevel);
uint32 moblevel = pVictim->getLevelForTarget(this);
@@ -5014,7 +5231,7 @@ void Player::UpdateSkillsToMaxSkillsForLevel()
if (GetUInt32Value(PLAYER_SKILL_INDEX(i)))
{
uint32 pskill = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF;
- if( IsProfessionSkill(pskill) || pskill == SKILL_RIDING )
+ if( IsProfessionOrRidingSkill(pskill))
continue;
uint32 data = GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i));
@@ -5042,7 +5259,12 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
if(i<PLAYER_MAX_SKILLS) //has skill
{
if(currVal)
+ {
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(currVal,maxVal));
+ learnSkillRewardedSpells(id, currVal);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL,id);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL,id);
+ }
else //remove
{
// clear skill fields
@@ -5050,27 +5272,11 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),0);
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0);
- // remove spells that depend on this skill when removing the skill
- for (PlayerSpellMap::const_iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next)
- {
- ++next;
- if(itr->second->state == PLAYERSPELL_REMOVED)
- continue;
-
- SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(itr->first);
- SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(itr->first);
-
- for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
- {
- if (_spell_idx->second->skillId == id)
- {
- // this may remove more than one spell (dependents)
- removeSpell(itr->first);
- next = m_spells.begin();
- break;
- }
- }
- }
+ // remove all spells that related to this skill
+ for (uint32 j=0; j<sSkillLineAbilityStore.GetNumRows(); ++j)
+ if(SkillLineAbilityEntry const *pAbility = sSkillLineAbilityStore.LookupEntry(j))
+ if (pAbility->skillId==id)
+ removeSpell(spellmgr.GetFirstSpellInChain(pAbility->spellId));
}
}
else if(currVal) //add
@@ -5090,24 +5296,26 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
else
SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,0));
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(currVal,maxVal));
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL,id);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL,id);
// apply skill bonuses
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0);
// temporary bonuses
- AuraList const& mModSkill = GetAurasByType(SPELL_AURA_MOD_SKILL);
- for(AuraList::const_iterator i = mModSkill.begin(); i != mModSkill.end(); ++i)
- if ((*i)->GetModifier()->m_miscvalue == int32(id))
- (*i)->ApplyModifier(true);
+ AuraEffectList const& mModSkill = GetAurasByType(SPELL_AURA_MOD_SKILL);
+ for(AuraEffectList::const_iterator j = mModSkill.begin(); j != mModSkill.end(); ++j)
+ if ((*j)->GetMiscValue() == int32(id))
+ (*j)->ApplyModifier(true);
// permanent bonuses
- AuraList const& mModSkillTalent = GetAurasByType(SPELL_AURA_MOD_SKILL_TALENT);
- for(AuraList::const_iterator i = mModSkillTalent.begin(); i != mModSkillTalent.end(); ++i)
- if ((*i)->GetModifier()->m_miscvalue == int32(id))
- (*i)->ApplyModifier(true);
+ AuraEffectList const& mModSkillTalent = GetAurasByType(SPELL_AURA_MOD_SKILL_TALENT);
+ for(AuraEffectList::const_iterator j = mModSkillTalent.begin(); j != mModSkillTalent.end(); ++j)
+ if ((*j)->GetMiscValue() == int32(id))
+ (*j)->ApplyModifier(true);
// Learn all spells for skill
- learnSkillRewardedSpells(id);
+ learnSkillRewardedSpells(id, currVal);
return;
}
}
@@ -5205,6 +5413,22 @@ uint16 Player::GetPureSkillValue(uint32 skill) const
return 0;
}
+int16 Player::GetSkillPermBonusValue(uint32 skill) const
+{
+ if(!skill)
+ return 0;
+
+ for (int i = 0; i < PLAYER_MAX_SKILLS; i++)
+ {
+ if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill)
+ {
+ return SKILL_PERM_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i)));
+ }
+ }
+
+ return 0;
+}
+
int16 Player::GetSkillTempBonusValue(uint32 skill) const
{
if(!skill)
@@ -5245,12 +5469,12 @@ void Player::SendInitialActionButtons()
sLog.outDetail( "Action Buttons for '%u' Initialized", GetGUIDLow() );
}
-void Player::addActionButton(const uint8 button, const uint16 action, const uint8 type, const uint8 misc)
+bool Player::addActionButton(const uint8 button, const uint16 action, const uint8 type, const uint8 misc)
{
if(button >= MAX_ACTION_BUTTONS)
{
sLog.outError( "Action %u not added into button %u for player %s: button must be < 132", action, button, GetName() );
- return;
+ return false;
}
// check cheating with adding non-known spells to action bar
@@ -5259,13 +5483,13 @@ void Player::addActionButton(const uint8 button, const uint16 action, const uint
if(!sSpellStore.LookupEntry(action))
{
sLog.outError( "Action %u not added into button %u for player %s: spell not exist", action, button, GetName() );
- return;
+ return false;
}
if(!HasSpell(action))
{
sLog.outError( "Action %u not added into button %u for player %s: player don't known this spell", action, button, GetName() );
- return;
+ return false;
}
}
@@ -5283,6 +5507,7 @@ void Player::addActionButton(const uint8 button, const uint16 action, const uint
};
sLog.outDetail( "Player '%u' Added Action '%u' to Button '%u'", GetGUIDLow(), action, button );
+ return true;
}
void Player::removeActionButton(uint8 button)
@@ -5299,11 +5524,6 @@ void Player::removeActionButton(uint8 button)
sLog.outDetail( "Action Button '%u' Removed from Player '%u'", button, GetGUIDLow() );
}
-void Player::SetDontMove(bool dontMove)
-{
- m_dontMove = dontMove;
-}
-
bool Player::SetPosition(float x, float y, float z, float orientation, bool teleport)
{
// prevent crash when a bad coord is sent by the client
@@ -5360,17 +5580,17 @@ void Player::SaveRecallPosition()
void Player::SendMessageToSet(WorldPacket *data, bool self, bool to_possessor)
{
- MapManager::Instance().GetMap(GetMapId(), this)->MessageBroadcast(this, data, self, to_possessor);
+ GetMap()->MessageBroadcast(this, data, self, to_possessor);
}
void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool to_possessor)
{
- MapManager::Instance().GetMap(GetMapId(), this)->MessageDistBroadcast(this, data, dist, self, to_possessor);
+ GetMap()->MessageDistBroadcast(this, data, dist, self, to_possessor);
}
void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool to_possessor, bool own_team_only)
{
- MapManager::Instance().GetMap(GetMapId(), this)->MessageDistBroadcast(this, data, dist, self, to_possessor, own_team_only);
+ GetMap()->MessageDistBroadcast(this, data, dist, self, to_possessor, own_team_only);
}
void Player::SendDirectMessage(WorldPacket *data)
@@ -5378,6 +5598,20 @@ void Player::SendDirectMessage(WorldPacket *data)
GetSession()->SendPacket(data);
}
+void Player::SendCinematicStart(uint32 CinematicSequenceId)
+{
+ WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4);
+ data << uint32(CinematicSequenceId);
+ SendDirectMessage(&data);
+}
+
+void Player::SendMovieStart(uint32 MovieId)
+{
+ WorldPacket data(SMSG_TRIGGER_MOVIE, 4);
+ data << uint32(MovieId);
+ SendDirectMessage(&data);
+}
+
void Player::CheckExploreSystem()
{
if (!isAlive())
@@ -5386,14 +5620,14 @@ void Player::CheckExploreSystem()
if (isInFlight())
return;
- uint16 areaFlag=MapManager::Instance().GetBaseMap(GetMapId())->GetAreaFlag(GetPositionX(),GetPositionY());
+ uint16 areaFlag=MapManager::Instance().GetBaseMap(GetMapId())->GetAreaFlag(GetPositionX(),GetPositionY(),GetPositionZ());
if(areaFlag==0xffff)
return;
int offset = areaFlag / 32;
if(offset >= 128)
{
- sLog.outError("ERROR: Wrong area flag %u in map data for (X: %f Y: %f) point to field PLAYER_EXPLORED_ZONES_1 + %u ( %u must be < 64 ).",areaFlag,GetPositionX(),GetPositionY(),offset,offset);
+ sLog.outError("Wrong area flag %u in map data for (X: %f Y: %f) point to field PLAYER_EXPLORED_ZONES_1 + %u ( %u must be < 128 ).",areaFlag,GetPositionX(),GetPositionY(),offset,offset);
return;
}
@@ -5404,6 +5638,8 @@ void Player::CheckExploreSystem()
{
SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA);
+
AreaTableEntry const *p = GetAreaEntryByAreaFlagAndMap(areaFlag,GetMapId());
if(!p)
{
@@ -5484,435 +5720,27 @@ void Player::setFactionForRace(uint8 race)
setFaction( getFactionForRace(race) );
}
-void Player::UpdateReputation() const
-{
- sLog.outDetail( "WORLD: Player::UpdateReputation" );
-
- for(FactionStateList::const_iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr)
- {
- SendFactionState(&(itr->second));
- }
-}
-
-void Player::SendFactionState(FactionState const* faction) const
-{
- if(faction->Flags & FACTION_FLAG_VISIBLE) //If faction is visible then update it
- {
- WorldPacket data(SMSG_SET_FACTION_STANDING, (16)); // last check 2.4.0
- data << (float) 0; // unk 2.4.0
- data << (uint32) 1; // count
- // for
- data << (uint32) faction->ReputationListID;
- data << (uint32) faction->Standing;
- // end for
- GetSession()->SendPacket(&data);
- }
-}
-
-void Player::SendInitialReputations()
-{
- WorldPacket data(SMSG_INITIALIZE_FACTIONS, (4+128*5));
- data << uint32 (0x00000080);
-
- RepListID a = 0;
-
- for (FactionStateList::const_iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr)
- {
- // fill in absent fields
- for (; a != itr->first; a++)
- {
- data << uint8 (0x00);
- data << uint32 (0x00000000);
- }
-
- // fill in encountered data
- data << uint8 (itr->second.Flags);
- data << uint32 (itr->second.Standing);
-
- ++a;
- }
-
- // fill in absent fields
- for (; a != 128; a++)
- {
- data << uint8 (0x00);
- data << uint32 (0x00000000);
- }
-
- GetSession()->SendPacket(&data);
-}
-
-FactionState const* Player::GetFactionState( FactionEntry const* factionEntry) const
-{
- FactionStateList::const_iterator itr = m_factions.find(factionEntry->reputationListID);
- if (itr != m_factions.end())
- return &itr->second;
-
- return NULL;
-}
-
-void Player::SetFactionAtWar(FactionState* faction, bool atWar)
-{
- // not allow declare war to own faction
- if(atWar && (faction->Flags & FACTION_FLAG_PEACE_FORCED) )
- return;
-
- // already set
- if(((faction->Flags & FACTION_FLAG_AT_WAR) != 0) == atWar)
- return;
-
- if( atWar )
- faction->Flags |= FACTION_FLAG_AT_WAR;
- else
- faction->Flags &= ~FACTION_FLAG_AT_WAR;
-
- faction->Changed = true;
-}
-
-void Player::SetFactionInactive(FactionState* faction, bool inactive)
-{
- // always invisible or hidden faction can't be inactive
- if(inactive && ((faction->Flags & (FACTION_FLAG_INVISIBLE_FORCED|FACTION_FLAG_HIDDEN)) || !(faction->Flags & FACTION_FLAG_VISIBLE) ) )
- return;
-
- // already set
- if(((faction->Flags & FACTION_FLAG_INACTIVE) != 0) == inactive)
- return;
-
- if(inactive)
- faction->Flags |= FACTION_FLAG_INACTIVE;
- else
- faction->Flags &= ~FACTION_FLAG_INACTIVE;
-
- faction->Changed = true;
-}
-
-void Player::SetFactionVisibleForFactionTemplateId(uint32 FactionTemplateId)
-{
- FactionTemplateEntry const*factionTemplateEntry = sFactionTemplateStore.LookupEntry(FactionTemplateId);
-
- if(!factionTemplateEntry)
- return;
-
- SetFactionVisibleForFactionId(factionTemplateEntry->faction);
-}
-
-void Player::SetFactionVisibleForFactionId(uint32 FactionId)
-{
- FactionEntry const *factionEntry = sFactionStore.LookupEntry(FactionId);
- if(!factionEntry)
- return;
-
- if(factionEntry->reputationListID < 0)
- return;
-
- FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID);
- if (itr == m_factions.end())
- return;
-
- SetFactionVisible(&itr->second);
-}
-
-void Player::SetFactionVisible(FactionState* faction)
-{
- // always invisible or hidden faction can't be make visible
- if(faction->Flags & (FACTION_FLAG_INVISIBLE_FORCED|FACTION_FLAG_HIDDEN))
- return;
-
- // already set
- if(faction->Flags & FACTION_FLAG_VISIBLE)
- return;
-
- faction->Flags |= FACTION_FLAG_VISIBLE;
- faction->Changed = true;
-
- if(!m_session->PlayerLoading())
- {
- // make faction visible in reputation list at client
- WorldPacket data(SMSG_SET_FACTION_VISIBLE, 4);
- data << faction->ReputationListID;
- GetSession()->SendPacket(&data);
- }
-}
-
-void Player::SetInitialFactions()
-{
- for(unsigned int i = 1; i < sFactionStore.GetNumRows(); i++)
- {
- FactionEntry const *factionEntry = sFactionStore.LookupEntry(i);
-
- if( factionEntry && (factionEntry->reputationListID >= 0))
- {
- FactionState newFaction;
- newFaction.ID = factionEntry->ID;
- newFaction.ReputationListID = factionEntry->reputationListID;
- newFaction.Standing = 0;
- newFaction.Flags = GetDefaultReputationFlags(factionEntry);
- newFaction.Changed = true;
-
- m_factions[newFaction.ReputationListID] = newFaction;
- }
- }
-}
-
-uint32 Player::GetDefaultReputationFlags(const FactionEntry *factionEntry) const
-{
- if (!factionEntry)
- return 0;
-
- uint32 raceMask = getRaceMask();
- uint32 classMask = getClassMask();
- for (int i=0; i < 4; i++)
- {
- if( (factionEntry->BaseRepRaceMask[i] & raceMask) &&
- (factionEntry->BaseRepClassMask[i]==0 ||
- (factionEntry->BaseRepClassMask[i] & classMask) ) )
- return factionEntry->ReputationFlags[i];
- }
- return 0;
-}
-
-int32 Player::GetBaseReputation(const FactionEntry *factionEntry) const
-{
- if (!factionEntry)
- return 0;
-
- uint32 raceMask = getRaceMask();
- uint32 classMask = getClassMask();
- for (int i=0; i < 4; i++)
- {
- if( (factionEntry->BaseRepRaceMask[i] & raceMask) &&
- (factionEntry->BaseRepClassMask[i]==0 ||
- (factionEntry->BaseRepClassMask[i] & classMask) ) )
- return factionEntry->BaseRepValue[i];
- }
-
- // in faction.dbc exist factions with (RepListId >=0, listed in character reputation list) with all BaseRepRaceMask[i]==0
- return 0;
-}
-
-int32 Player::GetReputation(uint32 faction_id) const
-{
- FactionEntry const *factionEntry = sFactionStore.LookupEntry(faction_id);
-
- if (!factionEntry)
- {
- sLog.outError("Player::GetReputation: Can't get reputation of %s for unknown faction (faction template id) #%u.",GetName(), faction_id);
- return 0;
- }
-
- return GetReputation(factionEntry);
-}
-
-int32 Player::GetReputation(const FactionEntry *factionEntry) const
-{
- // Faction without recorded reputation. Just ignore.
- if(!factionEntry)
- return 0;
-
- FactionStateList::const_iterator itr = m_factions.find(factionEntry->reputationListID);
- if (itr != m_factions.end())
- return GetBaseReputation(factionEntry) + itr->second.Standing;
-
- return 0;
-}
-
ReputationRank Player::GetReputationRank(uint32 faction) const
{
- FactionEntry const*factionEntry = sFactionStore.LookupEntry(faction);
- if(!factionEntry)
- return MIN_REPUTATION_RANK;
-
- return GetReputationRank(factionEntry);
-}
-
-ReputationRank Player::ReputationToRank(int32 standing) const
-{
- int32 Limit = Reputation_Cap + 1;
- for (int i = MAX_REPUTATION_RANK-1; i >= MIN_REPUTATION_RANK; --i)
- {
- Limit -= ReputationRank_Length[i];
- if (standing >= Limit )
- return ReputationRank(i);
- }
- return MIN_REPUTATION_RANK;
-}
-
-ReputationRank Player::GetReputationRank(const FactionEntry *factionEntry) const
-{
- int32 Reputation = GetReputation(factionEntry);
- return ReputationToRank(Reputation);
-}
-
-ReputationRank Player::GetBaseReputationRank(const FactionEntry *factionEntry) const
-{
- int32 Reputation = GetBaseReputation(factionEntry);
- return ReputationToRank(Reputation);
-}
-
-bool Player::ModifyFactionReputation(uint32 FactionTemplateId, int32 DeltaReputation)
-{
- FactionTemplateEntry const* factionTemplateEntry = sFactionTemplateStore.LookupEntry(FactionTemplateId);
-
- if(!factionTemplateEntry)
- {
- sLog.outError("Player::ModifyFactionReputation: Can't update reputation of %s for unknown faction (faction template id) #%u.", GetName(), FactionTemplateId);
- return false;
- }
-
- FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionTemplateEntry->faction);
-
- // Faction without recorded reputation. Just ignore.
- if(!factionEntry)
- return false;
-
- return ModifyFactionReputation(factionEntry, DeltaReputation);
-}
-
-bool Player::ModifyFactionReputation(FactionEntry const* factionEntry, int32 standing)
-{
- SimpleFactionsList const* flist = GetFactionTeamList(factionEntry->ID);
- if (flist)
- {
- bool res = false;
- for (SimpleFactionsList::const_iterator itr = flist->begin();itr != flist->end();++itr)
- {
- FactionEntry const *factionEntryCalc = sFactionStore.LookupEntry(*itr);
- if(factionEntryCalc)
- res = ModifyOneFactionReputation(factionEntryCalc, standing);
- }
- return res;
- }
- else
- return ModifyOneFactionReputation(factionEntry, standing);
-}
-
-bool Player::ModifyOneFactionReputation(FactionEntry const* factionEntry, int32 standing)
-{
- FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID);
- if (itr != m_factions.end())
- {
- int32 BaseRep = GetBaseReputation(factionEntry);
- int32 new_rep = BaseRep + itr->second.Standing + standing;
-
- if (new_rep > Reputation_Cap)
- new_rep = Reputation_Cap;
- else
- if (new_rep < Reputation_Bottom)
- new_rep = Reputation_Bottom;
-
- if(ReputationToRank(new_rep) <= REP_HOSTILE)
- SetFactionAtWar(&itr->second,true);
-
- itr->second.Standing = new_rep - BaseRep;
- itr->second.Changed = true;
-
- SetFactionVisible(&itr->second);
-
- for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
- {
- if(uint32 questid = GetQuestSlotQuestId(i))
- {
- Quest const* qInfo = objmgr.GetQuestTemplate(questid);
- if( qInfo && qInfo->GetRepObjectiveFaction() == factionEntry->ID )
- {
- QuestStatusData& q_status = mQuestStatus[questid];
- if( q_status.m_status == QUEST_STATUS_INCOMPLETE )
- {
- if(GetReputation(factionEntry) >= qInfo->GetRepObjectiveValue())
- if ( CanCompleteQuest( questid ) )
- CompleteQuest( questid );
- }
- else if( q_status.m_status == QUEST_STATUS_COMPLETE )
- {
- if(GetReputation(factionEntry) < qInfo->GetRepObjectiveValue())
- IncompleteQuest( questid );
- }
- }
- }
- }
-
- SendFactionState(&(itr->second));
-
- return true;
- }
- return false;
-}
-
-bool Player::SetFactionReputation(uint32 FactionTemplateId, int32 standing)
-{
- FactionTemplateEntry const* factionTemplateEntry = sFactionTemplateStore.LookupEntry(FactionTemplateId);
-
- if(!factionTemplateEntry)
- {
- sLog.outError("Player::SetFactionReputation: Can't set reputation of %s for unknown faction (faction template id) #%u.", GetName(), FactionTemplateId);
- return false;
- }
-
- FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionTemplateEntry->faction);
-
- // Faction without recorded reputation. Just ignore.
- if(!factionEntry)
- return false;
-
- return SetFactionReputation(factionEntry, standing);
-}
-
-bool Player::SetFactionReputation(FactionEntry const* factionEntry, int32 standing)
-{
- SimpleFactionsList const* flist = GetFactionTeamList(factionEntry->ID);
- if (flist)
- {
- bool res = false;
- for (SimpleFactionsList::const_iterator itr = flist->begin();itr != flist->end();++itr)
- {
- FactionEntry const *factionEntryCalc = sFactionStore.LookupEntry(*itr);
- if(factionEntryCalc)
- res = SetOneFactionReputation(factionEntryCalc, standing);
- }
- return res;
- }
- else
- return SetOneFactionReputation(factionEntry, standing);
-}
-
-bool Player::SetOneFactionReputation(FactionEntry const* factionEntry, int32 standing)
-{
- FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID);
- if (itr != m_factions.end())
- {
- if (standing > Reputation_Cap)
- standing = Reputation_Cap;
- else
- if (standing < Reputation_Bottom)
- standing = Reputation_Bottom;
-
- int32 BaseRep = GetBaseReputation(factionEntry);
- itr->second.Standing = standing - BaseRep;
- itr->second.Changed = true;
-
- SetFactionVisible(&itr->second);
-
- if(ReputationToRank(standing) <= REP_HOSTILE)
- SetFactionAtWar(&itr->second,true);
-
- SendFactionState(&(itr->second));
- return true;
- }
- return false;
+ FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction);
+ return GetReputationMgr().GetRank(factionEntry);
}
//Calculate total reputation percent player gain with quest/creature level
int32 Player::CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, bool for_quest)
{
- // for grey creature kill received 20%, in other case 100.
- int32 percent = (!for_quest && (creatureOrQuestLevel <= Trinity::XP::GetGrayLevel(getLevel()))) ? 20 : 100;
+ float percent = 100.0f;
+
+ float rate = for_quest ? sWorld.getRate(RATE_REPUTATION_LOWLEVEL_QUEST) : sWorld.getRate(RATE_REPUTATION_LOWLEVEL_KILL);
+
+ if(rate != 1.0f && creatureOrQuestLevel <= MaNGOS::XP::GetGrayLevel(getLevel()))
+ percent *= rate;
int32 repMod = GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN);
percent += rep > 0 ? repMod : -repMod;
- if(percent <=0)
+ if(percent <= 0.0f)
return 0;
return int32(sWorld.getRate(RATE_REPUTATION_GAIN)*rep*percent/100);
@@ -5937,16 +5765,16 @@ void Player::RewardReputation(Unit *pVictim, float rate)
int32 donerep1 = CalculateReputationGain(pVictim->getLevel(),Rep->repvalue1,false);
donerep1 = int32(donerep1*rate);
FactionEntry const *factionEntry1 = sFactionStore.LookupEntry(Rep->repfaction1);
- uint32 current_reputation_rank1 = GetReputationRank(factionEntry1);
- if(factionEntry1 && current_reputation_rank1 <= Rep->reputation_max_cap1)
- ModifyFactionReputation(factionEntry1, donerep1);
+ uint32 current_reputation_rank1 = GetReputationMgr().GetRank(factionEntry1);
+ if (factionEntry1 && current_reputation_rank1 <= Rep->reputation_max_cap1)
+ GetReputationMgr().ModifyReputation(factionEntry1, donerep1);
// Wiki: Team factions value divided by 2
- if(Rep->is_teamaward1)
+ if (factionEntry1 && Rep->is_teamaward1)
{
FactionEntry const *team1_factionEntry = sFactionStore.LookupEntry(factionEntry1->team);
if(team1_factionEntry)
- ModifyFactionReputation(team1_factionEntry, donerep1 / 2);
+ GetReputationMgr().ModifyReputation(team1_factionEntry, donerep1 / 2);
}
}
@@ -5955,16 +5783,16 @@ void Player::RewardReputation(Unit *pVictim, float rate)
int32 donerep2 = CalculateReputationGain(pVictim->getLevel(),Rep->repvalue2,false);
donerep2 = int32(donerep2*rate);
FactionEntry const *factionEntry2 = sFactionStore.LookupEntry(Rep->repfaction2);
- uint32 current_reputation_rank2 = GetReputationRank(factionEntry2);
- if(factionEntry2 && current_reputation_rank2 <= Rep->reputation_max_cap2)
- ModifyFactionReputation(factionEntry2, donerep2);
+ uint32 current_reputation_rank2 = GetReputationMgr().GetRank(factionEntry2);
+ if (factionEntry2 && current_reputation_rank2 <= Rep->reputation_max_cap2)
+ GetReputationMgr().ModifyReputation(factionEntry2, donerep2);
// Wiki: Team factions value divided by 2
- if(Rep->is_teamaward2)
+ if (factionEntry2 && Rep->is_teamaward2)
{
FactionEntry const *team2_factionEntry = sFactionStore.LookupEntry(factionEntry2->team);
if(team2_factionEntry)
- ModifyFactionReputation(team2_factionEntry, donerep2 / 2);
+ GetReputationMgr().ModifyReputation(team2_factionEntry, donerep2 / 2);
}
}
}
@@ -5977,10 +5805,10 @@ void Player::RewardReputation(Quest const *pQuest)
{
if(pQuest->RewRepFaction[i] && pQuest->RewRepValue[i] )
{
- int32 rep = CalculateReputationGain(pQuest->GetQuestLevel(),pQuest->RewRepValue[i],true);
+ int32 rep = CalculateReputationGain(GetQuestLevel(pQuest),pQuest->RewRepValue[i],true);
FactionEntry const* factionEntry = sFactionStore.LookupEntry(pQuest->RewRepFaction[i]);
if(factionEntry)
- ModifyFactionReputation(factionEntry, rep);
+ GetReputationMgr().ModifyReputation(factionEntry, rep);
}
}
@@ -6098,12 +5926,7 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor, bool pvpt
victim_guid = 0; // Don't show HK: <rank> message, only log.
}
- if(k_level <= 5)
- k_grey = 0;
- else if( k_level <= 39 )
- k_grey = k_level - 5 - k_level/10;
- else
- k_grey = k_level - 1 - k_level/5;
+ k_grey = Trinity::XP::GetGrayLevel(k_level);
if(v_level<=k_grey)
return false;
@@ -6119,6 +5942,7 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor, bool pvpt
ApplyModUInt32Value(PLAYER_FIELD_KILLS, 1, true);
// and those in a lifetime
ApplyModUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 1, true);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
}
else
{
@@ -6139,6 +5963,8 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor, bool pvpt
if(groupsize > 1)
honor /= groupsize;
+ // apply honor multiplier from aura (not stacking-get highest)
+ honor = int32(float(honor) * (float(GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HONOR_GAIN_PCT))+100.0f)/100.0f);
honor *= (((float)urand(8,12))/10); // approx honor: 80% - 120% of real honor
}
@@ -6168,8 +5994,8 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor, bool pvpt
{
// Check if allowed to receive it in current map
uint8 MapType = sWorld.getConfig(CONFIG_PVP_TOKEN_MAP_TYPE);
- if( (MapType == 1 && !InBattleGround() && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP))
- || (MapType == 2 && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP))
+ if( (MapType == 1 && !InBattleGround() && !HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
+ || (MapType == 2 && !HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|| (MapType == 3 && !InBattleGround()) )
return true;
@@ -6227,24 +6053,18 @@ void Player::ModifyArenaPoints( int32 value )
uint32 Player::GetGuildIdFromDB(uint64 guid)
{
- std::ostringstream ss;
- ss<<"SELECT guildid FROM guild_member WHERE guid='"<<guid<<"'";
- QueryResult *result = CharacterDatabase.Query( ss.str().c_str() );
- if( result )
- {
- uint32 v = result->Fetch()[0].GetUInt32();
- delete result;
- return v;
- }
- else
+ QueryResult* result = CharacterDatabase.PQuery("SELECT guildid FROM guild_member WHERE guid='%u'", GUID_LOPART(guid));
+ if(!result)
return 0;
+
+ uint32 id = result->Fetch()[0].GetUInt32();
+ delete result;
+ return id;
}
uint32 Player::GetRankFromDB(uint64 guid)
{
- std::ostringstream ss;
- ss<<"SELECT rank FROM guild_member WHERE guid='"<<guid<<"'";
- QueryResult *result = CharacterDatabase.Query( ss.str().c_str() );
+ QueryResult *result = CharacterDatabase.PQuery( "SELECT rank FROM guild_member WHERE guid='%u'", GUID_LOPART(guid) );
if( result )
{
uint32 v = result->Fetch()[0].GetUInt32();
@@ -6268,10 +6088,8 @@ uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type)
uint32 Player::GetZoneIdFromDB(uint64 guid)
{
- std::ostringstream ss;
-
- ss<<"SELECT zone FROM characters WHERE guid='"<<GUID_LOPART(guid)<<"'";
- QueryResult *result = CharacterDatabase.Query( ss.str().c_str() );
+ uint32 guidLow = GUID_LOPART(guid);
+ QueryResult *result = CharacterDatabase.PQuery( "SELECT zone FROM characters WHERE guid='%u'", guidLow );
if (!result)
return 0;
Field* fields = result->Fetch();
@@ -6281,22 +6099,19 @@ uint32 Player::GetZoneIdFromDB(uint64 guid)
if (!zone)
{
// stored zone is zero, use generic and slow zone detection
- ss.str("");
- ss<<"SELECT map,position_x,position_y FROM characters WHERE guid='"<<GUID_LOPART(guid)<<"'";
- result = CharacterDatabase.Query(ss.str().c_str());
+ result = CharacterDatabase.PQuery("SELECT map,position_x,position_y,position_z FROM characters WHERE guid='%u'", guidLow);
if( !result )
return 0;
fields = result->Fetch();
- uint32 map = fields[0].GetUInt32();
+ uint32 map = fields[0].GetUInt32();
float posx = fields[1].GetFloat();
float posy = fields[2].GetFloat();
+ float posz = fields[3].GetFloat();
delete result;
- zone = MapManager::Instance().GetZoneId(map,posx,posy);
+ zone = MapManager::Instance().GetZoneId(map,posx,posy,posz);
- ss.str("");
- ss << "UPDATE characters SET zone='"<<zone<<"' WHERE guid='"<<GUID_LOPART(guid)<<"'";
- CharacterDatabase.Execute(ss.str().c_str());
+ CharacterDatabase.PExecute("UPDATE characters SET zone='%u' WHERE guid='%u'", zone, guidLow);
}
return zone;
@@ -6313,39 +6128,38 @@ void Player::UpdateArea(uint32 newArea)
if(area && (area->flags & AREA_FLAG_ARENA))
{
if(!isGameMaster())
- SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);
+ SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}
else
{
// remove ffa flag only if not ffapvp realm
// removal in sanctuaries and capitals is handled in zone update
- if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP) && !sWorld.IsFFAPvPRealm())
- RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);
+ if(HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP) && !sWorld.IsFFAPvPRealm())
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}
UpdateAreaDependentAuras(newArea);
}
-void Player::UpdateZone(uint32 newZone)
+void Player::UpdateZone(uint32 newZone, uint32 newArea)
{
- uint32 oldZoneId = m_zoneUpdateId;
+ if(m_zoneUpdateId != newZone)
+ {
+ sOutdoorPvPMgr.HandlePlayerLeaveZone(this, m_zoneUpdateId);
+ sOutdoorPvPMgr.HandlePlayerEnterZone(this, newZone);
+ SendInitWorldStates(newZone, newArea); // only if really enters to new zone, not just area change, works strange...
+ }
+
m_zoneUpdateId = newZone;
m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL;
// zone changed, so area changed as well, update it
- UpdateArea(GetAreaId());
+ UpdateArea(newArea);
AreaTableEntry const* zone = GetAreaEntryByAreaID(newZone);
if(!zone)
return;
- // inform outdoor pvp
- if(oldZoneId != m_zoneUpdateId)
- {
- sOutdoorPvPMgr.HandlePlayerLeaveZone(this, oldZoneId);
- sOutdoorPvPMgr.HandlePlayerEnterZone(this, m_zoneUpdateId);
- }
-
if (sWorld.getConfig(CONFIG_WEATHER))
{
Weather *wth = sWorld.FindWeather(zone->ID);
@@ -6380,15 +6194,15 @@ void Player::UpdateZone(uint32 newZone)
pvpInfo.endTimer = time(0); // start toggle-off
}
- if(zone->flags & AREA_FLAG_SANCTUARY) // in sanctuary
+ if((zone->flags & AREA_FLAG_SANCTUARY) || zone->mapid == 609) // in sanctuary
{
- SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY);
+ SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
if(sWorld.IsFFAPvPRealm())
- RemoveFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}
else
{
- RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY);
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
}
if(zone->flags & AREA_FLAG_CAPITAL) // in capital city
@@ -6398,7 +6212,7 @@ void Player::UpdateZone(uint32 newZone)
InnEnter(time(0),GetMapId(),0,0,0);
if(sWorld.IsFFAPvPRealm())
- RemoveFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}
else // anywhere else
{
@@ -6412,7 +6226,7 @@ void Player::UpdateZone(uint32 newZone)
SetRestType(REST_TYPE_NO);
if(sWorld.IsFFAPvPRealm())
- SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}
}
else // not in tavern (leave city then)
@@ -6422,7 +6236,7 @@ void Player::UpdateZone(uint32 newZone)
// Set player to FFA PVP when not in rested environment.
if(sWorld.IsFFAPvPRealm())
- SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}
}
}
@@ -6432,6 +6246,9 @@ void Player::UpdateZone(uint32 newZone)
if(isAlive())
DestroyZoneLimitedItem( true, newZone );
+ // check some item equip limitations (in result lost CanTitanGrip at talent reset, for example)
+ AutoUnequipOffhandIfNeed();
+
// recent client version not send leave/join channel packets for built-in local channels
UpdateLocalChannels( newZone );
@@ -6449,7 +6266,7 @@ void Player::CheckDuelDistance(time_t currTime)
return;
uint64 duelFlagGUID = GetUInt64Value(PLAYER_DUEL_ARBITER);
- GameObject* obj = ObjectAccessor::GetGameObject(*this, duelFlagGUID);
+ GameObject* obj = GetMap()->GetGameObject(duelFlagGUID);
if(!obj)
return;
@@ -6490,6 +6307,8 @@ void Player::DuelComplete(DuelCompleteType type)
if(!duel)
return;
+ sLog.outDebug("Duel Complete %s %s", GetName(), duel->opponent->GetName());
+
WorldPacket data(SMSG_DUEL_COMPLETE, (1));
data << (uint8)((type != DUEL_INTERUPTED) ? 1 : 0);
GetSession()->SendPacket(&data);
@@ -6521,31 +6340,32 @@ void Player::DuelComplete(DuelCompleteType type)
duel->opponent->GetSession()->SendPacket(&data);*/
//Remove Duel Flag object
- GameObject* obj = ObjectAccessor::GetGameObject(*this, GetUInt64Value(PLAYER_DUEL_ARBITER));
+ GameObject* obj = GetMap()->GetGameObject(GetUInt64Value(PLAYER_DUEL_ARBITER));
if(obj)
duel->initiator->RemoveGameObject(obj,true);
/* remove auras */
- std::vector<uint32> auras2remove;
- AuraMap const& vAuras = duel->opponent->GetAuras();
- for (AuraMap::const_iterator i = vAuras.begin(); i != vAuras.end(); ++i)
+ AuraMap &itsAuras = duel->opponent->GetAuras();
+ for(AuraMap::iterator i = itsAuras.begin(); i != itsAuras.end();)
{
if (!i->second->IsPositive() && i->second->GetCasterGUID() == GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime)
- auras2remove.push_back(i->second->GetId());
+ {
+ duel->opponent->RemoveAura(i);
+ }
+ else
+ ++i;
}
- for(size_t i=0; i<auras2remove.size(); i++)
- duel->opponent->RemoveAurasDueToSpell(auras2remove[i]);
-
- auras2remove.clear();
- AuraMap const& auras = GetAuras();
- for (AuraMap::const_iterator i = auras.begin(); i != auras.end(); ++i)
+ AuraMap &myAuras = GetAuras();
+ for(AuraMap::iterator i = myAuras.begin(); i != myAuras.end();)
{
if (!i->second->IsPositive() && i->second->GetCasterGUID() == duel->opponent->GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime)
- auras2remove.push_back(i->second->GetId());
+ {
+ RemoveAura(i);
+ }
+ else
+ ++i;
}
- for(size_t i=0; i<auras2remove.size(); i++)
- RemoveAurasDueToSpell(auras2remove[i]);
// cleanup combo points
if(GetComboTarget()==duel->opponent->GetGUID())
@@ -6592,7 +6412,12 @@ void Player::_ApplyItemMods(Item *item, uint8 slot,bool apply)
sLog.outDetail("applying mods for item %u ",item->GetGUIDLow());
- uint32 attacktype = Player::GetAttackBySlot(slot);
+ uint8 attacktype = Player::GetAttackBySlot(slot);
+
+ //check disarm only on mod apply to allow remove item mods
+ if (apply && !CanUseAttackType(attacktype) )
+ return;
+
if(attacktype < MAX_ATTACK)
_ApplyWeaponDependentAuraMods(item,WeaponAttackType(attacktype),apply);
@@ -6610,19 +6435,43 @@ void Player::_ApplyItemMods(Item *item, uint8 slot,bool apply)
sLog.outDebug("_ApplyItemMods complete.");
}
-void Player::_ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply)
+void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool apply)
{
if(slot >= INVENTORY_SLOT_BAG_END || !proto)
return;
- for (int i = 0; i < 10; i++)
+ for (int i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
{
- float val = float (proto->ItemStat[i].ItemStatValue);
+ uint32 statType = 0;
+ int32 val = 0;
+
+ if(proto->ScalingStatDistribution)
+ {
+ if(ScalingStatDistributionEntry const *ssd = sScalingStatDistributionStore.LookupEntry(proto->ScalingStatDistribution))
+ {
+ statType = ssd->StatMod[i];
+
+ if(uint32 modifier = ssd->Modifier[i])
+ {
+ uint32 level = ((getLevel() > ssd->MaxLevel) ? ssd->MaxLevel : getLevel());
+ if(ScalingStatValuesEntry const *ssv = sScalingStatValuesStore.LookupEntry(level))
+ {
+ uint32 multiplier = ssv->Multiplier[proto->GetScalingStatValuesColumn()];
+ val = (multiplier * modifier) / 10000;
+ }
+ }
+ }
+ }
+ else
+ {
+ statType = proto->ItemStat[i].ItemStatType;
+ val = proto->ItemStat[i].ItemStatValue;
+ }
- if(val==0)
+ if(val == 0)
continue;
- switch (proto->ItemStat[i].ItemStatType)
+ switch (statType)
{
case ITEM_MOD_MANA:
HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, float(val), apply);
@@ -6740,6 +6589,32 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply)
case ITEM_MOD_EXPERTISE_RATING:
ApplyRatingMod(CR_EXPERTISE, int32(val), apply);
break;
+ case ITEM_MOD_ATTACK_POWER:
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(val), apply);
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(val), apply);
+ break;
+ case ITEM_MOD_RANGED_ATTACK_POWER:
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(val), apply);
+ break;
+ case ITEM_MOD_FERAL_ATTACK_POWER:
+ ApplyFeralAPBonus(int32(val), apply);
+ break;
+ case ITEM_MOD_SPELL_HEALING_DONE:
+ ApplySpellHealingBonus(int32(val), apply);
+ break;
+ case ITEM_MOD_SPELL_DAMAGE_DONE:
+ ApplySpellDamageBonus(int32(val), apply);
+ break;
+ case ITEM_MOD_MANA_REGENERATION:
+ ApplyManaRegenBonus(int32(val), apply);
+ break;
+ case ITEM_MOD_ARMOR_PENETRATION_RATING:
+ ApplyRatingMod(CR_ARMOR_PENETRATION, int32(val), apply);
+ break;
+ case ITEM_MOD_SPELL_POWER:
+ ApplySpellHealingBonus(int32(val), apply);
+ ApplySpellDamageBonus(int32(val), apply);
+ break;
}
}
@@ -6794,7 +6669,15 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply)
SetBaseWeaponDamage(attType, MAXDAMAGE, damage);
}
- if(!IsUseEquipedWeapon(slot==EQUIPMENT_SLOT_MAINHAND))
+ // Druids get feral AP bonus from weapon dps
+ if(getClass() == CLASS_DRUID)
+ {
+ int32 feral_bonus = proto->getFeralBonus();
+ if (feral_bonus > 0)
+ ApplyFeralAPBonus(feral_bonus, apply);
+ }
+
+ if(IsInFeralForm() || !CanUseAttackType(attType))
return;
if (proto->Delay)
@@ -6813,20 +6696,20 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply)
void Player::_ApplyWeaponDependentAuraMods(Item *item,WeaponAttackType attackType,bool apply)
{
- AuraList const& auraCritList = GetAurasByType(SPELL_AURA_MOD_CRIT_PERCENT);
- for(AuraList::const_iterator itr = auraCritList.begin(); itr!=auraCritList.end();++itr)
+ AuraEffectList const& auraCritList = GetAurasByType(SPELL_AURA_MOD_CRIT_PERCENT);
+ for(AuraEffectList::const_iterator itr = auraCritList.begin(); itr!=auraCritList.end();++itr)
_ApplyWeaponDependentAuraCritMod(item,attackType,*itr,apply);
- AuraList const& auraDamageFlatList = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE);
- for(AuraList::const_iterator itr = auraDamageFlatList.begin(); itr!=auraDamageFlatList.end();++itr)
+ AuraEffectList const& auraDamageFlatList = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE);
+ for(AuraEffectList::const_iterator itr = auraDamageFlatList.begin(); itr!=auraDamageFlatList.end();++itr)
_ApplyWeaponDependentAuraDamageMod(item,attackType,*itr,apply);
- AuraList const& auraDamagePCTList = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
- for(AuraList::const_iterator itr = auraDamagePCTList.begin(); itr!=auraDamagePCTList.end();++itr)
+ AuraEffectList const& auraDamagePCTList = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ for(AuraEffectList::const_iterator itr = auraDamagePCTList.begin(); itr!=auraDamagePCTList.end();++itr)
_ApplyWeaponDependentAuraDamageMod(item,attackType,*itr,apply);
}
-void Player::_ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attackType, Aura* aura, bool apply)
+void Player::_ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attackType, AuraEffect* aura, bool apply)
{
// generic not weapon specific case processes in aura code
if(aura->GetSpellProto()->EquippedItemClass == -1)
@@ -6843,15 +6726,14 @@ void Player::_ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attac
if (item->IsFitToSpellRequirements(aura->GetSpellProto()))
{
- HandleBaseModValue(mod, FLAT_MOD, float (aura->GetModifierValue()), apply);
+ HandleBaseModValue(mod, FLAT_MOD, float (aura->GetAmount()), apply);
}
}
-void Player::_ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType attackType, Aura* aura, bool apply)
+void Player::_ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType attackType, AuraEffect* aura, bool apply)
{
// ignore spell mods for not wands
- Modifier const* modifier = aura->GetModifier();
- if((modifier->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL)==0 && (getClassMask() & CLASSMASK_WAND_USERS)==0)
+ if((aura->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)==0 && (getClassMask() & CLASSMASK_WAND_USERS)==0)
return;
// generic not weapon specific case processes in aura code
@@ -6868,7 +6750,7 @@ void Player::_ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType att
}
UnitModifierType unitModType = TOTAL_VALUE;
- switch(modifier->m_auraname)
+ switch(aura->GetAuraName())
{
case SPELL_AURA_MOD_DAMAGE_DONE: unitModType = TOTAL_VALUE; break;
case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE: unitModType = TOTAL_PCT; break;
@@ -6877,7 +6759,7 @@ void Player::_ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType att
if (item->IsFitToSpellRequirements(aura->GetSpellProto()))
{
- HandleStatModifier(unitMod, unitModType, float(aura->GetModifierValue()),apply);
+ HandleStatModifier(unitMod, unitModType, float(aura->GetAmount()),apply);
}
}
@@ -6890,7 +6772,7 @@ void Player::ApplyItemEquipSpell(Item *item, bool apply, bool form_change)
if(!proto)
return;
- for (int i = 0; i < 5; i++)
+ for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
_Spell const& spellData = proto->Spells[i];
@@ -6916,29 +6798,15 @@ void Player::ApplyEquipSpell(SpellEntry const* spellInfo, Item* item, bool apply
if(apply)
{
// Cannot be used in this stance/form
- if(GetErrorAtShapeshiftedCast(spellInfo, m_form)!=0)
+ if(GetErrorAtShapeshiftedCast(spellInfo, m_form) != SPELL_CAST_OK)
return;
if(form_change) // check aura active state from other form
{
- bool found = false;
- for (int k=0; k < 3; ++k)
- {
- spellEffectPair spair = spellEffectPair(spellInfo->Id, k);
- for (AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair); ++iter)
- {
- if(!item || iter->second->GetCastItemGUID() == item->GetGUID())
- {
- found = true;
- break;
- }
- }
- if(found)
- break;
- }
-
- if(found) // and skip re-cast already active aura at form change
- return;
+ AuraMap const& auras = GetAuras();
+ for(AuraMap::const_iterator itr = auras.lower_bound(spellInfo->Id); itr != auras.upper_bound(spellInfo->Id); ++itr)
+ if(!item || itr->second->GetCastItemGUID()==item->GetGUID())
+ return;
}
DEBUG_LOG("WORLD: cast %s Equip spellId - %i", (item ? "item" : "itemset"), spellInfo->Id);
@@ -6950,7 +6818,7 @@ void Player::ApplyEquipSpell(SpellEntry const* spellInfo, Item* item, bool apply
if(form_change) // check aura compatibility
{
// Cannot be used in this stance/form
- if(GetErrorAtShapeshiftedCast(spellInfo, m_form)==0)
+ if(GetErrorAtShapeshiftedCast(spellInfo, m_form)==SPELL_CAST_OK)
return; // and remove only not compatible at form change
}
@@ -7003,7 +6871,7 @@ void Player::CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attTy
if (!Target || Target == this )
return;
- for (int i = 0; i < 5; i++)
+ for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
_Spell const& spellData = proto->Spells[i];
@@ -7031,7 +6899,7 @@ void Player::CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attTy
if(spellData.SpellPPMRate)
{
uint32 WeaponSpeed = GetAttackTime(attType);
- chance = GetPPMProcChance(WeaponSpeed, spellData.SpellPPMRate);
+ chance = GetPPMProcChance(WeaponSpeed, spellData.SpellPPMRate, spellInfo);
}
else if(chance > 100.0f)
{
@@ -7072,6 +6940,92 @@ void Player::CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attTy
}
}
+void Player::CastItemUseSpell(Item *item,SpellCastTargets const& targets,uint8 cast_count, uint32 glyphIndex)
+{
+ ItemPrototype const* proto = item->GetProto();
+ // special learning case
+ if(proto->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN || proto->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN_PET)
+ {
+ uint32 learn_spell_id = proto->Spells[0].SpellId;
+ uint32 learning_spell_id = proto->Spells[1].SpellId;
+
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(learn_spell_id);
+ if(!spellInfo)
+ {
+ sLog.outError("Player::CastItemUseSpell: Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, learn_spell_id);
+ SendEquipError(EQUIP_ERR_NONE,item,NULL);
+ return;
+ }
+
+ Spell *spell = new Spell(this, spellInfo, false);
+ spell->m_CastItem = item;
+ spell->m_cast_count = cast_count; //set count of casts
+ spell->m_currentBasePoints[0] = learning_spell_id;
+ spell->prepare(&targets);
+ return;
+ }
+
+ // use triggered flag only for items with many spell casts and for not first cast
+ int count = 0;
+
+ // item spells casted at use
+ for(int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
+ {
+ _Spell const& spellData = proto->Spells[i];
+
+ // no spell
+ if(!spellData.SpellId)
+ continue;
+
+ // wrong triggering type
+ if( spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_USE && spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_NO_DELAY_USE)
+ continue;
+
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellData.SpellId);
+ if(!spellInfo)
+ {
+ sLog.outError("Player::CastItemUseSpell: Item (Entry: %u) in have wrong spell id %u, ignoring",proto->ItemId, spellData.SpellId);
+ continue;
+ }
+
+ Spell *spell = new Spell(this, spellInfo, (count > 0));
+ spell->m_CastItem = item;
+ spell->m_cast_count = cast_count; // set count of casts
+ spell->m_glyphIndex = glyphIndex; // glyph index
+ spell->prepare(&targets);
+
+ ++count;
+ }
+
+ // Item enchantments spells casted at use
+ for(int e_slot = 0; e_slot < MAX_ENCHANTMENT_SLOT; ++e_slot)
+ {
+ uint32 enchant_id = item->GetEnchantmentId(EnchantmentSlot(e_slot));
+ SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
+ if(!pEnchant) continue;
+ for (int s=0;s<3;s++)
+ {
+ if(pEnchant->type[s]!=ITEM_ENCHANTMENT_TYPE_USE_SPELL)
+ continue;
+
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(pEnchant->spellid[s]);
+ if (!spellInfo)
+ {
+ sLog.outError("Player::CastItemUseSpell Enchant %i, cast unknown spell %i", pEnchant->ID, pEnchant->spellid[s]);
+ continue;
+ }
+
+ Spell *spell = new Spell(this, spellInfo, (count > 0));
+ spell->m_CastItem = item;
+ spell->m_cast_count = cast_count; // set count of casts
+ spell->m_glyphIndex = glyphIndex; // glyph index
+ spell->prepare(&targets);
+
+ ++count;
+ }
+ }
+}
+
void Player::_RemoveAllItemMods()
{
sLog.outDebug("_RemoveAllItemMods start.");
@@ -7247,7 +7201,7 @@ void Player::RemovedInsignia(Player* looterPlr)
// We have to convert player corpse to bones, not to be able to resurrect there
// SpawnCorpseBones isn't handy, 'cos it saves player while he in BG
- Corpse *bones = ObjectAccessor::Instance().ConvertCorpseForPlayer(GetGUID());
+ Corpse *bones = ObjectAccessor::Instance().ConvertCorpseForPlayer(GetGUID(),true);
if (!bones)
return;
@@ -7261,12 +7215,6 @@ void Player::RemovedInsignia(Player* looterPlr)
looterPlr->SendLoot(bones->GetGUID(), LOOT_INSIGNIA);
}
-/*Loot type MUST be
-1-corpse, go
-2-skinning
-3-Fishing
-*/
-
void Player::SendLootRelease( uint64 guid )
{
WorldPacket data( SMSG_LOOT_RELEASE_RESPONSE, (8+1) );
@@ -7276,6 +7224,9 @@ void Player::SendLootRelease( uint64 guid )
void Player::SendLoot(uint64 guid, LootType loot_type)
{
+ if (uint64 lguid = GetLootGUID())
+ m_session->DoLootRelease(lguid);
+
Loot *loot = 0;
PermissionTypes permission = ALL_PERMISSION;
@@ -7283,8 +7234,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
if (IS_GAMEOBJECT_GUID(guid))
{
sLog.outDebug(" IS_GAMEOBJECT_GUID(guid)");
- GameObject *go =
- ObjectAccessor::GetGameObject(*this, guid);
+ GameObject *go = GetMap()->GetGameObject(guid);
// not check distance for GO in case owned GO (fishing bobber case, for example)
// And permit out of range GO with no owner in case fishing hole
@@ -7296,7 +7246,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
loot = &go->loot;
- if(go->getLootState() == GO_READY)
+ if (go->getLootState() == GO_READY)
{
uint32 lootid = go->GetLootId();
@@ -7310,15 +7260,15 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
return;
}
- if(lootid)
+ if (lootid)
{
sLog.outDebug(" if(lootid)");
loot->clear();
- loot->FillLoot(lootid, LootTemplates_Gameobject, this);
+ loot->FillLoot(lootid, LootTemplates_Gameobject, this, false);
}
- if(loot_type == LOOT_FISHING)
- go->getFishLoot(loot);
+ if (loot_type == LOOT_FISHING)
+ go->getFishLoot(loot,this);
go->SetLootState(GO_ACTIVATED);
}
@@ -7333,39 +7283,28 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
return;
}
- if(loot_type == LOOT_DISENCHANTING)
- {
- loot = &item->loot;
-
- if(!item->m_lootGenerated)
- {
- item->m_lootGenerated = true;
- loot->clear();
- loot->FillLoot(item->GetProto()->DisenchantID, LootTemplates_Disenchant, this);
- }
- }
- else if(loot_type == LOOT_PROSPECTING)
- {
- loot = &item->loot;
+ loot = &item->loot;
- if(!item->m_lootGenerated)
- {
- item->m_lootGenerated = true;
- loot->clear();
- loot->FillLoot(item->GetEntry(), LootTemplates_Prospecting, this);
- }
- }
- else
+ if (!item->m_lootGenerated)
{
- loot = &item->loot;
+ item->m_lootGenerated = true;
+ loot->clear();
- if(!item->m_lootGenerated)
+ switch(loot_type)
{
- item->m_lootGenerated = true;
- loot->clear();
- loot->FillLoot(item->GetEntry(), LootTemplates_Item, this);
-
- loot->generateMoneyLoot(item->GetProto()->MinMoneyLoot,item->GetProto()->MaxMoneyLoot);
+ case LOOT_DISENCHANTING:
+ loot->FillLoot(item->GetProto()->DisenchantID, LootTemplates_Disenchant, this,true);
+ break;
+ case LOOT_PROSPECTING:
+ loot->FillLoot(item->GetEntry(), LootTemplates_Prospecting, this,true);
+ break;
+ case LOOT_MILLING:
+ loot->FillLoot(item->GetEntry(), LootTemplates_Milling, this,true);
+ break;
+ default:
+ loot->FillLoot(item->GetEntry(), LootTemplates_Item, this,true);
+ loot->generateMoneyLoot(item->GetProto()->MinMoneyLoot,item->GetProto()->MaxMoneyLoot);
+ break;
}
}
}
@@ -7387,7 +7326,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
uint32 pLevel = bones->loot.gold;
bones->loot.clear();
if(GetBattleGround()->GetTypeID() == BATTLEGROUND_AV)
- loot->FillLoot(1, LootTemplates_Creature, this);
+ loot->FillLoot(1, LootTemplates_Creature, this, true);
// It may need a better formula
// Now it works like this: lvl10: ~6copper, lvl70: ~9silver
bones->loot.gold = (uint32)( urand(50, 150) * 0.016f * pow( ((float)pLevel)/5.76f, 2.5f) * sWorld.getRate(RATE_DROP_MONEY) );
@@ -7398,7 +7337,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
}
else
{
- Creature *creature = ObjectAccessor::GetCreature(*this, guid);
+ Creature *creature = GetMap()->GetCreature(guid);
// must be in range and creature must be alive for pickpocket and must be dead for another loot
if (!creature || creature->isAlive()!=(loot_type == LOOT_PICKPOCKETING) || !creature->IsWithinDistInMap(this,INTERACTION_DISTANCE))
@@ -7407,7 +7346,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
return;
}
- if(loot_type == LOOT_PICKPOCKETING && IsFriendlyTo(creature))
+ if (loot_type == LOOT_PICKPOCKETING && IsFriendlyTo(creature))
{
SendLootRelease(guid);
return;
@@ -7415,15 +7354,15 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
loot = &creature->loot;
- if(loot_type == LOOT_PICKPOCKETING)
+ if (loot_type == LOOT_PICKPOCKETING)
{
- if ( !creature->lootForPickPocketed )
+ if (!creature->lootForPickPocketed)
{
creature->lootForPickPocketed = true;
loot->clear();
if (uint32 lootid = creature->GetCreatureInfo()->pickpocketLootId)
- loot->FillLoot(lootid, LootTemplates_Pickpocketing, this);
+ loot->FillLoot(lootid, LootTemplates_Pickpocketing, this, false);
// Generate extra money for pick pocket loot
const uint32 a = urand(0, creature->getLevel()/2);
@@ -7447,17 +7386,17 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
loot->clear();
}
- if(!creature->lootForBody)
+ if (!creature->lootForBody)
{
creature->lootForBody = true;
loot->clear();
if (uint32 lootid = creature->GetCreatureInfo()->lootid)
- loot->FillLoot(lootid, LootTemplates_Creature, recipient);
+ loot->FillLoot(lootid, LootTemplates_Creature, recipient, false);
loot->generateMoneyLoot(creature->GetCreatureInfo()->mingold,creature->GetCreatureInfo()->maxgold);
- if(Group* group = recipient->GetGroup())
+ if (Group* group = recipient->GetGroup())
{
group->UpdateLooterGuid(creature,true);
@@ -7483,20 +7422,20 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
if (loot_type == LOOT_SKINNING)
{
loot->clear();
- loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, this);
+ loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, this, false);
}
// set group rights only for loot_type != LOOT_SKINNING
else
{
if(Group* group = GetGroup())
{
- if( group == recipient->GetGroup() )
+ if (group == recipient->GetGroup())
{
- if(group->GetLootMethod() == FREE_FOR_ALL)
+ if (group->GetLootMethod() == FREE_FOR_ALL)
permission = ALL_PERMISSION;
- else if(group->GetLooterGuid() == GetGUID())
+ else if (group->GetLooterGuid() == GetGUID())
{
- if(group->GetLootMethod() == MASTER_LOOT)
+ if (group->GetLootMethod() == MASTER_LOOT)
permission = MASTER_PERMISSION;
else
permission = ALL_PERMISSION;
@@ -7507,7 +7446,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
else
permission = NONE_PERMISSION;
}
- else if(recipient == this)
+ else if (recipient == this)
permission = ALL_PERMISSION;
else
permission = NONE_PERMISSION;
@@ -7517,51 +7456,22 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
SetLootGUID(guid);
- QuestItemList *q_list = 0;
- if (permission != NONE_PERMISSION)
- {
- QuestItemMap const& lootPlayerQuestItems = loot->GetPlayerQuestItems();
- QuestItemMap::const_iterator itr = lootPlayerQuestItems.find(GetGUIDLow());
- if (itr == lootPlayerQuestItems.end())
- q_list = loot->FillQuestLoot(this);
- else
- q_list = itr->second;
- }
-
- QuestItemList *ffa_list = 0;
- if (permission != NONE_PERMISSION)
- {
- QuestItemMap const& lootPlayerFFAItems = loot->GetPlayerFFAItems();
- QuestItemMap::const_iterator itr = lootPlayerFFAItems.find(GetGUIDLow());
- if (itr == lootPlayerFFAItems.end())
- ffa_list = loot->FillFFALoot(this);
- else
- ffa_list = itr->second;
- }
-
- QuestItemList *conditional_list = 0;
- if (permission != NONE_PERMISSION)
+ // LOOT_INSIGNIA and LOOT_FISHINGHOLE unsupported by client
+ switch(loot_type)
{
- QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = loot->GetPlayerNonQuestNonFFAConditionalItems();
- QuestItemMap::const_iterator itr = lootPlayerNonQuestNonFFAConditionalItems.find(GetGUIDLow());
- if (itr == lootPlayerNonQuestNonFFAConditionalItems.end())
- conditional_list = loot->FillNonQuestNonFFAConditionalLoot(this);
- else
- conditional_list = itr->second;
+ case LOOT_INSIGNIA: loot_type = LOOT_SKINNING; break;
+ case LOOT_FISHINGHOLE: loot_type = LOOT_FISHING; break;
+ default: break;
}
- // LOOT_PICKPOCKETING, LOOT_PROSPECTING, LOOT_DISENCHANTING and LOOT_INSIGNIA unsupported by client, sending LOOT_SKINNING instead
- if(loot_type == LOOT_PICKPOCKETING || loot_type == LOOT_DISENCHANTING || loot_type == LOOT_PROSPECTING || loot_type == LOOT_INSIGNIA)
- loot_type = LOOT_SKINNING;
-
- if(loot_type == LOOT_FISHINGHOLE)
- loot_type = LOOT_FISHING;
+ // need know merged fishing/corpse loot type for achievements
+ loot->loot_type = loot_type;
WorldPacket data(SMSG_LOOT_RESPONSE, (9+50)); // we guess size
data << uint64(guid);
data << uint8(loot_type);
- data << LootView(*loot, q_list, ffa_list, conditional_list, this, permission);
+ data << LootView(*loot, this, permission);
SendDirectMessage(&data);
@@ -7569,7 +7479,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
if (permission != NONE_PERMISSION)
loot->AddLooter(GetGUID());
- if ( loot_type == LOOT_CORPSE && !IS_ITEM_GUID(guid) )
+ if (loot_type == LOOT_CORPSE && !IS_ITEM_GUID(guid))
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_LOOTING);
}
@@ -7594,20 +7504,16 @@ void Player::SendUpdateWorldState(uint32 Field, uint32 Value)
GetSession()->SendPacket(&data);
}
-void Player::SendInitWorldStates(bool forceZone, uint32 forceZoneId)
+void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
{
// data depends on zoneid/mapid...
BattleGround* bg = GetBattleGround();
uint16 NumberOfFields = 0;
uint32 mapid = GetMapId();
- uint32 zoneid;
- if(forceZone)
- zoneid = forceZoneId;
- else
- zoneid = GetZoneId();
OutdoorPvP * pvp = sOutdoorPvPMgr.GetOutdoorPvPToZoneId(zoneid);
- uint32 areaid = GetAreaId();
+
sLog.outDebug("Sending SMSG_INIT_WORLD_STATES to Map:%u, Zone: %u", mapid, zoneid);
+
// may be exist better way to do this...
switch(zoneid)
{
@@ -7628,46 +7534,46 @@ void Player::SendInitWorldStates(bool forceZone, uint32 forceZoneId)
case 1537:
case 2257:
case 2918:
- NumberOfFields = 6;
+ NumberOfFields = 8;
break;
case 139:
- NumberOfFields = 39;
+ NumberOfFields = 41;
break;
case 1377:
- NumberOfFields = 13;
+ NumberOfFields = 15;
break;
case 2597:
- NumberOfFields = 81;
+ NumberOfFields = 83;
break;
case 3277:
- NumberOfFields = 14;
+ NumberOfFields = 16;
break;
case 3358:
case 3820:
- NumberOfFields = 38;
+ NumberOfFields = 40;
break;
case 3483:
- NumberOfFields = 25;
+ NumberOfFields = 27;
break;
case 3518:
- NumberOfFields = 37;
+ NumberOfFields = 39;
break;
case 3519:
- NumberOfFields = 36;
+ NumberOfFields = 38;
break;
case 3521:
- NumberOfFields = 35;
+ NumberOfFields = 37;
break;
case 3698:
case 3702:
case 3968:
- NumberOfFields = 9;
+ NumberOfFields = 11;
break;
case 3703:
- NumberOfFields = 9;
+ NumberOfFields = 11;
break;
default:
- NumberOfFields = 10;
+ NumberOfFields = 12;
break;
}
@@ -7682,6 +7588,10 @@ void Player::SendInitWorldStates(bool forceZone, uint32 forceZoneId)
data << uint32(0x8d5) << uint32(0x0); // 4
data << uint32(0x8d4) << uint32(0x0); // 5
data << uint32(0x8d3) << uint32(0x0); // 6
+ // 7 1 - Arena season in progress, 0 - end of season
+ data << uint32(0xC77) << uint32(sWorld.getConfig(CONFIG_ARENA_SEASON_IN_PROGRESS));
+ // 8 Arena season id
+ data << uint32(0xF3D) << uint32(sWorld.getConfig(CONFIG_ARENA_SEASON_ID));
if(mapid == 530) // Outland
{
data << uint32(0x9bf) << uint32(0x0); // 7
@@ -8275,7 +8185,8 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap
// (this will be replace mainhand weapon at auto equip instead unwonted "you don't known dual wielding" ...
if(CanDualWield())
slots[1] = EQUIPMENT_SLOT_OFFHAND;
- };break;
+ break;
+ };
case INVTYPE_SHIELD:
slots[0] = EQUIPMENT_SLOT_OFFHAND;
break;
@@ -8284,6 +8195,8 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap
break;
case INVTYPE_2HWEAPON:
slots[0] = EQUIPMENT_SLOT_MAINHAND;
+ if (CanDualWield() && CanTitanGrip())
+ slots[1] = EQUIPMENT_SLOT_OFFHAND;
break;
case INVTYPE_TABARD:
slots[0] = EQUIPMENT_SLOT_TABARD;
@@ -8304,10 +8217,10 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap
slots[0] = EQUIPMENT_SLOT_RANGED;
break;
case INVTYPE_BAG:
- slots[0] = INVENTORY_SLOT_BAG_1;
- slots[1] = INVENTORY_SLOT_BAG_2;
- slots[2] = INVENTORY_SLOT_BAG_3;
- slots[3] = INVENTORY_SLOT_BAG_4;
+ slots[0] = INVENTORY_SLOT_BAG_START + 0;
+ slots[1] = INVENTORY_SLOT_BAG_START + 1;
+ slots[2] = INVENTORY_SLOT_BAG_START + 2;
+ slots[3] = INVENTORY_SLOT_BAG_START + 3;
break;
case INVTYPE_RELIC:
{
@@ -8329,6 +8242,10 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap
if (pClass == CLASS_WARLOCK)
slots[0] = EQUIPMENT_SLOT_RANGED;
break;
+ case ITEM_SUBCLASS_ARMOR_SIGIL:
+ if (pClass == CLASS_DEATH_KNIGHT)
+ slots[0] = EQUIPMENT_SLOT_RANGED;
+ break;
}
break;
}
@@ -8354,14 +8271,8 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap
{
if ( slots[i] != NULL_SLOT && !GetItemByPos( INVENTORY_SLOT_BAG_0, slots[i] ) )
{
- // in case 2hand equipped weapon offhand slot empty but not free
- if(slots[i]==EQUIPMENT_SLOT_OFFHAND)
- {
- Item* mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND );
- if(!mainItem || mainItem->GetProto()->InventoryType != INVTYPE_2HWEAPON)
- return slots[i];
- }
- else
+ // in case 2hand equipped weapon (without titan grip) offhand slot empty but not free
+ if(slots[i]!=EQUIPMENT_SLOT_OFFHAND || !IsTwoHandUsed())
return slots[i];
}
}
@@ -8411,7 +8322,7 @@ uint8 Player::CanUnequipItems( uint32 item, uint32 count ) const
return EQUIP_ERR_OK;
}
}
- for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
+ for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
{
pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
if( pItem && pItem->GetEntry() == item )
@@ -8453,7 +8364,7 @@ uint32 Player::GetItemCount( uint32 item, bool inBankAlso, Item* skipItem ) cons
if( pItem && pItem != skipItem && pItem->GetEntry() == item )
count += pItem->GetCount();
}
- for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
+ for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
{
Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
if( pItem && pItem != skipItem && pItem->GetEntry() == item )
@@ -8513,7 +8424,7 @@ Item* Player::GetItemByGuid( uint64 guid ) const
if( pItem && pItem->GetGUID() == guid )
return pItem;
}
- for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
+ for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
{
Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
if( pItem && pItem->GetGUID() == guid )
@@ -8559,7 +8470,7 @@ Item* Player::GetItemByPos( uint16 pos ) const
Item* Player::GetItemByPos( uint8 bag, uint8 slot ) const
{
- if( bag == INVENTORY_SLOT_BAG_0 && ( slot < BANK_SLOT_BAG_END || slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_END ) )
+ if( bag == INVENTORY_SLOT_BAG_0 && ( slot < BANK_SLOT_BAG_END || slot >= KEYRING_SLOT_START && slot < QUESTBAG_SLOT_END ) )
return m_items[slot];
else if(bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END
|| bag >= BANK_SLOT_BAG_START && bag < BANK_SLOT_BAG_END )
@@ -8582,14 +8493,14 @@ Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool useable) cons
default: return NULL;
}
- Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, slot);
+ Item* item = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, slot);
if (!item || item->GetProto()->Class != ITEM_CLASS_WEAPON)
return NULL;
if(!useable)
return item;
- if( item->IsBroken() || !IsUseEquipedWeapon(attackType==BASE_ATTACK) )
+ if( item->IsBroken() || IsInFeralForm())
return NULL;
return item;
@@ -8597,7 +8508,7 @@ Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool useable) cons
Item* Player::GetShield(bool useable) const
{
- Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ Item* item = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
if (!item || item->GetProto()->Class != ITEM_CLASS_ARMOR)
return NULL;
@@ -8610,7 +8521,7 @@ Item* Player::GetShield(bool useable) const
return item;
}
-uint32 Player::GetAttackBySlot( uint8 slot )
+uint8 Player::GetAttackBySlot( uint8 slot )
{
switch(slot)
{
@@ -8637,7 +8548,7 @@ bool Player::IsInventoryPos( uint8 bag, uint8 slot )
return true;
if( bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END )
return true;
- if( bag == INVENTORY_SLOT_BAG_0 && ( slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_END ) )
+ if( bag == INVENTORY_SLOT_BAG_0 && ( slot >= KEYRING_SLOT_START && slot < QUESTBAG_SLOT_END ) )
return true;
return false;
}
@@ -8758,7 +8669,7 @@ bool Player::HasItemCount( uint32 item, uint32 count, bool inBankAlso ) const
return true;
}
}
- for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
+ for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
{
Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
if( pItem && pItem->GetEntry() == item )
@@ -8818,31 +8729,76 @@ bool Player::HasItemCount( uint32 item, uint32 count, bool inBankAlso ) const
return false;
}
-Item* Player::GetItemOrItemWithGemEquipped( uint32 item ) const
+bool Player::HasItemOrGemWithIdEquipped( uint32 item, uint32 count, uint8 except_slot ) const
{
- Item *pItem;
- for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++)
+ uint32 tempcount = 0;
+ for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
{
- pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
- if( pItem && pItem->GetEntry() == item )
- return pItem;
+ if(i==int(except_slot))
+ continue;
+
+ Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+ if( pItem && pItem->GetEntry() == item)
+ {
+ tempcount += pItem->GetCount();
+ if( tempcount >= count )
+ return true;
+ }
}
ItemPrototype const *pProto = objmgr.GetItemPrototype(item);
if (pProto && pProto->GemProperties)
{
- for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++)
+ for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
{
- pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
- if( pItem && pItem->GetProto()->Socket[0].Color )
+ if(i==int(except_slot))
+ continue;
+
+ Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+ if( pItem && pItem->GetProto()->Socket[0].Color)
{
- if (pItem->GetGemCountWithID(item) > 0 )
- return pItem;
+ tempcount += pItem->GetGemCountWithID(item);
+ if( tempcount >= count )
+ return true;
}
}
}
- return NULL;
+ return false;
+}
+
+bool Player::HasItemOrGemWithLimitCategoryEquipped( uint32 limitCategory, uint32 count, uint8 except_slot ) const
+{
+ uint32 tempcount = 0;
+ for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
+ {
+ if(i==int(except_slot))
+ continue;
+
+ Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+ if (!pItem)
+ continue;
+
+ ItemPrototype const *pProto = pItem->GetProto();
+ if (!pProto)
+ continue;
+
+ if (pProto->ItemLimitCategory == limitCategory)
+ {
+ tempcount += pItem->GetCount();
+ if( tempcount >= count )
+ return true;
+ }
+
+ if( pProto->Socket[0].Color)
+ {
+ tempcount += pItem->GetGemCountWithLimitCategory(limitCategory);
+ if( tempcount >= count )
+ return true;
+ }
+ }
+
+ return false;
}
uint8 Player::_CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count ) const
@@ -8856,12 +8812,12 @@ uint8 Player::_CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem,
}
// no maximum
- if(pProto->MaxCount == 0)
+ if(pProto->MaxCount <= 0)
return EQUIP_ERR_OK;
uint32 curcount = GetItemCount(pProto->ItemId,true,pItem);
- if( curcount + count > pProto->MaxCount )
+ if (curcount + count > uint32(pProto->MaxCount))
{
if(no_space_count)
*no_space_count = count +curcount - pProto->MaxCount;
@@ -8876,13 +8832,13 @@ bool Player::HasItemTotemCategory( uint32 TotemCategory ) const
Item *pItem;
for(uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i)
{
- pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+ pItem = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, i );
if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory ))
return true;
}
- for(uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; ++i)
+ for(uint8 i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; ++i)
{
- pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+ pItem = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, i );
if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory ))
return true;
}
@@ -8892,7 +8848,7 @@ bool Player::HasItemTotemCategory( uint32 TotemCategory ) const
{
for(uint32 j = 0; j < pBag->GetBagSize(); ++j)
{
- pItem = GetItemByPos( i, j );
+ pItem = GetUseableItemByPos( i, j );
if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory ))
return true;
}
@@ -8920,6 +8876,18 @@ uint8 Player::_CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountV
if(slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_START+GetMaxKeyringSize() && !(pProto->BagFamily & BAG_FAMILY_MASK_KEYS))
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+ // vanitypet case (not use, vanity pets stored as spells)
+ if(slot >= VANITYPET_SLOT_START && slot < VANITYPET_SLOT_END)
+ return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+
+ // currencytoken case (disabled until proper implement)
+ if(slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END && !(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS))
+ return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+
+ // guestbag case (not use)
+ if(slot >= QUESTBAG_SLOT_START && slot < QUESTBAG_SLOT_END)
+ return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+
// prevent cheating
if(slot >= BUYBACK_SLOT_START && slot < BUYBACK_SLOT_END || slot >= PLAYER_SLOT_END)
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
@@ -8939,7 +8907,7 @@ uint8 Player::_CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountV
}
// non empty stack with space
- need_space = pProto->Stackable;
+ need_space = pProto->GetMaxStackSize();
}
// non empty slot, check item type
else
@@ -8949,10 +8917,11 @@ uint8 Player::_CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountV
return EQUIP_ERR_ITEM_CANT_STACK;
// check free space
- if(pItem2->GetCount() >= pProto->Stackable)
+ if(pItem2->GetCount() >= pProto->GetMaxStackSize())
return EQUIP_ERR_ITEM_CANT_STACK;
- need_space = pProto->Stackable - pItem2->GetCount();
+ // free stack space or infinity
+ need_space = pProto->GetMaxStackSize() - pItem2->GetCount();
}
if(need_space > count)
@@ -9006,9 +8975,9 @@ uint8 Player::_CanStoreItem_InBag( uint8 bag, ItemPosCountVec &dest, ItemPrototy
if( pItem2 )
{
- if(pItem2->GetEntry() == pProto->ItemId && pItem2->GetCount() < pProto->Stackable )
+ if(pItem2->GetEntry() == pProto->ItemId && pItem2->GetCount() < pProto->GetMaxStackSize())
{
- uint32 need_space = pProto->Stackable - pItem2->GetCount();
+ uint32 need_space = pProto->GetMaxStackSize() - pItem2->GetCount();
if(need_space > count)
need_space = count;
@@ -9025,7 +8994,7 @@ uint8 Player::_CanStoreItem_InBag( uint8 bag, ItemPosCountVec &dest, ItemPrototy
}
else
{
- uint32 need_space = pProto->Stackable;
+ uint32 need_space = pProto->GetMaxStackSize();
if(need_space > count)
need_space = count;
@@ -9063,9 +9032,9 @@ uint8 Player::_CanStoreItem_InInventorySlots( uint8 slot_begin, uint8 slot_end,
if( pItem2 )
{
- if(pItem2->GetEntry() == pProto->ItemId && pItem2->GetCount() < pProto->Stackable )
+ if(pItem2->GetEntry() == pProto->ItemId && pItem2->GetCount() < pProto->GetMaxStackSize())
{
- uint32 need_space = pProto->Stackable - pItem2->GetCount();
+ uint32 need_space = pProto->GetMaxStackSize() - pItem2->GetCount();
if(need_space > count)
need_space = count;
ItemPosCount newPosition = ItemPosCount((INVENTORY_SLOT_BAG_0 << 8) | j, need_space);
@@ -9081,7 +9050,7 @@ uint8 Player::_CanStoreItem_InInventorySlots( uint8 slot_begin, uint8 slot_end,
}
else
{
- uint32 need_space = pProto->Stackable;
+ uint32 need_space = pProto->GetMaxStackSize();
if(need_space > count)
need_space = count;
@@ -9160,11 +9129,11 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
if( bag != NULL_BAG )
{
// search stack in bag for merge to
- if( pProto->Stackable > 1 )
+ if( pProto->Stackable != 1 )
{
if( bag == INVENTORY_SLOT_BAG_0 ) // inventory
{
- res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,KEYRING_SLOT_END,dest,pProto,count,true,pItem,bag,slot);
+ res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,true,pItem,bag,slot);
if(res!=EQUIP_ERR_OK)
{
if(no_space_count)
@@ -9250,6 +9219,44 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
*no_space_count = count + no_similar_count;
return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
}
+
+ res = _CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START,CURRENCYTOKEN_SLOT_END,dest,pProto,count,false,pItem,bag,slot);
+ if(res!=EQUIP_ERR_OK)
+ {
+ if(no_space_count)
+ *no_space_count = count + no_similar_count;
+ return res;
+ }
+
+ if(count==0)
+ {
+ if(no_similar_count==0)
+ return EQUIP_ERR_OK;
+
+ if(no_space_count)
+ *no_space_count = count + no_similar_count;
+ return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
+ }
+ }
+ else if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
+ {
+ res = _CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START,CURRENCYTOKEN_SLOT_END,dest,pProto,count,false,pItem,bag,slot);
+ if(res!=EQUIP_ERR_OK)
+ {
+ if(no_space_count)
+ *no_space_count = count + no_similar_count;
+ return res;
+ }
+
+ if(count==0)
+ {
+ if(no_similar_count==0)
+ return EQUIP_ERR_OK;
+
+ if(no_space_count)
+ *no_space_count = count + no_similar_count;
+ return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
+ }
}
res = _CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START,INVENTORY_SLOT_ITEM_END,dest,pProto,count,false,pItem,bag,slot);
@@ -9298,9 +9305,9 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
// not specific bag or have space for partly store only in specific bag
// search stack for merge to
- if( pProto->Stackable > 1 )
+ if( pProto->Stackable != 1 )
{
- res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,KEYRING_SLOT_END,dest,pProto,count,true,pItem,bag,slot);
+ res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,true,pItem,bag,slot);
if(res!=EQUIP_ERR_OK)
{
if(no_space_count)
@@ -9398,6 +9405,26 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
}
}
+ else if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
+ {
+ res = _CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START,CURRENCYTOKEN_SLOT_END,dest,pProto,count,false,pItem,bag,slot);
+ if(res!=EQUIP_ERR_OK)
+ {
+ if(no_space_count)
+ *no_space_count = count + no_similar_count;
+ return res;
+ }
+
+ if(count==0)
+ {
+ if(no_similar_count==0)
+ return EQUIP_ERR_OK;
+
+ if(no_space_count)
+ *no_space_count = count + no_similar_count;
+ return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
+ }
+ }
for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
{
@@ -9468,10 +9495,12 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
int inv_slot_items[INVENTORY_SLOT_ITEM_END-INVENTORY_SLOT_ITEM_START];
int inv_bags[INVENTORY_SLOT_BAG_END-INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE];
int inv_keys[KEYRING_SLOT_END-KEYRING_SLOT_START];
+ int inv_tokens[CURRENCYTOKEN_SLOT_END-CURRENCYTOKEN_SLOT_START];
memset(inv_slot_items,0,sizeof(int)*(INVENTORY_SLOT_ITEM_END-INVENTORY_SLOT_ITEM_START));
memset(inv_bags,0,sizeof(int)*(INVENTORY_SLOT_BAG_END-INVENTORY_SLOT_BAG_START)*MAX_BAG_SIZE);
memset(inv_keys,0,sizeof(int)*(KEYRING_SLOT_END-KEYRING_SLOT_START));
+ memset(inv_tokens,0,sizeof(int)*(CURRENCYTOKEN_SLOT_END-CURRENCYTOKEN_SLOT_START));
for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
{
@@ -9493,6 +9522,16 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
}
}
+ for(int i = CURRENCYTOKEN_SLOT_START; i < CURRENCYTOKEN_SLOT_END; i++)
+ {
+ pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+
+ if (pItem2 && !pItem2->IsInTrade())
+ {
+ inv_tokens[i-CURRENCYTOKEN_SLOT_START] = pItem2->GetCount();
+ }
+ }
+
for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
{
if(Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
@@ -9536,14 +9575,14 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
return res;
// search stack for merge to
- if( pProto->Stackable > 1 )
+ if( pProto->Stackable != 1 )
{
bool b_found = false;
for(int t = KEYRING_SLOT_START; t < KEYRING_SLOT_END; t++)
{
pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t );
- if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_keys[t-KEYRING_SLOT_START] + pItem->GetCount() <= pProto->Stackable )
+ if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_keys[t-KEYRING_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
{
inv_keys[t-KEYRING_SLOT_START] += pItem->GetCount();
b_found = true;
@@ -9552,10 +9591,22 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
}
if (b_found) continue;
+ for(int t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; t++)
+ {
+ pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t );
+ if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_tokens[t-CURRENCYTOKEN_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
+ {
+ inv_tokens[t-CURRENCYTOKEN_SLOT_START] += pItem->GetCount();
+ b_found = true;
+ break;
+ }
+ }
+ if (b_found) continue;
+
for(int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; t++)
{
pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t );
- if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_slot_items[t-INVENTORY_SLOT_ITEM_START] + pItem->GetCount() <= pProto->Stackable )
+ if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_slot_items[t-INVENTORY_SLOT_ITEM_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
{
inv_slot_items[t-INVENTORY_SLOT_ITEM_START] += pItem->GetCount();
b_found = true;
@@ -9567,12 +9618,12 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
for(int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; t++)
{
pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, t );
- if( pBag )
+ if( pBag && ItemCanGoIntoBag(pItem->GetProto(), pBag->GetProto()))
{
for(uint32 j = 0; j < pBag->GetBagSize(); j++)
{
pItem2 = GetItemByPos( t, j );
- if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_bags[t-INVENTORY_SLOT_BAG_START][j] + pItem->GetCount() <= pProto->Stackable )
+ if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_bags[t-INVENTORY_SLOT_BAG_START][j] + pItem->GetCount() <= pProto->GetMaxStackSize())
{
inv_bags[t-INVENTORY_SLOT_BAG_START][j] += pItem->GetCount();
b_found = true;
@@ -9604,6 +9655,21 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
if (b_found) continue;
+ if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
+ {
+ for(uint32 t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t)
+ {
+ if( inv_tokens[t-CURRENCYTOKEN_SLOT_START] == 0 )
+ {
+ inv_tokens[t-CURRENCYTOKEN_SLOT_START] = 1;
+ b_found = true;
+ break;
+ }
+ }
+ }
+
+ if (b_found) continue;
+
for(int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; t++)
{
pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, t );
@@ -9699,11 +9765,6 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
ItemPrototype const *pProto = pItem->GetProto();
if( pProto )
{
- // May be here should be more stronger checks; STUNNED checked
- // ROOT, CONFUSED, DISTRACTED, FLEEING this needs to be checked.
- if (not_loading && hasUnitState(UNIT_STAT_STUNNED))
- return EQUIP_ERR_YOU_ARE_STUNNED;
-
if(pItem->IsBindedNotWith(GetGUID()))
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
@@ -9712,24 +9773,33 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
if(res != EQUIP_ERR_OK)
return res;
- // do not allow equipping gear except weapons, offhands, projectiles, relics in
- // - combat
- // - in-progress arenas
- if( !pProto->CanChangeEquipStateInCombat() )
+ // check this only in game
+ if(not_loading)
{
- if( isInCombat() )
- return EQUIP_ERR_NOT_IN_COMBAT;
+ // May be here should be more stronger checks; STUNNED checked
+ // ROOT, CONFUSED, DISTRACTED, FLEEING this needs to be checked.
+ if (hasUnitState(UNIT_STAT_STUNNED))
+ return EQUIP_ERR_YOU_ARE_STUNNED;
+
+ // do not allow equipping gear except weapons, offhands, projectiles, relics in
+ // - combat
+ // - in-progress arenas
+ if( !pProto->CanChangeEquipStateInCombat() )
+ {
+ if( isInCombat() )
+ return EQUIP_ERR_NOT_IN_COMBAT;
- if(BattleGround* bg = GetBattleGround())
- if( bg->isArena() && bg->GetStatus() == STATUS_IN_PROGRESS )
- return EQUIP_ERR_NOT_DURING_ARENA_MATCH;
- }
+ if(BattleGround* bg = GetBattleGround())
+ if( bg->isArena() && bg->GetStatus() == STATUS_IN_PROGRESS )
+ return EQUIP_ERR_NOT_DURING_ARENA_MATCH;
+ }
- if(isInCombat()&& pProto->Class == ITEM_CLASS_WEAPON && m_weaponChangeTimer != 0)
- return EQUIP_ERR_CANT_DO_RIGHT_NOW; // maybe exist better err
+ if(isInCombat()&& pProto->Class == ITEM_CLASS_WEAPON && m_weaponChangeTimer != 0)
+ return EQUIP_ERR_CANT_DO_RIGHT_NOW; // maybe exist better err
- if(IsNonMeleeSpellCasted(false))
- return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ if(IsNonMeleeSpellCasted(false))
+ return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ }
uint8 eslot = FindEquipSlot( pProto, slot, swap );
if( eslot == NULL_SLOT )
@@ -9741,33 +9811,9 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
if( !swap && GetItemByPos( INVENTORY_SLOT_BAG_0, eslot ) )
return EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE;
- // check unique-equipped on item
- if (pProto->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED)
- {
- // there is an equip limit on this item
- Item* tItem = GetItemOrItemWithGemEquipped(pProto->ItemId);
- if (tItem && (!swap || tItem->GetSlot() != eslot ) )
- return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
- }
-
- // check unique-equipped on gems
- for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)
- {
- uint32 enchant_id = pItem->GetEnchantmentId(EnchantmentSlot(enchant_slot));
- if(!enchant_id)
- continue;
- SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
- if(!enchantEntry)
- continue;
-
- ItemPrototype const* pGem = objmgr.GetItemPrototype(enchantEntry->GemID);
- if(pGem && (pGem->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED))
- {
- Item* tItem = GetItemOrItemWithGemEquipped(enchantEntry->GemID);
- if(tItem && (!swap || tItem->GetSlot() != eslot ))
- return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
- }
- }
+ // if swap ignore item (equipped also)
+ if(uint8 res2 = CanEquipUniqueItem(pItem, swap ? eslot : NULL_SLOT))
+ return res2;
// check unique-equipped special item classes
if (pProto->Class == ITEM_CLASS_QUIVER)
@@ -9794,33 +9840,42 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
if(eslot == EQUIPMENT_SLOT_OFFHAND)
{
- if( type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND )
+ if (type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND)
{
if(!CanDualWield())
return EQUIP_ERR_CANT_DUAL_WIELD;
}
-
- Item *mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND );
- if(mainItem)
+ else if (type == INVTYPE_2HWEAPON)
{
- if(mainItem->GetProto()->InventoryType == INVTYPE_2HWEAPON)
- return EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED;
+ if(!CanDualWield() || !CanTitanGrip())
+ return EQUIP_ERR_CANT_DUAL_WIELD;
}
+
+ if(IsTwoHandUsed())
+ return EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED;
}
// equip two-hand weapon case (with possible unequip 2 items)
if( type == INVTYPE_2HWEAPON )
{
- if(eslot != EQUIPMENT_SLOT_MAINHAND)
+ if (eslot == EQUIPMENT_SLOT_OFFHAND)
+ {
+ if (!CanTitanGrip())
+ return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;
+ }
+ else if (eslot != EQUIPMENT_SLOT_MAINHAND)
return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;
- // offhand item must can be stored in inventory for offhand item and it also must be unequipped
- Item *offItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND );
- ItemPosCountVec off_dest;
- if( offItem && (!not_loading ||
- CanUnequipItem(uint16(INVENTORY_SLOT_BAG_0) << 8 | EQUIPMENT_SLOT_OFFHAND,false) != EQUIP_ERR_OK ||
- CanStoreItem( NULL_BAG, NULL_SLOT, off_dest, offItem, false ) != EQUIP_ERR_OK ) )
- return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_INVENTORY_FULL;
+ if (!CanTitanGrip())
+ {
+ // offhand item must can be stored in inventory for offhand item and it also must be unequipped
+ Item *offItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND );
+ ItemPosCountVec off_dest;
+ if( offItem && (!not_loading ||
+ CanUnequipItem(uint16(INVENTORY_SLOT_BAG_0) << 8 | EQUIPMENT_SLOT_OFFHAND,false) != EQUIP_ERR_OK ||
+ CanStoreItem( NULL_BAG, NULL_SLOT, off_dest, offItem, false ) != EQUIP_ERR_OK ) )
+ return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_INVENTORY_FULL;
+ }
}
dest = ((INVENTORY_SLOT_BAG_0 << 8) | eslot);
return EQUIP_ERR_OK;
@@ -9892,29 +9947,17 @@ uint8 Player::CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *p
// in specific slot
if( bag != NULL_BAG && slot != NULL_SLOT )
{
- if( pProto->InventoryType == INVTYPE_BAG )
- {
- Bag *pBag = (Bag*)pItem;
- if( pBag )
- {
- if( slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END )
- {
- if( !HasBankBagSlot( slot ) )
- return EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT;
- if( uint8 cantuse = CanUseItem( pItem, not_loading ) != EQUIP_ERR_OK )
- return cantuse;
- }
- else
- {
- if( !pBag->IsEmpty() )
- return EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG;
- }
- }
- }
- else
+ if( slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END )
{
- if( slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END )
+ if (!pItem->IsBag())
return EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT;
+
+ Bag *pBag = (Bag*)pItem;
+ if( !HasBankBagSlot( slot ) )
+ return EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT;
+
+ if( uint8 cantuse = CanUseItem( pItem, not_loading ) != EQUIP_ERR_OK )
+ return cantuse;
}
res = _CanStoreItem_InSpecificSlot(bag,slot,dest,pProto,count,swap,pItem);
@@ -9938,7 +9981,7 @@ uint8 Player::CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *p
}
// search stack in bag for merge to
- if( pProto->Stackable > 1 )
+ if( pProto->Stackable != 1 )
{
if( bag == INVENTORY_SLOT_BAG_0 )
{
@@ -9990,7 +10033,7 @@ uint8 Player::CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *p
// not specific bag or have space for partly store only in specific bag
// search stack for merge to
- if( pProto->Stackable > 1 )
+ if( pProto->Stackable != 1 )
{
// in slots
res = _CanStoreItem_InInventorySlots(BANK_SLOT_ITEM_START,BANK_SLOT_ITEM_END,dest,pProto,count,true,pItem,bag,slot);
@@ -10146,7 +10189,7 @@ uint8 Player::CanUseAmmo( uint32 item ) const
}
if( pProto->RequiredSpell != 0 && !HasSpell( pProto->RequiredSpell ) )
return EQUIP_ERR_NO_REQUIRED_PROFICIENCY;
- /*if( GetReputation() < pProto->RequiredReputation )
+ /*if( GetReputationMgr().GetReputation() < pProto->RequiredReputation )
return EQUIP_ERR_CANT_EQUIP_REPUTATION;
*/
if( getLevel() < pProto->RequiredLevel )
@@ -10220,7 +10263,7 @@ Item* Player::StoreItem( ItemPosCountVec const& dest, Item* pItem, bool update )
return NULL;
Item* lastItem = pItem;
-
+ uint32 entry = pItem->GetEntry();
for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); )
{
uint16 pos = itr->pos;
@@ -10236,7 +10279,7 @@ Item* Player::StoreItem( ItemPosCountVec const& dest, Item* pItem, bool update )
lastItem = _StoreItem(pos,pItem,count,true,update);
}
-
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM, entry);
return lastItem;
}
@@ -10253,22 +10296,22 @@ Item* Player::_StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, boo
Item *pItem2 = GetItemByPos( bag, slot );
- if( !pItem2 )
+ if (!pItem2)
{
- if(clone)
+ if (clone)
pItem = pItem->CloneItem(count,this);
else
pItem->SetCount(count);
- if(!pItem)
+ if (!pItem)
return NULL;
- if( pItem->GetProto()->Bonding == BIND_WHEN_PICKED_UP ||
+ if (pItem->GetProto()->Bonding == BIND_WHEN_PICKED_UP ||
pItem->GetProto()->Bonding == BIND_QUEST_ITEM ||
- pItem->GetProto()->Bonding == BIND_WHEN_EQUIPED && IsBagPos(pos) )
+ (pItem->GetProto()->Bonding == BIND_WHEN_EQUIPED && IsBagPos(pos)))
pItem->SetBinding( true );
- if( bag == INVENTORY_SLOT_BAG_0 )
+ if (bag == INVENTORY_SLOT_BAG_0)
{
m_items[slot] = pItem;
SetUInt64Value( (uint16)(PLAYER_FIELD_INV_SLOT_HEAD + (slot * 2) ), pItem->GetGUID() );
@@ -10278,7 +10321,11 @@ Item* Player::_StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, boo
pItem->SetSlot( slot );
pItem->SetContainer( NULL );
- if( IsInWorld() && update )
+ // need update known currency
+ if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END)
+ UpdateKnownCurrencies(pItem->GetEntry(),true);
+
+ if (IsInWorld() && update)
{
pItem->AddToWorld();
pItem->SendUpdateToPlayer( this );
@@ -10286,20 +10333,16 @@ Item* Player::_StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, boo
pItem->SetState(ITEM_CHANGED, this);
}
- else
+ else if (Bag *pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, bag ))
{
- Bag *pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, bag );
- if( pBag )
+ pBag->StoreItem( slot, pItem, update );
+ if( IsInWorld() && update )
{
- pBag->StoreItem( slot, pItem, update );
- if( IsInWorld() && update )
- {
- pItem->AddToWorld();
- pItem->SendUpdateToPlayer( this );
- }
- pItem->SetState(ITEM_CHANGED, this);
- pBag->SetState(ITEM_CHANGED, this);
+ pItem->AddToWorld();
+ pItem->SendUpdateToPlayer( this );
}
+ pItem->SetState(ITEM_CHANGED, this);
+ pBag->SetState(ITEM_CHANGED, this);
}
AddEnchantmentDurations(pItem);
@@ -10309,19 +10352,19 @@ Item* Player::_StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, boo
}
else
{
- if( pItem2->GetProto()->Bonding == BIND_WHEN_PICKED_UP ||
+ if (pItem2->GetProto()->Bonding == BIND_WHEN_PICKED_UP ||
pItem2->GetProto()->Bonding == BIND_QUEST_ITEM ||
- pItem2->GetProto()->Bonding == BIND_WHEN_EQUIPED && IsBagPos(pos) )
+ (pItem2->GetProto()->Bonding == BIND_WHEN_EQUIPED && IsBagPos(pos)))
pItem2->SetBinding( true );
pItem2->SetCount( pItem2->GetCount() + count );
- if( IsInWorld() && update )
+ if (IsInWorld() && update)
pItem2->SendUpdateToPlayer( this );
- if(!clone)
+ if (!clone)
{
// delete item (it not in any slot currently)
- if( IsInWorld() && update )
+ if (IsInWorld() && update)
{
pItem->RemoveFromWorld();
pItem->DestroyForPlayer( this );
@@ -10333,6 +10376,7 @@ Item* Player::_StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, boo
pItem->SetOwnerGUID(GetGUID()); // prevent error at next SetState in case trade/mail/buy from vendor
pItem->SetState(ITEM_REMOVED, this);
}
+
// AddItemDurations(pItem2); - pItem2 already have duration listed for player
AddEnchantmentDurations(pItem2);
@@ -10344,108 +10388,107 @@ Item* Player::_StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, boo
Item* Player::EquipNewItem( uint16 pos, uint32 item, bool update )
{
- Item *pItem = Item::CreateItem( item, 1, this );
- if( pItem )
+ if (Item *pItem = Item::CreateItem( item, 1, this ))
{
ItemAddedQuestCheck( item, 1 );
- Item * retItem = EquipItem( pos, pItem, update );
-
- return retItem;
+ return EquipItem( pos, pItem, update );
}
+
return NULL;
}
Item* Player::EquipItem( uint16 pos, Item *pItem, bool update )
{
- if( pItem )
- {
- AddEnchantmentDurations(pItem);
- AddItemDurations(pItem);
- uint8 bag = pos >> 8;
- uint8 slot = pos & 255;
+ AddEnchantmentDurations(pItem);
+ AddItemDurations(pItem);
- Item *pItem2 = GetItemByPos( bag, slot );
+ uint8 bag = pos >> 8;
+ uint8 slot = pos & 255;
- if( !pItem2 )
- {
- VisualizeItem( slot, pItem);
+ Item *pItem2 = GetItemByPos( bag, slot );
- if(isAlive())
- {
- ItemPrototype const *pProto = pItem->GetProto();
+ if( !pItem2 )
+ {
+ VisualizeItem( slot, pItem);
- // item set bonuses applied only at equip and removed at unequip, and still active for broken items
- if(pProto && pProto->ItemSet)
- AddItemsSetItem(this,pItem);
+ if(isAlive())
+ {
+ ItemPrototype const *pProto = pItem->GetProto();
- _ApplyItemMods(pItem, slot, true);
+ // item set bonuses applied only at equip and removed at unequip, and still active for broken items
+ if(pProto && pProto->ItemSet)
+ AddItemsSetItem(this,pItem);
- if(pProto && isInCombat()&& pProto->Class == ITEM_CLASS_WEAPON && m_weaponChangeTimer == 0)
- {
- uint32 cooldownSpell = SPELL_ID_WEAPON_SWITCH_COOLDOWN_1_5s;
+ _ApplyItemMods(pItem, slot, true);
- if (getClass() == CLASS_ROGUE)
- cooldownSpell = SPELL_ID_WEAPON_SWITCH_COOLDOWN_1_0s;
+ if(pProto && isInCombat()&& pProto->Class == ITEM_CLASS_WEAPON && m_weaponChangeTimer == 0)
+ {
+ uint32 cooldownSpell = SPELL_ID_WEAPON_SWITCH_COOLDOWN_1_5s;
- SpellEntry const* spellProto = sSpellStore.LookupEntry(cooldownSpell);
+ if (getClass() == CLASS_ROGUE)
+ cooldownSpell = SPELL_ID_WEAPON_SWITCH_COOLDOWN_1_0s;
- if (!spellProto)
- sLog.outError("Weapon switch cooldown spell %u couldn't be found in Spell.dbc", cooldownSpell);
- else
- {
- m_weaponChangeTimer = spellProto->StartRecoveryTime;
-
- WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+4);
- data << uint64(GetGUID());
- data << uint8(1);
- data << uint32(cooldownSpell);
- data << uint32(0);
- GetSession()->SendPacket(&data);
- }
+ SpellEntry const* spellProto = sSpellStore.LookupEntry(cooldownSpell);
+
+ if (!spellProto)
+ sLog.outError("Weapon switch cooldown spell %u couldn't be found in Spell.dbc", cooldownSpell);
+ else
+ {
+ m_weaponChangeTimer = spellProto->StartRecoveryTime;
+
+ WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+4);
+ data << uint64(GetGUID());
+ data << uint8(1);
+ data << uint32(cooldownSpell);
+ data << uint32(0);
+ GetSession()->SendPacket(&data);
}
}
+ }
- if( IsInWorld() && update )
- {
- pItem->AddToWorld();
- pItem->SendUpdateToPlayer( this );
- }
+ if( IsInWorld() && update )
+ {
+ pItem->AddToWorld();
+ pItem->SendUpdateToPlayer( this );
+ }
- ApplyEquipCooldown(pItem);
+ ApplyEquipCooldown(pItem);
- if( slot == EQUIPMENT_SLOT_MAINHAND )
- UpdateExpertise(BASE_ATTACK);
- else if( slot == EQUIPMENT_SLOT_OFFHAND )
- UpdateExpertise(OFF_ATTACK);
- }
- else
- {
- pItem2->SetCount( pItem2->GetCount() + pItem->GetCount() );
- if( IsInWorld() && update )
- pItem2->SendUpdateToPlayer( this );
+ if( slot == EQUIPMENT_SLOT_MAINHAND )
+ UpdateExpertise(BASE_ATTACK);
+ else if( slot == EQUIPMENT_SLOT_OFFHAND )
+ UpdateExpertise(OFF_ATTACK);
+ }
+ else
+ {
+ pItem2->SetCount( pItem2->GetCount() + pItem->GetCount() );
+ if( IsInWorld() && update )
+ pItem2->SendUpdateToPlayer( this );
- // delete item (it not in any slot currently)
- //pItem->DeleteFromDB();
- if( IsInWorld() && update )
- {
- pItem->RemoveFromWorld();
- pItem->DestroyForPlayer( this );
- }
+ // delete item (it not in any slot currently)
+ //pItem->DeleteFromDB();
+ if( IsInWorld() && update )
+ {
+ pItem->RemoveFromWorld();
+ pItem->DestroyForPlayer( this );
+ }
- RemoveEnchantmentDurations(pItem);
- RemoveItemDurations(pItem);
+ RemoveEnchantmentDurations(pItem);
+ RemoveItemDurations(pItem);
- pItem->SetOwnerGUID(GetGUID()); // prevent error at next SetState in case trade/mail/buy from vendor
- pItem->SetState(ITEM_REMOVED, this);
- pItem2->SetState(ITEM_CHANGED, this);
+ pItem->SetOwnerGUID(GetGUID()); // prevent error at next SetState in case trade/mail/buy from vendor
+ pItem->SetState(ITEM_REMOVED, this);
+ pItem2->SetState(ITEM_CHANGED, this);
- ApplyEquipCooldown(pItem2);
+ ApplyEquipCooldown(pItem2);
- return pItem2;
- }
+ return pItem2;
}
+ // only for full equip instead adding to stack
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry());
+
return pItem;
}
@@ -10560,23 +10603,32 @@ void Player::RemoveItem( uint8 bag, uint8 slot, bool update )
// remove item dependent auras and casts (only weapon and armor slots)
if(slot < EQUIPMENT_SLOT_END)
+ {
RemoveItemDependentAurasAndCasts(pItem);
- // remove held enchantments
- if ( slot == EQUIPMENT_SLOT_MAINHAND )
- {
- if (pItem->GetItemSuffixFactor())
- {
- pItem->ClearEnchantment(PROP_ENCHANTMENT_SLOT_3);
- pItem->ClearEnchantment(PROP_ENCHANTMENT_SLOT_4);
- }
- else
+ // remove held enchantments, update expertise
+ if ( slot == EQUIPMENT_SLOT_MAINHAND )
{
- pItem->ClearEnchantment(PROP_ENCHANTMENT_SLOT_0);
- pItem->ClearEnchantment(PROP_ENCHANTMENT_SLOT_1);
+ if (pItem->GetItemSuffixFactor())
+ {
+ pItem->ClearEnchantment(PROP_ENCHANTMENT_SLOT_3);
+ pItem->ClearEnchantment(PROP_ENCHANTMENT_SLOT_4);
+ }
+ else
+ {
+ pItem->ClearEnchantment(PROP_ENCHANTMENT_SLOT_0);
+ pItem->ClearEnchantment(PROP_ENCHANTMENT_SLOT_1);
+ }
+
+ UpdateExpertise(BASE_ATTACK);
}
+ else if( slot == EQUIPMENT_SLOT_OFFHAND )
+ UpdateExpertise(OFF_ATTACK);
}
}
+ // need update known currency
+ else if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END)
+ UpdateKnownCurrencies(pItem->GetEntry(),false);
m_items[slot] = NULL;
SetUInt64Value((uint16)(PLAYER_FIELD_INV_SLOT_HEAD + (slot*2)), 0);
@@ -10595,11 +10647,6 @@ void Player::RemoveItem( uint8 bag, uint8 slot, bool update )
pItem->SetSlot( NULL_SLOT );
if( IsInWorld() && update )
pItem->SendUpdateToPlayer( this );
-
- if( slot == EQUIPMENT_SLOT_MAINHAND )
- UpdateExpertise(BASE_ATTACK);
- else if( slot == EQUIPMENT_SLOT_OFFHAND )
- UpdateExpertise(OFF_ATTACK);
}
}
@@ -10684,9 +10731,18 @@ void Player::DestroyItem( uint8 bag, uint8 slot, bool update )
// remove item dependent auras and casts (only weapon and armor slots)
RemoveItemDependentAurasAndCasts(pItem);
+ // update expertise
+ if ( slot == EQUIPMENT_SLOT_MAINHAND )
+ UpdateExpertise(BASE_ATTACK);
+ else if( slot == EQUIPMENT_SLOT_OFFHAND )
+ UpdateExpertise(OFF_ATTACK);
+
// equipment visual show
SetVisibleItemSlot(slot,NULL);
}
+ // need update known currency
+ else if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END)
+ UpdateKnownCurrencies(pItem->GetEntry(),false);
m_items[slot] = NULL;
}
@@ -10709,60 +10765,61 @@ void Player::DestroyItem( uint8 bag, uint8 slot, bool update )
void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool unequip_check)
{
sLog.outDebug( "STORAGE: DestroyItemCount item = %u, count = %u", item, count);
- Item *pItem;
- ItemPrototype const *pProto;
uint32 remcount = 0;
// in inventory
for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
{
- pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
- if( pItem && pItem->GetEntry() == item )
+ if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
{
- if( pItem->GetCount() + remcount <= count )
+ if (pItem->GetEntry() == item)
{
- // all items in inventory can unequipped
- remcount += pItem->GetCount();
- DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
+ if (pItem->GetCount() + remcount <= count)
+ {
+ // all items in inventory can unequipped
+ remcount += pItem->GetCount();
+ DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
- if(remcount >=count)
+ if (remcount >=count)
+ return;
+ }
+ else
+ {
+ ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount );
+ pItem->SetCount( pItem->GetCount() - count + remcount );
+ if (IsInWorld() & update)
+ pItem->SendUpdateToPlayer( this );
+ pItem->SetState(ITEM_CHANGED, this);
return;
- }
- else
- {
- pProto = pItem->GetProto();
- ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount );
- pItem->SetCount( pItem->GetCount() - count + remcount );
- if( IsInWorld() & update )
- pItem->SendUpdateToPlayer( this );
- pItem->SetState(ITEM_CHANGED, this);
- return;
+ }
}
}
}
- for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
+
+ for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
{
- pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
- if( pItem && pItem->GetEntry() == item )
+ if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
{
- if( pItem->GetCount() + remcount <= count )
+ if (pItem->GetEntry() == item)
{
- // all keys can be unequipped
- remcount += pItem->GetCount();
- DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
+ if (pItem->GetCount() + remcount <= count)
+ {
+ // all keys can be unequipped
+ remcount += pItem->GetCount();
+ DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
- if(remcount >=count)
+ if (remcount >=count)
+ return;
+ }
+ else
+ {
+ ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount );
+ pItem->SetCount( pItem->GetCount() - count + remcount );
+ if (IsInWorld() & update)
+ pItem->SendUpdateToPlayer( this );
+ pItem->SetState(ITEM_CHANGED, this);
return;
- }
- else
- {
- pProto = pItem->GetProto();
- ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount );
- pItem->SetCount( pItem->GetCount() - count + remcount );
- if( IsInWorld() & update )
- pItem->SendUpdateToPlayer( this );
- pItem->SetState(ITEM_CHANGED, this);
- return;
+ }
}
}
}
@@ -10774,27 +10831,28 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq
{
for(uint32 j = 0; j < pBag->GetBagSize(); j++)
{
- pItem = pBag->GetItemByPos(j);
- if( pItem && pItem->GetEntry() == item )
+ if(Item* pItem = pBag->GetItemByPos(j))
{
- // all items in bags can be unequipped
- if( pItem->GetCount() + remcount <= count )
+ if (pItem->GetEntry() == item)
{
- remcount += pItem->GetCount();
- DestroyItem( i, j, update );
+ // all items in bags can be unequipped
+ if (pItem->GetCount() + remcount <= count)
+ {
+ remcount += pItem->GetCount();
+ DestroyItem( i, j, update );
- if(remcount >=count)
+ if (remcount >=count)
+ return;
+ }
+ else
+ {
+ ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount );
+ pItem->SetCount( pItem->GetCount() - count + remcount );
+ if (IsInWorld() && update)
+ pItem->SendUpdateToPlayer( this );
+ pItem->SetState(ITEM_CHANGED, this);
return;
- }
- else
- {
- pProto = pItem->GetProto();
- ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount );
- pItem->SetCount( pItem->GetCount() - count + remcount );
- if( IsInWorld() && update )
- pItem->SendUpdateToPlayer( this );
- pItem->SetState(ITEM_CHANGED, this);
- return;
+ }
}
}
}
@@ -10804,29 +10862,30 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq
// in equipment and bag list
for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; i++)
{
- pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
- if( pItem && pItem->GetEntry() == item )
+ if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
{
- if( pItem->GetCount() + remcount <= count )
+ if (pItem && pItem->GetEntry() == item)
{
- if(!unequip_check || CanUnequipItem(INVENTORY_SLOT_BAG_0 << 8 | i,false) == EQUIP_ERR_OK )
+ if (pItem->GetCount() + remcount <= count)
{
- remcount += pItem->GetCount();
- DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
+ if (!unequip_check || CanUnequipItem(INVENTORY_SLOT_BAG_0 << 8 | i,false) == EQUIP_ERR_OK )
+ {
+ remcount += pItem->GetCount();
+ DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
- if(remcount >=count)
- return;
+ if (remcount >=count)
+ return;
+ }
+ }
+ else
+ {
+ ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount );
+ pItem->SetCount( pItem->GetCount() - count + remcount );
+ if (IsInWorld() & update)
+ pItem->SendUpdateToPlayer( this );
+ pItem->SetState(ITEM_CHANGED, this);
+ return;
}
- }
- else
- {
- pProto = pItem->GetProto();
- ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount );
- pItem->SetCount( pItem->GetCount() - count + remcount );
- if( IsInWorld() & update )
- pItem->SendUpdateToPlayer( this );
- pItem->SetState(ITEM_CHANGED, this);
- return;
}
}
}
@@ -10838,40 +10897,28 @@ void Player::DestroyZoneLimitedItem( bool update, uint32 new_zone )
// in inventory
for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
- {
- Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
- if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) )
- DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
- }
- for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
- {
- Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
- if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) )
- DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
- }
+ if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
+ if (pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone))
+ DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
+
+ for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
+ if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
+ if (pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone))
+ DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
// in inventory bags
for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
- {
- Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i );
- if( pBag )
- {
+ if (Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
for(uint32 j = 0; j < pBag->GetBagSize(); j++)
- {
- Item* pItem = pBag->GetItemByPos(j);
- if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) )
- DestroyItem( i, j, update);
- }
- }
- }
+ if (Item* pItem = pBag->GetItemByPos(j))
+ if (pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone))
+ DestroyItem( i, j, update);
// in equipment and bag list
for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; i++)
- {
- Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
- if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) )
- DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
- }
+ if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
+ if (pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone))
+ DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
}
void Player::DestroyConjuredItems( bool update )
@@ -10882,40 +10929,23 @@ void Player::DestroyConjuredItems( bool update )
// in inventory
for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
- {
- Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
- if( pItem && pItem->GetProto() &&
- (pItem->GetProto()->Class == ITEM_CLASS_CONSUMABLE) &&
- (pItem->GetProto()->Flags & ITEM_FLAGS_CONJURED) )
- DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
- }
+ if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
+ if (pItem->IsConjuredConsumable())
+ DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
// in inventory bags
for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
- {
- Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i );
- if( pBag )
- {
+ if (Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
for(uint32 j = 0; j < pBag->GetBagSize(); j++)
- {
- Item* pItem = pBag->GetItemByPos(j);
- if( pItem && pItem->GetProto() &&
- (pItem->GetProto()->Class == ITEM_CLASS_CONSUMABLE) &&
- (pItem->GetProto()->Flags & ITEM_FLAGS_CONJURED) )
- DestroyItem( i, j, update);
- }
- }
- }
+ if (Item* pItem = pBag->GetItemByPos(j))
+ if (pItem->IsConjuredConsumable())
+ DestroyItem( i, j, update);
// in equipment and bag list
for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; i++)
- {
- Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
- if( pItem && pItem->GetProto() &&
- (pItem->GetProto()->Class == ITEM_CLASS_CONSUMABLE) &&
- (pItem->GetProto()->Flags & ITEM_FLAGS_CONJURED) )
- DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
- }
+ if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
+ if (pItem->IsConjuredConsumable())
+ DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
}
void Player::DestroyItemCount( Item* pItem, uint32 &count, bool update )
@@ -11071,6 +11101,8 @@ void Player::SwapItem( uint16 src, uint16 dst )
return;
}
+ // SRC checks
+
if(pSrcItem->m_lootGenerated) // prevent swap looting item
{
//best error message found for attempting to swap while looting
@@ -11081,8 +11113,8 @@ void Player::SwapItem( uint16 src, uint16 dst )
// check unequip potability for equipped items and bank bags
if(IsEquipmentPos ( src ) || IsBagPos ( src ))
{
- // bags can be swapped with empty bag slots
- uint8 msg = CanUnequipItem( src, !IsBagPos ( src ) || IsBagPos ( dst ));
+ // bags can be swapped with empty bag slots, or with empty bag (items move possibility checked later)
+ uint8 msg = CanUnequipItem( src, !IsBagPos ( src ) || IsBagPos ( dst ) || pDstItem && pDstItem->IsBag() && ((Bag*)pDstItem)->IsEmpty());
if(msg != EQUIP_ERR_OK)
{
SendEquipError( msg, pSrcItem, pDstItem );
@@ -11097,6 +11129,34 @@ void Player::SwapItem( uint16 src, uint16 dst )
return;
}
+ // DST checks
+
+ if (pDstItem)
+ {
+ if(pDstItem->m_lootGenerated) // prevent swap looting item
+ {
+ //best error message found for attempting to swap while looting
+ SendEquipError( EQUIP_ERR_CANT_DO_RIGHT_NOW, pDstItem, NULL );
+ return;
+ }
+
+ // check unequip potability for equipped items and bank bags
+ if(IsEquipmentPos ( dst ) || IsBagPos ( dst ))
+ {
+ // bags can be swapped with empty bag slots, or with empty bag (items move possibility checked later)
+ uint8 msg = CanUnequipItem( dst, !IsBagPos ( dst ) || IsBagPos ( src ) || pSrcItem->IsBag() && ((Bag*)pSrcItem)->IsEmpty());
+ if(msg != EQUIP_ERR_OK)
+ {
+ SendEquipError( msg, pSrcItem, pDstItem );
+ return;
+ }
+ }
+ }
+
+ // NOW this is or item move (swap with empty), or swap with another item (including bags in bag possitions)
+ // or swap empty bag with another empty or not empty bag (with items exchange)
+
+ // Move case
if( !pDstItem )
{
if( IsInventoryPos( dst ) )
@@ -11139,140 +11199,187 @@ void Player::SwapItem( uint16 src, uint16 dst )
EquipItem( dest, pSrcItem, true);
AutoUnequipOffhandIfNeed();
}
+
+ return;
}
- else // if (!pDstItem)
+
+ // attempt merge to / fill target item
+ if(!pSrcItem->IsBag() && !pDstItem->IsBag())
{
- if(pDstItem->m_lootGenerated) // prevent swap looting item
- {
- //best error message found for attempting to swap while looting
- SendEquipError( EQUIP_ERR_CANT_DO_RIGHT_NOW, pDstItem, NULL );
+ uint8 msg;
+ ItemPosCountVec sDest;
+ uint16 eDest;
+ if( IsInventoryPos( dst ) )
+ msg = CanStoreItem( dstbag, dstslot, sDest, pSrcItem, false );
+ else if( IsBankPos ( dst ) )
+ msg = CanBankItem( dstbag, dstslot, sDest, pSrcItem, false );
+ else if( IsEquipmentPos ( dst ) )
+ msg = CanEquipItem( dstslot, eDest, pSrcItem, false );
+ else
return;
- }
- // check unequip potability for equipped items and bank bags
- if(IsEquipmentPos ( dst ) || IsBagPos ( dst ))
+ // can be merge/fill
+ if(msg == EQUIP_ERR_OK)
{
- // bags can be swapped with empty bag slots
- uint8 msg = CanUnequipItem( dst, !IsBagPos ( dst ) || IsBagPos ( src ) );
- if(msg != EQUIP_ERR_OK)
+ if( pSrcItem->GetCount() + pDstItem->GetCount() <= pSrcItem->GetProto()->GetMaxStackSize())
{
- SendEquipError( msg, pSrcItem, pDstItem );
- return;
- }
- }
-
- // attempt merge to / fill target item
- {
- uint8 msg;
- ItemPosCountVec sDest;
- uint16 eDest;
- if( IsInventoryPos( dst ) )
- msg = CanStoreItem( dstbag, dstslot, sDest, pSrcItem, false );
- else if( IsBankPos ( dst ) )
- msg = CanBankItem( dstbag, dstslot, sDest, pSrcItem, false );
- else if( IsEquipmentPos ( dst ) )
- msg = CanEquipItem( dstslot, eDest, pSrcItem, false );
- else
- return;
+ RemoveItem(srcbag, srcslot, true);
- // can be merge/fill
- if(msg == EQUIP_ERR_OK)
- {
- if( pSrcItem->GetCount() + pDstItem->GetCount() <= pSrcItem->GetProto()->Stackable )
+ if( IsInventoryPos( dst ) )
+ StoreItem( sDest, pSrcItem, true);
+ else if( IsBankPos ( dst ) )
+ BankItem( sDest, pSrcItem, true);
+ else if( IsEquipmentPos ( dst ) )
{
- RemoveItem(srcbag, srcslot, true);
-
- if( IsInventoryPos( dst ) )
- StoreItem( sDest, pSrcItem, true);
- else if( IsBankPos ( dst ) )
- BankItem( sDest, pSrcItem, true);
- else if( IsEquipmentPos ( dst ) )
- {
- EquipItem( eDest, pSrcItem, true);
- AutoUnequipOffhandIfNeed();
- }
+ EquipItem( eDest, pSrcItem, true);
+ AutoUnequipOffhandIfNeed();
}
- else
+ }
+ else
+ {
+ pSrcItem->SetCount( pSrcItem->GetCount() + pDstItem->GetCount() - pSrcItem->GetProto()->GetMaxStackSize());
+ pDstItem->SetCount( pSrcItem->GetProto()->GetMaxStackSize());
+ pSrcItem->SetState(ITEM_CHANGED, this);
+ pDstItem->SetState(ITEM_CHANGED, this);
+ if( IsInWorld() )
{
- pSrcItem->SetCount( pSrcItem->GetCount() + pDstItem->GetCount() - pSrcItem->GetProto()->Stackable );
- pDstItem->SetCount( pSrcItem->GetProto()->Stackable );
- pSrcItem->SetState(ITEM_CHANGED, this);
- pDstItem->SetState(ITEM_CHANGED, this);
- if( IsInWorld() )
- {
- pSrcItem->SendUpdateToPlayer( this );
- pDstItem->SendUpdateToPlayer( this );
- }
+ pSrcItem->SendUpdateToPlayer( this );
+ pDstItem->SendUpdateToPlayer( this );
}
- return;
}
+ return;
}
+ }
- // impossible merge/fill, do real swap
- uint8 msg;
+ // impossible merge/fill, do real swap
+ uint8 msg;
- // check src->dest move possibility
- ItemPosCountVec sDest;
- uint16 eDest;
- if( IsInventoryPos( dst ) )
- msg = CanStoreItem( dstbag, dstslot, sDest, pSrcItem, true );
- else if( IsBankPos( dst ) )
- msg = CanBankItem( dstbag, dstslot, sDest, pSrcItem, true );
- else if( IsEquipmentPos( dst ) )
- {
- msg = CanEquipItem( dstslot, eDest, pSrcItem, true );
- if( msg == EQUIP_ERR_OK )
- msg = CanUnequipItem( eDest, true );
- }
+ // check src->dest move possibility
+ ItemPosCountVec sDest;
+ uint16 eDest = 0;
+ if( IsInventoryPos( dst ) )
+ msg = CanStoreItem( dstbag, dstslot, sDest, pSrcItem, true );
+ else if( IsBankPos( dst ) )
+ msg = CanBankItem( dstbag, dstslot, sDest, pSrcItem, true );
+ else if( IsEquipmentPos( dst ) )
+ {
+ msg = CanEquipItem( dstslot, eDest, pSrcItem, true );
+ if( msg == EQUIP_ERR_OK )
+ msg = CanUnequipItem( eDest, true );
+ }
- if( msg != EQUIP_ERR_OK )
+ if( msg != EQUIP_ERR_OK )
+ {
+ SendEquipError( msg, pSrcItem, pDstItem );
+ return;
+ }
+
+ // check dest->src move possibility
+ ItemPosCountVec sDest2;
+ uint16 eDest2 = 0;
+ if( IsInventoryPos( src ) )
+ msg = CanStoreItem( srcbag, srcslot, sDest2, pDstItem, true );
+ else if( IsBankPos( src ) )
+ msg = CanBankItem( srcbag, srcslot, sDest2, pDstItem, true );
+ else if( IsEquipmentPos( src ) )
+ {
+ msg = CanEquipItem( srcslot, eDest2, pDstItem, true);
+ if( msg == EQUIP_ERR_OK )
+ msg = CanUnequipItem( eDest2, true);
+ }
+
+ if( msg != EQUIP_ERR_OK )
+ {
+ SendEquipError( msg, pDstItem, pSrcItem );
+ return;
+ }
+
+ // Check bag swap with item exchange (one from empty in not bag possition (equipped (not possible in fact) or store)
+ if(pSrcItem->IsBag() && pDstItem->IsBag())
+ {
+ Bag* emptyBag = NULL;
+ Bag* fullBag = NULL;
+ if(((Bag*)pSrcItem)->IsEmpty() && !IsBagPos(src))
{
- SendEquipError( msg, pSrcItem, pDstItem );
- return;
+ emptyBag = (Bag*)pSrcItem;
+ fullBag = (Bag*)pDstItem;
}
-
- // check dest->src move possibility
- ItemPosCountVec sDest2;
- uint16 eDest2;
- if( IsInventoryPos( src ) )
- msg = CanStoreItem( srcbag, srcslot, sDest2, pDstItem, true );
- else if( IsBankPos( src ) )
- msg = CanBankItem( srcbag, srcslot, sDest2, pDstItem, true );
- else if( IsEquipmentPos( src ) )
+ else if(((Bag*)pDstItem)->IsEmpty() && !IsBagPos(dst))
{
- msg = CanEquipItem( srcslot, eDest2, pDstItem, true);
- if( msg == EQUIP_ERR_OK )
- msg = CanUnequipItem( eDest2, true);
+ emptyBag = (Bag*)pDstItem;
+ fullBag = (Bag*)pSrcItem;
}
- if( msg != EQUIP_ERR_OK )
+ // bag swap (with items exchange) case
+ if(emptyBag && fullBag)
{
- SendEquipError( msg, pDstItem, pSrcItem );
- return;
- }
+ ItemPrototype const* emotyProto = emptyBag->GetProto();
- // now do moves, remove...
- RemoveItem(dstbag, dstslot, false);
- RemoveItem(srcbag, srcslot, false);
+ uint32 count = 0;
- // add to dest
- if( IsInventoryPos( dst ) )
- StoreItem(sDest, pSrcItem, true);
- else if( IsBankPos( dst ) )
- BankItem(sDest, pSrcItem, true);
- else if( IsEquipmentPos( dst ) )
- EquipItem(eDest, pSrcItem, true);
-
- // add to src
- if( IsInventoryPos( src ) )
- StoreItem(sDest2, pDstItem, true);
- else if( IsBankPos( src ) )
- BankItem(sDest2, pDstItem, true);
- else if( IsEquipmentPos( src ) )
- EquipItem(eDest2, pDstItem, true);
+ for(int i=0; i < fullBag->GetBagSize(); ++i)
+ {
+ Item *bagItem = fullBag->GetItemByPos(i);
+ if (!bagItem)
+ continue;
- AutoUnequipOffhandIfNeed();
+ ItemPrototype const* bagItemProto = bagItem->GetProto();
+ if (!bagItemProto || !ItemCanGoIntoBag(bagItemProto, emotyProto))
+ {
+ // one from items not go to empry target bag
+ SendEquipError( EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG, pSrcItem, pDstItem );
+ return;
+ }
+
+ ++count;
+ }
+
+
+ if (count > emptyBag->GetBagSize())
+ {
+ // too small targeted bag
+ SendEquipError( EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, pSrcItem, pDstItem );
+ return;
+ }
+
+ // Items swap
+ count = 0; // will pos in new bag
+ for(int i=0; i< fullBag->GetBagSize(); ++i)
+ {
+ Item *bagItem = fullBag->GetItemByPos(i);
+ if (!bagItem)
+ continue;
+
+ fullBag->RemoveItem(i, true);
+ emptyBag->StoreItem(count, bagItem, true);
+ bagItem->SetState(ITEM_CHANGED, this);
+
+ ++count;
+ }
+ }
}
+
+ // now do moves, remove...
+ RemoveItem(dstbag, dstslot, false);
+ RemoveItem(srcbag, srcslot, false);
+
+ // add to dest
+ if( IsInventoryPos( dst ) )
+ StoreItem(sDest, pSrcItem, true);
+ else if( IsBankPos( dst ) )
+ BankItem(sDest, pSrcItem, true);
+ else if( IsEquipmentPos( dst ) )
+ EquipItem(eDest, pSrcItem, true);
+
+ // add to src
+ if( IsInventoryPos( src ) )
+ StoreItem(sDest2, pDstItem, true);
+ else if( IsBankPos( src ) )
+ BankItem(sDest2, pDstItem, true);
+ else if( IsEquipmentPos( src ) )
+ EquipItem(eDest2, pDstItem, true);
+
+ AutoUnequipOffhandIfNeed();
}
void Player::AddItemToBuyBackSlot( Item *pItem )
@@ -11613,6 +11720,7 @@ void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool a
if(!ignore_condition && pEnchant->EnchantmentCondition && !((Player*)this)->EnchantmentFitsRequirements(pEnchant->EnchantmentCondition, -1))
return;
+ if (!item->IsBroken())
for (int s=0; s<3; s++)
{
uint32 enchant_display_type = pEnchant->type[s];
@@ -11840,6 +11948,40 @@ void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool a
((Player*)this)->ApplyRatingMod(CR_EXPERTISE, enchant_amount, apply);
sLog.outDebug("+ %u EXPERTISE", enchant_amount);
break;
+ case ITEM_MOD_ATTACK_POWER:
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(enchant_amount), apply);
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
+ sLog.outDebug("+ %u ATTACK_POWER", enchant_amount);
+ break;
+ case ITEM_MOD_RANGED_ATTACK_POWER:
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
+ sLog.outDebug("+ %u RANGED_ATTACK_POWER", enchant_amount);
+ break;
+ case ITEM_MOD_FERAL_ATTACK_POWER:
+ ((Player*)this)->ApplyFeralAPBonus(enchant_amount, apply);
+ sLog.outDebug("+ %u FERAL_ATTACK_POWER", enchant_amount);
+ break;
+ case ITEM_MOD_SPELL_HEALING_DONE:
+ ((Player*)this)->ApplySpellHealingBonus(enchant_amount, apply);
+ sLog.outDebug("+ %u SPELL_HEALING_DONE", enchant_amount);
+ break;
+ case ITEM_MOD_SPELL_DAMAGE_DONE:
+ ((Player*)this)->ApplySpellDamageBonus(enchant_amount, apply);
+ sLog.outDebug("+ %u SPELL_DAMAGE_DONE", enchant_amount);
+ break;
+ case ITEM_MOD_MANA_REGENERATION:
+ ((Player*)this)->ApplyManaRegenBonus(enchant_amount, apply);
+ sLog.outDebug("+ %u MANA_REGENERATION", enchant_amount);
+ break;
+ case ITEM_MOD_ARMOR_PENETRATION_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_ARMOR_PENETRATION, enchant_amount, apply);
+ sLog.outDebug("+ %u ARMOR PENETRATION", enchant_amount);
+ break;
+ case ITEM_MOD_SPELL_POWER:
+ ((Player*)this)->ApplySpellHealingBonus(enchant_amount, apply);
+ ((Player*)this)->ApplySpellDamageBonus(enchant_amount, apply);
+ sLog.outDebug("+ %u SPELL_POWER", enchant_amount);
+ break;
default:
break;
}
@@ -11863,8 +12005,14 @@ void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool a
}
break;
}
+ case ITEM_ENCHANTMENT_TYPE_USE_SPELL:
+ // processed in Player::CastItemUseSpell
+ break;
+ case ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET:
+ // nothing do..
+ break;
default:
- sLog.outError("Unknown item enchantment display type: %d",enchant_display_type);
+ sLog.outError("Unknown item enchantment (id = %d) display type: %d", enchant_id, enchant_display_type);
break;
} /*switch(enchant_display_type)*/
} /*for*/
@@ -11930,7 +12078,7 @@ void Player::SendNewItem(Item *item, uint32 count, bool received, bool created,
data << GetItemCount(item->GetEntry()); // count of items in inventory
if (broadcast && GetGroup())
- GetGroup()->BroadcastPacket(&data);
+ GetGroup()->BroadcastPacket(&data, true);
else
GetSession()->SendPacket(&data);
}
@@ -11944,7 +12092,7 @@ void Player::PrepareQuestMenu( uint64 guid )
Object *pObject;
QuestRelations* pObjectQR;
QuestRelations* pObjectQIR;
- Creature *pCreature = ObjectAccessor::GetCreature(*this, guid);
+ Creature *pCreature = GetMap()->GetCreature(guid);
if( pCreature )
{
pObject = (Object*)pCreature;
@@ -11953,7 +12101,7 @@ void Player::PrepareQuestMenu( uint64 guid )
}
else
{
- GameObject *pGameObject = ObjectAccessor::GetGameObject(*this, guid);
+ GameObject *pGameObject = GetMap()->GetGameObject(guid);
if( pGameObject )
{
pObject = (Object*)pGameObject;
@@ -12030,11 +12178,11 @@ void Player::SendPreparedQuest( uint64 guid )
qe._Delay = 0;
qe._Emote = 0;
std::string title = "";
- Creature *pCreature = ObjectAccessor::GetCreature(*this, guid);
+ Creature *pCreature = GetMap()->GetCreature(guid);
if( pCreature )
{
uint32 textid = pCreature->GetNpcTextId();
- GossipText * gossiptext = objmgr.GetGossipText(textid);
+ GossipText const* gossiptext = objmgr.GetGossipText(textid);
if( !gossiptext )
{
qe._Delay = 0; //TEXTEMOTE_MESSAGE; //zyg: player emote
@@ -12094,7 +12242,7 @@ Quest const * Player::GetNextQuest( uint64 guid, Quest const *pQuest )
QuestRelations* pObjectQR;
QuestRelations* pObjectQIR;
- Creature *pCreature = ObjectAccessor::GetCreature(*this, guid);
+ Creature *pCreature = GetMap()->GetCreature(guid);
if( pCreature )
{
pObject = (Object*)pCreature;
@@ -12103,7 +12251,7 @@ Quest const * Player::GetNextQuest( uint64 guid, Quest const *pQuest )
}
else
{
- GameObject *pGameObject = ObjectAccessor::GetGameObject(*this, guid);
+ GameObject *pGameObject = GetMap()->GetGameObject(guid);
if( pGameObject )
{
pObject = (Object*)pGameObject;
@@ -12157,14 +12305,14 @@ bool Player::CanAddQuest( Quest const *pQuest, bool msg )
{
uint32 count = pQuest->GetSrcItemCount();
ItemPosCountVec dest;
- uint8 msg = CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, srcitem, count );
+ uint8 msg2 = CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, srcitem, count );
// player already have max number (in most case 1) source item, no additional item needed and quest can be added.
- if( msg == EQUIP_ERR_CANT_CARRY_MORE_OF_THIS )
+ if( msg2 == EQUIP_ERR_CANT_CARRY_MORE_OF_THIS )
return true;
- else if( msg != EQUIP_ERR_OK )
+ else if( msg2 != EQUIP_ERR_OK )
{
- SendEquipError( msg, NULL, NULL );
+ SendEquipError( msg2, NULL, NULL );
return false;
}
}
@@ -12225,7 +12373,7 @@ bool Player::CanCompleteQuest( uint32 quest_id )
}
uint32 repFacId = qInfo->GetRepObjectiveFaction();
- if ( repFacId && GetReputation(repFacId) < qInfo->GetRepObjectiveValue() )
+ if ( repFacId && GetReputationMgr().GetReputation(repFacId) < qInfo->GetRepObjectiveValue() )
return false;
return true;
@@ -12338,8 +12486,6 @@ void Player::AddQuest( Quest const *pQuest, Object *questGiver )
// if not exist then created with set uState==NEW and rewarded=false
QuestStatusData& questStatusData = mQuestStatus[quest_id];
- if (questStatusData.uState != QUEST_NEW)
- questStatusData.uState = QUEST_CHANGED;
// check for repeatable quests status reset
questStatusData.m_status = QUEST_STATUS_INCOMPLETE;
@@ -12347,21 +12493,22 @@ void Player::AddQuest( Quest const *pQuest, Object *questGiver )
if ( pQuest->HasFlag( QUEST_TRINITY_FLAGS_DELIVER ) )
{
- for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
+ for(int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
questStatusData.m_itemcount[i] = 0;
}
if ( pQuest->HasFlag(QUEST_TRINITY_FLAGS_KILL_OR_CAST | QUEST_TRINITY_FLAGS_SPEAKTO) )
{
- for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
+ for(int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
questStatusData.m_creatureOrGOcount[i] = 0;
}
GiveQuestSourceItem( pQuest );
- AdjustQuestReqItemCount( pQuest );
+ AdjustQuestReqItemCount( pQuest, questStatusData );
if( pQuest->GetRepObjectiveFaction() )
- SetFactionVisibleForFactionId(pQuest->GetRepObjectiveFaction());
+ if(FactionEntry const* factionEntry = sFactionStore.LookupEntry(pQuest->GetRepObjectiveFaction()))
+ GetReputationMgr().SetVisible(factionEntry);
uint32 qtime = 0;
if( pQuest->HasFlag( QUEST_TRINITY_FLAGS_TIMED ) )
@@ -12370,10 +12517,10 @@ void Player::AddQuest( Quest const *pQuest, Object *questGiver )
// shared timed quest
if(questGiver && questGiver->GetTypeId()==TYPEID_PLAYER)
- limittime = ((Player*)questGiver)->getQuestStatusMap()[quest_id].m_timer / 1000;
+ limittime = ((Player*)questGiver)->getQuestStatusMap()[quest_id].m_timer / IN_MILISECONDS;
AddTimedQuest( quest_id );
- questStatusData.m_timer = limittime * 1000;
+ questStatusData.m_timer = limittime * IN_MILISECONDS;
qtime = static_cast<uint32>(time(NULL)) + limittime;
}
else
@@ -12381,10 +12528,26 @@ void Player::AddQuest( Quest const *pQuest, Object *questGiver )
SetQuestSlot(log_slot, quest_id, qtime);
+ if (questStatusData.uState != QUEST_NEW)
+ questStatusData.uState = QUEST_CHANGED;
+
//starting initial quest script
if(questGiver && pQuest->GetQuestStartScript()!=0)
sWorld.ScriptsStart(sQuestStartScripts, pQuest->GetQuestStartScript(), questGiver, this);
+ // Some spells applied at quest activation
+ SpellAreaForQuestMapBounds saBounds = spellmgr.GetSpellAreaForQuestMapBounds(quest_id,true);
+ if(saBounds.first != saBounds.second)
+ {
+ uint32 zone, area;
+ GetZoneAndAreaId(zone,area);
+
+ for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
+ if(itr->second->autocast && itr->second->IsFitToRequirements(this,zone,area))
+ if( !HasAura(itr->second->spellId) )
+ CastSpell(this,itr->second->spellId,true);
+ }
+
UpdateForQuestsGO();
}
@@ -12482,10 +12645,20 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
if ( getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) )
GiveXP( XP , NULL );
else
- ModifyMoney( int32(pQuest->GetRewMoneyMaxLevel() * sWorld.getRate(RATE_DROP_MONEY)) );
+ {
+ uint32 money = uint32(pQuest->GetRewMoneyMaxLevel() * sWorld.getRate(RATE_DROP_MONEY));
+ ModifyMoney( money );
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD, money);
+ }
// Give player extra money if GetRewOrReqMoney > 0 and get ReqMoney if negative
- ModifyMoney( pQuest->GetRewOrReqMoney() );
+ if(pQuest->GetRewOrReqMoney())
+ {
+ ModifyMoney( pQuest->GetRewOrReqMoney() );
+
+ if(pQuest->GetRewOrReqMoney() > 0)
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD, pQuest->GetRewOrReqMoney());
+ }
// honor reward
if(pQuest->GetRewHonorableKills())
@@ -12498,6 +12671,12 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
SetTitle(titleEntry);
}
+ if(pQuest->GetBonusTalents())
+ {
+ m_questRewardTalentCount+=pQuest->GetBonusTalents();
+ InitTalentForLevel();
+ }
+
// Send reward mail
if(pQuest->GetRewMailTemplateId())
{
@@ -12529,12 +12708,13 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
Loot questMailLoot;
- questMailLoot.FillLoot(pQuest->GetQuestId(), LootTemplates_QuestMail, this);
+ questMailLoot.FillLoot(pQuest->GetQuestId(), LootTemplates_QuestMail, this,true);
// fill mail
MailItemsInfo mi; // item list preparing
- for(size_t i = 0; mi.size() < MAX_MAIL_ITEMS && i < questMailLoot.items.size(); ++i)
+ uint32 max_slot = questMailLoot.GetMaxSlotInLootFor(this);
+ for(uint32 i = 0; mi.size() < MAX_MAIL_ITEMS && i < max_slot; ++i)
{
if(LootItem* lootitem = questMailLoot.LootItemInSlot(i,this))
{
@@ -12546,23 +12726,14 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
}
}
- for(size_t i = 0; mi.size() < MAX_MAIL_ITEMS && i < questMailLoot.quest_items.size(); ++i)
- {
- if(LootItem* lootitem = questMailLoot.LootItemInSlot(i+questMailLoot.items.size(),this))
- {
- if(Item* item = Item::CreateItem(lootitem->itemid,lootitem->count,this))
- {
- item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
- mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
- }
- }
- }
-
WorldSession::SendMailTo(this, mailType, MAIL_STATIONERY_NORMAL, senderGuidOrEntry, GetGUIDLow(), "", 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE,pQuest->GetRewMailDelaySecs(),pQuest->GetRewMailTemplateId());
}
if(pQuest->IsDaily())
+ {
SetDailyQuestStatus(quest_id);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, 1);
+ }
if ( !pQuest->IsRepeatable() )
SetQuestStatus(quest_id, QUEST_STATUS_COMPLETE);
@@ -12575,6 +12746,37 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
SendQuestReward( pQuest, XP, questGiver );
if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED;
+ if (pQuest->GetZoneOrSort() > 0)
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE, pQuest->GetZoneOrSort());
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, pQuest->GetQuestId());
+
+ uint32 zone = 0;
+ uint32 area = 0;
+
+ // remove auras from spells with quest reward state limitations
+ SpellAreaForQuestMapBounds saEndBounds = spellmgr.GetSpellAreaForQuestEndMapBounds(quest_id);
+ if(saEndBounds.first != saEndBounds.second)
+ {
+ GetZoneAndAreaId(zone,area);
+
+ for(SpellAreaForAreaMap::const_iterator itr = saEndBounds.first; itr != saEndBounds.second; ++itr)
+ if(!itr->second->IsFitToRequirements(this,zone,area))
+ RemoveAurasDueToSpell(itr->second->spellId);
+ }
+
+ // Some spells applied at quest reward
+ SpellAreaForQuestMapBounds saBounds = spellmgr.GetSpellAreaForQuestMapBounds(quest_id,false);
+ if(saBounds.first != saBounds.second)
+ {
+ if(!zone || !area)
+ GetZoneAndAreaId(zone,area);
+
+ for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
+ if(itr->second->autocast && itr->second->IsFitToRequirements(this,zone,area))
+ if( !HasAura(itr->second->spellId) )
+ CastSpell(this,itr->second->spellId,true);
+ }
}
void Player::FailQuest( uint32 quest_id )
@@ -12599,8 +12801,9 @@ void Player::FailTimedQuest( uint32 quest_id )
{
QuestStatusData& q_status = mQuestStatus[quest_id];
- if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED;
q_status.m_timer = 0;
+ if (q_status.uState != QUEST_NEW)
+ q_status.uState = QUEST_CHANGED;
IncompleteQuest( quest_id );
@@ -12710,14 +12913,14 @@ bool Player::SatisfyQuestPreviousQuest( Quest const* qInfo, bool msg )
// each-from-all exclusive group ( < 0)
// can be start if only all quests in prev quest exclusive group completed and rewarded
- ObjectMgr::ExclusiveQuestGroups::iterator iter = objmgr.mExclusiveQuestGroups.lower_bound(qPrevInfo->GetExclusiveGroup());
+ ObjectMgr::ExclusiveQuestGroups::iterator iter2 = objmgr.mExclusiveQuestGroups.lower_bound(qPrevInfo->GetExclusiveGroup());
ObjectMgr::ExclusiveQuestGroups::iterator end = objmgr.mExclusiveQuestGroups.upper_bound(qPrevInfo->GetExclusiveGroup());
- assert(iter!=end); // always must be found if qPrevInfo->ExclusiveGroup != 0
+ assert(iter2!=end); // always must be found if qPrevInfo->ExclusiveGroup != 0
- for(; iter != end; ++iter)
+ for(; iter2 != end; ++iter2)
{
- uint32 exclude_Id = iter->second;
+ uint32 exclude_Id = iter2->second;
// skip checked quest id, only state of other quests in group is interesting
if(exclude_Id == prevId)
@@ -12745,14 +12948,14 @@ bool Player::SatisfyQuestPreviousQuest( Quest const* qInfo, bool msg )
// each-from-all exclusive group ( < 0)
// can be start if only all quests in prev quest exclusive group active
- ObjectMgr::ExclusiveQuestGroups::iterator iter = objmgr.mExclusiveQuestGroups.lower_bound(qPrevInfo->GetExclusiveGroup());
+ ObjectMgr::ExclusiveQuestGroups::iterator iter2 = objmgr.mExclusiveQuestGroups.lower_bound(qPrevInfo->GetExclusiveGroup());
ObjectMgr::ExclusiveQuestGroups::iterator end = objmgr.mExclusiveQuestGroups.upper_bound(qPrevInfo->GetExclusiveGroup());
- assert(iter!=end); // always must be found if qPrevInfo->ExclusiveGroup != 0
+ assert(iter2!=end); // always must be found if qPrevInfo->ExclusiveGroup != 0
- for(; iter != end; ++iter)
+ for(; iter2 != end; ++iter2)
{
- uint32 exclude_Id = iter->second;
+ uint32 exclude_Id = iter2->second;
// skip checked quest id, only state of other quests in group is interesting
if(exclude_Id == prevId)
@@ -12800,7 +13003,7 @@ bool Player::SatisfyQuestRace( Quest const* qInfo, bool msg )
bool Player::SatisfyQuestReputation( Quest const* qInfo, bool msg )
{
uint32 fIdMin = qInfo->GetRequiredMinRepFaction(); //Min required rep
- if(fIdMin && GetReputation(fIdMin) < qInfo->GetRequiredMinRepValue())
+ if(fIdMin && GetReputationMgr().GetReputation(fIdMin) < qInfo->GetRequiredMinRepValue())
{
if( msg )
SendCanTakeQuestResponse( INVALIDREASON_DONT_HAVE_REQ );
@@ -12808,7 +13011,7 @@ bool Player::SatisfyQuestReputation( Quest const* qInfo, bool msg )
}
uint32 fIdMax = qInfo->GetRequiredMaxRepFaction(); //Max required rep
- if(fIdMax && GetReputation(fIdMax) >= qInfo->GetRequiredMaxRepValue())
+ if(fIdMax && GetReputationMgr().GetReputation(fIdMax) >= qInfo->GetRequiredMaxRepValue())
{
if( msg )
SendCanTakeQuestResponse( INVALIDREASON_DONT_HAVE_REQ );
@@ -13086,18 +13289,18 @@ uint32 Player::GetReqKillOrCastCurrentCount(uint32 quest_id, int32 entry)
if( !qInfo )
return 0;
- for (int j = 0; j < QUEST_OBJECTIVES_COUNT; j++)
+ for (int j = 0; j < QUEST_OBJECTIVES_COUNT; ++j)
if ( qInfo->ReqCreatureOrGOId[j] == entry )
return mQuestStatus[quest_id].m_creatureOrGOcount[j];
return 0;
}
-void Player::AdjustQuestReqItemCount( Quest const* pQuest )
+void Player::AdjustQuestReqItemCount( Quest const* pQuest, QuestStatusData& questStatusData )
{
if ( pQuest->HasFlag( QUEST_TRINITY_FLAGS_DELIVER ) )
{
- for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
+ for(int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
{
uint32 reqitemcount = pQuest->ReqItemCount[i];
if( reqitemcount != 0 )
@@ -13105,9 +13308,8 @@ void Player::AdjustQuestReqItemCount( Quest const* pQuest )
uint32 quest_id = pQuest->GetQuestId();
uint32 curitemcount = GetItemCount(pQuest->ReqItemId[i],true);
- QuestStatusData& q_status = mQuestStatus[quest_id];
- q_status.m_itemcount[i] = std::min(curitemcount, reqitemcount);
- if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED;
+ questStatusData.m_itemcount[i] = std::min(curitemcount, reqitemcount);
+ if (questStatusData.uState != QUEST_NEW) questStatusData.uState = QUEST_CHANGED;
}
}
}
@@ -13115,7 +13317,7 @@ void Player::AdjustQuestReqItemCount( Quest const* pQuest )
uint16 Player::FindQuestSlot( uint32 quest_id ) const
{
- for ( uint16 i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
+ for ( uint16 i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
if ( GetQuestSlotQuestId(i) == quest_id )
return i;
@@ -13163,7 +13365,7 @@ void Player::GroupEventHappens( uint32 questId, WorldObject const* pEventObject
void Player::ItemAddedQuestCheck( uint32 entry, uint32 count )
{
- for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
{
uint32 questid = GetQuestSlotQuestId(i);
if ( questid == 0 )
@@ -13204,7 +13406,7 @@ void Player::ItemAddedQuestCheck( uint32 entry, uint32 count )
void Player::ItemRemovedQuestCheck( uint32 entry, uint32 count )
{
- for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
{
uint32 questid = GetQuestSlotQuestId(i);
if(!questid)
@@ -13246,7 +13448,8 @@ void Player::ItemRemovedQuestCheck( uint32 entry, uint32 count )
void Player::KilledMonster( uint32 entry, uint64 guid )
{
uint32 addkillcount = 1;
- for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, entry, addkillcount);
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
{
uint32 questid = GetQuestSlotQuestId(i);
if(!questid)
@@ -13301,7 +13504,7 @@ void Player::CastedCreatureOrGO( uint32 entry, uint64 guid, uint32 spell_id )
bool isCreature = IS_CREATURE_GUID(guid);
uint32 addCastCount = 1;
- for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
{
uint32 questid = GetQuestSlotQuestId(i);
if(!questid)
@@ -13368,7 +13571,7 @@ void Player::CastedCreatureOrGO( uint32 entry, uint64 guid, uint32 spell_id )
void Player::TalkedToCreature( uint32 entry, uint64 guid )
{
uint32 addTalkCount = 1;
- for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
{
uint32 questid = GetQuestSlotQuestId(i);
if(!questid)
@@ -13423,7 +13626,7 @@ void Player::TalkedToCreature( uint32 entry, uint64 guid )
void Player::MoneyChanged( uint32 count )
{
- for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
{
uint32 questid = GetQuestSlotQuestId(i);
if (!questid)
@@ -13451,15 +13654,51 @@ void Player::MoneyChanged( uint32 count )
}
}
+void Player::ReputationChanged(FactionEntry const* factionEntry )
+{
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
+ {
+ if(uint32 questid = GetQuestSlotQuestId(i))
+ {
+ if(Quest const* qInfo = objmgr.GetQuestTemplate(questid))
+ {
+ if(qInfo->GetRepObjectiveFaction() == factionEntry->ID )
+ {
+ QuestStatusData& q_status = mQuestStatus[questid];
+ if( q_status.m_status == QUEST_STATUS_INCOMPLETE )
+ {
+ if(GetReputationMgr().GetReputation(factionEntry) >= qInfo->GetRepObjectiveValue())
+ if ( CanCompleteQuest( questid ) )
+ CompleteQuest( questid );
+ }
+ else if( q_status.m_status == QUEST_STATUS_COMPLETE )
+ {
+ if(GetReputationMgr().GetReputation(factionEntry) < qInfo->GetRepObjectiveValue())
+ IncompleteQuest( questid );
+ }
+ }
+ }
+ }
+ }
+}
+
bool Player::HasQuestForItem( uint32 itemid ) const
{
- for( QuestStatusMap::const_iterator i = mQuestStatus.begin( ); i != mQuestStatus.end( ); ++i )
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
{
- QuestStatusData const& q_status = i->second;
+ uint32 questid = GetQuestSlotQuestId(i);
+ if ( questid == 0 )
+ continue;
+
+ QuestStatusMap::const_iterator qs_itr = mQuestStatus.find(questid);
+ if(qs_itr == mQuestStatus.end())
+ continue;
+
+ QuestStatusData const& q_status = qs_itr->second;
if (q_status.m_status == QUEST_STATUS_INCOMPLETE)
{
- Quest const* qinfo = objmgr.GetQuestTemplate(i->first);
+ Quest const* qinfo = objmgr.GetQuestTemplate(questid);
if(!qinfo)
continue;
@@ -13479,28 +13718,21 @@ bool Player::HasQuestForItem( uint32 itemid ) const
for (int j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; j++)
{
// examined item is a source item
- if (qinfo->ReqSourceId[j] == itemid && qinfo->ReqSourceRef[j] > 0 && qinfo->ReqSourceRef[j] <= QUEST_OBJECTIVES_COUNT)
+ if (qinfo->ReqSourceId[j] == itemid)
{
- uint32 idx = qinfo->ReqSourceRef[j]-1;
+ ItemPrototype const *pProto = objmgr.GetItemPrototype(itemid);
- // total count of created ReqItems and SourceItems is less than ReqItemCount
- if(qinfo->ReqItemId[idx] != 0 &&
- q_status.m_itemcount[idx] * qinfo->ReqSourceCount[j] + GetItemCount(itemid,true) < qinfo->ReqItemCount[idx] * qinfo->ReqSourceCount[j])
+ // 'unique' item
+ if (pProto->MaxCount && GetItemCount(itemid,true) < pProto->MaxCount)
return true;
- // total count of casted ReqCreatureOrGOs and SourceItems is less than ReqCreatureOrGOCount
- if (qinfo->ReqCreatureOrGOId[idx] != 0)
+ // allows custom amount drop when not 0
+ if (qinfo->ReqSourceCount[j])
{
- if(q_status.m_creatureOrGOcount[idx] * qinfo->ReqSourceCount[j] + GetItemCount(itemid,true) < qinfo->ReqCreatureOrGOCount[idx] * qinfo->ReqSourceCount[j])
+ if (GetItemCount(itemid,true) < qinfo->ReqSourceCount[j])
return true;
- }
- // spell with SPELL_EFFECT_QUEST_COMPLETE or SPELL_EFFECT_SEND_EVENT (with script) case
- else if(qinfo->ReqSpell[idx] != 0)
- {
- // not casted and need more reagents/item for use.
- if(!q_status.m_explored && GetItemCount(itemid,true) < qinfo->ReqSourceCount[j])
- return true;
- }
+ } else if (GetItemCount(itemid,true) < pProto->Stackable)
+ return true;
}
}
}
@@ -13524,13 +13756,12 @@ void Player::SendQuestReward( Quest const *pQuest, uint32 XP, Object * questGive
uint32 questid = pQuest->GetQuestId();
sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questid );
gameeventmgr.HandleQuestComplete(questid);
- WorldPacket data( SMSG_QUESTGIVER_QUEST_COMPLETE, (4+4+4+4+4+4+pQuest->GetRewItemsCount()*8) );
- data << questid;
- data << uint32(0x03);
+ WorldPacket data( SMSG_QUESTGIVER_QUEST_COMPLETE, (4+4+4+4+4) );
+ data << uint32(questid);
if ( getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) )
{
- data << XP;
+ data << uint32(XP);
data << uint32(pQuest->GetRewOrReqMoney());
}
else
@@ -13538,16 +13769,9 @@ void Player::SendQuestReward( Quest const *pQuest, uint32 XP, Object * questGive
data << uint32(0);
data << uint32(pQuest->GetRewOrReqMoney() + int32(pQuest->GetRewMoneyMaxLevel() * sWorld.getRate(RATE_DROP_MONEY)));
}
- data << uint32(0); // new 2.3.0, HonorPoints?
- data << uint32( pQuest->GetRewItemsCount() ); // max is 5
- for (uint32 i = 0; i < pQuest->GetRewItemsCount(); ++i)
- {
- if ( pQuest->RewItemId[i] > 0 )
- data << pQuest->RewItemId[i] << pQuest->RewItemCount[i];
- else
- data << uint32(0) << uint32(0);
- }
+ data << uint32(10*Trinity::Honor::hk_honor_at_level(getLevel(), pQuest->GetRewHonorableKills()));
+ data << uint32(pQuest->GetBonusTalents()); // bonus talents
GetSession()->SendPacket( &data );
if (pQuest->GetQuestCompleteScript() != 0)
@@ -13558,8 +13782,9 @@ void Player::SendQuestFailed( uint32 quest_id )
{
if( quest_id )
{
- WorldPacket data( SMSG_QUESTGIVER_QUEST_FAILED, 4 );
+ WorldPacket data( SMSG_QUESTGIVER_QUEST_FAILED, 4+4 );
data << quest_id;
+ data << uint32(0); // failed reason (4 for inventory is full)
GetSession()->SendPacket( &data );
sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_FAILED");
}
@@ -13598,10 +13823,10 @@ void Player::SendPushToPartyResponse( Player *pPlayer, uint32 msg )
void Player::SendQuestUpdateAddItem( Quest const* pQuest, uint32 item_idx, uint32 count )
{
- WorldPacket data( SMSG_QUESTUPDATE_ADD_ITEM, (4+4) );
+ WorldPacket data( SMSG_QUESTUPDATE_ADD_ITEM, 0 );
sLog.outDebug( "WORLD: Sent SMSG_QUESTUPDATE_ADD_ITEM" );
- data << pQuest->ReqItemId[item_idx];
- data << count;
+ //data << pQuest->ReqItemId[item_idx];
+ //data << count;
GetSession()->SendPacket( &data );
}
@@ -13647,7 +13872,7 @@ bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid )
if(!LoadValues( fields[1].GetString()))
{
- sLog.outError("ERROR: Player #%d have broken data in `data` field. Can't be loaded.",GUID_LOPART(guid));
+ sLog.outError("Player #%d have broken data in `data` field. Can't be loaded for character list.",GUID_LOPART(guid));
if(delete_result) delete result;
return false;
}
@@ -13717,7 +13942,7 @@ void Player::_LoadArenaTeamInfo(QueryResult *result)
ArenaTeam* aTeam = objmgr.GetArenaTeamById(arenateamid);
if(!aTeam)
{
- sLog.outError("FATAL: couldn't load arenateam %u", arenateamid);
+ sLog.outError("Player::_LoadArenaTeamInfo: couldn't load arenateam %u, week %u, season %u, rating %u", arenateamid, played_week, played_season, personal_rating);
continue;
}
uint8 arenaSlot = aTeam->GetSlot();
@@ -13835,13 +14060,13 @@ float Player::GetFloatValueFromDB(uint16 index, uint64 guid)
bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
{
- //// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [28] [29] 30 31 32 33
- //QueryResult *result = CharacterDatabase.PQuery("SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty, arena_pending_points FROM characters WHERE guid = '%u'", guid);
+ //// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [28] [29] 30 31 32 33 34 35 36 37 38 39 40
+ //QueryResult *result = CharacterDatabase.PQuery("SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty, arena_pending_points,bgid,bgteam,bgmap,bgx,bgy,bgz,bgo FROM characters WHERE guid = '%u'", guid);
QueryResult *result = holder->GetResult(PLAYER_LOGIN_QUERY_LOADFROM);
if(!result)
{
- sLog.outError("ERROR: Player (GUID: %u) not found in table `characters`, can't load. ",guid);
+ sLog.outError("Player (GUID: %u) not found in table `characters`, can't load. ",guid);
return false;
}
@@ -13853,7 +14078,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
// player should be able to load/delete character only with correct account!
if( dbAccountId != GetSession()->GetAccountId() )
{
- sLog.outError("ERROR: Player (GUID: %u) loading from wrong account (is: %u, should be: %u)",guid,GetSession()->GetAccountId(),dbAccountId);
+ sLog.outError("Player (GUID: %u) loading from wrong account (is: %u, should be: %u)",guid,GetSession()->GetAccountId(),dbAccountId);
delete result;
return false;
}
@@ -13863,7 +14088,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
m_name = fields[3].GetCppString();
// check name limitations
- if(!ObjectMgr::IsValidName(m_name) || GetSession()->GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(m_name))
+ if(!ObjectMgr::IsValidName(m_name) || (GetSession()->GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(m_name)))
{
delete result;
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid ='%u'", uint32(AT_LOGIN_RENAME),guid);
@@ -13872,7 +14097,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
if(!LoadValues( fields[2].GetString()))
{
- sLog.outError("ERROR: Player #%d have broken data in `data` field. Can't be loaded.",GUID_LOPART(guid));
+ sLog.outError("Player #%d have broken data in `data` field. Can't be loaded.",GUID_LOPART(guid));
delete result;
return false;
}
@@ -13904,23 +14129,18 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
//Need to call it to initialize m_team (m_team can be calculated from m_race)
//Other way is to saves m_team into characters table.
setFactionForRace(m_race);
- SetCharm(0);
m_class = fields[5].GetUInt8();
- PlayerInfo const *info = objmgr.GetPlayerInfo(m_race, m_class);
- if(!info)
- {
- sLog.outError("Player have incorrect race/class pair. Can't be loaded.");
- delete result;
+ // load home bind and check in same time class/race pair, it used later for restore broken positions
+ if(!_LoadHomeBind(holder->GetResult(PLAYER_LOGIN_QUERY_LOADHOMEBIND)))
return false;
- }
InitPrimaryProffesions(); // to max set before any spell loaded
+ // init saved position, and fix it later if problematic
uint32 transGUID = fields[24].GetUInt32();
Relocate(fields[6].GetFloat(),fields[7].GetFloat(),fields[8].GetFloat(),fields[10].GetFloat());
- SetFallInformation(0, fields[8].GetFloat());
SetMapId(fields[9].GetUInt32());
SetDifficulty(fields[32].GetUInt32()); // may be changed in _LoadGroup
@@ -13954,10 +14174,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
if(!IsPositionValid())
{
- sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
-
- SetMapId(info->mapId);
- Relocate(info->positionX,info->positionY,info->positionZ,0.0f);
+ sLog.outError("Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
+ RelocateToHomebind();
transGUID = 0;
@@ -13967,49 +14185,57 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
m_movementInfo.t_o = 0.0f;
}
- if(!_LoadHomeBind(holder->GetResult(PLAYER_LOGIN_QUERY_LOADHOMEBIND)))
- return false;
+ uint32 bgid = fields[34].GetUInt32();
+ uint32 bgteam = fields[35].GetUInt32();
- // load the player's map here if it's not already loaded
- Map *map = GetMap();
- if (!map)
+ if(bgid) //saved in BattleGround
{
- AreaTrigger const* at = objmgr.GetGoBackTrigger(GetMapId());
- if(at)
+ SetBattleGroundEntryPoint(fields[36].GetUInt32(),fields[37].GetFloat(),fields[38].GetFloat(),fields[39].GetFloat(),fields[40].GetFloat());
+
+ // check entry point and fix to homebind if need
+ MapEntry const* mapEntry = sMapStore.LookupEntry(m_bgEntryPoint.mapid);
+ if(!mapEntry || mapEntry->Instanceable() || !MapManager::IsValidMapCoord(m_bgEntryPoint))
+ SetBattleGroundEntryPoint(m_homebindMapId,m_homebindX,m_homebindY,m_homebindZ,0.0f);
+
+ BattleGround *currentBg = sBattleGroundMgr.GetBattleGround(bgid, BATTLEGROUND_TYPE_NONE);
+
+ if(currentBg && currentBg->IsPlayerInBattleGround(GetGUID()))
{
- SetMapId(at->target_mapId);
- Relocate(at->target_X, at->target_Y, at->target_Z, GetOrientation());
- sLog.outError("Player (guidlow %d) is teleported to gobacktrigger (Map: %u X: %f Y: %f Z: %f O: %f).",guid,GetMapId(),GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
+ BattleGroundQueueTypeId bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(currentBg->GetTypeID(), currentBg->GetArenaType());
+ AddBattleGroundQueueId(bgQueueTypeId);
+
+ SetBattleGroundId(currentBg->GetInstanceID(), currentBg->GetTypeID());
+ SetBGTeam(bgteam);
+
+ //join player to battleground group
+ currentBg->EventPlayerLoggedIn(this, GetGUID());
+ currentBg->AddOrSetPlayerToCorrectBgGroup(this, GetGUID(), bgteam);
+
+ SetInviteForBattleGroundQueueType(bgQueueTypeId,currentBg->GetInstanceID());
}
else
{
- SetMapId(m_homebindMapId);
- Relocate(m_homebindX, m_homebindY, m_homebindZ, GetOrientation());
- sLog.outError("Player (guidlow %d) is teleported to home (Map: %u X: %f Y: %f Z: %f O: %f).",guid,GetMapId(),GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
+ Relocate(GetBattleGroundEntryPoint());
+ //RemoveArenaAuras(true);
}
-
- map = GetMap();
- if(!map)
+ }
+ else
+ {
+ MapEntry const* mapEntry = sMapStore.LookupEntry(GetMapId());
+ // if server restart after player save in BG or area
+ // player can have current coordinates in to BG/Arean map, fix this
+ if(!mapEntry || mapEntry->IsBattleGroundOrArena())
{
- sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
+ // return to BG master
+ SetMapId(fields[36].GetUInt32());
+ Relocate(fields[37].GetFloat(),fields[38].GetFloat(),fields[39].GetFloat(),fields[40].GetFloat());
- SetMapId(info->mapId);
- Relocate(info->positionX,info->positionY,info->positionZ,0.0f);
-
- map = GetMap();
- if(!map)
- {
- sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
- sLog.outError("CRASH.");
- assert(false);
- }
+ // check entry point and fix to homebind if need
+ mapEntry = sMapStore.LookupEntry(GetMapId());
+ if(!mapEntry || mapEntry->IsBattleGroundOrArena() || !IsPositionValid())
+ RelocateToHomebind();
}
}
- // since the player may not be bound to the map yet, make sure subsequent
- // getmap calls won't create new maps
- SetInstanceId(map->GetInstanceId());
-
- SaveRecallPosition();
if (transGUID != 0)
{
@@ -14024,12 +14250,11 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
// transport size limited
m_movementInfo.t_x > 50 || m_movementInfo.t_y > 50 || m_movementInfo.t_z > 50 )
{
- sLog.outError("ERROR: Player (guidlow %d) have invalid transport coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",
+ sLog.outError("Player (guidlow %d) have invalid transport coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",
guid,GetPositionX()+m_movementInfo.t_x,GetPositionY()+m_movementInfo.t_y,
GetPositionZ()+m_movementInfo.t_z,GetOrientation()+m_movementInfo.t_o);
- SetMapId(info->mapId);
- Relocate(info->positionX,info->positionY,info->positionZ,0.0f);
+ RelocateToHomebind();
m_movementInfo.t_x = 0.0f;
m_movementInfo.t_y = 0.0f;
@@ -14046,6 +14271,14 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
{
if( (*iter)->GetGUIDLow() == transGUID)
{
+ MapEntry const* transMapEntry = sMapStore.LookupEntry((*iter)->GetMapId());
+ // client without expansion support
+ if(GetSession()->Expansion() < transMapEntry->Expansion())
+ {
+ sLog.outDebug("Player %s using client without required expansion tried login at transport at non accessible map %u", GetName(), (*iter)->GetMapId());
+ break;
+ }
+
m_transport = *iter;
m_transport->AddPassenger(this);
SetMapId(m_transport->GetMapId());
@@ -14055,11 +14288,10 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
if(!m_transport)
{
- sLog.outError("ERROR: Player (guidlow %d) have invalid transport guid (%u). Teleport to default race/class locations.",
+ sLog.outError("Player (guidlow %d) have problems with transport guid (%u). Teleport to default race/class locations.",
guid,transGUID);
- SetMapId(info->mapId);
- Relocate(info->positionX,info->positionY,info->positionZ,0.0f);
+ RelocateToHomebind();
m_movementInfo.t_x = 0.0f;
m_movementInfo.t_y = 0.0f;
@@ -14069,6 +14301,71 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
transGUID = 0;
}
}
+ else // not transport case
+ {
+ MapEntry const* mapEntry = sMapStore.LookupEntry(GetMapId());
+ // client without expansion support
+ if(GetSession()->Expansion() < mapEntry->Expansion())
+ {
+ sLog.outDebug("Player %s using client without required expansion tried login at non accessible map %u", GetName(), GetMapId());
+ RelocateToHomebind();
+ }
+ }
+
+ // NOW player must have valid map
+ // load the player's map here if it's not already loaded
+ Map *map = GetMap();
+
+ if (!map)
+ {
+ AreaTrigger const* at = objmgr.GetGoBackTrigger(GetMapId());
+ if(at)
+ {
+ SetMapId(at->target_mapId);
+ Relocate(at->target_X, at->target_Y, at->target_Z, GetOrientation());
+ sLog.outError("Player (guidlow %d) is teleported to gobacktrigger (Map: %u X: %f Y: %f Z: %f O: %f).",guid,GetMapId(),GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
+ }
+ else
+ {
+ RelocateToHomebind();
+ sLog.outError("Player (guidlow %d) is teleported to home (Map: %u X: %f Y: %f Z: %f O: %f).",guid,GetMapId(),GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
+ }
+
+ map = GetMap();
+ if(!map)
+ {
+ sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
+ delete result;
+ return false;
+
+ /*SetMapId(info->mapId);
+ Relocate(info->positionX,info->positionY,info->positionZ,0.0f);
+
+ map = GetMap();
+ if(!map)
+ {
+ sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
+ sLog.outError("CRASH.");
+ assert(false);
+ }*/
+ }
+ }
+
+ // since the player may not be bound to the map yet, make sure subsequent
+ // getmap calls won't create new maps
+ SetInstanceId(map->GetInstanceId());
+
+ // if the player is in an instance and it has been reset in the meantime teleport him to the entrance
+ if(GetInstanceId() && !sInstanceSaveManager.GetInstanceSave(GetInstanceId()))
+ {
+ AreaTrigger const* at = objmgr.GetMapEntranceTrigger(GetMapId());
+ if(at)
+ Relocate(at->target_X, at->target_Y, at->target_Z, at->target_Orientation);
+ else
+ sLog.outError("Player %s(GUID: %u) logged in to a reset instance (map: %u) and there is no aretrigger leading to this map. Thus he can't be ported back to the entrance. This _might_ be an exploit attempt.", GetName(), GetGUIDLow(), GetMapId());
+ }
+
+ SaveRecallPosition();
time_t now = time(NULL);
time_t logoutTime = time_t(fields[16].GetUInt64());
@@ -14119,10 +14416,10 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
uint32 extraflags = fields[25].GetUInt32();
m_stableSlots = fields[26].GetUInt32();
- if(m_stableSlots > 2)
+ if(m_stableSlots > MAX_PET_STABLES)
{
- sLog.outError("Player can have not more 2 stable slots, but have in DB %u",uint32(m_stableSlots));
- m_stableSlots = 2;
+ sLog.outError("Player can have not more %u stable slots, but have in DB %u",MAX_PET_STABLES,uint32(m_stableSlots));
+ m_stableSlots = MAX_PET_STABLES;
}
m_atLoginFlags = fields[27].GetUInt32();
@@ -14145,35 +14442,18 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
SetUInt32Value(UNIT_CHANNEL_SPELL,0);
// clear charm/summon related fields
- SetCharm(NULL);
- SetPet(NULL);
- SetCharmerGUID(NULL);
- SetOwnerGUID(NULL);
- SetCreatorGUID(NULL);
+ SetUInt64Value(UNIT_FIELD_SUMMONEDBY, 0);
+ SetUInt64Value(UNIT_FIELD_CHARMEDBY, 0);
+ SetUInt64Value(UNIT_FIELD_CHARM, 0);
+ SetUInt64Value(UNIT_FIELD_SUMMON, 0);
+ SetUInt64Value(PLAYER_FARSIGHT, 0);
+ SetCreatorGUID(0);
// reset some aura modifiers before aura apply
- SetFarSight(NULL);
SetUInt32Value(PLAYER_TRACK_CREATURES, 0 );
SetUInt32Value(PLAYER_TRACK_RESOURCES, 0 );
- // reset skill modifiers and set correct unlearn flags
- for (uint32 i = 0; i < PLAYER_MAX_SKILLS; i++)
- {
- SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0);
-
- // set correct unlearn bit
- uint32 id = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF;
- if(!id) continue;
-
- SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(id);
- if(!pSkill) continue;
-
- // enable unlearn button for primary professions only
- if (pSkill->categoryId == SKILL_CATEGORY_PROFESSION)
- SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,1));
- else
- SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,0));
- }
+ _LoadSkills();
// make sure the unit is considered out of combat for proper loading
ClearInCombat();
@@ -14191,6 +14471,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
// reset stats before loading any modifiers
InitStatsForLevel();
InitTaxiNodesForLevel();
+ InitGlyphsForLevel();
+ InitRunes();
// apply original stats mods before spell loading or item equipment that call before equip _RemoveStatsMods()
@@ -14198,25 +14480,25 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
//_LoadMail();
_LoadAuras(holder->GetResult(PLAYER_LOGIN_QUERY_LOADAURAS), time_diff);
-
+ _LoadGlyphAuras();
// add ghost flag (must be after aura load: PLAYER_FLAGS_GHOST set in aura)
if( HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST) )
m_deathState = DEAD;
_LoadSpells(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSPELLS));
- // after spell load
- InitTalentForLevel();
- learnSkillRewardedSpells();
-
// after spell load, learn rewarded spell if need also
_LoadQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS));
_LoadDailyQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS));
+ // after spell and quest load
+ InitTalentForLevel();
+ learnDefaultSpells();
+
_LoadTutorials(holder->GetResult(PLAYER_LOGIN_QUERY_LOADTUTORIALS));
// must be before inventory (some items required reputation check)
- _LoadReputation(holder->GetResult(PLAYER_LOGIN_QUERY_LOADREPUTATION));
+ m_reputationMgr.LoadFromDB(holder->GetResult(PLAYER_LOGIN_QUERY_LOADREPUTATION));
_LoadInventory(holder->GetResult(PLAYER_LOGIN_QUERY_LOADINVENTORY), time_diff);
@@ -14230,9 +14512,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
m_social = sSocialMgr.LoadFromDB(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSOCIALLIST), GetGUIDLow());
- //if(!_LoadHomeBind(holder->GetResult(PLAYER_LOGIN_QUERY_LOADHOMEBIND)))
- // return false;
-
// check PLAYER_CHOSEN_TITLE compatibility with PLAYER__FIELD_KNOWN_TITLES
// note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded
if(uint32 curTitle = GetUInt32Value(PLAYER_CHOSEN_TITLE))
@@ -14242,7 +14521,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
}
// Not finish taxi flight path
- if(!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes))
+ if(!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes,GetTeam()))
{
// problems with taxi path loading
TaxiNodesEntry const* nodeEntry = NULL;
@@ -14252,8 +14531,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
if(!nodeEntry) // don't know taxi start node, to homebind
{
sLog.outError("Character %u have wrong data in taxi destination list, teleport to homebind.",GetGUIDLow());
- SetMapId(m_homebindMapId);
- Relocate( m_homebindX, m_homebindY, m_homebindZ,0.0f);
+ RelocateToHomebind();
SaveRecallPosition(); // save as recall also to prevent recall and fall from sky
}
else // have start node, to it
@@ -14278,6 +14556,9 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
// flight will started later
}
+ // has to be called after last Relocate() in Player::LoadFromDB
+ SetFallInformation(0, GetPositionZ());
+
_LoadSpellCooldowns(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSPELLCOOLDOWNS));
// Spell code allow apply any auras to dead character in load time in aura/spell/item loading
@@ -14311,6 +14592,28 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
break;
}
+ switch(sWorld.getConfig(CONFIG_GM_VISIBLE_STATE))
+ {
+ default:
+ case 0: SetGMVisible(false); break; // invisible
+ case 1: break; // visible
+ case 2: // save state
+ if(extraflags & PLAYER_EXTRA_GM_INVISIBLE)
+ SetGMVisible(false);
+ break;
+ }
+
+ /*switch(sWorld.getConfig(CONFIG_GM_ACCEPT_TICKETS))
+ {
+ default:
+ case 0: break; // disable
+ case 1: SetAcceptTicket(true); break; // enable
+ case 2: // save state
+ if(extraflags & PLAYER_EXTRA_GM_ACCEPT_TICKETS)
+ SetAcceptTicket(true);
+ break;
+ }*/
+
switch(sWorld.getConfig(CONFIG_GM_CHAT))
{
default:
@@ -14336,6 +14639,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
_LoadDeclinedNames(holder->GetResult(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES));
+ m_achievementMgr.LoadFromDB(holder->GetResult(PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS), holder->GetResult(PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS));
+ m_achievementMgr.CheckAllAchievementCriteria();
return true;
}
@@ -14373,9 +14678,15 @@ void Player::_LoadActions(QueryResult *result)
uint8 button = fields[0].GetUInt8();
- addActionButton(button, fields[1].GetUInt16(), fields[2].GetUInt8(), fields[3].GetUInt8());
+ if(addActionButton(button, fields[1].GetUInt16(), fields[2].GetUInt8(), fields[3].GetUInt8()))
+ m_actionButtons[button].uState = ACTIONBUTTON_UNCHANGED;
+ else
+ {
+ sLog.outError( " ...at loading, and will deleted in DB also");
- m_actionButtons[button].uState = ACTIONBUTTON_UNCHANGED;
+ // Will deleted in DB at next save (it can create data until save but marked as deleted)
+ m_actionButtons[button].uState = ACTIONBUTTON_DELETED;
+ }
}
while( result->NextRow() );
@@ -14385,45 +14696,36 @@ void Player::_LoadActions(QueryResult *result)
void Player::_LoadAuras(QueryResult *result, uint32 timediff)
{
- m_Auras.clear();
- for (int i = 0; i < TOTAL_AURAS; i++)
- m_modAuras[i].clear();
-
- // all aura related fields
- for(int i = UNIT_FIELD_AURA; i <= UNIT_FIELD_AURASTATE; ++i)
- SetUInt32Value(i, 0);
+ sLog.outDebug("Loading auras for player %u",GetGUIDLow());
- //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow());
+ //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_mask,stackcount,amount0,amount1,amount2,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow());
if(result)
{
do
{
+ int32 damage[3];
Field *fields = result->Fetch();
uint64 caster_guid = fields[0].GetUInt64();
uint32 spellid = fields[1].GetUInt32();
- uint32 effindex = fields[2].GetUInt32();
+ uint32 effmask = fields[2].GetUInt32();
uint32 stackcount = fields[3].GetUInt32();
- int32 damage = (int32)fields[4].GetUInt32();
- int32 maxduration = (int32)fields[5].GetUInt32();
- int32 remaintime = (int32)fields[6].GetUInt32();
- int32 remaincharges = (int32)fields[7].GetUInt32();
+ damage[0] = int32(fields[4].GetUInt32());
+ damage[1] = int32(fields[5].GetUInt32());
+ damage[2] = int32(fields[6].GetUInt32());
+ int32 maxduration = (int32)fields[7].GetUInt32();
+ int32 remaintime = (int32)fields[8].GetUInt32();
+ int32 remaincharges = (int32)fields[9].GetUInt32();
SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid);
if(!spellproto)
{
- sLog.outError("Unknown aura (spellid %u, effindex %u), ignore.",spellid,effindex);
- continue;
- }
-
- if(effindex >= 3)
- {
- sLog.outError("Invalid effect index (spellid %u, effindex %u), ignore.",spellid,effindex);
+ sLog.outError("Unknown aura (spellid %u), ignore.",spellid);
continue;
}
// negative effects should continue counting down after logout
- if (remaintime != -1 && !IsPositiveEffect(spellid, effindex))
+ if (remaintime != -1 && !IsPositiveSpell(spellid))
{
if(remaintime <= int32(timediff))
continue;
@@ -14438,21 +14740,12 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
remaincharges = spellproto->procCharges;
}
else
- remaincharges = -1;
-
- //do not load single target auras (unless they were cast by the player)
- if (caster_guid != GetGUID() && IsSingleTargetSpell(spellproto))
- continue;
+ remaincharges = 0;
- for(uint32 i=0; i<stackcount; i++)
- {
- Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL);
- if(!damage)
- damage = aura->GetModifier()->m_amount;
- aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges);
- AddAura(aura);
- sLog.outDetail("Added aura spellid %u, effect %u", spellproto->Id, effindex);
- }
+ Aura* aura = new Aura(spellproto, effmask, NULL, this, NULL, NULL);
+ aura->SetLoadedState(caster_guid,maxduration,remaintime,remaincharges, stackcount, &damage[0]);
+ AddAura(aura);
+ sLog.outDetail("Added aura spellid %u, effectmask %u", spellproto->Id, effmask);
}
while( result->NextRow() );
@@ -14463,6 +14756,36 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
CastSpell(this,SPELL_ID_PASSIVE_BATTLE_STANCE,true);
}
+void Player::_LoadGlyphAuras()
+{
+ for (uint8 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i)
+ {
+ if (uint32 glyph = GetGlyph(i))
+ {
+ if (GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph))
+ {
+ if (GlyphSlotEntry const *gs = sGlyphSlotStore.LookupEntry(GetGlyphSlot(i)))
+ {
+ if(gp->TypeFlags == gs->TypeFlags)
+ {
+ CastSpell(this, gp->SpellId, true);
+ continue;
+ }
+ else
+ sLog.outError("Player %s has glyph with typeflags %u in slot with typeflags %u, removing.", m_name.c_str(), gp->TypeFlags, gs->TypeFlags);
+ }
+ else
+ sLog.outError("Player %s has not existing glyph slot entry %u on index %u", m_name.c_str(), GetGlyphSlot(i), i);
+ }
+ else
+ sLog.outError("Player %s has not existing glyph entry %u on index %u", m_name.c_str(), glyph, i);
+
+ // On any error remove glyph
+ SetGlyph(i, 0);
+ }
+ }
+}
+
void Player::LoadCorpse()
{
if( isAlive() )
@@ -14638,15 +14961,16 @@ void Player::_LoadInventory(QueryResult *result, uint32 timediff)
// load mailed item which should receive current player
void Player::_LoadMailedItems(Mail *mail)
{
- QueryResult* result = CharacterDatabase.PQuery("SELECT item_guid, item_template FROM mail_items WHERE mail_id='%u'", mail->messageID);
+ // data needs to be at first place for Item::LoadFromDB
+ QueryResult* result = CharacterDatabase.PQuery("SELECT data, item_guid, item_template FROM mail_items JOIN item_instance ON item_guid = guid WHERE mail_id='%u'", mail->messageID);
if(!result)
return;
do
{
Field *fields = result->Fetch();
- uint32 item_guid_low = fields[0].GetUInt32();
- uint32 item_template = fields[1].GetUInt32();
+ uint32 item_guid_low = fields[1].GetUInt32();
+ uint32 item_template = fields[2].GetUInt32();
mail->AddItem(item_guid_low, item_template);
@@ -14662,7 +14986,7 @@ void Player::_LoadMailedItems(Mail *mail)
Item *item = NewItemOrBag(proto);
- if(!item->LoadFromDB(item_guid_low, 0))
+ if(!item->LoadFromDB(item_guid_low, 0, result))
{
sLog.outError( "Player::_LoadMailedItems - Item in mail (%u) doesn't exist !!!! - item guid: %u, deleted from mail", mail->messageID, item_guid_low);
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", item_guid_low);
@@ -14748,7 +15072,7 @@ void Player::LoadPet()
// just not added to the map
if(IsInWorld())
{
- Pet *pet = new Pet;
+ Pet *pet = new Pet(this);
if(!pet->LoadPetFromDB(this,0,0,true))
delete pet;
}
@@ -14798,7 +15122,7 @@ void Player::_LoadQuestStatus(QueryResult *result)
if (quest_time <= sWorld.GetGameTime())
questStatusData.m_timer = 1;
else
- questStatusData.m_timer = (quest_time - sWorld.GetGameTime()) * 1000;
+ questStatusData.m_timer = (quest_time - sWorld.GetGameTime()) * IN_MILISECONDS;
}
else
quest_time = 0;
@@ -14843,6 +15167,9 @@ void Player::_LoadQuestStatus(QueryResult *result)
if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(pQuest->GetCharTitleId()))
SetTitle(titleEntry);
}
+
+ if(pQuest->GetBonusTalents())
+ m_questRewardTalentCount+=pQuest->GetBonusTalents();
}
sLog.outDebug("Quest status is {%u} for quest {%u} for player (GUID: %u)", questStatusData.m_status, quest_id, GetGUIDLow());
@@ -14901,68 +15228,9 @@ void Player::_LoadDailyQuestStatus(QueryResult *result)
m_DailyQuestChanged = false;
}
-void Player::_LoadReputation(QueryResult *result)
-{
- m_factions.clear();
-
- // Set initial reputations (so everything is nifty before DB data load)
- SetInitialFactions();
-
- //QueryResult *result = CharacterDatabase.PQuery("SELECT faction,standing,flags FROM character_reputation WHERE guid = '%u'",GetGUIDLow());
-
- if(result)
- {
- do
- {
- Field *fields = result->Fetch();
-
- FactionEntry const *factionEntry = sFactionStore.LookupEntry(fields[0].GetUInt32());
- if( factionEntry && (factionEntry->reputationListID >= 0))
- {
- FactionState* faction = &m_factions[factionEntry->reputationListID];
-
- // update standing to current
- faction->Standing = int32(fields[1].GetUInt32());
-
- uint32 dbFactionFlags = fields[2].GetUInt32();
-
- if( dbFactionFlags & FACTION_FLAG_VISIBLE )
- SetFactionVisible(faction); // have internal checks for forced invisibility
-
- if( dbFactionFlags & FACTION_FLAG_INACTIVE)
- SetFactionInactive(faction,true); // have internal checks for visibility requirement
-
- if( dbFactionFlags & FACTION_FLAG_AT_WAR ) // DB at war
- SetFactionAtWar(faction,true); // have internal checks for FACTION_FLAG_PEACE_FORCED
- else // DB not at war
- {
- // allow remove if visible (and then not FACTION_FLAG_INVISIBLE_FORCED or FACTION_FLAG_HIDDEN)
- if( faction->Flags & FACTION_FLAG_VISIBLE )
- SetFactionAtWar(faction,false); // have internal checks for FACTION_FLAG_PEACE_FORCED
- }
-
- // set atWar for hostile
- if(GetReputationRank(factionEntry) <= REP_HOSTILE)
- SetFactionAtWar(faction,true);
-
- // reset changed flag if values similar to saved in DB
- if(faction->Flags==dbFactionFlags)
- faction->Changed = false;
- }
- }
- while( result->NextRow() );
-
- delete result;
- }
-}
-
void Player::_LoadSpells(QueryResult *result)
{
- for (PlayerSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
- delete itr->second;
- m_spells.clear();
-
- //QueryResult *result = CharacterDatabase.PQuery("SELECT spell,slot,active FROM character_spell WHERE guid = '%u'",GetGUIDLow());
+ //QueryResult *result = CharacterDatabase.PQuery("SELECT spell,active,disabled FROM character_spell WHERE guid = '%u'",GetGUIDLow());
if(result)
{
@@ -14970,7 +15238,7 @@ void Player::_LoadSpells(QueryResult *result)
{
Field *fields = result->Fetch();
- addSpell(fields[0].GetUInt16(), fields[2].GetBool(), false, true, fields[1].GetUInt16(), fields[3].GetBool());
+ addSpell(fields[0].GetUInt16(), fields[1].GetBool(), false, false, fields[2].GetBool());
}
while( result->NextRow() );
@@ -15042,6 +15310,14 @@ void Player::_LoadBoundInstances(QueryResult *result)
// so the value read from the DB may be wrong here but only if the InstanceSave is loaded
// and in that case it is not used
+ MapEntry const* mapEntry = sMapStore.LookupEntry(mapId);
+ if(!mapEntry || !mapEntry->IsDungeon())
+ {
+ sLog.outError("_LoadBoundInstances: player %s(%d) has bind to not existed or not dungeon map %d", GetName(), GetGUIDLow(), mapId);
+ CharacterDatabase.PExecute("DELETE FROM character_instance WHERE guid = '%d' AND instance = '%d'", GetGUIDLow(), instanceId);
+ continue;
+ }
+
if(!perm && group)
{
sLog.outError("_LoadBoundInstances: player %s(%d) is in group %d but has a non-permanent character bind to map %d,%d,%d", GetName(), GetGUIDLow(), GUID_LOPART(group->GetLeaderGUID()), mapId, instanceId, difficulty);
@@ -15119,29 +15395,29 @@ InstancePlayerBind* Player::BindToInstance(InstanceSave *save, bool permanent, b
void Player::SendRaidInfo()
{
+ uint32 counter = 0;
+
WorldPacket data(SMSG_RAID_INSTANCE_INFO, 4);
- uint32 counter = 0, i;
- for(i = 0; i < TOTAL_DIFFICULTIES; i++)
- for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
- if(itr->second.perm) counter++;
+ size_t p_counter = data.wpos();
+ data << uint32(counter); // placeholder
- data << counter;
- for(i = 0; i < TOTAL_DIFFICULTIES; i++)
+ for(int i = 0; i < TOTAL_DIFFICULTIES; ++i)
{
for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
{
if(itr->second.perm)
{
InstanceSave *save = itr->second.save;
- data << (save->GetMapId());
- data << (uint32)(save->GetResetTime() - time(NULL));
- data << save->GetInstanceId();
- data << uint32(counter);
- counter--;
+ data << uint32(save->GetMapId());
+ data << uint32(save->GetResetTime() - time(NULL));
+ data << uint32(save->GetInstanceId());
+ data << uint32(save->GetDifficulty());
+ ++counter;
}
}
}
+ data.put<uint32>(p_counter,counter);
GetSession()->SendPacket(&data);
}
@@ -15275,7 +15551,7 @@ bool Player::Satisfy(AccessRequirement const *ar, uint32 target_map, bool report
if(missingItem)
GetSession()->SendAreaTriggerMessage(GetSession()->GetTrinityString(LANG_LEVEL_MINREQUIRED_AND_ITEM), ar->levelMin, objmgr.GetItemPrototype(missingItem)->Name1);
else if(missingKey)
- SendTransferAborted(target_map, TRANSFER_ABORT_DIFFICULTY2);
+ SendTransferAborted(target_map, TRANSFER_ABORT_DIFFICULTY);
else if(missingHeroicQuest)
GetSession()->SendAreaTriggerMessage(ar->heroicQuestFailedText.c_str());
else if(missingQuest)
@@ -15291,6 +15567,13 @@ bool Player::Satisfy(AccessRequirement const *ar, uint32 target_map, bool report
bool Player::_LoadHomeBind(QueryResult *result)
{
+ PlayerInfo const *info = objmgr.GetPlayerInfo(getRace(), getClass());
+ if(!info)
+ {
+ sLog.outError("Player have incorrect race/class pair. Can't be loaded.");
+ return false;
+ }
+
bool ok = false;
//QueryResult *result = CharacterDatabase.PQuery("SELECT map,zone,position_x,position_y,position_z FROM character_homebind WHERE guid = '%u'", GUID_LOPART(playerGuid));
if (result)
@@ -15303,9 +15586,11 @@ bool Player::_LoadHomeBind(QueryResult *result)
m_homebindZ = fields[4].GetFloat();
delete result;
- // accept saved data only for valid position (and non instanceable)
+ MapEntry const* bindMapEntry = sMapStore.LookupEntry(m_homebindMapId);
+
+ // accept saved data only for valid position (and non instanceable), and accessable
if( MapManager::IsValidMapCoord(m_homebindMapId,m_homebindX,m_homebindY,m_homebindZ) &&
- !sMapStore.LookupEntry(m_homebindMapId)->Instanceable() )
+ !bindMapEntry->Instanceable() && GetSession()->Expansion() >= bindMapEntry->Expansion())
{
ok = true;
}
@@ -15315,9 +15600,6 @@ bool Player::_LoadHomeBind(QueryResult *result)
if(!ok)
{
- PlayerInfo const *info = objmgr.GetPlayerInfo(getRace(), getClass());
- if(!info) return false;
-
m_homebindMapId = info->mapId;
m_homebindZoneId = info->zoneId;
m_homebindX = info->positionX;
@@ -15327,7 +15609,7 @@ bool Player::_LoadHomeBind(QueryResult *result)
CharacterDatabase.PExecute("INSERT INTO character_homebind (guid,map,zone,position_x,position_y,position_z) VALUES ('%u', '%u', '%u', '%f', '%f', '%f')", GetGUIDLow(), m_homebindMapId, (uint32)m_homebindZoneId, m_homebindX, m_homebindY, m_homebindZ);
}
- DEBUG_LOG("Setting player home position: mapid is: %u, zoneid is %u, X is %f, Y is %f, Z is %f\n",
+ DEBUG_LOG("Setting player home position: mapid is: %u, zoneid is %u, X is %f, Y is %f, Z is %f",
m_homebindMapId, m_homebindZoneId, m_homebindX, m_homebindY, m_homebindZ);
return true;
@@ -15345,12 +15627,6 @@ void Player::SaveToDB()
// first save/honor gain after midnight will also update the player's honor fields
UpdateHonorFields();
- // players aren't saved on battleground maps
- uint32 mapid = IsBeingTeleported() ? GetTeleportDest().mapid : GetMapId();
- const MapEntry * me = sMapStore.LookupEntry(mapid);
- if(!me || me->IsBattleGroundOrArena())
- return;
-
int is_save_resting = HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ? 1 : 0;
//save, far from tavern/city
//save, but in tavern/city
@@ -15365,10 +15641,9 @@ void Player::SaveToDB()
uint32 tmp_displayid = GetDisplayId();
// Set player sit state to standing on save, also stealth and shifted form
- SetByteValue(UNIT_FIELD_BYTES_1, 0, 0); // stand state
+ SetByteValue(UNIT_FIELD_BYTES_1, 0, UNIT_STAND_STATE_STAND);
SetByteValue(UNIT_FIELD_BYTES_2, 3, 0); // shapeshift
- SetByteValue(UNIT_FIELD_BYTES_1, 3, 0); // stand flags?
- RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
+ RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
SetDisplayId(GetNativeDisplayId());
bool inworld = IsInWorld();
@@ -15386,23 +15661,14 @@ void Player::SaveToDB()
"taximask, online, cinematic, "
"totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, "
"trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, "
- "death_expire_time, taxi_path, arena_pending_points, latency) VALUES ("
+ "death_expire_time, taxi_path, arena_pending_points, latency, bgid, bgteam, bgmap, bgx, bgy, bgz, bgo) VALUES ("
<< GetGUIDLow() << ", "
<< GetSession()->GetAccountId() << ", '"
<< sql_name << "', "
<< m_race << ", "
<< m_class << ", ";
- bool save_to_dest = false;
- if(IsBeingTeleported())
- {
- // don't save to battlegrounds or arenas
- const MapEntry *entry = sMapStore.LookupEntry(GetTeleportDest().mapid);
- if(entry && entry->map_type != MAP_BATTLEGROUND && entry->map_type != MAP_ARENA)
- save_to_dest = true;
- }
-
- if(!save_to_dest)
+ if(!IsBeingTeleported())
{
ss << GetMapId() << ", "
<< (uint32)GetDifficulty() << ", "
@@ -15427,12 +15693,11 @@ void Player::SaveToDB()
ss << GetUInt32Value(i) << " ";
}
- ss << "', '";
+ ss << "', ";
- for( i = 0; i < 8; i++ )
- ss << m_taxi.GetTaximask(i) << " ";
+ ss << m_taxi; // string with TaxiMaskSize numbers
- ss << "', ";
+ ss << ", ";
ss << (inworld ? 1 : 0);
ss << ", ";
@@ -15475,7 +15740,7 @@ void Player::SaveToDB()
ss << uint32(m_stableSlots); // to prevent save uint8 as char
ss << ", ";
- ss << uint32(m_atLoginFlags);
+ ss << uint32(m_atLoginFlags & ((1<<AT_LOAD_PET_FLAGS) -1));
ss << ", ";
ss << GetZoneId();
@@ -15486,9 +15751,19 @@ void Player::SaveToDB()
ss << ", '";
ss << m_taxi.SaveTaxiDestinationsToString();
- ss << "', '0', '";
+ ss << "', '0', ";
ss << GetSession()->GetLatency();
- ss << "' )";
+ ss << ", ";
+ ss << GetBattleGroundId();
+ ss << ", ";
+ ss << GetBGTeam();
+ ss << ", ";
+ ss << m_bgEntryPoint.mapid << ", "
+ << finiteAlways(m_bgEntryPoint.x) << ", "
+ << finiteAlways(m_bgEntryPoint.y) << ", "
+ << finiteAlways(m_bgEntryPoint.z) << ", "
+ << finiteAlways(m_bgEntryPoint.o);
+ ss << ")";
CharacterDatabase.Execute( ss.str().c_str() );
@@ -15503,7 +15778,8 @@ void Player::SaveToDB()
_SaveSpellCooldowns();
_SaveActions();
_SaveAuras();
- _SaveReputation();
+ m_achievementMgr.SaveToDB();
+ m_reputationMgr.SaveToDB();
CharacterDatabase.CommitTransaction();
@@ -15517,23 +15793,6 @@ void Player::SaveToDB()
// save pet (hunter pet level and experience and all type pets health/mana).
if(Pet* pet = GetPet())
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
-
- //to prevent access to DB we should cache some data, which is used very often
- CachePlayerInfoMap::iterator _iter = objmgr.m_mPlayerInfoMap.find(GetGUIDLow());
- if(_iter != objmgr.m_mPlayerInfoMap.end())//skip new players
- {
- _iter->second->unLevel = getLevel();
-
- _iter->second->unArenaInfoSlot0 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 0 * 6 + 5);
- _iter->second->unArenaInfoSlot1 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 * 6 + 5);
- _iter->second->unArenaInfoSlot2 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 2 * 6 + 5);
-
- _iter->second->unfield = GetUInt32Value(UNIT_FIELD_BYTES_0);
-
- _iter->second->unArenaInfoId0 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (0 * 6));
- _iter->second->unArenaInfoId1 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (1 * 6));
- _iter->second->unArenaInfoId2 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (2 * 6));
- }
}
// fast save function for item/money cheating preventing - save only inventory and money state
@@ -15578,56 +15837,36 @@ void Player::_SaveAuras()
CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u'",GetGUIDLow());
AuraMap const& auras = GetAuras();
+ for(AuraMap::const_iterator itr = auras.begin(); itr !=auras.end() ; ++itr)
+ {
+ // skip:
+ // area auras or single cast auras casted by other unit
+ // passive auras and stances
+ if (itr->second->IsPassive()
+ || itr->second->IsAuraType(SPELL_AURA_MOD_SHAPESHIFT)
+ || itr->second->IsAuraType(SPELL_AURA_MOD_STEALTH)
+ || itr->second->IsRemovedOnShapeLost())
+ continue;
+ bool isCaster = itr->second->GetCasterGUID() == GetGUID();
+ if (!isCaster)
+ if (itr->second->IsSingleTarget()
+ || itr->second->IsAreaAura())
+ continue;
- if (auras.empty())
- return;
-
- spellEffectPair lastEffectPair = auras.begin()->first;
- uint32 stackCounter = 1;
-
- for(AuraMap::const_iterator itr = auras.begin(); ; ++itr)
- {
- if(itr == auras.end() || lastEffectPair != itr->first)
+ int32 amounts[MAX_SPELL_EFFECTS];
+ for (uint8 i=0;i<MAX_SPELL_EFFECTS;++i)
{
- AuraMap::const_iterator itr2 = itr;
- // save previous spellEffectPair to db
- itr2--;
- SpellEntry const *spellInfo = itr2->second->GetSpellProto();
-
- //skip all auras from spells that are passive or need a shapeshift
- if (!(itr2->second->IsPassive() || itr2->second->IsRemovedOnShapeLost()))
- {
- //do not save single target auras (unless they were cast by the player)
- if (!(itr2->second->GetCasterGUID() != GetGUID() && IsSingleTargetSpell(spellInfo)))
- {
- uint8 i;
- // or apply at cast SPELL_AURA_MOD_SHAPESHIFT or SPELL_AURA_MOD_STEALTH auras
- for (i = 0; i < 3; i++)
- if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT ||
- spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH)
- break;
-
- if (i == 3)
- {
- CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges) "
- "VALUES ('%u', '" I64FMTD "' ,'%u', '%u', '%u', '%d', '%d', '%d', '%d')",
- GetGUIDLow(), itr2->second->GetCasterGUID(), (uint32)itr2->second->GetId(), (uint32)itr2->second->GetEffIndex(), (uint32)itr2->second->GetStackAmount(), itr2->second->GetModifier()->m_amount,int(itr2->second->GetAuraMaxDuration()),int(itr2->second->GetAuraDuration()),int(itr2->second->m_procCharges));
- }
- }
- }
-
- if(itr == auras.end())
- break;
+ if (AuraEffect * partAura = itr->second->GetPartAura(i))
+ amounts[i]=partAura->GetAmount();
+ else
+ amounts[i]=0;
}
- //TODO: if need delete this
- if (lastEffectPair == itr->first)
- stackCounter++;
- else
- {
- lastEffectPair = itr->first;
- stackCounter = 1;
- }
+ CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_mask,stackcount,amount0, amount1, amount2,maxduration,remaintime,remaincharges) "
+ "VALUES ('%u', '" I64FMTD "', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
+ GetGUIDLow(), itr->second->GetCasterGUID(),(uint32)itr->second->GetId(), (uint32)itr->second->GetEffectMask(),
+ (int32)itr->second->GetStackAmount(), (int32)amounts[0], (int32)amounts[1], (int32)amounts[2]
+ ,int(itr->second->GetAuraMaxDuration()),int(itr->second->GetAuraDuration()),int(itr->second->GetAuraCharges()));
}
}
@@ -15767,11 +16006,11 @@ void Player::_SaveQuestStatus()
case QUEST_NEW :
CharacterDatabase.PExecute("INSERT INTO character_queststatus (guid,quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4) "
"VALUES ('%u', '%u', '%u', '%u', '%u', '" I64FMTD "', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')",
- GetGUIDLow(), i->first, i->second.m_status, i->second.m_rewarded, i->second.m_explored, uint64(i->second.m_timer / 1000 + sWorld.GetGameTime()), i->second.m_creatureOrGOcount[0], i->second.m_creatureOrGOcount[1], i->second.m_creatureOrGOcount[2], i->second.m_creatureOrGOcount[3], i->second.m_itemcount[0], i->second.m_itemcount[1], i->second.m_itemcount[2], i->second.m_itemcount[3]);
+ GetGUIDLow(), i->first, i->second.m_status, i->second.m_rewarded, i->second.m_explored, uint64(i->second.m_timer / IN_MILISECONDS+ sWorld.GetGameTime()), i->second.m_creatureOrGOcount[0], i->second.m_creatureOrGOcount[1], i->second.m_creatureOrGOcount[2], i->second.m_creatureOrGOcount[3], i->second.m_itemcount[0], i->second.m_itemcount[1], i->second.m_itemcount[2], i->second.m_itemcount[3]);
break;
case QUEST_CHANGED :
CharacterDatabase.PExecute("UPDATE character_queststatus SET status = '%u',rewarded = '%u',explored = '%u',timer = '" I64FMTD "',mobcount1 = '%u',mobcount2 = '%u',mobcount3 = '%u',mobcount4 = '%u',itemcount1 = '%u',itemcount2 = '%u',itemcount3 = '%u',itemcount4 = '%u' WHERE guid = '%u' AND quest = '%u' ",
- i->second.m_status, i->second.m_rewarded, i->second.m_explored, uint64(i->second.m_timer / 1000 + sWorld.GetGameTime()), i->second.m_creatureOrGOcount[0], i->second.m_creatureOrGOcount[1], i->second.m_creatureOrGOcount[2], i->second.m_creatureOrGOcount[3], i->second.m_itemcount[0], i->second.m_itemcount[1], i->second.m_itemcount[2], i->second.m_itemcount[3], GetGUIDLow(), i->first );
+ i->second.m_status, i->second.m_rewarded, i->second.m_explored, uint64(i->second.m_timer / IN_MILISECONDS + sWorld.GetGameTime()), i->second.m_creatureOrGOcount[0], i->second.m_creatureOrGOcount[1], i->second.m_creatureOrGOcount[2], i->second.m_creatureOrGOcount[3], i->second.m_itemcount[0], i->second.m_itemcount[1], i->second.m_itemcount[2], i->second.m_itemcount[3], GetGUIDLow(), i->first );
break;
case QUEST_UNCHANGED:
break;
@@ -15797,33 +16036,28 @@ void Player::_SaveDailyQuestStatus()
GetGUIDLow(), GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx),uint64(m_lastDailyQuestTime));
}
-void Player::_SaveReputation()
-{
- for(FactionStateList::iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr)
- {
- if (itr->second.Changed)
- {
- CharacterDatabase.PExecute("DELETE FROM character_reputation WHERE guid = '%u' AND faction='%u'", GetGUIDLow(), itr->second.ID);
- CharacterDatabase.PExecute("INSERT INTO character_reputation (guid,faction,standing,flags) VALUES ('%u', '%u', '%i', '%u')", GetGUIDLow(), itr->second.ID, itr->second.Standing, itr->second.Flags);
- itr->second.Changed = false;
- }
- }
-}
-
void Player::_SaveSpells()
{
- for (PlayerSpellMap::const_iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next)
+ for (PlayerSpellMap::iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end();)
{
- ++next;
if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED)
CharacterDatabase.PExecute("DELETE FROM character_spell WHERE guid = '%u' and spell = '%u'", GetGUIDLow(), itr->first);
- if (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED)
- CharacterDatabase.PExecute("INSERT INTO character_spell (guid,spell,slot,active,disabled) VALUES ('%u', '%u', '%u','%u','%u')", GetGUIDLow(), itr->first, itr->second->slotId,itr->second->active ? 1 : 0,itr->second->disabled ? 1 : 0);
+
+ // add only changed/new not dependent spells
+ if (!itr->second->dependent && (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED))
+ CharacterDatabase.PExecute("INSERT INTO character_spell (guid,spell,active,disabled) VALUES ('%u', '%u', '%u', '%u')", GetGUIDLow(), itr->first, itr->second->active ? 1 : 0,itr->second->disabled ? 1 : 0);
if (itr->second->state == PLAYERSPELL_REMOVED)
- _removeSpell(itr->first);
+ {
+ delete itr->second;
+ m_spells.erase(itr++);
+ }
else
+ {
itr->second->state = PLAYERSPELL_UNCHANGED;
+ ++itr;
+ }
+
}
}
@@ -15995,6 +16229,42 @@ void Player::SetFloatValueInDB(uint16 index, float value, uint64 guid)
Player::SetUInt32ValueInDB(index, temp, guid);
}
+void Player::Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair)
+{
+ Tokens tokens;
+ if(!LoadValuesArrayFromDB(tokens, guid))
+ return;
+
+ uint32 unit_bytes0 = GetUInt32ValueFromArray(tokens, UNIT_FIELD_BYTES_0);
+ uint8 race = unit_bytes0 & 0xFF;
+ uint8 class_ = (unit_bytes0 >> 8) & 0xFF;
+
+ PlayerInfo const* info = objmgr.GetPlayerInfo(race, class_);
+ if(!info)
+ return;
+
+ unit_bytes0 &= ~(0xFF << 16);
+ unit_bytes0 |= (gender << 16);
+ SetUInt32ValueInArray(tokens, UNIT_FIELD_BYTES_0, unit_bytes0);
+
+ SetUInt32ValueInArray(tokens, UNIT_FIELD_DISPLAYID, gender ? info->displayId_f : info->displayId_m);
+ SetUInt32ValueInArray(tokens, UNIT_FIELD_NATIVEDISPLAYID, gender ? info->displayId_f : info->displayId_m);
+
+ SetUInt32ValueInArray(tokens, PLAYER_BYTES, (skin | (face << 8) | (hairStyle << 16) | (hairColor << 24)));
+
+ uint32 player_bytes2 = GetUInt32ValueFromArray(tokens, PLAYER_BYTES_2);
+ player_bytes2 &= ~0xFF;
+ player_bytes2 |= facialHair;
+ SetUInt32ValueInArray(tokens, PLAYER_BYTES_2, player_bytes2);
+
+ uint32 player_bytes3 = GetUInt32ValueFromArray(tokens, PLAYER_BYTES_3);
+ player_bytes3 &= ~0xFF;
+ player_bytes3 |= gender;
+ SetUInt32ValueInArray(tokens, PLAYER_BYTES_3, player_bytes3);
+
+ SaveValuesArrayInDB(tokens, guid);
+}
+
void Player::SendAttackSwingNotStanding()
{
WorldPacket data(SMSG_ATTACKSWING_NOTSTANDING, 0);
@@ -16027,20 +16297,11 @@ void Player::SendAttackSwingBadFacingAttack()
void Player::SendAutoRepeatCancel()
{
- WorldPacket data(SMSG_CANCEL_AUTO_REPEAT, 0);
+ WorldPacket data(SMSG_CANCEL_AUTO_REPEAT, GetPackGUID().size());
+ data.append(GetPackGUID()); // may be it's target guid
GetSession()->SendPacket( &data );
}
-void Player::PlaySound(uint32 Sound, bool OnlySelf)
-{
- WorldPacket data(SMSG_PLAY_SOUND, 4);
- data << Sound;
- if (OnlySelf)
- GetSession()->SendPacket( &data );
- else
- SendMessageToSet( &data, true );
-}
-
void Player::SendExplorationExperience(uint32 Area, uint32 Experience)
{
WorldPacket data( SMSG_EXPLORATION_EXPERIENCE, 8 );
@@ -16181,11 +16442,32 @@ void Player::UpdateDuelFlag(time_t currTime)
duel->opponent->duel->startTime = currTime;
}
+Pet* Player::GetPet() const
+{
+ if(uint64 pet_guid = GetPetGUID())
+ {
+ if(!IS_PET_GUID(pet_guid))
+ return NULL;
+
+ if(Pet* pet = ObjectAccessor::GetPet(pet_guid))
+ return pet;
+
+ //there may be a guardian in slot
+ //sLog.outError("Player::GetPet: Pet %u not exist.",GUID_LOPART(pet_guid));
+ //const_cast<Player*>(this)->SetPetGUID(0);
+ }
+
+ return NULL;
+}
+
void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
{
if(!pet)
pet = GetPet();
+ if(pet)
+ sLog.outDebug("RemovePet %u, %u, %u", pet->GetEntry(), mode, returnreagent);
+
if(returnreagent && (pet || m_temporaryUnsummonedPetNumber))
{
//returning of reagents only for players, so best done here
@@ -16215,25 +16497,6 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
if(!pet || pet->GetOwnerGUID()!=GetGUID())
return;
- // only if current pet in slot
- switch(pet->getPetType())
- {
- case MINI_PET:
- m_miniPet = 0;
- break;
- case GUARDIAN_PET:
- m_guardianPets.erase(pet->GetGUID());
- break;
- case POSSESSED_PET:
- m_guardianPets.erase(pet->GetGUID());
- pet->RemoveCharmedOrPossessedBy(NULL);
- break;
- default:
- if(GetPetGUID() == pet->GetGUID())
- SetPet(NULL);
- break;
- }
-
pet->CombatStop();
if(returnreagent)
@@ -16250,7 +16513,18 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
}
}
- pet->SavePetToDB(mode);
+ // only if current pet in slot
+ switch(pet->getPetType())
+ {
+ case POSSESSED_PET:
+ pet->RemoveCharmedOrPossessedBy(NULL);
+ break;
+ default:
+ pet->SavePetToDB(mode);
+ break;
+ }
+
+ SetGuardian(pet, false);
pet->CleanupsBeforeDelete();
pet->AddObjectToRemoveList();
@@ -16258,8 +16532,9 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
if(pet->isControlled())
{
- WorldPacket data(SMSG_PET_SPELLS, 8);
+ WorldPacket data(SMSG_PET_SPELLS, 8+4);
data << uint64(0);
+ data << uint32(0);
GetSession()->SendPacket(&data);
if(GetGroup())
@@ -16267,66 +16542,29 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
}
}
-void Player::RemoveMiniPet()
-{
- if(Pet* pet = GetMiniPet())
- {
- pet->Remove(PET_SAVE_AS_DELETED);
- m_miniPet = 0;
- }
-}
-
-Pet* Player::GetMiniPet()
-{
- if(!m_miniPet)
- return NULL;
- return ObjectAccessor::GetPet(m_miniPet);
-}
-
-void Player::RemoveGuardians()
-{
- while(!m_guardianPets.empty())
- {
- uint64 guid = *m_guardianPets.begin();
- if(Pet* pet = ObjectAccessor::GetPet(guid))
- pet->Remove(PET_SAVE_AS_DELETED);
-
- m_guardianPets.erase(guid);
- }
-}
-
-bool Player::HasGuardianWithEntry(uint32 entry)
+void Player::StopCastingCharm()
{
- // pet guid middle part is entry (and creature also)
- // and in guardian list must be guardians with same entry _always_
- for(GuardianPetList::const_iterator itr = m_guardianPets.begin(); itr != m_guardianPets.end(); ++itr)
- if(GUID_ENPART(*itr)==entry)
- return true;
-
- return false;
-}
+ ExitVehicle();
-void Player::Uncharm()
-{
Unit* charm = GetCharm();
if(!charm)
return;
- if(charm->GetTypeId() == TYPEID_UNIT && ((Creature*)charm)->isPet()
- && ((Pet*)charm)->getPetType() == POSSESSED_PET)
+ if(charm->GetTypeId() == TYPEID_UNIT)
{
- ((Pet*)charm)->Remove(PET_SAVE_AS_DELETED);
+ if(((Creature*)charm)->isPet() && ((Pet*)charm)->getPetType() == POSSESSED_PET)
+ ((Pet*)charm)->Remove(PET_SAVE_AS_DELETED);
}
- else
+ if(GetCharmGUID())
{
- charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM);
- charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS_PET);
- charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS);
+ charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM);
+ charm->RemoveAurasByType(SPELL_AURA_MOD_POSSESS_PET);
+ charm->RemoveAurasByType(SPELL_AURA_MOD_POSSESS);
}
if(GetCharmGUID())
{
- sLog.outError("CRASH ALARM! Player %s is not able to uncharm unit (Entry: %u, Type: %u)", GetName(), charm->GetEntry(), charm->GetTypeId());
+ sLog.outCrash("Player %s is not able to uncharm unit (Entry: %u, Type: %u)", GetName(), charm->GetEntry(), charm->GetTypeId());
}
}
@@ -16347,6 +16585,10 @@ void Player::Say(const std::string& text, const uint32 language)
WorldPacket data(SMSG_MESSAGECHAT, 200);
BuildPlayerChat(&data, CHAT_MSG_SAY, text, language);
SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY),true);
+
+ if(sWorld.getConfig(CONFIG_CHATLOG_PUBLIC))
+ sLog.outChat("[SAY] Player %s says (language %u): %s",
+ GetName(), language, text.c_str());
}
void Player::Yell(const std::string& text, const uint32 language)
@@ -16354,6 +16596,10 @@ void Player::Yell(const std::string& text, const uint32 language)
WorldPacket data(SMSG_MESSAGECHAT, 200);
BuildPlayerChat(&data, CHAT_MSG_YELL, text, language);
SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL),true);
+
+ if(sWorld.getConfig(CONFIG_CHATLOG_PUBLIC))
+ sLog.outChat("[YELL] Player %s yells (language %u): %s",
+ GetName(), language, text.c_str());
}
void Player::TextEmote(const std::string& text)
@@ -16361,6 +16607,10 @@ void Player::TextEmote(const std::string& text)
WorldPacket data(SMSG_MESSAGECHAT, 200);
BuildPlayerChat(&data, CHAT_MSG_EMOTE, text, LANG_UNIVERSAL);
SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true, !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT), true );
+
+ if(sWorld.getConfig(CONFIG_CHATLOG_PUBLIC))
+ sLog.outChat("[TEXTEMOTE] Player %s emotes: %s",
+ GetName(), text.c_str());
}
void Player::Whisper(const std::string& text, uint32 language,uint64 receiver)
@@ -16370,6 +16620,10 @@ void Player::Whisper(const std::string& text, uint32 language,uint64 receiver)
Player *rPlayer = objmgr.GetPlayer(receiver);
+ if(sWorld.getConfig(CONFIG_CHATLOG_WHISPER))
+ sLog.outChat("[WHISPER] Player %s tells %s: %s",
+ GetName(), rPlayer->GetName(), text.c_str());
+
// when player you are whispering to is dnd, he cannot receive your message, unless you are in gm mode
if(!rPlayer->isDND() || isGameMaster())
{
@@ -16406,71 +16660,80 @@ void Player::PetSpellInitialize()
{
Pet* pet = GetPet();
- if(pet)
- {
- uint8 addlist = 0;
+ if(!pet)
+ return;
- sLog.outDebug("Pet Spells Groups");
+ sLog.outDebug("Pet Spells Groups");
- CreatureInfo const *cinfo = pet->GetCreatureInfo();
+ CharmInfo *charmInfo = pet->GetCharmInfo();
- if(pet->isControlled() && (pet->getPetType() == HUNTER_PET || cinfo && cinfo->type == CREATURE_TYPE_DEMON && getClass() == CLASS_WARLOCK))
- {
- for(PetSpellMap::iterator itr = pet->m_spells.begin();itr != pet->m_spells.end();++itr)
- {
- if(itr->second->state == PETSPELL_REMOVED)
- continue;
- ++addlist;
- }
- }
+ WorldPacket data(SMSG_PET_SPELLS, 8+4+4+4+10*4);
+ data << uint64(pet->GetGUID());
+ data << uint32(pet->GetCreatureInfo()->family); // creature family (required for pet talents)
+ data << uint32(0);
+ data << uint8(pet->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0);
- // first line + actionbar + spellcount + spells + last adds
- WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);
+ // action bar loop
+ for(uint32 i = 0; i < MAX_SPELL_CONTROL_BAR; ++i)
+ {
+ data << uint32(charmInfo->GetActionBarEntry(i)->Raw);
+ }
- CharmInfo *charmInfo = pet->GetCharmInfo();
+ size_t spellsCountPos = data.wpos();
- //16
- data << (uint64)pet->GetGUID() << uint32(0x00000000) << uint8(pet->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0);
+ // spells count
+ uint8 addlist = 0;
+ data << uint8(addlist); // placeholder
- for(uint32 i = 0; i < 10; i++) //40
+ if(pet->isControlled() && ((pet->getPetType() == HUNTER_PET) || ((pet->GetCreatureInfo()->type == CREATURE_TYPE_DEMON) && (getClass() == CLASS_WARLOCK))))
+ {
+ // spells loop
+ for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr)
{
- data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type);
+ if(itr->second->state == PETSPELL_REMOVED)
+ continue;
+
+ data << uint16(itr->first);
+ data << uint16(itr->second->active); // pet spell active state isn't boolean
+ ++addlist;
}
+ }
- data << uint8(addlist); //1
+ data.put<uint8>(spellsCountPos, addlist);
- if(addlist && pet->isControlled())
- {
- for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr)
- {
- if(itr->second->state == PETSPELL_REMOVED)
- continue;
+ uint8 cooldownsCount = pet->m_CreatureSpellCooldowns.size() + pet->m_CreatureCategoryCooldowns.size();
+ data << uint8(cooldownsCount);
- data << uint16(itr->first);
- data << uint16(itr->second->active); // pet spell active state isn't boolean
- }
- }
+ time_t curTime = time(NULL);
- //data << uint8(0x01) << uint32(0x6010) << uint32(0x01) << uint32(0x05) << uint16(0x00); //15
- uint8 count = 3; //1+8+8+8=25
+ for(CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureSpellCooldowns.begin(); itr != pet->m_CreatureSpellCooldowns.end(); ++itr)
+ {
+ time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILISECONDS : 0;
- // if count = 0, then end of packet...
- data << count;
- // uint32 value is spell id...
- // uint64 value is constant 0, unknown...
- data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3
- //data << uint32(0x5fd1) << uint64(0); // if count = 2
- data << uint32(0x8e8c) << uint64(0); // if count = 3
- data << uint32(0x8e8b) << uint64(0); // if count = 3
+ data << uint16(itr->first); // spellid
+ data << uint16(0); // spell category?
+ data << uint32(cooldown); // cooldown
+ data << uint32(0); // category cooldown
+ }
- GetSession()->SendPacket(&data);
+ for(CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureCategoryCooldowns.begin(); itr != pet->m_CreatureCategoryCooldowns.end(); ++itr)
+ {
+ time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILISECONDS : 0;
+
+ data << uint16(itr->first); // spellid
+ data << uint16(0); // spell category?
+ data << uint32(0); // cooldown
+ data << uint32(cooldown); // category cooldown
}
+
+ data.hexlike();
+
+ GetSession()->SendPacket(&data);
}
void Player::PossessSpellInitialize()
{
Unit* charm = GetCharm();
-
if(!charm)
return;
@@ -16482,32 +16745,69 @@ void Player::PossessSpellInitialize()
return;
}
- uint8 addlist = 0;
- WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);// first line + actionbar + spellcount + spells + last adds
+ WorldPacket data(SMSG_PET_SPELLS, 20+40+1+1);
- //16
- data << (uint64)charm->GetGUID() << uint32(0x00000000) << uint8(0) << uint8(0) << uint16(0);
+ //basic info 20
+ data << uint64(charm->GetGUID());
+ data << uint32(0x00000000);
+ data << uint32(0);
+ data << uint32(0);
- for(uint32 i = 0; i < 10; i++) //40
- {
+ //action bar 40
+ for(uint32 i = 0; i < 10; i++)
data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type);
- }
- data << uint8(addlist); //1
+ //addlist 1
+ data << uint8(0);
- uint8 count = 3;
- data << count;
- data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3
- data << uint32(0x8e8c) << uint64(0); // if count = 3
- data << uint32(0x8e8b) << uint64(0); // if count = 3
+ //cooldown 1
+ data << uint8(0);
GetSession()->SendPacket(&data);
}
-void Player::CharmSpellInitialize()
+void Player::VehicleSpellInitialize()
{
- Unit* charm = GetCharm();
+ Unit* charm = m_Vehicle;
+ if(!charm)
+ return;
+
+ WorldPacket data(SMSG_PET_SPELLS, 8+4+4+4+4*10+1+1);
+ data << uint64(charm->GetGUID());
+ data << uint32(0x00000000);
+ data << uint32(0x00000000);
+ data << uint32(0x00000101);
+
+ for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
+ {
+ uint32 spellId = ((Creature*)charm)->m_spells[i];
+ if(!spellId)
+ continue;
+
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
+ if(!spellInfo)
+ continue;
+
+ if(IsPassiveSpell(spellId) || spellInfo->activeIconID == 2158) //flight
+ {
+ charm->CastSpell(charm, spellId, true);
+ data << uint16(0) << uint8(0) << uint8(i+8);
+ }
+ else
+ data << uint16(spellId) << uint8(0) << uint8(i+8);
+ }
+
+ for(uint32 i = CREATURE_MAX_SPELLS; i < MAX_SPELL_CONTROL_BAR; ++i)
+ data << uint16(0) << uint8(0) << uint8(i+8);
+
+ data << uint8(0);
+ data << uint8(0);
+ GetSession()->SendPacket(&data);
+}
+void Player::CharmSpellInitialize()
+{
+ Unit* charm = GetFirstControlled();
if(!charm)
return;
@@ -16519,14 +16819,12 @@ void Player::CharmSpellInitialize()
}
uint8 addlist = 0;
-
if(charm->GetTypeId() != TYPEID_PLAYER)
{
CreatureInfo const *cinfo = ((Creature*)charm)->GetCreatureInfo();
-
- if(cinfo && cinfo->type == CREATURE_TYPE_DEMON && getClass() == CLASS_WARLOCK)
+ //if(cinfo && cinfo->type == CREATURE_TYPE_DEMON && getClass() == CLASS_WARLOCK)
{
- for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
+ for(uint32 i = 0; i < MAX_SPELL_CHARM; ++i)
{
if(charmInfo->GetCharmSpell(i)->spellId)
++addlist;
@@ -16534,27 +16832,29 @@ void Player::CharmSpellInitialize()
}
}
- WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);// first line + actionbar + spellcount + spells + last adds
-
- data << (uint64)charm->GetGUID() << uint32(0x00000000);
+ WorldPacket data(SMSG_PET_SPELLS, 20+40+1+4*addlist+1);// first line + actionbar + spellcount + spells + last adds
+ //basic info 20
+ data << uint64(charm->GetGUID());
+ data << uint32(0);
+ data << uint32(0);
if(charm->GetTypeId() != TYPEID_PLAYER)
data << uint8(((Creature*)charm)->GetReactState()) << uint8(charmInfo->GetCommandState());
else
data << uint8(0) << uint8(0);
-
data << uint16(0);
- for(uint32 i = 0; i < 10; i++) //40
+ //action bar 40
+ for(uint32 i = 0; i < MAX_SPELL_CONTROL_BAR; ++i) //40
{
data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type);
}
+ //add list
data << uint8(addlist); //1
-
if(addlist)
{
- for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
+ for(uint32 i = 0; i < MAX_SPELL_CHARM; ++i)
{
CharmSpellEntry *cspell = charmInfo->GetCharmSpell(i);
if(cspell->spellId)
@@ -16565,49 +16865,19 @@ void Player::CharmSpellInitialize()
}
}
- uint8 count = 3;
- data << count;
- data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3
- data << uint32(0x8e8c) << uint64(0); // if count = 3
- data << uint32(0x8e8b) << uint64(0); // if count = 3
+ //cooldown
+ uint8 count = 0;
+ data << uint8(count); // cooldowns count
GetSession()->SendPacket(&data);
}
-int32 Player::GetTotalFlatMods(uint32 spellId, SpellModOp op)
-{
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
- if (!spellInfo) return 0;
- int32 total = 0;
- for (SpellModList::iterator itr = m_spellMods[op].begin(); itr != m_spellMods[op].end(); ++itr)
- {
- SpellModifier *mod = *itr;
-
- if(!IsAffectedBySpellmod(spellInfo,mod))
- continue;
-
- if (mod->type == SPELLMOD_FLAT)
- total += mod->value;
- }
- return total;
-}
-
-int32 Player::GetTotalPctMods(uint32 spellId, SpellModOp op)
+void Player::SendRemoveControlBar()
{
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
- if (!spellInfo) return 0;
- int32 total = 0;
- for (SpellModList::iterator itr = m_spellMods[op].begin(); itr != m_spellMods[op].end(); ++itr)
- {
- SpellModifier *mod = *itr;
-
- if(!IsAffectedBySpellmod(spellInfo,mod))
- continue;
-
- if (mod->type == SPELLMOD_PCT)
- total += mod->value;
- }
- return total;
+ WorldPacket data(SMSG_PET_SPELLS, 8+4);
+ data << uint64(0);
+ data << uint32(0);
+ GetSession()->SendPacket(&data);
}
bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell)
@@ -16627,22 +16897,27 @@ bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mo
return false;
}
- return spellmgr.IsAffectedBySpell(spellInfo,mod->spellId,mod->effectId,mod->mask);
+ return spellmgr.IsAffectedByMod(spellInfo, mod);
}
void Player::AddSpellMod(SpellModifier* mod, bool apply)
{
uint16 Opcode= (mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER;
- for(int eff=0;eff<64;++eff)
+ uint8 i=0;
+ flag96 _mask;
+ for(int eff=0;eff<96;++eff)
{
- uint64 _mask = uint64(1) << eff;
+ if ((eff!=0) && (eff%32==0))
+ i++;
+
+ _mask[i] = uint32(1) << (eff-(32*i));
if ( mod->mask & _mask)
{
int32 val = 0;
for (SpellModList::iterator itr = m_spellMods[mod->op].begin(); itr != m_spellMods[mod->op].end(); ++itr)
{
- if ((*itr)->type == mod->type && (*itr)->mask & _mask)
+ if ((*itr)->type == mod->type && (*itr)->mask & _mask )
val += (*itr)->value;
}
val += apply ? mod->value : -(mod->value);
@@ -16679,7 +16954,7 @@ void Player::RemoveSpellMods(Spell const* spell)
if (mod && mod->charges == -1 && (mod->lastAffected == spell || mod->lastAffected==NULL))
{
- RemoveAurasDueToSpell(mod->spellId);
+ RemoveAurasDueToSpell(mod->spellId, 0, AURA_REMOVE_BY_EXPIRE);
if (m_spellMods[i].empty())
break;
else
@@ -16741,6 +17016,27 @@ void Player::RemovePetitionsAndSigns(uint64 guid, uint32 type)
CharacterDatabase.CommitTransaction();
}
+void Player::LeaveAllArenaTeams(uint64 guid)
+{
+ QueryResult *result = CharacterDatabase.PQuery("SELECT arena_team_member.arenateamid FROM arena_team_member JOIN arena_team ON arena_team_member.arenateamid = arena_team.arenateamid WHERE guid='%u'", GUID_LOPART(guid));
+ if(!result)
+ return;
+
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 at_id = fields[0].GetUInt32();
+ if(at_id != 0)
+ {
+ ArenaTeam * at = objmgr.GetArenaTeamById(at_id);
+ if(at)
+ at->DelMember(guid);
+ }
+ } while (result->NextRow());
+
+ delete result;
+}
+
void Player::SetRestBonus (float rest_bonus_new)
{
// Prevent resting on max level
@@ -16771,7 +17067,7 @@ void Player::HandleStealthedUnitsDetection()
{
std::list<Unit*> stealthedUnits;
Trinity::AnyStealthedCheck u_check;
- Trinity::UnitListSearcher<Trinity::AnyStealthedCheck > searcher(stealthedUnits, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyStealthedCheck > searcher(this, stealthedUnits, u_check);
VisitNearbyObject(World::GetMaxVisibleDistance(), searcher);
for (std::list<Unit*>::iterator i = stealthedUnits.begin(); i != stealthedUnits.end(); ++i)
@@ -16919,6 +17215,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, uint32 mount_i
//Checks and preparations done, DO FLIGHT
ModifyMoney(-(int32)totalcost);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, totalcost);
// prevent stealth flight
//RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK);
@@ -16964,7 +17261,7 @@ void Player::ProhibitSpellScholl(SpellSchoolMask idSchoolMask, uint32 unTimeMs )
{
data << unSpellId;
data << unTimeMs; // in m.secs
- AddSpellCooldown(unSpellId, 0, curTime + unTimeMs/1000);
+ AddSpellCooldown(unSpellId, 0, curTime + unTimeMs/IN_MILISECONDS);
}
}
GetSession()->SendPacket(&data);
@@ -17030,7 +17327,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
return false;
}
- Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*this, vendorguid,UNIT_NPC_FLAG_VENDOR);
+ Creature *pCreature = GetNPCIfCanInteractWith(vendorguid,UNIT_NPC_FLAG_VENDOR);
if (!pCreature)
{
sLog.outDebug( "WORLD: BuyItemFromVendor - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(vendorguid)) );
@@ -17331,6 +17628,102 @@ void Player::UpdatePvP(bool state, bool ovrride)
}
}
+void Player::AddSpellAndCategoryCooldowns(SpellEntry const* spellInfo, uint32 itemId, Spell* spell, bool infinityCooldown)
+{
+ // init cooldown values
+ uint32 cat = 0;
+ int32 rec = -1;
+ int32 catrec = -1;
+
+ // some special item spells without correct cooldown in SpellInfo
+ // cooldown information stored in item prototype
+ // This used in same way in WorldSession::HandleItemQuerySingleOpcode data sending to client.
+
+ if(itemId)
+ {
+ if(ItemPrototype const* proto = ObjectMgr::GetItemPrototype(itemId))
+ {
+ for(int idx = 0; idx < 5; ++idx)
+ {
+ if(proto->Spells[idx].SpellId == spellInfo->Id)
+ {
+ cat = proto->Spells[idx].SpellCategory;
+ rec = proto->Spells[idx].SpellCooldown;
+ catrec = proto->Spells[idx].SpellCategoryCooldown;
+ break;
+ }
+ }
+ }
+ }
+
+ // if no cooldown found above then base at DBC data
+ if(rec < 0 && catrec < 0)
+ {
+ cat = spellInfo->Category;
+ rec = spellInfo->RecoveryTime;
+ catrec = spellInfo->CategoryRecoveryTime;
+ }
+
+ time_t curTime = time(NULL);
+
+ time_t catrecTime;
+ time_t recTime;
+
+ // overwrite time for selected category
+ if(infinityCooldown)
+ {
+ // use +MONTH as infinity mark for spell cooldown (will checked as MONTH/2 at save ans skipped)
+ // but not allow ignore until reset or re-login
+ catrecTime = catrec > 0 ? curTime+MONTH : 0;
+ recTime = rec > 0 ? curTime+MONTH : catrecTime;
+ }
+ else
+ {
+ // shoot spells used equipped item cooldown values already assigned in GetAttackTime(RANGED_ATTACK)
+ // prevent 0 cooldowns set by another way
+ if (rec <= 0 && catrec <= 0 && (cat == 76 || IsAutoRepeatRangedSpell(spellInfo) && spellInfo->Id != SPELL_ID_AUTOSHOT))
+ rec = GetAttackTime(RANGED_ATTACK);
+
+ // Now we have cooldown data (if found any), time to apply mods
+ if(rec > 0)
+ ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, rec, spell);
+
+ if(catrec > 0)
+ ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, catrec, spell);
+
+ // replace negative cooldowns by 0
+ if (rec < 0) rec = 0;
+ if (catrec < 0) catrec = 0;
+
+ // no cooldown after applying spell mods
+ if( rec == 0 && catrec == 0)
+ return;
+
+ catrecTime = catrec ? curTime+catrec/IN_MILISECONDS : 0;
+ recTime = rec ? curTime+rec/IN_MILISECONDS : catrecTime;
+ }
+
+ // self spell cooldown
+ if(recTime > 0)
+ AddSpellCooldown(spellInfo->Id, itemId, recTime);
+
+ // category spells
+ if (cat && catrec > 0)
+ {
+ SpellCategoryStore::const_iterator i_scstore = sSpellCategoryStore.find(cat);
+ if(i_scstore != sSpellCategoryStore.end())
+ {
+ for(SpellCategorySet::const_iterator i_scset = i_scstore->second.begin(); i_scset != i_scstore->second.end(); ++i_scset)
+ {
+ if(*i_scset == spellInfo->Id) // skip main spell, already handled above
+ continue;
+
+ AddSpellCooldown(*i_scset, itemId, catrecTime);
+ }
+ }
+ }
+}
+
void Player::AddSpellCooldown(uint32 spellid, uint32 itemid, time_t end_time)
{
SpellCooldown sc;
@@ -17339,25 +17732,41 @@ void Player::AddSpellCooldown(uint32 spellid, uint32 itemid, time_t end_time)
m_spellCooldowns[spellid] = sc;
}
-void Player::SendCooldownEvent(SpellEntry const *spellInfo)
+void Player::SendCooldownEvent(SpellEntry const *spellInfo, uint32 itemId, Spell* spell)
{
- if ( !(spellInfo->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE) )
- return;
+ // start cooldowns at server side, if any
+ AddSpellAndCategoryCooldowns(spellInfo,itemId,spell);
- // Get spell cooldown
- int32 cooldown = GetSpellRecoveryTime(spellInfo);
- // Apply spellmods
- ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, cooldown);
- if (cooldown < 0)
- cooldown = 0;
- // Add cooldown
- AddSpellCooldown(spellInfo->Id, 0, time(NULL) + cooldown / 1000);
- // Send activate
+ // Send activate cooldown timer (possible 0) at client side
WorldPacket data(SMSG_COOLDOWN_EVENT, (4+8));
data << spellInfo->Id;
data << GetGUID();
SendDirectMessage(&data);
}
+
+void Player::UpdatePotionCooldown(Spell* spell)
+{
+ // no potion used i combat or still in combat
+ if(!m_lastPotionId || isInCombat())
+ return;
+
+ // Call not from spell cast, send cooldown event for item spells if no in combat
+ if(!spell)
+ {
+ // spell/item pair let set proper cooldown (except not existed charged spell cooldown spellmods for potions)
+ if(ItemPrototype const* proto = ObjectMgr::GetItemPrototype(m_lastPotionId))
+ for(int idx = 0; idx < 5; ++idx)
+ if(proto->Spells[idx].SpellId && proto->Spells[idx].SpellTrigger == ITEM_SPELLTRIGGER_ON_USE)
+ if(SpellEntry const* spellInfo = sSpellStore.LookupEntry(proto->Spells[idx].SpellId))
+ SendCooldownEvent(spellInfo,m_lastPotionId);
+ }
+ // from spell cases (m_lastPotionId set in Spell::SendSpellCooldown)
+ else
+ SendCooldownEvent(spell->m_spellInfo,m_lastPotionId,spell);
+
+ m_lastPotionId = 0;
+}
+
//slot to be excluded while counting
bool Player::EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot)
{
@@ -17522,13 +17931,14 @@ void Player::LeaveBattleground(bool teleportToEntryPoint)
{
if(BattleGround *bg = GetBattleGround())
{
- bool need_debuf = bg->isBattleGround() && !isGameMaster() && (bg->GetStatus() == STATUS_IN_PROGRESS) && sWorld.getConfig(CONFIG_BATTLEGROUND_CAST_DESERTER);
-
bg->RemovePlayerAtLeave(GetGUID(), teleportToEntryPoint, true);
// call after remove to be sure that player resurrected for correct cast
- if(need_debuf)
- CastSpell(this, 26013, true); // Deserter
+ if( bg->isBattleGround() && !isGameMaster() && sWorld.getConfig(CONFIG_BATTLEGROUND_CAST_DESERTER) )
+ {
+ if( bg->GetStatus() == STATUS_IN_PROGRESS || bg->GetStatus() == STATUS_WAIT_JOIN )
+ CastSpell(this, 26013, true); // Deserter
+ }
}
}
@@ -17558,7 +17968,7 @@ void Player::ReportedAfkBy(Player* reporter)
return;
// check if player has 'Idle' or 'Inactive' debuff
- if(m_bgAfkReporter.find(reporter->GetGUIDLow())==m_bgAfkReporter.end() && !HasAura(43680,0) && !HasAura(43681,0) && reporter->CanReportAfkDueToLimit())
+ if(m_bgAfkReporter.find(reporter->GetGUIDLow())==m_bgAfkReporter.end() && !HasAura(43680) && !HasAura(43681) && reporter->CanReportAfkDueToLimit())
{
m_bgAfkReporter.insert(reporter->GetGUIDLow());
// 3 players have to complain to apply debuff
@@ -17574,9 +17984,13 @@ void Player::ReportedAfkBy(Player* reporter)
bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bool is3dDistance) const
{
// Always can see self
- if (u == this)
+ if (m_mover == u || this == u)
return true;
+ // phased visibility (both must phased in same way)
+ if(!InSamePhase(u))
+ return false;
+
// player visible for other player if not logout and at same transport
// including case when player is out of world
bool at_same_transport =
@@ -17602,38 +18016,33 @@ bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bool
if(!u->IsVisibleInGridForPlayer(this))
return false;
- // If the player is currently channeling vision, update visibility from the target unit's location
- const WorldObject* target = GetFarsightTarget();
- if (!target || !HasFarsightVision()) // Vision needs to be on the farsight target
- target = this;
-
// different visible distance checks
if(isInFlight()) // what see player in flight
{
- if (!target->IsWithinDistInMap(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
+ if (!m_seer->IsWithinDistInMap(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
return false;
}
else if(!u->isAlive()) // distance for show body
{
- if (!target->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
+ if (!m_seer->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
return false;
}
else if(u->GetTypeId()==TYPEID_PLAYER) // distance for show player
{
// Players far than max visible distance for player or not in our map are not visible too
- if (!at_same_transport && !target->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
+ if (!at_same_transport && !m_seer->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
return false;
}
else if(u->GetCharmerOrOwnerGUID()) // distance for show pet/charmed
{
// Pet/charmed far than max visible distance for player or not in our map are not visible too
- if (!target->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
+ if (!m_seer->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
return false;
}
else // distance for show creature
{
// Units far than max visible distance for creature or not in our map are not visible too
- if (!target->IsWithinDistInMap(u
+ if (!m_seer->IsWithinDistInMap(u
, u->isActiveObject() ? (MAX_VISIBILITY_DISTANCE - (inVisibleList ? 0.0f : World::GetVisibleUnitGreyDistance()))
: (World::GetMaxVisibleDistanceForCreature() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))
, is3dDistance))
@@ -17654,7 +18063,7 @@ bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bool
}
// GM's can see everyone with invisibilitymask with less or equal security level
- if(m_invisibilityMask || u->m_invisibilityMask)
+ if(m_mover->m_invisibilityMask || u->m_invisibilityMask)
{
if(isGameMaster())
{
@@ -17665,7 +18074,7 @@ bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bool
}
// player see other player with stealth/invisibility only if he in same group or raid or same team (raid/team case dependent from conf setting)
- if(!canDetectInvisibilityOf(u))
+ if(!m_mover->canDetectInvisibilityOf(u))
if(!(u->GetTypeId()==TYPEID_PLAYER && !IsHostileTo(u) && IsGroupVisibleFor(((Player*)u))))
return false;
}
@@ -17680,7 +18089,7 @@ bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bool
detect = false;
if(m_DetectInvTimer < 300 || !HaveAtClient(u))
if(!(u->GetTypeId()==TYPEID_PLAYER && !IsHostileTo(u) && IsGroupVisibleFor(((Player*)u))))
- if(!detect || !canDetectStealthOf(u, GetDistance(u)))
+ if(!detect || !m_mover->canDetectStealthOf(u, GetDistance(u)))
return false;
}
@@ -17793,7 +18202,7 @@ void Player::UpdateVisibilityOf(WorldObject* target)
void Player::SendInitialVisiblePackets(Unit* target)
{
- SendAuraDurationsForTarget(target);
+ SendAurasForTarget(target);
if(target->isAlive())
{
if(target->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE)
@@ -17914,7 +18323,7 @@ void Player::AddComboPoints(Unit* target, int8 count)
return;
// without combo points lost (duration checked in aura)
- RemoveSpellsCausingAura(SPELL_AURA_RETAIN_COMBO_POINTS);
+ RemoveAurasByType(SPELL_AURA_RETAIN_COMBO_POINTS);
if(target->GetGUID() == m_comboTarget)
{
@@ -17923,8 +18332,8 @@ void Player::AddComboPoints(Unit* target, int8 count)
else
{
if(m_comboTarget)
- if(Unit* target = ObjectAccessor::GetUnit(*this,m_comboTarget))
- target->RemoveComboPointHolder(GetGUIDLow());
+ if(Unit* target2 = ObjectAccessor::GetUnit(*this,m_comboTarget))
+ target2->RemoveComboPointHolder(GetGUIDLow());
m_comboTarget = target->GetGUID();
m_comboPoints = count;
@@ -17944,7 +18353,7 @@ void Player::ClearComboPoints()
return;
// without combopoints lost (duration checked in aura)
- RemoveSpellsCausingAura(SPELL_AURA_RETAIN_COMBO_POINTS);
+ RemoveAurasByType(SPELL_AURA_RETAIN_COMBO_POINTS);
m_comboPoints = 0;
@@ -17958,7 +18367,8 @@ void Player::ClearComboPoints()
void Player::SetGroup(Group *group, int8 subgroup)
{
- if(group == NULL) m_group.unlink();
+ if(group == NULL)
+ m_group.unlink();
else
{
// never use SetGroup without a subgroup unless you specify NULL for group
@@ -17970,7 +18380,7 @@ void Player::SetGroup(Group *group, int8 subgroup)
void Player::SendInitialPacketsBeforeAddToMap()
{
- WorldPacket data(SMSG_SET_REST_START, 4);
+ WorldPacket data(SMSG_SET_REST_START_OBSOLETE, 4);
data << uint32(0); // unknown, may be rest state time or experience
GetSession()->SendPacket(&data);
@@ -17997,9 +18407,13 @@ void Player::SendInitialPacketsBeforeAddToMap()
GetSession()->SendPacket(&data);
SendInitialActionButtons();
- SendInitialReputations();
- UpdateZone(GetZoneId());
- SendInitWorldStates();
+ m_reputationMgr.SendInitialReputations();
+ m_achievementMgr.SendAllAchievementData();
+
+ // update zone
+ uint32 newzone, newarea;
+ GetZoneAndAreaId(newzone,newarea);
+ UpdateZone(newzone,newarea); // also call SendInitWorldStates();
// SMSG_SET_AURA_SINGLE
@@ -18015,6 +18429,10 @@ void Player::SendInitialPacketsBeforeAddToMap()
void Player::SendInitialPacketsAfterAddToMap()
{
+ WorldPacket data(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement
+ data << uint32(0x00000000); // on blizz it increments periodically
+ GetSession()->SendPacket(&data);
+
CastSpell(this, 836, true); // LOGINEFFECT
// set some aura effects that send packet to player client after add player to map
@@ -18028,7 +18446,7 @@ void Player::SendInitialPacketsAfterAddToMap()
};
for(AuraType const* itr = &auratypes[0]; itr && itr[0] != SPELL_AURA_NONE; ++itr)
{
- Unit::AuraList const& auraList = GetAurasByType(*itr);
+ Unit::AuraEffectList const& auraList = GetAurasByType(*itr);
if(!auraList.empty())
auraList.front()->ApplyModifier(true,true);
}
@@ -18039,12 +18457,13 @@ void Player::SendInitialPacketsAfterAddToMap()
// manual send package (have code in ApplyModifier(true,true); that don't must be re-applied.
if(HasAuraType(SPELL_AURA_MOD_ROOT))
{
- WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
- data.append(GetPackGUID());
- data << (uint32)2;
- SendMessageToSet(&data,true);
+ WorldPacket data2(SMSG_FORCE_MOVE_ROOT, 10);
+ data2.append(GetPackGUID());
+ data2 << (uint32)2;
+ SendMessageToSet(&data2,true);
}
+ SendAurasForTarget(this);
SendEnchantmentDurations(); // must be after add to map
SendItemDurations(); // must be after add to map
}
@@ -18057,16 +18476,24 @@ void Player::SendUpdateToOutOfRangeGroupMembers()
group->UpdatePlayerOutOfRange(this);
m_groupUpdateMask = GROUP_UPDATE_FLAG_NONE;
- m_auraUpdateMask = 0;
+ m_auraRaidUpdateMask = 0;
if(Pet *pet = GetPet())
- pet->ResetAuraUpdateMask();
+ pet->ResetAuraUpdateMaskForRaid();
}
-void Player::SendTransferAborted(uint32 mapid, uint16 reason)
+void Player::SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg)
{
WorldPacket data(SMSG_TRANSFER_ABORTED, 4+2);
data << uint32(mapid);
- data << uint16(reason); // transfer abort reason
+ data << uint8(reason); // transfer abort reason
+ switch(reason)
+ {
+ case TRANSFER_ABORT_INSUF_EXPAN_LVL:
+ case TRANSFER_ABORT_DIFFICULTY:
+ case TRANSFER_ABORT_UNIQUE_MESSAGE:
+ data << uint8(arg);
+ break;
+ }
GetSession()->SendPacket(&data);
}
@@ -18091,7 +18518,7 @@ void Player::SendInstanceResetWarning(uint32 mapid, uint32 time)
void Player::ApplyEquipCooldown( Item * pItem )
{
- for(int i = 0; i <5; ++i)
+ for(int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
_Spell const& spellData = pItem->GetProto()->Spells[i];
@@ -18132,22 +18559,18 @@ void Player::resetSpells()
learnQuestRewardedSpells();
}
-void Player::learnDefaultSpells(bool loading)
+void Player::learnDefaultSpells()
{
// learn default race/class spells
PlayerInfo const *info = objmgr.GetPlayerInfo(getRace(),getClass());
- std::list<CreateSpellPair>::const_iterator spell_itr;
- for (spell_itr = info->spell.begin(); spell_itr!=info->spell.end(); ++spell_itr)
+ for (PlayerCreateInfoSpells::const_iterator itr = info->spell.begin(); itr!=info->spell.end(); ++itr)
{
- uint16 tspell = spell_itr->first;
- if (tspell)
- {
- sLog.outDebug("PLAYER: Adding initial spell, id = %u",tspell);
- if(loading || !spell_itr->second) // not care about passive spells or loading case
- addSpell(tspell,spell_itr->second);
- else // but send in normal spell in game learn case
- learnSpell(tspell);
- }
+ uint32 tspell = *itr;
+ sLog.outDebug("PLAYER (Class: %u Race: %u): Adding initial spell, id = %u",uint32(getClass()),uint32(getRace()), tspell);
+ if(!IsInWorld()) // will send in INITIAL_SPELLS in list anyway at map add
+ addSpell(tspell,true,true,true,false);
+ else // but send in normal spell in game learn case
+ learnSpell(tspell,true);
}
}
@@ -18239,7 +18662,7 @@ void Player::learnQuestRewardedSpells()
}
}
-void Player::learnSkillRewardedSpells(uint32 skill_id )
+void Player::learnSkillRewardedSpells(uint32 skill_id, uint32 skill_value )
{
uint32 raceMask = getRaceMask();
uint32 classMask = getClassMask();
@@ -18257,35 +18680,56 @@ void Player::learnSkillRewardedSpells(uint32 skill_id )
if (sSpellStore.LookupEntry(pAbility->spellId))
{
- // Ok need learn spell
- learnSpell(pAbility->spellId);
+ // need unlearn spell
+ if (skill_value < pAbility->req_skill_value)
+ removeSpell(pAbility->spellId);
+ // need learn
+ else if (!IsInWorld())
+ addSpell(pAbility->spellId,true,true,true,false);
+ else
+ learnSpell(pAbility->spellId,true);
}
}
}
-void Player::learnSkillRewardedSpells()
+void Player::SendAurasForTarget(Unit *target)
{
- for (uint16 i=0; i < PLAYER_MAX_SKILLS; i++)
- {
- if(!GetUInt32Value(PLAYER_SKILL_INDEX(i)))
- continue;
-
- uint32 pskill = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF;
+ if(!target || target->GetVisibleAuras()->empty()) // speedup things
+ return;
- learnSkillRewardedSpells(pskill);
- }
-}
+ WorldPacket data(SMSG_AURA_UPDATE_ALL);
+ data.append(target->GetPackGUID());
-void Player::SendAuraDurationsForTarget(Unit* target)
-{
- for(Unit::AuraMap::const_iterator itr = target->GetAuras().begin(); itr != target->GetAuras().end(); ++itr)
+ Unit::VisibleAuraMap const *visibleAuras = target->GetVisibleAuras();
+ for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
{
- Aura* aura = itr->second;
- if(aura->GetAuraSlot() >= MAX_AURAS || aura->IsPassive() || aura->GetCasterGUID()!=GetGUID())
- continue;
+ Aura * aura=itr->second;
+ data << uint8(aura->GetAuraSlot());
+ data << uint32(aura->GetId());
+
+ // flags
+ data << aura->m_auraFlags;
+ // level
+ data << aura->m_auraLevel;
+ // charges
+ data << uint8(aura->GetStackAmount()>1 ? aura->GetStackAmount() : aura->GetAuraCharges());
- aura->SendAuraDurationForCaster(this);
+ if(!(aura->m_auraFlags & AFLAG_CASTER))
+ {
+ if (Unit * caster = aura->GetCaster())
+ data.append(caster->GetPackGUID());
+ else
+ data << uint8(0);
+ }
+
+ if(aura->m_auraFlags & AFLAG_DURATION) // include aura duration
+ {
+ data << uint32(aura->GetAuraMaxDuration());
+ data << uint32(aura->GetAuraDuration());
+ }
}
+
+ GetSession()->SendPacket(&data);
}
void Player::SetDailyQuestStatus( uint32 quest_id )
@@ -18317,7 +18761,7 @@ BattleGround* Player::GetBattleGround() const
if(GetBattleGroundId()==0)
return NULL;
- return sBattleGroundMgr.GetBattleGround(GetBattleGroundId());
+ return sBattleGroundMgr.GetBattleGround(GetBattleGroundId(), m_bgTypeID);
}
bool Player::InArena() const
@@ -18329,7 +18773,7 @@ bool Player::InArena() const
return true;
}
-bool Player::GetBGAccessByLevel(uint32 bgTypeId) const
+bool Player::GetBGAccessByLevel(BattleGroundTypeId bgTypeId) const
{
// get a template bg instead of running one
BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
@@ -18342,46 +18786,26 @@ bool Player::GetBGAccessByLevel(uint32 bgTypeId) const
return true;
}
-uint32 Player::GetMinLevelForBattleGroundQueueId(uint32 queue_id)
-{
- if(queue_id < 1)
- return 0;
-
- if(queue_id >=6)
- queue_id = 6;
-
- return 10*(queue_id+1);
-}
-
-uint32 Player::GetMaxLevelForBattleGroundQueueId(uint32 queue_id)
-{
- if(queue_id >=6)
- return 255; // hardcoded max level
-
- return 10*(queue_id+2)-1;
-}
-
-//TODO make this more generic - current implementation is wrong
-uint32 Player::GetBattleGroundQueueIdFromLevel() const
+BGQueueIdBasedOnLevel Player::GetBattleGroundQueueIdFromLevel(BattleGroundTypeId bgTypeId) const
{
+ //returned to hardcoded version of this function, because there is no way to code it dynamic
uint32 level = getLevel();
- if(level <= 19)
- return 0;
- else if (level > 69)
- return 6;
- else
- return level/10 - 1; // 20..29 -> 1, 30-39 -> 2, ...
- /*
- assert(bgTypeId < MAX_BATTLEGROUND_TYPES);
- BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
- assert(bg);
- return (getLevel() - bg->GetMinLevel()) / 10;*/
+ if( bgTypeId == BATTLEGROUND_AV )
+ level--;
+
+ uint32 queue_id = (level / 10) - 1; // for ranges 0 - 19, 20 - 29, 30 - 39, 40 - 49, 50 - 59, 60 - 69, 70 -79, 80
+ if( queue_id >= MAX_BATTLEGROUND_QUEUES )
+ {
+ sLog.outError("BattleGround: too high queue_id %u this shouldn't happen", queue_id);
+ return QUEUE_ID_MAX_LEVEL_80;
+ }
+ return BGQueueIdBasedOnLevel(queue_id);
}
float Player::GetReputationPriceDiscount( Creature const* pCreature ) const
{
FactionTemplateEntry const* vendor_faction = pCreature->getFactionTemplateEntry();
- if(!vendor_faction)
+ if(!vendor_faction || !vendor_faction->faction)
return 1.0f;
ReputationRank rank = GetReputationRank(vendor_faction->faction);
@@ -18398,28 +18822,42 @@ bool Player::IsSpellFitByClassAndRace( uint32 spell_id ) const
SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spell_id);
SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spell_id);
+ if(lower==upper)
+ return true;
for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
{
// skip wrong race skills
if( _spell_idx->second->racemask && (_spell_idx->second->racemask & racemask) == 0)
- return false;
+ continue;
// skip wrong class skills
if( _spell_idx->second->classmask && (_spell_idx->second->classmask & classmask) == 0)
- return false;
+ continue;
+
+ return true;
}
- return true;
+
+ return false;
}
-bool Player::HasQuestForGO(int32 GOId)
+bool Player::HasQuestForGO(int32 GOId) const
{
- for( QuestStatusMap::iterator i = mQuestStatus.begin( ); i != mQuestStatus.end( ); ++i )
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
{
- QuestStatusData qs=i->second;
+ uint32 questid = GetQuestSlotQuestId(i);
+ if ( questid == 0 )
+ continue;
+
+ QuestStatusMap::const_iterator qs_itr = mQuestStatus.find(questid);
+ if(qs_itr == mQuestStatus.end())
+ continue;
+
+ QuestStatusData const& qs = qs_itr->second;
+
if (qs.m_status == QUEST_STATUS_INCOMPLETE)
{
- Quest const* qinfo = objmgr.GetQuestTemplate(i->first);
+ Quest const* qinfo = objmgr.GetQuestTemplate(questid);
if(!qinfo)
continue;
@@ -18479,6 +18917,7 @@ void Player::SummonIfPossible(bool agree)
}
// drop flag at summon
+ // this code can be reached only when GM is summoning player who carries flag, because player should be immune to summoning spells when he carries flag
if(BattleGround *bg = GetBattleGround())
bg->EventPlayerDroppedFlag(this);
@@ -18514,9 +18953,8 @@ void Player::AutoUnequipOffhandIfNeed()
if(!offItem)
return;
- Item *mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND );
-
- if(!mainItem || mainItem->GetProto()->InventoryType != INVTYPE_2HWEAPON)
+ // need unequip offhand for 2h-weapon without TitanGrip (in any from hands)
+ if (CanTitanGrip() || (offItem->GetProto()->InventoryType != INVTYPE_2HWEAPON && !IsTwoHandUsed()))
return;
ItemPosCountVec off_dest;
@@ -18528,7 +18966,16 @@ void Player::AutoUnequipOffhandIfNeed()
}
else
{
- sLog.outError("Player::EquipItem: Can's store offhand item at 2hand item equip for player (GUID: %u).",GetGUIDLow());
+ MailItemsInfo mi;
+ mi.AddItem(offItem->GetGUIDLow(), offItem->GetEntry(), offItem);
+ MoveItemFromInventory(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND, true);
+ CharacterDatabase.BeginTransaction();
+ offItem->DeleteFromInventoryDB(); // deletes item from character's inventory
+ offItem->SaveToDB(); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
+ CharacterDatabase.CommitTransaction();
+
+ std::string subject = GetSession()->GetMangosString(LANG_NOT_EQUIPPED_ITEM);
+ WorldSession::SendMailTo(this, MAIL_NORMAL, MAIL_STATIONERY_GM, GetGUIDLow(), GetGUIDLow(), subject, 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
}
}
@@ -18549,7 +18996,7 @@ bool Player::HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item cons
case ITEM_CLASS_WEAPON:
{
for(int i= EQUIPMENT_SLOT_MAINHAND; i < EQUIPMENT_SLOT_TABARD; ++i)
- if(Item *item = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
+ if(Item *item = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, i ))
if(item!=ignoreItem && item->IsFitToSpellRequirements(spellInfo))
return true;
break;
@@ -18558,17 +19005,17 @@ bool Player::HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item cons
{
// tabard not have dependent spells
for(int i= EQUIPMENT_SLOT_START; i< EQUIPMENT_SLOT_MAINHAND; ++i)
- if(Item *item = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
+ if(Item *item = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, i ))
if(item!=ignoreItem && item->IsFitToSpellRequirements(spellInfo))
return true;
// shields can be equipped to offhand slot
- if(Item *item = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
+ if(Item *item = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
if(item!=ignoreItem && item->IsFitToSpellRequirements(spellInfo))
return true;
// ranged slot can have some armor subclasses
- if(Item *item = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED))
+ if(Item *item = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED))
if(item!=ignoreItem && item->IsFitToSpellRequirements(spellInfo))
return true;
@@ -18582,6 +19029,24 @@ bool Player::HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item cons
return false;
}
+bool Player::CanNoReagentCast(SpellEntry const* spellInfo) const
+{
+ // don't take reagents for spells with SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP
+ if (spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP &&
+ HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION))
+ return true;
+
+ // Check no reagent use mask
+ flag96 noReagentMask;
+ noReagentMask[0] = GetUInt32Value(PLAYER_NO_REAGENT_COST_1);
+ noReagentMask[1] = GetUInt32Value(PLAYER_NO_REAGENT_COST_1+1);
+ noReagentMask[2] = GetUInt32Value(PLAYER_NO_REAGENT_COST_1+2);
+ if (spellInfo->SpellFamilyFlags & noReagentMask)
+ return true;
+
+ return false;
+}
+
void Player::RemoveItemDependentAurasAndCasts( Item * pItem )
{
AuraMap& auras = GetAuras();
@@ -18605,8 +19070,7 @@ void Player::RemoveItemDependentAurasAndCasts( Item * pItem )
}
// no alt item, remove aura, restart check
- RemoveAurasDueToSpell(aura->GetId());
- itr = auras.begin();
+ RemoveAura(itr);
}
// currently casted spells can be dependent from item
@@ -18623,11 +19087,11 @@ uint32 Player::GetResurrectionSpellId()
// search priceless resurrection possibilities
uint32 prio = 0;
uint32 spell_id = 0;
- AuraList const& dummyAuras = GetAurasByType(SPELL_AURA_DUMMY);
- for(AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
+ AuraEffectList const& dummyAuras = GetAurasByType(SPELL_AURA_DUMMY);
+ for(AuraEffectList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
{
// Soulstone Resurrection // prio: 3 (max, non death persistent)
- if( prio < 2 && (*itr)->GetSpellProto()->SpellVisual == 99 && (*itr)->GetSpellProto()->SpellIconID == 92 )
+ if( prio < 2 && (*itr)->GetSpellProto()->SpellVisual[0] == 99 && (*itr)->GetSpellProto()->SpellIconID == 92 )
{
switch((*itr)->GetId())
{
@@ -18637,6 +19101,7 @@ uint32 Player::GetResurrectionSpellId()
case 20764: spell_id = 20760; break; // rank 4
case 20765: spell_id = 20761; break; // rank 5
case 27239: spell_id = 27240; break; // rank 6
+ case 47883: spell_id = 47882; break; // rank 7
default:
sLog.outError("Unhandled spell %%u: S.Resurrection",(*itr)->GetId());
continue;
@@ -18659,6 +19124,26 @@ uint32 Player::GetResurrectionSpellId()
return spell_id;
}
+// Used in triggers for check "Only to targets that grant experience or honor" req
+bool Player::isHonorOrXPTarget(Unit* pVictim)
+{
+ uint32 v_level = pVictim->getLevel();
+ uint32 k_grey = Trinity::XP::GetGrayLevel(getLevel());
+
+ // Victim level less gray level
+ if(v_level<=k_grey)
+ return false;
+
+ if(pVictim->GetTypeId() == TYPEID_UNIT)
+ {
+ if (((Creature*)pVictim)->isTotem() ||
+ ((Creature*)pVictim)->isPet() ||
+ ((Creature*)pVictim)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL)
+ return false;
+ }
+ return true;
+}
+
bool Player::RewardPlayerAndGroupAtKill(Unit* pVictim)
{
bool PvP = pVictim->isCharmedOwnedByPlayerOrPlayer();
@@ -18756,6 +19241,31 @@ bool Player::RewardPlayerAndGroupAtKill(Unit* pVictim)
return xp || honored_kill;
}
+void Player::RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject* pRewardSource)
+{
+ uint64 creature_guid = pRewardSource->GetTypeId()==TYPEID_UNIT ? pRewardSource->GetGUID() : uint64(0);
+
+ // prepare data for near group iteration
+ if(Group *pGroup = GetGroup())
+ {
+ for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+ {
+ Player* pGroupGuy = itr->getSource();
+ if(!pGroupGuy)
+ continue;
+
+ if(!pGroupGuy->IsAtGroupRewardDistance(pRewardSource))
+ continue; // member (alive or dead) or his corpse at req. distance
+
+ // quest objectives updated only for alive group member or dead but with not released body
+ if(pGroupGuy->isAlive()|| !pGroupGuy->GetCorpse())
+ pGroupGuy->KilledMonster(creature_id, creature_guid);
+ }
+ }
+ else // if (!pGroup)
+ KilledMonster(creature_id, creature_guid);
+}
+
bool Player::IsAtGroupRewardDistance(WorldObject const* pRewardSource) const
{
if(pRewardSource->GetDistance(this) <= sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE))
@@ -18780,12 +19290,15 @@ uint32 Player::GetBaseWeaponSkillValue (WeaponAttackType attType) const
return 0;
// weapon skill or (unarmed for base attack)
- uint32 skill = item ? item->GetSkill() : SKILL_UNARMED;
+ uint32 skill = item ? item->GetSkill() : uint32(SKILL_UNARMED);
return GetBaseSkillValue(skill);
}
void Player::ResurectUsingRequestData()
{
+ /// Teleport before resurrecting, otherwise the player might get attacked from creatures near his corpse
+ TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation());
+
ResurrectPlayer(0.0f,false);
if(GetMaxHealth() > m_resurrectHealth)
@@ -18803,8 +19316,6 @@ void Player::ResurectUsingRequestData()
SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY) );
SpawnCorpseBones();
-
- TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation());
}
void Player::SetClientControl(Unit* target, uint8 allowMove)
@@ -18813,34 +19324,25 @@ void Player::SetClientControl(Unit* target, uint8 allowMove)
data.append(target->GetPackGUID());
data << uint8(allowMove);
GetSession()->SendPacket(&data);
+ if(target == this)
+ SetMover(this);
}
void Player::UpdateZoneDependentAuras( uint32 newZone )
{
// remove new continent flight forms
- if( !isGameMaster() &&
- GetVirtualMapForMapAndZone(GetMapId(),newZone) != 530)
+ if( !IsAllowUseFlyMountsHere() )
{
- RemoveSpellsCausingAura(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED);
- RemoveSpellsCausingAura(SPELL_AURA_FLY);
+ RemoveAurasByType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED);
+ RemoveAurasByType(SPELL_AURA_FLY);
}
- // Some spells applied at enter into zone (with subzones)
- // Human Illusion
- // NOTE: these are removed by RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP);
- if ( newZone == 2367 ) // Old Hillsbrad Foothills
- {
- uint32 spellid = 0;
- // all horde races
- if( GetTeam() == HORDE )
- spellid = getGender() == GENDER_FEMALE ? 35481 : 35480;
- // and some alliance races
- else if( getRace() == RACE_NIGHTELF || getRace() == RACE_DRAENEI )
- spellid = getGender() == GENDER_FEMALE ? 35483 : 35482;
-
- if(spellid && !HasAura(spellid,0) )
- CastSpell(this,spellid,true);
- }
+ // Some spells applied at enter into zone (with subzones), aura removed in UpdateAreaDependentAuras that called always at zone->area update
+ SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAreaMapBounds(newZone);
+ for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
+ if(itr->second->autocast && itr->second->IsFitToRequirements(this,newZone,0))
+ if( !HasAura(itr->second->spellId) )
+ CastSpell(this,itr->second->spellId,true);
}
void Player::UpdateAreaDependentAuras( uint32 newArea )
@@ -18849,26 +19351,18 @@ void Player::UpdateAreaDependentAuras( uint32 newArea )
for(AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();)
{
// use m_zoneUpdateId for speed: UpdateArea called from UpdateZone or instead UpdateZone in both cases m_zoneUpdateId up-to-date
- if(!IsSpellAllowedInLocation(iter->second->GetSpellProto(),GetMapId(),m_zoneUpdateId,newArea))
+ if(spellmgr.GetSpellAllowedInLocationError(iter->second->GetSpellProto(),GetMapId(),m_zoneUpdateId,newArea,this) != SPELL_CAST_OK)
RemoveAura(iter);
else
++iter;
}
- // unmount if enter in this subzone
- if( newArea == 35)
- RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
- // Dragonmaw Illusion
- else if( newArea == 3759 || newArea == 3966 || newArea == 3939 )
- {
- if( GetDummyAura(40214) )
- {
- if( !HasAura(40216,0) )
- CastSpell(this,40216,true);
- if( !HasAura(42016,0) )
- CastSpell(this,42016,true);
- }
- }
+ // some auras applied at subzone enter
+ SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAreaMapBounds(newArea);
+ for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
+ if(itr->second->autocast && itr->second->IsFitToRequirements(this,m_zoneUpdateId,newArea))
+ if( !HasAura(itr->second->spellId) )
+ CastSpell(this,itr->second->spellId,true);
}
uint32 Player::GetCorpseReclaimDelay(bool pvp) const
@@ -18954,7 +19448,7 @@ void Player::SendCorpseReclaimDelay(bool load)
//! corpse reclaim delay 30 * 1000ms or longer at often deaths
WorldPacket data(SMSG_CORPSE_RECLAIM_DELAY, 4);
- data << uint32(delay*1000);
+ data << uint32(delay*IN_MILISECONDS);
GetSession()->SendPacket( &data );
}
@@ -18999,21 +19493,85 @@ PartyResult Player::CanUninviteFromGroup() const
return PARTY_RESULT_OK;
}
+void Player::SetBattleGroundRaid(Group* group, int8 subgroup)
+{
+ //we must move references from m_group to m_originalGroup
+ SetOriginalGroup(GetGroup(), GetSubGroup());
+
+ m_group.unlink();
+ m_group.link(group, this);
+ m_group.setSubGroup((uint8)subgroup);
+}
+
+void Player::RemoveFromBattleGroundRaid()
+{
+ //remove existing reference
+ m_group.unlink();
+ if( Group* group = GetOriginalGroup() )
+ {
+ m_group.link(group, this);
+ m_group.setSubGroup(GetOriginalSubGroup());
+ }
+ SetOriginalGroup(NULL);
+}
+
+void Player::SetOriginalGroup(Group *group, int8 subgroup)
+{
+ if( group == NULL )
+ m_originalGroup.unlink();
+ else
+ {
+ // never use SetOriginalGroup without a subgroup unless you specify NULL for group
+ assert(subgroup >= 0);
+ m_originalGroup.link(group, this);
+ m_originalGroup.setSubGroup((uint8)subgroup);
+ }
+}
+
void Player::UpdateUnderwaterState( Map* m, float x, float y, float z )
{
- float water_z = m->GetWaterLevel(x,y);
- float height_z = m->GetHeight(x,y,z, false); // use .map base surface height
- uint8 flag1 = m->GetTerrainType(x,y);
+ LiquidData liquid_status;
+ ZLiquidStatus res = m->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquid_status);
+ if (!res)
+ {
+ m_MirrorTimerFlags &= ~(UNDERWATER_INWATER|UNDERWATER_INLAVA|UNDERWATER_INSLIME|UNDERWARER_INDARKWATER);
+ // Small hack for enable breath in WMO
+ if (IsInWater())
+ m_MirrorTimerFlags|=UNDERWATER_INWATER;
+ return;
+ }
+
+ // All liquids type - check under water position
+ if (liquid_status.type&(MAP_LIQUID_TYPE_WATER|MAP_LIQUID_TYPE_OCEAN|MAP_LIQUID_TYPE_MAGMA|MAP_LIQUID_TYPE_SLIME))
+ {
+ if ( res & LIQUID_MAP_UNDER_WATER)
+ m_MirrorTimerFlags |= UNDERWATER_INWATER;
+ else
+ m_MirrorTimerFlags &= ~UNDERWATER_INWATER;
+ }
- //!Underwater check, not in water if underground or above water level
- if (height_z <= INVALID_HEIGHT || z < (height_z-2) || z > (water_z - 2) )
- m_isunderwater &= 0x7A;
- else if ((z < (water_z - 2)) && (flag1 & 0x01))
- m_isunderwater |= 0x01;
+ // Allow travel in dark water on taxi or transport
+ if ((liquid_status.type & MAP_LIQUID_TYPE_DARK_WATER) && !isInFlight() && !GetTransport())
+ m_MirrorTimerFlags |= UNDERWARER_INDARKWATER;
+ else
+ m_MirrorTimerFlags &= ~UNDERWARER_INDARKWATER;
- //!in lava check, anywhere under lava level
- if ((height_z <= INVALID_HEIGHT || z < (height_z - 0)) && (flag1 == 0x00) && IsInWater())
- m_isunderwater |= 0x80;
+ // in lava check, anywhere in lava level
+ if (liquid_status.type&MAP_LIQUID_TYPE_MAGMA)
+ {
+ if (res & (LIQUID_MAP_UNDER_WATER|LIQUID_MAP_IN_WATER|LIQUID_MAP_WATER_WALK))
+ m_MirrorTimerFlags |= UNDERWATER_INLAVA;
+ else
+ m_MirrorTimerFlags &= ~UNDERWATER_INLAVA;
+ }
+ // in slime check, anywhere in slime level
+ if (liquid_status.type&MAP_LIQUID_TYPE_SLIME)
+ {
+ if (res & (LIQUID_MAP_UNDER_WATER|LIQUID_MAP_IN_WATER|LIQUID_MAP_WATER_WALK))
+ m_MirrorTimerFlags |= UNDERWATER_INSLIME;
+ else
+ m_MirrorTimerFlags &= ~UNDERWATER_INSLIME;
+ }
}
void Player::SetCanParry( bool value )
@@ -19046,140 +19604,157 @@ bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const
//-------------TRINITY---------------
//***********************************
-void Player::HandleFallDamage(MovementInfo& movementInfo)
+void Player::StopCastingBindSight()
{
- if(movementInfo.fallTime < 1500)
- return;
-
- // calculate total z distance of the fall
- float z_diff = m_lastFallZ - movementInfo.z;
- sLog.outDebug("zDiff = %f", z_diff);
-
- //Players with low fall distance, Feather Fall or physical immunity (charges used) are ignored
- // 14.57 can be calculated by resolving damageperc formular below to 0
- if (z_diff >= 14.57f && !isDead() && !isGameMaster() &&
- !HasAuraType(SPELL_AURA_HOVER) && !HasAuraType(SPELL_AURA_FEATHER_FALL) &&
- !HasAuraType(SPELL_AURA_FLY) && !IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL,true) )
+ if(WorldObject* target = GetViewpoint())
{
- //Safe fall, fall height reduction
- int32 safe_fall = GetTotalAuraModifier(SPELL_AURA_SAFE_FALL);
-
- float damageperc = 0.018f*(z_diff-safe_fall)-0.2426f;
-
- if(damageperc >0 )
+ if(target->isType(TYPEMASK_UNIT))
{
- uint32 damage = (uint32)(damageperc * GetMaxHealth()*sWorld.getRate(RATE_DAMAGE_FALL));
-
- float height = movementInfo.z;
- UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height);
-
- if (damage > 0)
- {
- //Prevent fall damage from being more than the player maximum health
- if (damage > GetMaxHealth())
- damage = GetMaxHealth();
-
- // Gust of Wind
- if (GetDummyAura(43621))
- damage = GetMaxHealth()/2;
-
- EnvironmentalDamage(GetGUID(), DAMAGE_FALL, damage);
- }
-
- //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction
- DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall);
+ ((Unit*)target)->RemoveAura(SPELL_AURA_BIND_SIGHT, GetGUID());
+ ((Unit*)target)->RemoveAura(SPELL_AURA_MOD_POSSESS, GetGUID());
+ ((Unit*)target)->RemoveAura(SPELL_AURA_MOD_POSSESS_PET, GetGUID());
}
}
}
-void Player::HandleFallUnderMap()
+void Player::SetViewpoint(WorldObject* target, bool apply)
{
- if(InBattleGround()
- && GetBattleGround()
- && GetBattleGround()->HandlePlayerUnderMap(this))
+ if(apply)
{
- // do nothing, the handle already did if returned true
+ sLog.outDebug("Player::CreateViewpoint: Player %s create seer %u (TypeId: %u).", GetName(), target->GetEntry(), target->GetTypeId());
+
+ if(!AddUInt64Value(PLAYER_FARSIGHT, target->GetGUID()))
+ {
+ sLog.outCrash("Player::CreateViewpoint: Player %s cannot add new viewpoint!", GetName());
+ return;
+ }
+
+ if(target->isType(TYPEMASK_UNIT) && !m_Vehicle)
+ ((Unit*)target)->AddPlayerToVision(this);
}
else
{
- // NOTE: this is actually called many times while falling
- // even after the player has been teleported away
- // TODO: discard movement packets after the player is rooted
- if(isAlive())
+ sLog.outDebug("Player::CreateViewpoint: Player %s remove seer", GetName());
+
+ if(!RemoveUInt64Value(PLAYER_FARSIGHT, target->GetGUID()))
{
- EnvironmentalDamage(GetGUID(),DAMAGE_FALL_TO_VOID, GetMaxHealth());
- // change the death state to CORPSE to prevent the death timer from
- // starting in the next player update
- KillPlayer();
- BuildPlayerRepop();
+ sLog.outCrash("Player::CreateViewpoint: Player %s cannot remove current viewpoint!", GetName());
+ return;
}
- // cancel the death timer here if started
- RepopAtGraveyard();
+ if(target->isType(TYPEMASK_UNIT) && !m_Vehicle)
+ ((Unit*)target)->RemovePlayerFromVision(this);
+
+ //must immediately set seer back otherwise may crash
+ m_seer = this;
+
+ //WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0);
+ //GetSession()->SendPacket(&data);
}
}
-void Player::SetViewport(uint64 guid, bool moveable)
+WorldObject* Player::GetViewpoint() const
{
- WorldPacket data(SMSG_CLIENT_CONTROL_UPDATE, 8+1);
- data.appendPackGUID(guid); // Packed guid of object to set client's view to
- data << (moveable ? uint8(0x01) : uint8(0x00)); // 0 - can't move; 1 - can move
- m_session->SendPacket(&data);
- sLog.outDetail("Viewport for "I64FMT" (%s) changed to "I64FMT, GetGUID(), GetName(), guid);
+ if(uint64 guid = GetUInt64Value(PLAYER_FARSIGHT))
+ return (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*this, guid, TYPEMASK_SEER);
+ return NULL;
}
-WorldObject* Player::GetFarsightTarget() const
-{
- // Players can have in farsight field another player's guid, a creature's guid, or a dynamic object's guid
- if (uint64 guid = GetUInt64Value(PLAYER_FARSIGHT))
- return (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*this, guid, TYPEMASK_PLAYER | TYPEMASK_UNIT | TYPEMASK_DYNAMICOBJECT);
- return NULL;
+bool Player::CanUseBattleGroundObject()
+{
+ // TODO : some spells gives player ForceReaction to one faction (ReputationMgr::ApplyForceReaction)
+ // maybe gameobject code should handle that ForceReaction usage
+ // BUG: sometimes when player clicks on flag in AB - client won't send gameobject_use, only gameobject_report_use packet
+ return ( //InBattleGround() && // in battleground - not need, check in other cases
+ //!IsMounted() && - not correct, player is dismounted when he clicks on flag
+ //player cannot use object when he is invulnerable (immune)
+ !isTotalImmune() && // not totally immune
+ //i'm not sure if these two are correct, because invisible players should get visible when they click on flag
+ !HasStealthAura() && // not stealthed
+ !HasInvisibilityAura() && // not invisible
+ !HasAura(SPELL_RECENTLY_DROPPED_FLAG) && // can't pickup
+ isAlive() // live player
+ );
}
-void Player::StopCastingBindSight()
+bool Player::CanCaptureTowerPoint()
{
- if(WorldObject* target = GetFarsightTarget())
- {
- if(target->isType(TYPEMASK_UNIT))
- {
- ((Unit*)target)->RemoveAuraTypeByCaster(SPELL_AURA_BIND_SIGHT, GetGUID());
- ((Unit*)target)->RemoveAuraTypeByCaster(SPELL_AURA_MOD_POSSESS, GetGUID());
- ((Unit*)target)->RemoveAuraTypeByCaster(SPELL_AURA_MOD_POSSESS_PET, GetGUID());
- }
- }
+ return ( !HasStealthAura() && // not stealthed
+ !HasInvisibilityAura() && // not invisible
+ isAlive() // live player
+ );
}
-void Player::ClearFarsight()
+uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair)
{
- if (GetUInt64Value(PLAYER_FARSIGHT))
- {
- SetUInt64Value(PLAYER_FARSIGHT, 0);
- WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0);
- GetSession()->SendPacket(&data);
- }
+ uint32 level = getLevel();
+
+ if(level > GT_MAX_LEVEL)
+ level = GT_MAX_LEVEL; // max level in this dbc
+
+ uint8 hairstyle = GetByteValue(PLAYER_BYTES, 2);
+ uint8 haircolor = GetByteValue(PLAYER_BYTES, 3);
+ uint8 facialhair = GetByteValue(PLAYER_BYTES_2, 0);
+
+ if((hairstyle == newhairstyle) && (haircolor == newhaircolor) && (facialhair == newfacialhair))
+ return 0;
+
+ GtBarberShopCostBaseEntry const *bsc = sGtBarberShopCostBaseStore.LookupEntry(level - 1);
+
+ if(!bsc) // shouldn't happen
+ return 0xFFFFFFFF;
+
+ float cost = 0;
+
+ if(hairstyle != newhairstyle)
+ cost += bsc->cost; // full price
+
+ if((haircolor != newhaircolor) && (hairstyle == newhairstyle))
+ cost += bsc->cost * 0.5f; // +1/2 of price
+
+ if(facialhair != newfacialhair)
+ cost += bsc->cost * 0.75f; // +3/4 of price
+
+ return uint32(cost);
}
-void Player::SetFarsightTarget(WorldObject* obj)
+void Player::InitGlyphsForLevel()
{
- if (!obj || !obj->isType(TYPEMASK_PLAYER | TYPEMASK_UNIT | TYPEMASK_DYNAMICOBJECT))
- return;
+ for(uint32 i = 0; i < sGlyphSlotStore.GetNumRows(); ++i)
+ if(GlyphSlotEntry const * gs = sGlyphSlotStore.LookupEntry(i))
+ if(gs->Order)
+ SetGlyphSlot(gs->Order - 1, gs->Id);
+
+ uint32 level = getLevel();
+ uint32 value = 0;
- // Remove the current target if there is one
- StopCastingBindSight();
+ // 0x3F = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 for 80 level
+ if(level >= 15)
+ value |= (0x01 | 0x02);
+ if(level >= 30)
+ value |= 0x08;
+ if(level >= 50)
+ value |= 0x04;
+ if(level >= 70)
+ value |= 0x10;
+ if(level >= 80)
+ value |= 0x20;
- SetUInt64Value(PLAYER_FARSIGHT, obj->GetGUID());
+ SetUInt32Value(PLAYER_GLYPHS_ENABLED, value);
}
-bool Player::isAllowUseBattleGroundObject()
+bool Player::isTotalImmune()
{
- return ( //InBattleGround() && // in battleground - not need, check in other cases
- !IsMounted() && // not mounted
- !isTotalImmunity() && // not totally immuned
- !HasStealthAura() && // not stealthed
- !HasInvisibilityAura() && // not invisible
- !HasAura(SPELL_RECENTLY_DROPPED_FLAG, 0) && // can't pickup
- isAlive() // live player
- );
+ AuraEffectList const& immune = GetAurasByType(SPELL_AURA_SCHOOL_IMMUNITY);
+
+ uint32 immuneMask = 0;
+ for(AuraEffectList::const_iterator itr = immune.begin(); itr != immune.end(); ++itr)
+ {
+ immuneMask |= (*itr)->GetMiscValue();
+ if( immuneMask & SPELL_SCHOOL_MASK_ALL ) // total immunity
+ return true;
+ }
+ return false;
}
bool Player::HasTitle(uint32 bitIndex)
@@ -19199,23 +19774,22 @@ void Player::SetTitle(CharTitlesEntry const* title)
SetFlag(PLAYER__FIELD_KNOWN_TITLES+fieldIndexOffset, flag);
}
-
/*-----------------------TRINITY--------------------------*/
bool Player::isTotalImmunity()
{
- AuraList const& immune = GetAurasByType(SPELL_AURA_SCHOOL_IMMUNITY);
+ AuraEffectList const& immune = GetAurasByType(SPELL_AURA_SCHOOL_IMMUNITY);
- for(AuraList::const_iterator itr = immune.begin(); itr != immune.end(); ++itr)
+ for(AuraEffectList::const_iterator itr = immune.begin(); itr != immune.end(); ++itr)
{
- if (((*itr)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_ALL) !=0) // total immunity
+ if (((*itr)->GetMiscValue() & SPELL_SCHOOL_MASK_ALL) !=0) // total immunity
{
return true;
}
- if (((*itr)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) !=0) // physical damage immunity
+ if (((*itr)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) !=0) // physical damage immunity
{
- for(AuraList::const_iterator i = immune.begin(); i != immune.end(); ++i)
+ for(AuraEffectList::const_iterator i = immune.begin(); i != immune.end(); ++i)
{
- if (((*i)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_MAGIC) !=0) // magic immunity
+ if (((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_MAGIC) !=0) // magic immunity
{
return true;
}
@@ -19233,9 +19807,9 @@ void Player::UpdateCharmedAI()
//kill self if charm aura has infinite duration
if(charmer->IsInEvadeMode())
{
- AuraList const& auras = GetAurasByType(SPELL_AURA_MOD_CHARM);
- for(AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
- if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->IsPermanent())
+ AuraEffectList const& auras = GetAurasByType(SPELL_AURA_MOD_CHARM);
+ for(AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
+ if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetParentAura()->IsPermanent())
{
charmer->DealDamage(this, GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
return;
@@ -19257,3 +19831,612 @@ void Player::UpdateCharmedAI()
}
}
+void Player::ConvertRune(uint8 index, uint8 newType)
+{
+ SetCurrentRune(index, newType);
+
+ WorldPacket data(SMSG_CONVERT_RUNE, 2);
+ data << uint8(index);
+ data << uint8(newType);
+ GetSession()->SendPacket(&data);
+}
+
+void Player::ResyncRunes(uint8 count)
+{
+ WorldPacket data(SMSG_RESYNC_RUNES, count * 2);
+ for(uint32 i = 0; i < count; ++i)
+ {
+ data << uint8(GetCurrentRune(i)); // rune type
+ data << uint8(255 - (GetRuneCooldown(i) * 51)); // passed cooldown time (0-255)
+ }
+ GetSession()->SendPacket(&data);
+}
+
+void Player::AddRunePower(uint8 index)
+{
+ WorldPacket data(SMSG_ADD_RUNE_POWER, 4);
+ data << uint32(1 << index); // mask (0x00-0x3F probably)
+ GetSession()->SendPacket(&data);
+}
+
+void Player::InitRunes()
+{
+ if(getClass() != CLASS_DEATH_KNIGHT)
+ return;
+
+ m_runes = new Runes;
+
+ m_runes->runeState = 0;
+
+ for(uint32 i = 0; i < MAX_RUNES; ++i)
+ {
+ SetBaseRune(i, i / 2); // init base types
+ SetCurrentRune(i, i / 2); // init current types
+ SetRuneCooldown(i, 0); // reset cooldowns
+ m_runes->SetRuneState(i);
+ }
+
+ for(uint32 i = 0; i < NUM_RUNE_TYPES; ++i)
+ SetFloatValue(PLAYER_RUNE_REGEN_1 + i, 0.1f);
+}
+
+void Player::AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store, bool broadcast)
+{
+ Loot loot;
+ loot.FillLoot (loot_id,store,this,true);
+
+ uint32 max_slot = loot.GetMaxSlotInLootFor(this);
+ for(uint32 i = 0; i < max_slot; ++i)
+ {
+ LootItem* lootItem = loot.LootItemInSlot(i,this);
+
+ ItemPosCountVec dest;
+ uint8 msg = CanStoreNewItem (bag,slot,dest,lootItem->itemid,lootItem->count);
+ if(msg != EQUIP_ERR_OK && slot != NULL_SLOT)
+ msg = CanStoreNewItem( bag, NULL_SLOT,dest,lootItem->itemid,lootItem->count);
+ if( msg != EQUIP_ERR_OK && bag != NULL_BAG)
+ msg = CanStoreNewItem( NULL_BAG, NULL_SLOT,dest,lootItem->itemid,lootItem->count);
+ if(msg != EQUIP_ERR_OK)
+ {
+ SendEquipError( msg, NULL, NULL );
+ continue;
+ }
+
+ Item* pItem = StoreNewItem (dest,lootItem->itemid,true,lootItem->randomPropertyId);
+ SendNewItem(pItem, lootItem->count, false, false, broadcast);
+ }
+}
+
+uint32 Player::CalculateTalentsPoints() const
+{
+ uint32 base_talent = getLevel() < 10 ? 0 : uint32((getLevel()-9)*sWorld.getRate(RATE_TALENT));
+
+ if(getClass() != CLASS_DEATH_KNIGHT)
+ return base_talent;
+
+ uint32 talentPointsForLevel =
+ (getLevel() < 56 ? 0 : uint32((getLevel()-55)*sWorld.getRate(RATE_TALENT)))
+ + m_questRewardTalentCount;
+
+ if(talentPointsForLevel > base_talent)
+ talentPointsForLevel = base_talent;
+
+ return talentPointsForLevel;
+}
+
+bool Player::IsAllowUseFlyMountsHere() const
+{
+ if (isGameMaster())
+ return true;
+
+ uint32 v_map = GetVirtualMapForMapAndZone(GetMapId(), GetZoneId());
+ return v_map == 530 || v_map == 571 && HasSpell(54197);
+}
+
+void Player::learnSpellHighRank(uint32 spellid)
+{
+ learnSpell(spellid,false);
+
+ if(uint32 next = spellmgr.GetNextSpellInChain(spellid))
+ learnSpellHighRank(next);
+}
+
+void Player::_LoadSkills()
+{
+ // Note: skill data itself loaded from `data` field. This is only cleanup part of load
+
+ // reset skill modifiers and set correct unlearn flags
+ for (uint32 i = 0; i < PLAYER_MAX_SKILLS; i++)
+ {
+ SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0);
+
+ // set correct unlearn bit
+ uint32 id = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF;
+ if(!id) continue;
+
+ SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(id);
+ if(!pSkill) continue;
+
+ // enable unlearn button for primary professions only
+ if (pSkill->categoryId == SKILL_CATEGORY_PROFESSION)
+ SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,1));
+ else
+ SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,0));
+
+ // set fixed skill ranges
+ switch(GetSkillRangeType(pSkill,false))
+ {
+ case SKILL_RANGE_LANGUAGE: // 300..300
+ SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(300,300));
+ break;
+ case SKILL_RANGE_MONO: // 1..1, grey monolite bar
+ SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(1,1));
+ break;
+ default:
+ break;
+ }
+
+ uint32 vskill = SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i)));
+ learnSkillRewardedSpells(id, vskill);
+ }
+
+ // special settings
+ if(getClass()==CLASS_DEATH_KNIGHT)
+ {
+ uint32 base_level = std::min(getLevel(),sWorld.getConfig (CONFIG_START_HEROIC_PLAYER_LEVEL));
+ if(base_level < 1)
+ base_level = 1;
+ uint32 base_skill = (base_level-1)*5; // 270 at starting level 55
+ if(base_skill < 1)
+ base_skill = 1; // skill mast be known and then > 0 in any case
+
+ if(GetPureSkillValue (SKILL_FIRST_AID) < base_skill)
+ SetSkill(SKILL_FIRST_AID,base_skill, base_skill);
+ if(GetPureSkillValue (SKILL_AXES) < base_skill)
+ SetSkill(SKILL_AXES, base_skill,base_skill);
+ if(GetPureSkillValue (SKILL_DEFENSE) < base_skill)
+ SetSkill(SKILL_DEFENSE, base_skill,base_skill);
+ if(GetPureSkillValue (SKILL_POLEARMS) < base_skill)
+ SetSkill(SKILL_POLEARMS, base_skill,base_skill);
+ if(GetPureSkillValue (SKILL_SWORDS) < base_skill)
+ SetSkill(SKILL_SWORDS, base_skill,base_skill);
+ if(GetPureSkillValue (SKILL_2H_AXES) < base_skill)
+ SetSkill(SKILL_2H_AXES, base_skill,base_skill);
+ if(GetPureSkillValue (SKILL_2H_SWORDS) < base_skill)
+ SetSkill(SKILL_2H_SWORDS, base_skill,base_skill);
+ if(GetPureSkillValue (SKILL_UNARMED) < base_skill)
+ SetSkill(SKILL_UNARMED, base_skill,base_skill);
+ }
+}
+
+uint32 Player::GetPhaseMaskForSpawn() const
+{
+ uint32 phase = PHASEMASK_NORMAL;
+ if(!isGameMaster())
+ phase = GetPhaseMask();
+ else
+ {
+ AuraEffectList const& phases = GetAurasByType(SPELL_AURA_PHASE);
+ if(!phases.empty())
+ phase = phases.front()->GetMiscValue();
+ }
+
+ // some aura phases include 1 normal map in addition to phase itself
+ if(uint32 n_phase = phase & ~PHASEMASK_NORMAL)
+ return n_phase;
+
+ return PHASEMASK_NORMAL;
+}
+
+uint8 Player::CanEquipUniqueItem(Item* pItem, uint8 eslot, uint32 limit_count) const
+{
+ ItemPrototype const* pProto = pItem->GetProto();
+
+ // proto based limitations
+ if(uint8 res = CanEquipUniqueItem(pProto,eslot,limit_count))
+ return res;
+
+ // check unique-equipped on gems
+ for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)
+ {
+ uint32 enchant_id = pItem->GetEnchantmentId(EnchantmentSlot(enchant_slot));
+ if(!enchant_id)
+ continue;
+ SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
+ if(!enchantEntry)
+ continue;
+
+ ItemPrototype const* pGem = objmgr.GetItemPrototype(enchantEntry->GemID);
+ if(!pGem)
+ continue;
+
+ // include for check equip another gems with same limit category for not equipped item (and then not counted)
+ uint32 gem_limit_count = !pItem->IsEquipped() && pGem->ItemLimitCategory
+ ? pItem->GetGemCountWithLimitCategory(pGem->ItemLimitCategory) : 1;
+
+ if(uint8 res = CanEquipUniqueItem(pGem, eslot,gem_limit_count))
+ return res;
+ }
+
+ return EQUIP_ERR_OK;
+}
+
+uint8 Player::CanEquipUniqueItem( ItemPrototype const* itemProto, uint8 except_slot, uint32 limit_count) const
+{
+ // check unique-equipped on item
+ if (itemProto->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED)
+ {
+ // there is an equip limit on this item
+ if(HasItemOrGemWithIdEquipped(itemProto->ItemId,1,except_slot))
+ return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
+ }
+
+ // check unique-equipped limit
+ if (itemProto->ItemLimitCategory)
+ {
+ ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(itemProto->ItemLimitCategory);
+ if(!limitEntry)
+ return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
+
+ if(limit_count > limitEntry->maxCount)
+ return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE; // attempt add too many limit category items (gems)
+
+ // there is an equip limit on this item
+ if(HasItemOrGemWithLimitCategoryEquipped(itemProto->ItemLimitCategory,limitEntry->maxCount-limit_count+1,except_slot))
+ return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
+ }
+
+ return EQUIP_ERR_OK;
+}
+
+void Player::HandleFall(MovementInfo const& movementInfo)
+{
+ // calculate total z distance of the fall
+ float z_diff = m_lastFallZ - movementInfo.z;
+ //sLog.outDebug("zDiff = %f", z_diff);
+
+ //Players with low fall distance, Feather Fall or physical immunity (charges used) are ignored
+ // 14.57 can be calculated by resolving damageperc formula below to 0
+ if (z_diff >= 14.57f && !isDead() && !isGameMaster() &&
+ !HasAuraType(SPELL_AURA_HOVER) && !HasAuraType(SPELL_AURA_FEATHER_FALL) &&
+ !HasAuraType(SPELL_AURA_FLY) && !IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL) )
+ {
+ //Safe fall, fall height reduction
+ int32 safe_fall = GetTotalAuraModifier(SPELL_AURA_SAFE_FALL);
+
+ float damageperc = 0.018f*(z_diff-safe_fall)-0.2426f;
+
+ if(damageperc >0 )
+ {
+ uint32 damage = (uint32)(damageperc * GetMaxHealth()*sWorld.getRate(RATE_DAMAGE_FALL));
+
+ float height = movementInfo.z;
+ UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height);
+
+ if (damage > 0)
+ {
+ //Prevent fall damage from being more than the player maximum health
+ if (damage > GetMaxHealth())
+ damage = GetMaxHealth();
+
+ // Gust of Wind
+ if (GetDummyAura(43621))
+ damage = GetMaxHealth()/2;
+
+ EnvironmentalDamage(DAMAGE_FALL, damage);
+
+ // recheck alive, might have died of EnvironmentalDamage
+ if (isAlive())
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING, uint32(z_diff*100));
+ }
+
+ //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction
+ DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall);
+ }
+ }
+}
+
+void Player::UpdateAchievementCriteria( AchievementCriteriaTypes type, uint32 miscvalue1/*=0*/, uint32 miscvalue2/*=0*/, Unit *unit/*=NULL*/, uint32 time/*=0*/ )
+{
+ GetAchievementMgr().UpdateAchievementCriteria(type, miscvalue1,miscvalue2,unit,time);
+}
+
+void Player::LearnTalent(uint32 talentId, uint32 talentRank)
+{
+ uint32 CurTalentPoints = GetFreeTalentPoints();
+
+ if(CurTalentPoints == 0)
+ return;
+
+ if (talentRank >= MAX_TALENT_RANK)
+ return;
+
+ TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentId );
+
+ if(!talentInfo)
+ return;
+
+ TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
+
+ if(!talentTabInfo)
+ return;
+
+ // prevent learn talent for different class (cheating)
+ if( (getClassMask() & talentTabInfo->ClassMask) == 0 )
+ return;
+
+ // find current max talent rank
+ int32 curtalent_maxrank = 0;
+ for(int32 k = MAX_TALENT_RANK-1; k > -1; --k)
+ {
+ if(talentInfo->RankID[k] && HasSpell(talentInfo->RankID[k]))
+ {
+ curtalent_maxrank = k + 1;
+ break;
+ }
+ }
+
+ // we already have same or higher talent rank learned
+ if(curtalent_maxrank >= (talentRank + 1))
+ return;
+
+ // check if we have enough talent points
+ if(CurTalentPoints < (talentRank - curtalent_maxrank + 1))
+ return;
+
+ // Check if it requires another talent
+ if (talentInfo->DependsOn > 0)
+ {
+ if(TalentEntry const *depTalentInfo = sTalentStore.LookupEntry(talentInfo->DependsOn))
+ {
+ bool hasEnoughRank = false;
+ for (int i = talentInfo->DependsOnRank; i < MAX_TALENT_RANK; i++)
+ {
+ if (depTalentInfo->RankID[i] != 0)
+ if (HasSpell(depTalentInfo->RankID[i]))
+ hasEnoughRank = true;
+ }
+ if (!hasEnoughRank)
+ return;
+ }
+ }
+
+ // Find out how many points we have in this field
+ uint32 spentPoints = 0;
+
+ uint32 tTab = talentInfo->TalentTab;
+ if (talentInfo->Row > 0)
+ {
+ unsigned int numRows = sTalentStore.GetNumRows();
+ for (unsigned int i = 0; i < numRows; i++) // Loop through all talents.
+ {
+ // Someday, someone needs to revamp
+ const TalentEntry *tmpTalent = sTalentStore.LookupEntry(i);
+ if (tmpTalent) // the way talents are tracked
+ {
+ if (tmpTalent->TalentTab == tTab)
+ {
+ for (int j = 0; j < MAX_TALENT_RANK; j++)
+ {
+ if (tmpTalent->RankID[j] != 0)
+ {
+ if (HasSpell(tmpTalent->RankID[j]))
+ {
+ spentPoints += j + 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // not have required min points spent in talent tree
+ if(spentPoints < (talentInfo->Row * MAX_TALENT_RANK))
+ return;
+
+ // spell not set in talent.dbc
+ uint32 spellid = talentInfo->RankID[talentRank];
+ if( spellid == 0 )
+ {
+ sLog.outError("Talent.dbc have for talent: %u Rank: %u spell id = 0", talentId, talentRank);
+ return;
+ }
+
+ // already known
+ if(HasSpell(spellid))
+ return;
+
+ // learn! (other talent ranks will unlearned at learning)
+ learnSpell(spellid, false);
+ sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talentId, talentRank, spellid);
+
+ // update free talent points
+ SetFreeTalentPoints(CurTalentPoints - (talentRank - curtalent_maxrank + 1));
+}
+
+void Player::LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank)
+{
+ Pet *pet = GetPet();
+
+ if(!pet)
+ return;
+
+ if(petGuid != pet->GetGUID())
+ return;
+
+ uint32 CurTalentPoints = pet->GetFreeTalentPoints();
+
+ if(CurTalentPoints == 0)
+ return;
+
+ if (talentRank >= MAX_PET_TALENT_RANK)
+ return;
+
+ TalentEntry const *talentInfo = sTalentStore.LookupEntry(talentId);
+
+ if(!talentInfo)
+ return;
+
+ TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
+
+ if(!talentTabInfo)
+ return;
+
+ CreatureInfo const *ci = pet->GetCreatureInfo();
+
+ if(!ci)
+ return;
+
+ CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
+
+ if(!pet_family)
+ return;
+
+ if(pet_family->petTalentType < 0) // not hunter pet
+ return;
+
+ // prevent learn talent for different family (cheating)
+ if(!((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask))
+ return;
+
+ // find current max talent rank
+ int32 curtalent_maxrank = 0;
+ for(int32 k = MAX_TALENT_RANK-1; k > -1; --k)
+ {
+ if(talentInfo->RankID[k] && pet->HasSpell(talentInfo->RankID[k]))
+ {
+ curtalent_maxrank = k + 1;
+ break;
+ }
+ }
+
+ // we already have same or higher talent rank learned
+ if(curtalent_maxrank >= (talentRank + 1))
+ return;
+
+ // check if we have enough talent points
+ if(CurTalentPoints < (talentRank - curtalent_maxrank + 1))
+ return;
+
+ // Check if it requires another talent
+ if (talentInfo->DependsOn > 0)
+ {
+ if(TalentEntry const *depTalentInfo = sTalentStore.LookupEntry(talentInfo->DependsOn))
+ {
+ bool hasEnoughRank = false;
+ for (int i = talentInfo->DependsOnRank; i < MAX_TALENT_RANK; i++)
+ {
+ if (depTalentInfo->RankID[i] != 0)
+ if (pet->HasSpell(depTalentInfo->RankID[i]))
+ hasEnoughRank = true;
+ }
+ if (!hasEnoughRank)
+ return;
+ }
+ }
+
+ // Find out how many points we have in this field
+ uint32 spentPoints = 0;
+
+ uint32 tTab = talentInfo->TalentTab;
+ if (talentInfo->Row > 0)
+ {
+ unsigned int numRows = sTalentStore.GetNumRows();
+ for (unsigned int i = 0; i < numRows; ++i) // Loop through all talents.
+ {
+ // Someday, someone needs to revamp
+ const TalentEntry *tmpTalent = sTalentStore.LookupEntry(i);
+ if (tmpTalent) // the way talents are tracked
+ {
+ if (tmpTalent->TalentTab == tTab)
+ {
+ for (int j = 0; j < MAX_TALENT_RANK; j++)
+ {
+ if (tmpTalent->RankID[j] != 0)
+ {
+ if (pet->HasSpell(tmpTalent->RankID[j]))
+ {
+ spentPoints += j + 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // not have required min points spent in talent tree
+ if(spentPoints < (talentInfo->Row * MAX_PET_TALENT_RANK))
+ return;
+
+ // spell not set in talent.dbc
+ uint32 spellid = talentInfo->RankID[talentRank];
+ if( spellid == 0 )
+ {
+ sLog.outError("Talent.dbc have for talent: %u Rank: %u spell id = 0", talentId, talentRank);
+ return;
+ }
+
+ // already known
+ if(pet->HasSpell(spellid))
+ return;
+
+ // learn! (other talent ranks will unlearned at learning)
+ pet->learnSpell(spellid);
+ sLog.outDetail("PetTalentID: %u Rank: %u Spell: %u\n", talentId, talentRank, spellid);
+
+ // update free talent points
+ pet->SetFreeTalentPoints(CurTalentPoints - (talentRank - curtalent_maxrank + 1));
+}
+
+void Player::UpdateKnownCurrencies(uint32 itemId, bool apply)
+{
+ if(CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(itemId))
+ {
+ if(apply)
+ SetFlag64(PLAYER_FIELD_KNOWN_CURRENCIES,(1LL << (ctEntry->BitIndex-1)));
+ else
+ RemoveFlag64(PLAYER_FIELD_KNOWN_CURRENCIES,(1LL << (ctEntry->BitIndex-1)));
+ }
+}
+
+void Player::UpdateFallInformationIfNeed( MovementInfo const& minfo,uint16 opcode )
+{
+ if (m_lastFallTime >= minfo.fallTime || m_lastFallZ <=minfo.z || opcode == MSG_MOVE_FALL_LAND)
+ SetFallInformation(minfo.fallTime, minfo.z);
+}
+
+void Player::UnsummonPetTemporaryIfAny()
+{
+ Pet* pet = GetPet();
+ if(!pet)
+ return;
+
+ if(!m_temporaryUnsummonedPetNumber && pet->isControlled() && !pet->isTemporarySummoned() )
+ {
+ m_temporaryUnsummonedPetNumber = pet->GetCharmInfo()->GetPetNumber();
+ m_oldpetspell = pet->GetUInt32Value(UNIT_CREATED_BY_SPELL);
+ }
+
+ RemovePet(pet, PET_SAVE_AS_CURRENT);
+}
+
+void Player::ResummonPetTemporaryUnSummonedIfAny()
+{
+ if(!m_temporaryUnsummonedPetNumber)
+ return;
+
+ // not resummon in not appropriate state
+ if(IsPetNeedBeTemporaryUnsummoned())
+ return;
+
+ if(GetPetGUID())
+ return;
+
+ Pet* NewPet = new Pet(this);
+ if(!NewPet->LoadPetFromDB(this, 0, m_temporaryUnsummonedPetNumber, true))
+ delete NewPet;
+
+ m_temporaryUnsummonedPetNumber = 0;
+}
diff --git a/src/game/Player.h b/src/game/Player.h
index 7d530a57228..a40a7f1c40c 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -35,6 +35,9 @@
#include "Pet.h"
#include "MapReference.h"
#include "Util.h" // for Tokens typedef
+#include "AchievementMgr.h"
+#include "ReputationMgr.h"
+#include "BattleGround.h"
#include<string>
#include<vector>
@@ -45,8 +48,8 @@ class DynamicObject;
class Creature;
class Pet;
class PlayerMenu;
-class Transport;
class UpdateMask;
+class SpellCastTargets;
class PlayerSocial;
class OutdoorPvP;
@@ -54,6 +57,7 @@ typedef std::deque<Mail*> PlayerMails;
#define PLAYER_MAX_SKILLS 127
#define PLAYER_MAX_DAILY_QUESTS 25
+#define AT_LOAD_PET_FLAGS 16
// Note: SPELLMOD_* values is aura types in fact
enum SpellModType
@@ -62,6 +66,18 @@ enum SpellModType
SPELLMOD_PCT = 108 // SPELL_AURA_ADD_PCT_MODIFIER
};
+// 2^n values, Player::m_isunderwater is a bitmask. These are mangos internal values, they are never send to any client
+enum PlayerUnderwaterState
+{
+ UNDERWATER_NONE = 0x00,
+ UNDERWATER_INWATER = 0x01, // terrain type is water and player is afflicted by it
+ UNDERWATER_INLAVA = 0x02, // terrain type is lava and player is afflicted by it
+ UNDERWATER_INSLIME = 0x04, // terrain type is lava and player is afflicted by it
+ UNDERWARER_INDARKWATER = 0x08, // terrain type is dark water and player is afflicted by it
+
+ UNDERWATER_EXIST_TIMERS = 0x10
+};
+
enum PlayerSpellState
{
PLAYERSPELL_UNCHANGED = 0,
@@ -72,27 +88,26 @@ enum PlayerSpellState
struct PlayerSpell
{
- uint16 slotId : 16;
PlayerSpellState state : 8;
- bool active : 1;
- bool disabled : 1;
+ bool active : 1; // show in spellbook
+ bool dependent : 1; // learned as result another spell learn, skill grow, quest reward, etc
+ bool disabled : 1; // first rank has been learned in result talent learn but currently talent unlearned, save max learned ranks
};
-#define SPELL_WITHOUT_SLOT_ID uint16(-1)
-
+// Spell modifier (used for modify other spells)
struct SpellModifier
{
+ SpellModifier() : charges(0), lastAffected(NULL) {}
SpellModOp op : 8;
SpellModType type : 8;
int16 charges : 16;
int32 value;
- uint64 mask;
+ flag96 mask;
uint32 spellId;
- uint32 effectId;
Spell const* lastAffected;
};
-typedef UNORDERED_MAP<uint16, PlayerSpell*> PlayerSpellMap;
+typedef UNORDERED_MAP<uint32, PlayerSpell*> PlayerSpellMap;
typedef std::list<SpellModifier*> SpellModList;
struct SpellCooldown
@@ -141,8 +156,6 @@ enum ActionButtonType
typedef std::map<uint8,ActionButton> ActionButtonList;
-typedef std::pair<uint16, uint8> CreateSpellPair;
-
struct PlayerCreateInfoItem
{
PlayerCreateInfoItem(uint32 id, uint32 amount) : item_id(id), item_amount(amount) {}
@@ -174,6 +187,8 @@ struct PlayerLevelInfo
uint8 stats[MAX_STATS];
};
+typedef std::list<uint32> PlayerCreateInfoSpells;
+
struct PlayerInfo
{
// existence checked by displayId != 0 // existence checked by displayId != 0
@@ -189,7 +204,7 @@ struct PlayerInfo
uint16 displayId_m;
uint16 displayId_f;
PlayerCreateInfoItems item;
- std::list<CreateSpellPair> spell;
+ PlayerCreateInfoSpells spell;
std::list<uint16> action[4];
PlayerLevelInfo* levelInfo; //[level-1] 0..MaxPlayerLevel-1
@@ -224,32 +239,38 @@ struct Areas
float y2;
};
-enum FactionFlags
+#define MAX_RUNES 6
+#define RUNE_COOLDOWN 5 // 5*2=10 sec
+
+enum RuneType
{
- FACTION_FLAG_VISIBLE = 0x01, // makes visible in client (set or can be set at interaction with target of this faction)
- FACTION_FLAG_AT_WAR = 0x02, // enable AtWar-button in client. player controlled (except opposition team always war state), Flag only set on initial creation
- FACTION_FLAG_HIDDEN = 0x04, // hidden faction from reputation pane in client (player can gain reputation, but this update not sent to client)
- FACTION_FLAG_INVISIBLE_FORCED = 0x08, // always overwrite FACTION_FLAG_VISIBLE and hide faction in rep.list, used for hide opposite team factions
- FACTION_FLAG_PEACE_FORCED = 0x10, // always overwrite FACTION_FLAG_AT_WAR, used for prevent war with own team factions
- FACTION_FLAG_INACTIVE = 0x20, // player controlled, state stored in characters.data ( CMSG_SET_FACTION_INACTIVE )
- FACTION_FLAG_RIVAL = 0x40 // flag for the two competing outland factions
+ RUNE_BLOOD = 0,
+ RUNE_UNHOLY = 1,
+ RUNE_FROST = 2,
+ RUNE_DEATH = 3,
+ NUM_RUNE_TYPES = 4
};
-typedef uint32 RepListID;
-struct FactionState
+struct RuneInfo
{
- uint32 ID;
- RepListID ReputationListID;
- uint32 Flags;
- int32 Standing;
- bool Changed;
+ uint8 BaseRune;
+ uint8 CurrentRune;
+ uint8 Cooldown;
};
-typedef std::map<RepListID,FactionState> FactionStateList;
-
-typedef std::map<uint32,ReputationRank> ForcedReactions;
+struct Runes
+{
+ RuneInfo runes[MAX_RUNES];
+ uint8 runeState; // mask of available runes
-typedef std::set<uint64> GuardianPetList;
+ void SetRuneState(uint8 index, bool set = true)
+ {
+ if(set)
+ runeState |= (1 << index); // usable
+ else
+ runeState &= ~(1 << index); // on cooldown
+ }
+};
struct EnchantDuration
{
@@ -328,52 +349,6 @@ enum DrunkenState
DRUNKEN_SMASHED = 3
};
-enum PlayerStateType
-{
- /*
- PLAYER_STATE_DANCE
- PLAYER_STATE_SLEEP
- PLAYER_STATE_SIT
- PLAYER_STATE_STAND
- PLAYER_STATE_READYUNARMED
- PLAYER_STATE_WORK
- PLAYER_STATE_POINT(DNR)
- PLAYER_STATE_NONE // not used or just no state, just standing there?
- PLAYER_STATE_STUN
- PLAYER_STATE_DEAD
- PLAYER_STATE_KNEEL
- PLAYER_STATE_USESTANDING
- PLAYER_STATE_STUN_NOSHEATHE
- PLAYER_STATE_USESTANDING_NOSHEATHE
- PLAYER_STATE_WORK_NOSHEATHE
- PLAYER_STATE_SPELLPRECAST
- PLAYER_STATE_READYRIFLE
- PLAYER_STATE_WORK_NOSHEATHE_MINING
- PLAYER_STATE_WORK_NOSHEATHE_CHOPWOOD
- PLAYER_STATE_AT_EASE
- PLAYER_STATE_READY1H
- PLAYER_STATE_SPELLKNEELSTART
- PLAYER_STATE_SUBMERGED
- */
-
- PLAYER_STATE_NONE = 0,
- PLAYER_STATE_SIT = 1,
- PLAYER_STATE_SIT_CHAIR = 2,
- PLAYER_STATE_SLEEP = 3,
- PLAYER_STATE_SIT_LOW_CHAIR = 4,
- PLAYER_STATE_SIT_MEDIUM_CHAIR = 5,
- PLAYER_STATE_SIT_HIGH_CHAIR = 6,
- PLAYER_STATE_DEAD = 7,
- PLAYER_STATE_KNEEL = 8,
-
- PLAYER_STATE_FORM_ALL = 0x00FF0000,
-
- PLAYER_STATE_FLAG_ALWAYS_STAND = 0x01, // byte 4
- PLAYER_STATE_FLAG_CREEP = 0x02000000,
- PLAYER_STATE_FLAG_UNTRACKABLE = 0x04000000,
- PLAYER_STATE_FLAG_ALL = 0xFF000000,
-};
-
enum PlayerFlags
{
PLAYER_FLAGS_GROUP_LEADER = 0x00000001,
@@ -382,17 +357,25 @@ enum PlayerFlags
PLAYER_FLAGS_GM = 0x00000008,
PLAYER_FLAGS_GHOST = 0x00000010,
PLAYER_FLAGS_RESTING = 0x00000020,
- PLAYER_FLAGS_FFA_PVP = 0x00000080,
+ PLAYER_FLAGS_UNK7 = 0x00000040,
+ PLAYER_FLAGS_UNK8 = 0x00000080, // pre-3.0.3 PLAYER_FLAGS_FFA_PVP flag for FFA PVP state
PLAYER_FLAGS_CONTESTED_PVP = 0x00000100, // Player has been involved in a PvP combat and will be attacked by contested guards
PLAYER_FLAGS_IN_PVP = 0x00000200,
PLAYER_FLAGS_HIDE_HELM = 0x00000400,
PLAYER_FLAGS_HIDE_CLOAK = 0x00000800,
- PLAYER_FLAGS_UNK1 = 0x00001000, // played long time
- PLAYER_FLAGS_UNK2 = 0x00002000, // played too long time
- PLAYER_FLAGS_UNK3 = 0x00008000, // strange visual effect (2.0.1), looks like PLAYER_FLAGS_GHOST flag
- PLAYER_FLAGS_SANCTUARY = 0x00010000, // player entered sanctuary
- PLAYER_FLAGS_UNK4 = 0x00020000, // taxi benchmark mode (on/off) (2.0.1)
- PLAYER_UNK = 0x00040000, // 2.0.8...
+ PLAYER_FLAGS_UNK13 = 0x00001000, // played long time
+ PLAYER_FLAGS_UNK14 = 0x00002000, // played too long time
+ PLAYER_FLAGS_UNK15 = 0x00004000,
+ PLAYER_FLAGS_UNK16 = 0x00008000, // strange visual effect (2.0.1), looks like PLAYER_FLAGS_GHOST flag
+ PLAYER_FLAGS_UNK17 = 0x00010000, // pre-3.0.3 PLAYER_FLAGS_SANCTUARY flag for player entered sanctuary
+ PLAYER_FLAGS_UNK18 = 0x00020000, // taxi benchmark mode (on/off) (2.0.1)
+ PLAYER_FLAGS_PVP_TIMER = 0x00040000, // 3.0.2, pvp timer active (after you disable pvp manually)
+ PLAYER_FLAGS_UNK20 = 0x00080000,
+ PLAYER_FLAGS_UNK21 = 0x00100000,
+ PLAYER_FLAGS_UNK22 = 0x00200000,
+ PLAYER_FLAGS_UNK23 = 0x00400000,
+ PLAYER_ALLOW_ONLY_ABILITY = 0x00800000, // used by bladestorm and killing spree
+ PLAYER_FLAGS_UNK25 = 0x01000000 // disabled all melee ability on tab include autoattack
};
// used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1<<bit_index) without (-1)
@@ -472,17 +455,7 @@ enum ActivateTaxiReplies
ERR_TAXINOTSTANDING = 12
};
-enum LootType
-{
- LOOT_CORPSE = 1,
- LOOT_SKINNING = 2,
- LOOT_FISHING = 3,
- LOOT_PICKPOCKETING = 4, // unsupported by client, sending LOOT_SKINNING instead
- LOOT_DISENCHANTING = 5, // unsupported by client, sending LOOT_SKINNING instead
- LOOT_PROSPECTING = 6, // unsupported by client, sending LOOT_SKINNING instead
- LOOT_INSIGNIA = 7, // unsupported by client, sending LOOT_SKINNING instead
- LOOT_FISHINGHOLE = 8 // unsupported by client, sending LOOT_FISHING instead
-};
+
enum MirrorTimerType
{
@@ -490,6 +463,8 @@ enum MirrorTimerType
BREATH_TIMER = 1,
FIRE_TIMER = 2
};
+#define MAX_TIMERS 3
+#define DISABLED_MIRROR_TIMER -1
// 2^n values
enum PlayerExtraFlags
@@ -511,7 +486,8 @@ enum AtLoginFlags
AT_LOGIN_NONE = 0,
AT_LOGIN_RENAME = 1,
AT_LOGIN_RESET_SPELLS = 2,
- AT_LOGIN_RESET_TALENTS = 4
+ AT_LOGIN_RESET_TALENTS = 4,
+ AT_LOGIN_CUSTOMIZE = 8,
};
typedef std::map<uint32, QuestStatusData> QuestStatusMap;
@@ -543,11 +519,13 @@ enum PlayerSlots
// first slot for item stored (in any way in player m_items data)
PLAYER_SLOT_START = 0,
// last+1 slot for item stored (in any way in player m_items data)
- PLAYER_SLOT_END = 118,
+ PLAYER_SLOT_END = 200,
PLAYER_SLOTS_COUNT = (PLAYER_SLOT_END - PLAYER_SLOT_START)
};
-enum EquipmentSlots
+#define INVENTORY_SLOT_BAG_0 255
+
+enum EquipmentSlots // 19 slots
{
EQUIPMENT_SLOT_START = 0,
EQUIPMENT_SLOT_HEAD = 0,
@@ -572,111 +550,67 @@ enum EquipmentSlots
EQUIPMENT_SLOT_END = 19
};
-enum InventorySlots
+enum InventorySlots // 4 slots
{
- INVENTORY_SLOT_BAG_0 = 255,
INVENTORY_SLOT_BAG_START = 19,
- INVENTORY_SLOT_BAG_1 = 19,
- INVENTORY_SLOT_BAG_2 = 20,
- INVENTORY_SLOT_BAG_3 = 21,
- INVENTORY_SLOT_BAG_4 = 22,
- INVENTORY_SLOT_BAG_END = 23,
+ INVENTORY_SLOT_BAG_END = 23
+};
+enum InventoryPackSlots // 16 slots
+{
INVENTORY_SLOT_ITEM_START = 23,
- INVENTORY_SLOT_ITEM_1 = 23,
- INVENTORY_SLOT_ITEM_2 = 24,
- INVENTORY_SLOT_ITEM_3 = 25,
- INVENTORY_SLOT_ITEM_4 = 26,
- INVENTORY_SLOT_ITEM_5 = 27,
- INVENTORY_SLOT_ITEM_6 = 28,
- INVENTORY_SLOT_ITEM_7 = 29,
- INVENTORY_SLOT_ITEM_8 = 30,
- INVENTORY_SLOT_ITEM_9 = 31,
- INVENTORY_SLOT_ITEM_10 = 32,
- INVENTORY_SLOT_ITEM_11 = 33,
- INVENTORY_SLOT_ITEM_12 = 34,
- INVENTORY_SLOT_ITEM_13 = 35,
- INVENTORY_SLOT_ITEM_14 = 36,
- INVENTORY_SLOT_ITEM_15 = 37,
- INVENTORY_SLOT_ITEM_16 = 38,
INVENTORY_SLOT_ITEM_END = 39
};
-enum BankSlots
+enum BankItemSlots // 28 slots
{
BANK_SLOT_ITEM_START = 39,
- BANK_SLOT_ITEM_1 = 39,
- BANK_SLOT_ITEM_2 = 40,
- BANK_SLOT_ITEM_3 = 41,
- BANK_SLOT_ITEM_4 = 42,
- BANK_SLOT_ITEM_5 = 43,
- BANK_SLOT_ITEM_6 = 44,
- BANK_SLOT_ITEM_7 = 45,
- BANK_SLOT_ITEM_8 = 46,
- BANK_SLOT_ITEM_9 = 47,
- BANK_SLOT_ITEM_10 = 48,
- BANK_SLOT_ITEM_11 = 49,
- BANK_SLOT_ITEM_12 = 50,
- BANK_SLOT_ITEM_13 = 51,
- BANK_SLOT_ITEM_14 = 52,
- BANK_SLOT_ITEM_15 = 53,
- BANK_SLOT_ITEM_16 = 54,
- BANK_SLOT_ITEM_17 = 55,
- BANK_SLOT_ITEM_18 = 56,
- BANK_SLOT_ITEM_19 = 57,
- BANK_SLOT_ITEM_20 = 58,
- BANK_SLOT_ITEM_21 = 59,
- BANK_SLOT_ITEM_22 = 60,
- BANK_SLOT_ITEM_23 = 61,
- BANK_SLOT_ITEM_24 = 62,
- BANK_SLOT_ITEM_25 = 63,
- BANK_SLOT_ITEM_26 = 64,
- BANK_SLOT_ITEM_27 = 65,
- BANK_SLOT_ITEM_28 = 66,
- BANK_SLOT_ITEM_END = 67,
+ BANK_SLOT_ITEM_END = 67
+};
+enum BankBagSlots // 7 slots
+{
BANK_SLOT_BAG_START = 67,
- BANK_SLOT_BAG_1 = 67,
- BANK_SLOT_BAG_2 = 68,
- BANK_SLOT_BAG_3 = 69,
- BANK_SLOT_BAG_4 = 70,
- BANK_SLOT_BAG_5 = 71,
- BANK_SLOT_BAG_6 = 72,
- BANK_SLOT_BAG_7 = 73,
BANK_SLOT_BAG_END = 74
};
-enum BuyBackSlots
+enum BuyBackSlots // 12 slots
{
// stored in m_buybackitems
BUYBACK_SLOT_START = 74,
- BUYBACK_SLOT_1 = 74,
- BUYBACK_SLOT_2 = 75,
- BUYBACK_SLOT_3 = 76,
- BUYBACK_SLOT_4 = 77,
- BUYBACK_SLOT_5 = 78,
- BUYBACK_SLOT_6 = 79,
- BUYBACK_SLOT_7 = 80,
- BUYBACK_SLOT_8 = 81,
- BUYBACK_SLOT_9 = 82,
- BUYBACK_SLOT_10 = 83,
- BUYBACK_SLOT_11 = 84,
- BUYBACK_SLOT_12 = 85,
BUYBACK_SLOT_END = 86
};
-enum KeyRingSlots
+enum KeyRingSlots // 32 slots
{
KEYRING_SLOT_START = 86,
KEYRING_SLOT_END = 118
};
+enum VanityPetSlots // 18 slots
+{
+ VANITYPET_SLOT_START = 118, // not use, vanity pets stored as spells
+ VANITYPET_SLOT_END = 136 // not allowed any content in.
+};
+
+enum CurrencyTokenSlots // 32 slots
+{
+ CURRENCYTOKEN_SLOT_START = 136,
+ CURRENCYTOKEN_SLOT_END = 168
+};
+
+enum QuestBagSlots // 32 slots
+{
+ QUESTBAG_SLOT_START = 168, // not use
+ QUESTBAG_SLOT_END = 200 // not allowed any content in.
+};
+
struct ItemPosCount
{
- ItemPosCount(uint16 _pos, uint8 _count) : pos(_pos), count(_count) {}
+ ItemPosCount(uint16 _pos, uint32 _count) : pos(_pos), count(_count) {}
bool isContainedIn(std::vector<ItemPosCount> const& vec) const;
uint16 pos;
- uint8 count;
+ uint32 count;
};
typedef std::vector<ItemPosCount> ItemPosCountVec;
@@ -689,14 +623,15 @@ enum TradeSlots
enum TransferAbortReason
{
- TRANSFER_ABORT_MAX_PLAYERS = 0x0001, // Transfer Aborted: instance is full
- TRANSFER_ABORT_NOT_FOUND = 0x0002, // Transfer Aborted: instance not found
- TRANSFER_ABORT_TOO_MANY_INSTANCES = 0x0003, // You have entered too many instances recently.
- TRANSFER_ABORT_ZONE_IN_COMBAT = 0x0005, // Unable to zone in while an encounter is in progress.
- TRANSFER_ABORT_INSUF_EXPAN_LVL1 = 0x0106, // You must have TBC expansion installed to access this area.
- TRANSFER_ABORT_DIFFICULTY1 = 0x0007, // Normal difficulty mode is not available for %s.
- TRANSFER_ABORT_DIFFICULTY2 = 0x0107, // Heroic difficulty mode is not available for %s.
- TRANSFER_ABORT_DIFFICULTY3 = 0x0207 // Epic difficulty mode is not available for %s.
+ TRANSFER_ABORT_ERROR = 0x00,
+ TRANSFER_ABORT_MAX_PLAYERS = 0x01, // Transfer Aborted: instance is full
+ TRANSFER_ABORT_NOT_FOUND = 0x02, // Transfer Aborted: instance not found
+ TRANSFER_ABORT_TOO_MANY_INSTANCES = 0x03, // You have entered too many instances recently.
+ TRANSFER_ABORT_ZONE_IN_COMBAT = 0x05, // Unable to zone in while an encounter is in progress.
+ TRANSFER_ABORT_INSUF_EXPAN_LVL = 0x06, // You must have <TBC,WotLK> expansion installed to access this area.
+ TRANSFER_ABORT_DIFFICULTY = 0x07, // <Normal,Heroic,Epic> difficulty mode is not available for %s.
+ TRANSFER_ABORT_UNIQUE_MESSAGE = 0x08, // Until you've escaped TLK's grasp, you cannot leave this place!
+ TRANSFER_ABORT_TOO_MANY_REALM_INSTANCES = 0x09 // Additional instances cannot be launched, please try again later.
};
enum InstanceResetWarningType
@@ -707,41 +642,6 @@ enum InstanceResetWarningType
RAID_INSTANCE_WELCOME = 4 // Welcome to %s. This raid instance is scheduled to reset in %s.
};
-struct MovementInfo
-{
- // common
- //uint32 flags;
- uint8 unk1;
- uint32 time;
- float x, y, z, o;
- // transport
- uint64 t_guid;
- float t_x, t_y, t_z, t_o;
- uint32 t_time;
- // swimming and unk
- float s_pitch;
- // last fall time
- uint32 fallTime;
- // jumping
- float j_unk, j_sinAngle, j_cosAngle, j_xyspeed;
- // spline
- float u_unk1;
-
- MovementInfo()
- {
- //flags =
- time = t_time = fallTime = 0;
- unk1 = 0;
- x = y = z = o = t_x = t_y = t_z = t_o = s_pitch = j_unk = j_sinAngle = j_cosAngle = j_xyspeed = u_unk1 = 0.0f;
- t_guid = 0;
- }
-
- /*void SetMovementFlags(uint32 _flags)
- {
- flags = _flags;
- }*/
-};
-
// flags that use in movement check for example at spell casting
MovementFlags const movementFlagsMask = MovementFlags(
MOVEMENTFLAG_FORWARD |MOVEMENTFLAG_BACKWARD |MOVEMENTFLAG_STRAFE_LEFT|MOVEMENTFLAG_STRAFE_RIGHT|
@@ -812,8 +712,9 @@ enum PlayerLoginQueryIndex
PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES = 16,
PLAYER_LOGIN_QUERY_LOADGUILD = 17,
PLAYER_LOGIN_QUERY_LOADARENAINFO = 18,
-
- MAX_PLAYER_LOGIN_QUERY
+ PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS = 19,
+ PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS = 20,
+ MAX_PLAYER_LOGIN_QUERY = 21
};
// Player summoning auto-decline time (in secs)
@@ -842,7 +743,7 @@ struct AccessRequirement
std::string questFailedText;
uint32 heroicQuest;
std::string heroicQuestFailedText;
- };
+};
class TRINITY_DLL_SPEC PlayerTaxi
{
@@ -850,11 +751,9 @@ class TRINITY_DLL_SPEC PlayerTaxi
PlayerTaxi();
~PlayerTaxi() {}
// Nodes
- void InitTaxiNodesForLevel(uint32 race, uint32 level);
+ void InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint32 level);
void LoadTaxiMask(const char* data);
- void SaveTaxiMask(const char* data);
- uint32 GetTaximask( uint8 index ) const { return m_taximask[index]; }
bool IsTaximaskNodeKnown(uint32 nodeidx) const
{
uint8 field = uint8((nodeidx - 1) / 32);
@@ -876,7 +775,7 @@ class TRINITY_DLL_SPEC PlayerTaxi
void AppendTaximaskTo(ByteBuffer& data,bool all);
// Destinations
- bool LoadTaxiDestinationsFromString(const std::string& values);
+ bool LoadTaxiDestinationsFromString(const std::string& values, uint32 team);
std::string SaveTaxiDestinationsToString();
void ClearTaxiDestinations() { m_TaxiDestinations.clear(); }
@@ -890,11 +789,15 @@ class TRINITY_DLL_SPEC PlayerTaxi
return GetTaxiDestination();
}
bool empty() const { return m_TaxiDestinations.empty(); }
+
+ friend std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi);
private:
TaxiMask m_taximask;
std::deque<uint32> m_TaxiDestinations;
};
+std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi);
+
class TRINITY_DLL_SPEC Player : public Unit
{
friend class WorldSession;
@@ -912,16 +815,6 @@ class TRINITY_DLL_SPEC Player : public Unit
void AddToWorld();
void RemoveFromWorld();
- void SetViewport(uint64 guid, bool movable);
- void StopCastingCharm() { Uncharm(); }
- void StopCastingBindSight();
- WorldObject* GetFarsightTarget() const;
- void ClearFarsight();
- void SetFarsightTarget(WorldObject* target);
- // Controls if vision is currently on farsight object, updated in FAR_SIGHT opcode
- void SetFarsightVision(bool apply) { m_farsightVision = apply; }
- bool HasFarsightVision() const { return m_farsightVision; }
-
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0);
bool TeleportTo(WorldLocation const &loc, uint32 options = 0)
@@ -952,10 +845,12 @@ class TRINITY_DLL_SPEC Player : public Unit
void SendInitialPacketsBeforeAddToMap();
void SendInitialPacketsAfterAddToMap();
- void SendTransferAborted(uint32 mapid, uint16 reason);
+ void SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg = 0);
void SendInstanceResetWarning(uint32 mapid, uint32 time);
+ Creature* GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask);
bool CanInteractWithNPCs(bool alive = true) const;
+ GameObject* GetGameObjectIfCanInteractWith(uint64 guid, GameobjectTypes type) const;
bool ToggleAFK();
bool ToggleDND();
@@ -965,10 +860,12 @@ class TRINITY_DLL_SPEC Player : public Unit
std::string afkMsg;
std::string dndMsg;
+ uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair);
+
PlayerSocial *GetSocial() { return m_social; }
PlayerTaxi m_taxi;
- void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(),getLevel()); }
+ void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(), getClass(), getLevel()); }
bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, uint32 mount_id = 0 , Creature* npc = NULL);
// mount_id can be used in scripting calls
bool isAcceptWhispers() const { return m_ExtraFlags & PLAYER_EXTRA_ACCEPT_WHISPERS; }
@@ -1019,16 +916,10 @@ class TRINITY_DLL_SPEC Player : public Unit
int GetTimeInnEnter() const { return time_inn_enter; };
void UpdateInnerTime (int time) { time_inn_enter = time; };
+ Pet* GetPet() const;
Pet* SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 despwtime);
void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false);
- void RemoveMiniPet();
- Pet* GetMiniPet();
- void SetMiniPet(Pet* pet) { m_miniPet = pet->GetGUID(); }
- void RemoveGuardians();
- bool HasGuardianWithEntry(uint32 entry);
- void AddGuardian(Pet* pet) { m_guardianPets.insert(pet->GetGUID()); }
- GuardianPetList const& GetGuardians() const { return m_guardianPets; }
- void Uncharm();
+ uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn
void Say(const std::string& text, const uint32 language);
void Yell(const std::string& text, const uint32 language);
@@ -1047,9 +938,15 @@ class TRINITY_DLL_SPEC Player : public Unit
Item* GetItemByGuid( uint64 guid ) const;
Item* GetItemByPos( uint16 pos ) const;
Item* GetItemByPos( uint8 bag, uint8 slot ) const;
+ inline Item* GetUseableItemByPos( uint8 bag, uint8 slot ) const //Does additional check for disarmed weapons
+ {
+ if (!CanUseAttackType(GetAttackBySlot(slot)))
+ return NULL;
+ return GetItemByPos(bag, slot);
+ }
Item* GetWeaponForAttack(WeaponAttackType attackType, bool useable = false) const;
Item* GetShield(bool useable = false) const;
- static uint32 GetAttackBySlot( uint8 slot ); // MAX_ATTACK if not weapon slot
+ static uint8 GetAttackBySlot( uint8 slot ); // MAX_ATTACK if not weapon slot
std::vector<Item *> &GetItemUpdateQueue() { return m_itemUpdateQueue; }
static bool IsInventoryPos( uint16 pos ) { return IsInventoryPos(pos >> 8,pos & 255); }
static bool IsInventoryPos( uint8 bag, uint8 slot );
@@ -1063,7 +960,9 @@ class TRINITY_DLL_SPEC Player : public Unit
bool HasBankBagSlot( uint8 slot ) const;
bool HasItemCount( uint32 item, uint32 count, bool inBankAlso = false ) const;
bool HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item const* ignoreItem = NULL);
- Item* GetItemOrItemWithGemEquipped( uint32 item ) const;
+ bool CanNoReagentCast(SpellEntry const* spellInfo) const;
+ bool HasItemOrGemWithIdEquipped( uint32 item, uint32 count, uint8 except_slot = NULL_SLOT) const;
+ bool HasItemOrGemWithLimitCategoryEquipped( uint32 limitCategory, uint32 count, uint8 except_slot = NULL_SLOT) const;
uint8 CanTakeMoreSimilarItems(Item* pItem) const { return _CanTakeMoreSimilarItems(pItem->GetEntry(),pItem->GetCount(),pItem); }
uint8 CanTakeMoreSimilarItems(uint32 entry, uint32 count) const { return _CanTakeMoreSimilarItems(entry,count,NULL); }
uint8 CanStoreNewItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count = NULL ) const
@@ -1081,6 +980,9 @@ class TRINITY_DLL_SPEC Player : public Unit
uint8 CanStoreItems( Item **pItem,int count) const;
uint8 CanEquipNewItem( uint8 slot, uint16 &dest, uint32 item, bool swap ) const;
uint8 CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading = true ) const;
+
+ uint8 CanEquipUniqueItem( Item * pItem, uint8 except_slot = NULL_SLOT, uint32 limit_count = 1 ) const;
+ uint8 CanEquipUniqueItem( ItemPrototype const* itemProto, uint8 except_slot = NULL_SLOT, uint32 limit_count = 1 ) const;
uint8 CanUnequipItems( uint32 item, uint32 count ) const;
uint8 CanUnequipItem( uint16 src, bool swap ) const;
uint8 CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, Item *pItem, bool swap, bool not_loading = true ) const;
@@ -1094,6 +996,8 @@ class TRINITY_DLL_SPEC Player : public Unit
Item* EquipItem( uint16 pos, Item *pItem, bool update );
void AutoUnequipOffhandIfNeed();
bool StoreNewItemInBestSlots(uint32 item_id, uint32 item_count);
+ void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store, bool broadcast = false);
+ void AutoStoreLoot(uint32 loot_id, LootStore const& store, bool broadcast = false) { AutoStoreLoot(NULL_BAG,NULL_SLOT,loot_id,store,broadcast); }
uint8 _CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL) const;
uint8 _CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item *pItem = NULL, bool swap = false, uint32* no_space_count = NULL ) const;
@@ -1135,12 +1039,16 @@ class TRINITY_DLL_SPEC Player : public Unit
void AddArmorProficiency(uint32 newflag) { m_ArmorProficiency |= newflag; }
uint32 GetWeaponProficiency() const { return m_WeaponProficiency; }
uint32 GetArmorProficiency() const { return m_ArmorProficiency; }
- bool IsInFeralForm() const { return m_form == FORM_CAT || m_form == FORM_BEAR || m_form == FORM_DIREBEAR; }
bool IsUseEquipedWeapon( bool mainhand ) const
{
// disarm applied only to mainhand weapon
return !IsInFeralForm() && (!mainhand || !HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISARMED) );
}
+ bool IsTwoHandUsed() const
+ {
+ Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
+ return mainItem && mainItem->GetProto()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip();
+ }
void SendNewItem( Item *item, uint32 count, bool received, bool created, bool broadcast = false );
bool BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint64 bagguid, uint8 slot);
@@ -1171,6 +1079,8 @@ class TRINITY_DLL_SPEC Player : public Unit
/*** QUEST SYSTEM ***/
/*********************************************************/
+ uint32 GetQuestLevel( Quest const* pQuest ) const { return pQuest && pQuest->GetQuestLevel() ? pQuest->GetQuestLevel() : getLevel(); }
+
void PrepareQuestMenu( uint64 guid );
void SendPreparedQuest( uint64 guid );
bool IsActiveQuest( uint32 quest_id ) const;
@@ -1238,7 +1148,6 @@ class TRINITY_DLL_SPEC Player : public Unit
}
}
uint32 GetReqKillOrCastCurrentCount(uint32 quest_id, int32 entry);
- void AdjustQuestReqItemCount( Quest const* pQuest );
void AreaExploredOrEventHappens( uint32 questId );
void GroupEventHappens( uint32 questId, WorldObject const* pEventObject );
void ItemAddedQuestCheck( uint32 entry, uint32 count );
@@ -1247,8 +1156,9 @@ class TRINITY_DLL_SPEC Player : public Unit
void CastedCreatureOrGO( uint32 entry, uint64 guid, uint32 spell_id );
void TalkedToCreature( uint32 entry, uint64 guid );
void MoneyChanged( uint32 value );
+ void ReputationChanged(FactionEntry const* factionEntry );
bool HasQuestForItem( uint32 itemid ) const;
- bool HasQuestForGO(int32 GOId);
+ bool HasQuestForGO(int32 GOId) const;
void UpdateForQuestsGO();
bool CanShareQuest(uint32 quest_id) const;
@@ -1275,6 +1185,7 @@ class TRINITY_DLL_SPEC Player : public Unit
/*********************************************************/
bool LoadFromDB(uint32 guid, SqlQueryHolder *holder);
+
bool MinimalLoadFromDB(QueryResult *result, uint32 guid);
static bool LoadValuesArrayFromDB(Tokens& data,uint64 guid);
static uint32 GetUInt32ValueFromArray(Tokens const& data, uint16 index);
@@ -1296,6 +1207,7 @@ class TRINITY_DLL_SPEC Player : public Unit
static void SetFloatValueInArray(Tokens& data,uint16 index, float value);
static void SetUInt32ValueInDB(uint16 index, uint32 value, uint64 guid);
static void SetFloatValueInDB(uint16 index, float value, uint64 guid);
+ static void Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair);
static void SavePositionInDB(uint32 mapid, float x,float y,float z,float o,uint32 zone,uint64 guid);
bool m_mailsLoaded;
@@ -1352,7 +1264,7 @@ class TRINITY_DLL_SPEC Player : public Unit
void SetSelection(const uint64 &guid) { m_curSelection = guid; SetUInt64Value(UNIT_FIELD_TARGET, guid); }
uint8 GetComboPoints() { return m_comboPoints; }
- uint64 GetComboTarget() { return m_comboTarget; }
+ const uint64& GetComboTarget() const { return m_comboTarget; }
void AddComboPoints(Unit* target, int8 count);
void ClearComboPoints();
@@ -1388,10 +1300,7 @@ class TRINITY_DLL_SPEC Player : public Unit
Item* GetMItem(uint32 id)
{
ItemMap::const_iterator itr = mMitems.find(id);
- if (itr != mMitems.end())
- return itr->second;
-
- return NULL;
+ return itr != mMitems.end() ? itr->second : NULL;
}
void AddMItem(Item* it)
@@ -1403,30 +1312,30 @@ class TRINITY_DLL_SPEC Player : public Unit
bool RemoveMItem(uint32 id)
{
- ItemMap::iterator i = mMitems.find(id);
- if (i == mMitems.end())
- return false;
-
- mMitems.erase(i);
- return true;
+ return mMitems.erase(id) ? true : false;
}
void PetSpellInitialize();
void CharmSpellInitialize();
void PossessSpellInitialize();
+ void VehicleSpellInitialize();
+ void SendRemoveControlBar();
bool HasSpell(uint32 spell) const;
+ bool HasActiveSpell(uint32 spell) const; // show in spellbook
TrainerSpellState GetTrainerSpellState(TrainerSpell const* trainer_spell) const;
bool IsSpellFitByClassAndRace( uint32 spell_id ) const;
+ bool IsNeedCastPassiveSpellAtLearn(SpellEntry const* spellInfo) const;
void SendProficiency(uint8 pr1, uint32 pr2);
void SendInitialSpells();
- bool addSpell(uint32 spell_id, bool active, bool learning = true, bool loading = false, uint16 slot_id=SPELL_WITHOUT_SLOT_ID, bool disabled = false);
- void learnSpell(uint32 spell_id);
- void removeSpell(uint32 spell_id, bool disabled = false);
+ bool addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled);
+ void learnSpell(uint32 spell_id, bool dependent);
+ void removeSpell(uint32 spell_id, bool disabled = false, bool update_action_bar_for_low_rank = false);
void resetSpells();
- void learnDefaultSpells(bool loading = false);
+ void learnDefaultSpells();
void learnQuestRewardedSpells();
void learnQuestRewardedSpells(Quest const* quest);
+ void learnSpellHighRank(uint32 spellid);
uint32 GetFreeTalentPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS1); }
void SetFreeTalentPoints(uint32 points) { SetUInt32Value(PLAYER_CHARACTER_POINTS1,points); }
@@ -1434,6 +1343,17 @@ class TRINITY_DLL_SPEC Player : public Unit
uint32 resetTalentsCost() const;
void InitTalentForLevel();
+ void LearnTalent(uint32 talentId, uint32 talentRank);
+ void LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank);
+
+ uint32 CalculateTalentsPoints() const;
+
+ void InitGlyphsForLevel();
+ void SetGlyphSlot(uint8 slot, uint32 slottype) { SetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot, slottype); }
+ uint32 GetGlyphSlot(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot); }
+ void SetGlyph(uint8 slot, uint32 glyph) { SetUInt32Value(PLAYER_FIELD_GLYPHS_1 + slot, glyph); }
+ uint32 GetGlyph(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_GLYPHS_1 + slot); }
+
uint32 GetFreePrimaryProffesionPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS2); }
void SetFreePrimaryProffesions(uint16 profs) { SetUInt32Value(PLAYER_CHARACTER_POINTS2,profs); }
void InitPrimaryProffesions();
@@ -1442,8 +1362,6 @@ class TRINITY_DLL_SPEC Player : public Unit
PlayerSpellMap & GetSpellMap() { return m_spells; }
void AddSpellMod(SpellModifier* mod, bool apply);
- int32 GetTotalFlatMods(uint32 spellId, SpellModOp op);
- int32 GetTotalPctMods(uint32 spellId, SpellModOp op);
bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell = NULL);
template <class T> T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell const* spell = NULL);
void RemoveSpellMods(Spell const* spell);
@@ -1459,14 +1377,17 @@ class TRINITY_DLL_SPEC Player : public Unit
time_t t = time(NULL);
return itr != m_spellCooldowns.end() && itr->second.end > t ? itr->second.end - t : 0;
}
+ void AddSpellAndCategoryCooldowns(SpellEntry const* spellInfo, uint32 itemId, Spell* spell = NULL, bool infinityCooldown = false );
void AddSpellCooldown(uint32 spell_id, uint32 itemid, time_t end_time);
- void SendCooldownEvent(SpellEntry const *spellInfo);
+ void SendCooldownEvent(SpellEntry const *spellInfo, uint32 itemId = 0, Spell* spell = NULL);
void ProhibitSpellScholl(SpellSchoolMask idSchoolMask, uint32 unTimeMs );
void RemoveSpellCooldown(uint32 spell_id) { m_spellCooldowns.erase(spell_id); }
void RemoveArenaSpellCooldowns();
void RemoveAllSpellCooldown();
void _LoadSpellCooldowns(QueryResult *result);
void _SaveSpellCooldowns();
+ void SetLastPotionId(uint32 item_id) { m_lastPotionId = item_id; }
+ void UpdatePotionCooldown(Spell* spell = NULL);
void setResurrectRequestData(uint64 guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
{
@@ -1492,13 +1413,13 @@ class TRINITY_DLL_SPEC Player : public Unit
m_cinematic = cine;
}
- void addActionButton(uint8 button, uint16 action, uint8 type, uint8 misc);
+ bool addActionButton(uint8 button, uint16 action, uint8 type, uint8 misc);
void removeActionButton(uint8 button);
void SendInitialActionButtons();
PvPInfo pvpInfo;
void UpdatePvP(bool state, bool ovrride=false);
- void UpdateZone(uint32 newZone);
+ void UpdateZone(uint32 newZone,uint32 newArea);
void UpdateArea(uint32 newArea);
void UpdateZoneDependentAuras( uint32 zone_id ); // zones
@@ -1548,6 +1469,7 @@ class TRINITY_DLL_SPEC Player : public Unit
static uint32 GetArenaTeamIdFromDB(uint64 guid, uint8 slot);
void SetArenaTeamIdInvited(uint32 ArenaTeamId) { m_ArenaTeamIdInvited = ArenaTeamId; }
uint32 GetArenaTeamIdInvited() { return m_ArenaTeamIdInvited; }
+ static void LeaveAllArenaTeams(uint64 guid);
void SetDifficulty(uint32 dungeon_difficulty) { m_dungeonDifficulty = dungeon_difficulty; }
uint8 GetDifficulty() { return m_dungeonDifficulty; }
@@ -1573,9 +1495,12 @@ class TRINITY_DLL_SPEC Player : public Unit
void UpdateArmor();
void UpdateMaxHealth();
void UpdateMaxPower(Powers power);
+ void ApplyFeralAPBonus(int32 amount, bool apply);
void UpdateAttackPowerAndDamage(bool ranged = false);
void UpdateShieldBlockValue();
void UpdateDamagePhysical(WeaponAttackType attType);
+ void ApplySpellDamageBonus(int32 amount, bool apply);
+ void ApplySpellHealingBonus(int32 amount, bool apply);
void UpdateSpellDamageAndHealingBonus();
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, float& min_damage, float& max_damage);
@@ -1593,6 +1518,8 @@ class TRINITY_DLL_SPEC Player : public Unit
uint32 GetRangedCritDamageReduction(uint32 damage) const;
uint32 GetSpellCritDamageReduction(uint32 damage) const;
uint32 GetDotDamageReduction(uint32 damage) const;
+ uint32 GetBaseSpellDamageBonus() { return m_baseSpellDamage;}
+ uint32 GetBaseSpellHealingBonus() { return m_baseSpellHealing;}
float GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const;
void UpdateBlockPercentage();
@@ -1600,9 +1527,14 @@ class TRINITY_DLL_SPEC Player : public Unit
void UpdateAllCritPercentages();
void UpdateParryPercentage();
void UpdateDodgePercentage();
+ void UpdateMeleeHitChances();
+ void UpdateRangedHitChances();
+ void UpdateSpellHitChances();
+
void UpdateAllSpellCritChances();
void UpdateSpellCritChance(uint32 school);
void UpdateExpertise(WeaponAttackType attType);
+ void ApplyManaRegenBonus(int32 amount, bool apply);
void UpdateManaRegen();
const uint64& GetLootGUID() const { return m_lootGuid; }
@@ -1618,8 +1550,6 @@ class TRINITY_DLL_SPEC Player : public Unit
void SendDelayResponse(const uint32);
void SendLogXPGain(uint32 GivenXP,Unit* victim,uint32 RestXP);
- //Low Level Packets
- void PlaySound(uint32 Sound, bool OnlySelf);
//notifiers
void SendAttackSwingCantAttack();
void SendAttackSwingCancelAttack();
@@ -1662,6 +1592,7 @@ class TRINITY_DLL_SPEC Player : public Unit
uint32 DurabilityRepairAll(bool cost, float discountMod, bool guildBank);
uint32 DurabilityRepair(uint16 pos, bool cost, float discountMod, bool guildBank);
+ void UpdateMirrorTimers();
void StopMirrorTimers()
{
StopMirrorTimer(FATIGUE_TIMER);
@@ -1679,21 +1610,25 @@ class TRINITY_DLL_SPEC Player : public Unit
void UpdateDefense();
void UpdateWeaponSkill (WeaponAttackType attType);
- void UpdateCombatSkills(Unit *pVictim, WeaponAttackType attType, MeleeHitOutcome outcome, bool defence);
+ void UpdateCombatSkills(Unit *pVictim, WeaponAttackType attType, bool defence);
void SetSkill(uint32 id, uint16 currVal, uint16 maxVal);
- uint16 GetMaxSkillValue(uint32 skill) const; // max + perm. bonus
+ uint16 GetMaxSkillValue(uint32 skill) const; // max + perm. bonus + temp bonus
uint16 GetPureMaxSkillValue(uint32 skill) const; // max
uint16 GetSkillValue(uint32 skill) const; // skill value + perm. bonus + temp bonus
uint16 GetBaseSkillValue(uint32 skill) const; // skill value + perm. bonus
uint16 GetPureSkillValue(uint32 skill) const; // skill value
+ int16 GetSkillPermBonusValue(uint32 skill) const;
int16 GetSkillTempBonusValue(uint32 skill) const;
bool HasSkill(uint32 skill) const;
- void learnSkillRewardedSpells( uint32 id );
- void learnSkillRewardedSpells();
+ void learnSkillRewardedSpells(uint32 id, uint32 value);
- void SetDontMove(bool dontMove);
- bool GetDontMove() const { return m_dontMove; }
+ WorldLocation& GetTeleportDest() { return m_teleport_dest; }
+ bool IsBeingTeleported() const { return mSemaphoreTeleport_Near || mSemaphoreTeleport_Far; }
+ bool IsBeingTeleportedNear() const { return mSemaphoreTeleport_Near; }
+ bool IsBeingTeleportedFar() const { return mSemaphoreTeleport_Far; }
+ void SetSemaphoreTeleportNear(bool semphsetting) { mSemaphoreTeleport_Near = semphsetting; }
+ void SetSemaphoreTeleportFar(bool semphsetting) { mSemaphoreTeleport_Far = semphsetting; }
void CheckExploreSystem(void);
@@ -1704,40 +1639,15 @@ class TRINITY_DLL_SPEC Player : public Unit
bool IsAtGroupRewardDistance(WorldObject const* pRewardSource) const;
bool RewardPlayerAndGroupAtKill(Unit* pVictim);
+ void RewardPlayerAndGroupAtEvent(uint32 creature_id,WorldObject* pRewardSource);
+ bool isHonorOrXPTarget(Unit* pVictim);
- FactionStateList m_factions;
- ForcedReactions m_forcedReactions;
- FactionStateList const& GetFactionStateList() { return m_factions; }
- uint32 GetDefaultReputationFlags(const FactionEntry *factionEntry) const;
- int32 GetBaseReputation(const FactionEntry *factionEntry) const;
- int32 GetReputation(uint32 faction_id) const;
- int32 GetReputation(const FactionEntry *factionEntry) const;
- ReputationRank GetReputationRank(uint32 faction) const;
- ReputationRank GetReputationRank(const FactionEntry *factionEntry) const;
- ReputationRank GetBaseReputationRank(const FactionEntry *factionEntry) const;
- ReputationRank ReputationToRank(int32 standing) const;
- const static int32 ReputationRank_Length[MAX_REPUTATION_RANK];
- const static int32 Reputation_Cap = 42999;
- const static int32 Reputation_Bottom = -42000;
- bool ModifyFactionReputation(uint32 FactionTemplateId, int32 DeltaReputation);
- bool ModifyFactionReputation(FactionEntry const* factionEntry, int32 standing);
- bool ModifyOneFactionReputation(FactionEntry const* factionEntry, int32 standing);
- bool SetFactionReputation(uint32 FactionTemplateId, int32 standing);
- bool SetFactionReputation(FactionEntry const* factionEntry, int32 standing);
- bool SetOneFactionReputation(FactionEntry const* factionEntry, int32 standing);
- int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, bool for_quest);
+ ReputationMgr& GetReputationMgr() { return m_reputationMgr; }
+ ReputationMgr const& GetReputationMgr() const { return m_reputationMgr; }
+ ReputationRank GetReputationRank(uint32 faction_id) const;
void RewardReputation(Unit *pVictim, float rate);
void RewardReputation(Quest const *pQuest);
- void SetInitialFactions();
- void UpdateReputation() const;
- void SendFactionState(FactionState const* faction) const;
- void SendInitialReputations();
- FactionState const* GetFactionState( FactionEntry const* factionEntry) const;
- void SetFactionAtWar(FactionState* faction, bool atWar);
- void SetFactionInactive(FactionState* faction, bool inactive);
- void SetFactionVisible(FactionState* faction);
- void SetFactionVisibleForFactionTemplateId(uint32 FactionTemplateId);
- void SetFactionVisibleForFactionId(uint32 FactionId);
+
void UpdateSkillsForLevel();
void UpdateSkillsToMaxSkillsForLevel(); // for .levelup
void ModifySkillBonus(uint32 skillid,int32 val, bool talent);
@@ -1770,6 +1680,8 @@ class TRINITY_DLL_SPEC Player : public Unit
void SetCanParry(bool value);
bool CanBlock() const { return m_canBlock; }
void SetCanBlock(bool value);
+ bool CanTitanGrip() const { return m_canTitanGrip ; }
+ void SetCanTitanGrip(bool value) { m_canTitanGrip = value; }
void SetRegularAttackTime();
void SetBaseModValue(BaseModGroup modGroup, BaseModType modType, float value) { m_auraBaseMod[modGroup][modType] = value; }
@@ -1781,8 +1693,8 @@ class TRINITY_DLL_SPEC Player : public Unit
void _RemoveAllStatBonuses();
void _ApplyWeaponDependentAuraMods(Item *item, WeaponAttackType attackType, bool apply);
- void _ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attackType, Aura* aura, bool apply);
- void _ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType attackType, Aura* aura, bool apply);
+ void _ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attackType, AuraEffect* aura, bool apply);
+ void _ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType attackType, AuraEffect* aura, bool apply);
void _ApplyItemMods(Item *item,uint8 slot,bool apply);
void _RemoveAllItemMods();
@@ -1798,12 +1710,13 @@ class TRINITY_DLL_SPEC Player : public Unit
void ApplyEquipSpell(SpellEntry const* spellInfo, Item* item, bool apply, bool form_change = false);
void UpdateEquipSpellsAtFormChange();
void CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attType);
+ void CastItemUseSpell(Item *item,SpellCastTargets const& targets,uint8 cast_count, uint32 glyphIndex);
- void SendInitWorldStates(bool force = false, uint32 forceZoneId = 0);
+ void SendInitWorldStates(uint32 zone, uint32 area);
void SendUpdateWorldState(uint32 Field, uint32 Value);
void SendDirectMessage(WorldPacket *data);
- void SendAuraDurationsForTarget(Unit* target);
+ void SendAurasForTarget(Unit *target);
PlayerMenu* PlayerTalkClass;
std::vector<ItemSetEffect *> ItemSetEff;
@@ -1817,51 +1730,55 @@ class TRINITY_DLL_SPEC Player : public Unit
/*** BATTLEGROUND SYSTEM ***/
/*********************************************************/
- bool InBattleGround() const { return m_bgBattleGroundID != 0; }
- uint32 GetBattleGroundId() const { return m_bgBattleGroundID; }
+ bool InBattleGround() const { return m_bgBattleGroundID != 0; }
+ bool InArena() const;
+ uint32 GetBattleGroundId() const { return m_bgBattleGroundID; }
+ BattleGroundTypeId GetBattleGroundTypeId() const { return m_bgTypeID; }
BattleGround* GetBattleGround() const;
- bool InArena() const;
- static uint32 GetMinLevelForBattleGroundQueueId(uint32 queue_id);
- static uint32 GetMaxLevelForBattleGroundQueueId(uint32 queue_id);
- uint32 GetBattleGroundQueueIdFromLevel() const;
+
+ BGQueueIdBasedOnLevel GetBattleGroundQueueIdFromLevel(BattleGroundTypeId bgTypeId) const;
bool InBattleGroundQueue() const
{
- for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
- if (m_bgBattleGroundQueueID[i].bgQueueType != 0)
+ for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
+ if (m_bgBattleGroundQueueID[i].bgQueueTypeId != BATTLEGROUND_QUEUE_NONE)
return true;
return false;
}
- uint32 GetBattleGroundQueueId(uint32 index) const { return m_bgBattleGroundQueueID[index].bgQueueType; }
- uint32 GetBattleGroundQueueIndex(uint32 bgQueueType) const
+ BattleGroundQueueTypeId GetBattleGroundQueueTypeId(uint32 index) const { return m_bgBattleGroundQueueID[index].bgQueueTypeId; }
+ uint32 GetBattleGroundQueueIndex(BattleGroundQueueTypeId bgQueueTypeId) const
{
- for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
- if (m_bgBattleGroundQueueID[i].bgQueueType == bgQueueType)
+ for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
+ if (m_bgBattleGroundQueueID[i].bgQueueTypeId == bgQueueTypeId)
return i;
return PLAYER_MAX_BATTLEGROUND_QUEUES;
}
- bool IsInvitedForBattleGroundQueueType(uint32 bgQueueType) const
+ bool IsInvitedForBattleGroundQueueType(BattleGroundQueueTypeId bgQueueTypeId) const
{
- for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
- if (m_bgBattleGroundQueueID[i].bgQueueType == bgQueueType)
+ for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
+ if (m_bgBattleGroundQueueID[i].bgQueueTypeId == bgQueueTypeId)
return m_bgBattleGroundQueueID[i].invitedToInstance != 0;
- return PLAYER_MAX_BATTLEGROUND_QUEUES;
+ return false;
}
- bool InBattleGroundQueueForBattleGroundQueueType(uint32 bgQueueType) const
+ bool InBattleGroundQueueForBattleGroundQueueType(BattleGroundQueueTypeId bgQueueTypeId) const
{
- return GetBattleGroundQueueIndex(bgQueueType) < PLAYER_MAX_BATTLEGROUND_QUEUES;
+ return GetBattleGroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES;
}
- void SetBattleGroundId(uint32 val) { m_bgBattleGroundID = val; }
- uint32 AddBattleGroundQueueId(uint32 val)
+ void SetBattleGroundId(uint32 val, BattleGroundTypeId bgTypeId)
+ {
+ m_bgBattleGroundID = val;
+ m_bgTypeID = bgTypeId;
+ }
+ uint32 AddBattleGroundQueueId(BattleGroundQueueTypeId val)
{
- for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
+ for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
{
- if (m_bgBattleGroundQueueID[i].bgQueueType == 0 || m_bgBattleGroundQueueID[i].bgQueueType == val)
+ if (m_bgBattleGroundQueueID[i].bgQueueTypeId == BATTLEGROUND_QUEUE_NONE || m_bgBattleGroundQueueID[i].bgQueueTypeId == val)
{
- m_bgBattleGroundQueueID[i].bgQueueType = val;
+ m_bgBattleGroundQueueID[i].bgQueueTypeId = val;
m_bgBattleGroundQueueID[i].invitedToInstance = 0;
return i;
}
@@ -1870,48 +1787,40 @@ class TRINITY_DLL_SPEC Player : public Unit
}
bool HasFreeBattleGroundQueueId()
{
- for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
- if (m_bgBattleGroundQueueID[i].bgQueueType == 0)
+ for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
+ if (m_bgBattleGroundQueueID[i].bgQueueTypeId == BATTLEGROUND_QUEUE_NONE)
return true;
return false;
}
- void RemoveBattleGroundQueueId(uint32 val)
+ void RemoveBattleGroundQueueId(BattleGroundQueueTypeId val)
{
- for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
+ for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
{
- if (m_bgBattleGroundQueueID[i].bgQueueType == val)
+ if (m_bgBattleGroundQueueID[i].bgQueueTypeId == val)
{
- m_bgBattleGroundQueueID[i].bgQueueType = 0;
+ m_bgBattleGroundQueueID[i].bgQueueTypeId = BATTLEGROUND_QUEUE_NONE;
m_bgBattleGroundQueueID[i].invitedToInstance = 0;
return;
}
}
}
- void SetInviteForBattleGroundQueueType(uint32 bgQueueType, uint32 instanceId)
+ void SetInviteForBattleGroundQueueType(BattleGroundQueueTypeId bgQueueTypeId, uint32 instanceId)
{
- for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
- if (m_bgBattleGroundQueueID[i].bgQueueType == bgQueueType)
+ for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
+ if (m_bgBattleGroundQueueID[i].bgQueueTypeId == bgQueueTypeId)
m_bgBattleGroundQueueID[i].invitedToInstance = instanceId;
}
bool IsInvitedForBattleGroundInstance(uint32 instanceId) const
{
- for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
+ for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
if (m_bgBattleGroundQueueID[i].invitedToInstance == instanceId)
return true;
return false;
}
- uint32 GetBattleGroundEntryPointMap() const { return m_bgEntryPointMap; }
- float GetBattleGroundEntryPointX() const { return m_bgEntryPointX; }
- float GetBattleGroundEntryPointY() const { return m_bgEntryPointY; }
- float GetBattleGroundEntryPointZ() const { return m_bgEntryPointZ; }
- float GetBattleGroundEntryPointO() const { return m_bgEntryPointO; }
+ WorldLocation const& GetBattleGroundEntryPoint() const { return m_bgEntryPoint; }
void SetBattleGroundEntryPoint(uint32 Map, float PosX, float PosY, float PosZ, float PosO )
{
- m_bgEntryPointMap = Map;
- m_bgEntryPointX = PosX;
- m_bgEntryPointY = PosY;
- m_bgEntryPointZ = PosZ;
- m_bgEntryPointO = PosO;
+ m_bgEntryPoint = WorldLocation(Map,PosX,PosY,PosZ,PosO);
}
void SetBGTeam(uint32 team) { m_bgTeam = team; }
@@ -1923,9 +1832,11 @@ class TRINITY_DLL_SPEC Player : public Unit
void ReportedAfkBy(Player* reporter);
void ClearAfkReports() { m_bgAfkReporter.clear(); }
- bool GetBGAccessByLevel(uint32 bgTypeId) const;
- bool isAllowUseBattleGroundObject();
+ bool GetBGAccessByLevel(BattleGroundTypeId bgTypeId) const;
bool isTotalImmunity();
+ bool CanUseBattleGroundObject();
+ bool isTotalImmune();
+ bool CanCaptureTowerPoint();
/*********************************************************/
/*** OUTDOOR PVP SYSTEM ***/
@@ -1939,7 +1850,7 @@ class TRINITY_DLL_SPEC Player : public Unit
/*** REST SYSTEM ***/
/*********************************************************/
- bool isRested() const { return GetRestTime() >= 10000; }
+ bool isRested() const { return GetRestTime() >= 10*IN_MILISECONDS; }
uint32 GetXPRestBonus(uint32 xp);
uint32 GetRestTime() const { return m_restTime;};
void SetRestTime(uint32 v) { m_restTime = v;};
@@ -1948,7 +1859,7 @@ class TRINITY_DLL_SPEC Player : public Unit
/*** ENVIROMENTAL SYSTEM ***/
/*********************************************************/
- void EnvironmentalDamage(uint64 guid, EnviromentalDamage type, uint32 damage);
+ void EnvironmentalDamage(EnviromentalDamage type, uint32 damage);
/*********************************************************/
/*** FLOOD FILTER SYSTEM ***/
@@ -1961,38 +1872,31 @@ class TRINITY_DLL_SPEC Player : public Unit
/*********************************************************/
/*** VARIOUS SYSTEMS ***/
/*********************************************************/
- MovementInfo m_movementInfo;
- uint32 m_lastFallTime;
- float m_lastFallZ;
+ void UpdateFallInformationIfNeed(MovementInfo const& minfo,uint16 opcode);
+ Unit *m_mover;
+ WorldObject *m_seer;
void SetFallInformation(uint32 time, float z)
{
m_lastFallTime = time;
m_lastFallZ = z;
}
+ void HandleFall(MovementInfo const& movementInfo);
+
bool isMoving() const { return HasUnitMovementFlag(movementFlagsMask); }
bool isMovingOrTurning() const { return HasUnitMovementFlag(movementOrTurningFlagsMask); }
bool CanFly() const { return HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY); }
bool IsFlying() const { return HasUnitMovementFlag(MOVEMENTFLAG_FLYING); }
-
- void HandleDrowning();
- void HandleFallDamage(MovementInfo& movementInfo);
- void HandleFallUnderMap();
+ bool IsAllowUseFlyMountsHere() const;
void SetClientControl(Unit* target, uint8 allowMove);
- uint64 GetFarSight() const { return GetUInt64Value(PLAYER_FARSIGHT); }
- void SetFarSight(uint64 guid) { SetUInt64Value(PLAYER_FARSIGHT, guid); }
-
- // Transports
- Transport * GetTransport() const { return m_transport; }
- void SetTransport(Transport * t) { m_transport = t; }
-
- float GetTransOffsetX() const { return m_movementInfo.t_x; }
- float GetTransOffsetY() const { return m_movementInfo.t_y; }
- float GetTransOffsetZ() const { return m_movementInfo.t_z; }
- float GetTransOffsetO() const { return m_movementInfo.t_o; }
- uint32 GetTransTime() const { return m_movementInfo.t_time; }
+ void SetMover(Unit* target) { m_mover = target; }
+ void SetSeer(WorldObject *target) { m_seer = target; }
+ void SetViewpoint(WorldObject *target, bool apply);
+ WorldObject* GetViewpoint() const;
+ void StopCastingCharm();
+ void StopCastingBindSight();
uint32 GetSaveTimer() const { return m_nextSave; }
void SetSaveTimer(uint32 timer) { m_nextSave = timer; }
@@ -2011,6 +1915,7 @@ class TRINITY_DLL_SPEC Player : public Unit
float m_homebindX;
float m_homebindY;
float m_homebindZ;
+ void RelocateToHomebind() { SetMapId(m_homebindMapId); Relocate(m_homebindX,m_homebindY,m_homebindZ); }
// currently visible objects at player client
typedef std::set<uint64> ClientGUIDs;
@@ -2036,15 +1941,20 @@ class TRINITY_DLL_SPEC Player : public Unit
bool HasAtLoginFlag(AtLoginFlags f) const { return m_atLoginFlags & f; }
void SetAtLoginFlag(AtLoginFlags f) { m_atLoginFlags |= f; }
+ uint32 GetAtLoginFlag() { return m_atLoginFlags; }
+ void SetPetAtLoginFlag(uint8 f) { m_atLoginFlags |= uint32(f<<AT_LOAD_PET_FLAGS); }
LookingForGroup m_lookingForGroup;
// Temporarily removed pet cache
uint32 GetTemporaryUnsummonedPetNumber() const { return m_temporaryUnsummonedPetNumber; }
void SetTemporaryUnsummonedPetNumber(uint32 petnumber) { m_temporaryUnsummonedPetNumber = petnumber; }
- uint32 GetOldPetSpell() const { return m_oldpetspell; }
- void SetOldPetSpell(uint32 petspell) { m_oldpetspell = petspell; }
+ void UnsummonPetTemporaryIfAny();
+ void ResummonPetTemporaryUnSummonedIfAny();
+ bool IsPetNeedBeTemporaryUnsummoned() const { return !IsInWorld() || !isAlive() || IsMounted() /*+in flight*/; }
+ void SendCinematicStart(uint32 CinematicSequenceId);
+ void SendMovieStart(uint32 MovieId);
/*********************************************************/
/*** INSTANCE SYSTEM ***/
@@ -2079,22 +1989,39 @@ class TRINITY_DLL_SPEC Player : public Unit
GroupReference& GetGroupRef() { return m_group; }
void SetGroup(Group *group, int8 subgroup = -1);
uint8 GetSubGroup() const { return m_group.getSubGroup(); }
- uint32 GetGroupUpdateFlag() { return m_groupUpdateMask; }
+ uint32 GetGroupUpdateFlag() const { return m_groupUpdateMask; }
void SetGroupUpdateFlag(uint32 flag) { m_groupUpdateMask |= flag; }
- uint64 GetAuraUpdateMask() { return m_auraUpdateMask; }
- void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
- void UnsetAuraUpdateMask(uint8 slot) { m_auraUpdateMask &= ~(uint64(1) << slot); }
+ const uint64& GetAuraUpdateMaskForRaid() const { return m_auraRaidUpdateMask; }
+ void SetAuraUpdateMaskForRaid(uint8 slot) { m_auraRaidUpdateMask |= (uint64(1) << slot); }
Player* GetNextRandomRaidMember(float radius);
PartyResult CanUninviteFromGroup() const;
+ // BattleGround Group System
+ void SetBattleGroundRaid(Group *group, int8 subgroup = -1);
+ void RemoveFromBattleGroundRaid();
+ Group * GetOriginalGroup() { return m_originalGroup.getTarget(); }
+ GroupReference& GetOriginalGroupRef() { return m_originalGroup; }
+ uint8 GetOriginalSubGroup() const { return m_originalGroup.getSubGroup(); }
+ void SetOriginalGroup(Group *group, int8 subgroup = -1);
GridReference<Player> &GetGridRef() { return m_gridRef; }
MapReference &GetMapRef() { return m_mapRef; }
bool isAllowedToLoot(Creature* creature);
- WorldLocation& GetTeleportDest() { return m_teleport_dest; }
-
DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
+ uint8 GetRunesState() const { return m_runes->runeState; }
+ uint8 GetBaseRune(uint8 index) const { return m_runes->runes[index].BaseRune; }
+ uint8 GetCurrentRune(uint8 index) const { return m_runes->runes[index].CurrentRune; }
+ uint8 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; }
+ void SetBaseRune(uint8 index, uint8 baseRune) { m_runes->runes[index].BaseRune = baseRune; }
+ void SetCurrentRune(uint8 index, uint8 currentRune) { m_runes->runes[index].CurrentRune = currentRune; }
+ void SetRuneCooldown(uint8 index, uint8 cooldown) { m_runes->runes[index].Cooldown = cooldown; m_runes->SetRuneState(index, (cooldown == 0) ? true : false); }
+ void ConvertRune(uint8 index, uint8 newType);
+ void ResyncRunes(uint8 count);
+ void AddRunePower(uint8 index);
+ void InitRunes();
+ AchievementMgr& GetAchievementMgr() { return m_achievementMgr; }
+ void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1=0, uint32 miscvalue2=0, Unit *unit=NULL, uint32 time=0);
bool HasTitle(uint32 bitIndex);
bool HasTitle(CharTitlesEntry const* title) { return HasTitle(title->bit_index); }
void SetTitle(CharTitlesEntry const* title);
@@ -2107,20 +2034,17 @@ class TRINITY_DLL_SPEC Player : public Unit
/* this variable is set to bg->m_InstanceID, when player is teleported to BG - (it is battleground's GUID)*/
uint32 m_bgBattleGroundID;
+ BattleGroundTypeId m_bgTypeID;
/*
this is an array of BG queues (BgTypeIDs) in which is player
*/
struct BgBattleGroundQueueID_Rec
{
- uint32 bgQueueType;
+ BattleGroundQueueTypeId bgQueueTypeId;
uint32 invitedToInstance;
};
BgBattleGroundQueueID_Rec m_bgBattleGroundQueueID[PLAYER_MAX_BATTLEGROUND_QUEUES];
- uint32 m_bgEntryPointMap;
- float m_bgEntryPointX;
- float m_bgEntryPointY;
- float m_bgEntryPointZ;
- float m_bgEntryPointO;
+ WorldLocation m_bgEntryPoint;
std::set<uint32> m_bgAfkReporter;
uint8 m_bgAfkReportedCount;
@@ -2144,6 +2068,7 @@ class TRINITY_DLL_SPEC Player : public Unit
void _LoadActions(QueryResult *result);
void _LoadAuras(QueryResult *result, uint32 timediff);
+ void _LoadGlyphAuras();
void _LoadBoundInstances(QueryResult *result);
void _LoadInventory(QueryResult *result, uint32 timediff);
void _LoadMailInit(QueryResult *resultUnread, QueryResult *resultDelivery);
@@ -2152,7 +2077,7 @@ class TRINITY_DLL_SPEC Player : public Unit
void _LoadQuestStatus(QueryResult *result);
void _LoadDailyQuestStatus(QueryResult *result);
void _LoadGroup(QueryResult *result);
- void _LoadReputation(QueryResult *result);
+ void _LoadSkills();
void _LoadSpells(QueryResult *result);
void _LoadTutorials(QueryResult *result);
void _LoadFriendList(QueryResult *result);
@@ -2170,7 +2095,6 @@ class TRINITY_DLL_SPEC Player : public Unit
void _SaveMail();
void _SaveQuestStatus();
void _SaveDailyQuestStatus();
- void _SaveReputation();
void _SaveSpells();
void _SaveTutorials();
@@ -2180,13 +2104,11 @@ class TRINITY_DLL_SPEC Player : public Unit
/*********************************************************/
/*** ENVIRONMENTAL SYSTEM ***/
/*********************************************************/
- void HandleLava();
void HandleSobering();
- void StartMirrorTimer(MirrorTimerType Type, uint32 MaxValue);
- void ModifyMirrorTimer(MirrorTimerType Type, uint32 MaxValue, uint32 CurrentValue, uint32 Regen);
+ void SendMirrorTimer(MirrorTimerType Type, uint32 MaxValue, uint32 CurrentValue, int32 Regen);
void StopMirrorTimer(MirrorTimerType Type);
- uint8 m_isunderwater;
- bool m_isInWater;
+ void HandleDrowning(uint32 time_diff);
+ int32 getMaxTimer(MirrorTimerType timer);
/*********************************************************/
/*** HONOR SYSTEM ***/
@@ -2194,7 +2116,6 @@ class TRINITY_DLL_SPEC Player : public Unit
time_t m_lastHonorUpdateTime;
void outDebugValues() const;
- bool _removeSpell(uint16 spell_id);
uint64 m_lootGuid;
uint32 m_race;
@@ -2227,10 +2148,16 @@ class TRINITY_DLL_SPEC Player : public Unit
PlayerMails m_mail;
PlayerSpellMap m_spells;
SpellCooldowns m_spellCooldowns;
+ uint32 m_lastPotionId; // last used health/mana potion in combat, that block next potion use
ActionButtonList m_actionButtons;
float m_auraBaseMod[BASEMOD_END][MOD_END];
+ int16 m_baseRatingValue[MAX_COMBAT_RATING];
+ uint16 m_baseSpellDamage;
+ uint16 m_baseSpellHealing;
+ uint16 m_baseFeralAP;
+ uint16 m_baseManaRegen;
SpellModList m_spellMods[MAX_SPELLMOD];
int32 m_SpellModRemoveCount;
@@ -2247,8 +2174,6 @@ class TRINITY_DLL_SPEC Player : public Unit
typedef std::list<Channel*> JoinedChannelsList;
JoinedChannelsList m_channels;
- bool m_dontMove;
-
int m_cinematic;
Player *pTrader;
@@ -2264,8 +2189,6 @@ class TRINITY_DLL_SPEC Player : public Unit
bool m_DailyQuestChanged;
time_t m_lastDailyQuestTime;
- uint32 m_regenTimer;
- uint32 m_breathTimer;
uint32 m_drunkTimer;
uint16 m_drunk;
uint32 m_weaponChangeTimer;
@@ -2283,8 +2206,10 @@ class TRINITY_DLL_SPEC Player : public Unit
uint32 m_ArmorProficiency;
bool m_canParry;
bool m_canBlock;
+ bool m_canTitanGrip;
uint8 m_swingErrorMsg;
float m_ammoDPS;
+
////////////////////Rest System/////////////////////
int time_inn_enter;
uint32 inn_pos_mapid;
@@ -2295,28 +2220,20 @@ class TRINITY_DLL_SPEC Player : public Unit
RestType rest_type;
////////////////////Rest System/////////////////////
- // Transports
- Transport * m_transport;
-
uint32 m_resetTalentsCost;
time_t m_resetTalentsTime;
uint32 m_usedTalentCount;
+ uint32 m_questRewardTalentCount;
// Social
PlayerSocial *m_social;
// Groups
GroupReference m_group;
+ GroupReference m_originalGroup;
Group *m_groupInvite;
uint32 m_groupUpdateMask;
- uint64 m_auraUpdateMask;
-
- // Temporarily removed pet cache
- uint32 m_temporaryUnsummonedPetNumber;
- uint32 m_oldpetspell;
-
- uint64 m_miniPet;
- GuardianPetList m_guardianPets;
+ uint64 m_auraRaidUpdateMask;
// Player summoning
time_t m_summon_expire;
@@ -2325,12 +2242,8 @@ class TRINITY_DLL_SPEC Player : public Unit
float m_summon_y;
float m_summon_z;
- // Far Teleport
- WorldLocation m_teleport_dest;
-
- bool m_farsightVision;
-
DeclinedName *m_declinedname;
+ Runes *m_runes;
private:
// internal common parts for CanStore/StoreItem functions
uint8 _CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool swap, Item *pSrcItem ) const;
@@ -2338,11 +2251,35 @@ class TRINITY_DLL_SPEC Player : public Unit
uint8 _CanStoreItem_InInventorySlots( uint8 slot_begin, uint8 slot_end, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool merge, Item *pSrcItem, uint8 skip_bag, uint8 skip_slot ) const;
Item* _StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, bool update );
+ void UpdateKnownCurrencies(uint32 itemId, bool apply);
+ int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, bool for_quest);
+ void AdjustQuestReqItemCount( Quest const* pQuest, QuestStatusData& questStatusData );
+
GridReference<Player> m_gridRef;
MapReference m_mapRef;
void UpdateCharmedAI();
UnitAI *i_AI;
+
+ uint32 m_lastFallTime;
+ float m_lastFallZ;
+
+ int32 m_MirrorTimer[MAX_TIMERS];
+ uint8 m_MirrorTimerFlags;
+ uint8 m_MirrorTimerFlagsLast;
+ bool m_isInWater;
+
+ // Current teleport data
+ WorldLocation m_teleport_dest;
+ bool mSemaphoreTeleport_Near;
+ bool mSemaphoreTeleport_Far;
+
+ // Temporary removed pet cache
+ uint32 m_temporaryUnsummonedPetNumber;
+ uint32 m_oldpetspell;
+
+ AchievementMgr m_achievementMgr;
+ ReputationMgr m_reputationMgr;
};
void AddItemsSetItem(Player*player,Item *item);
@@ -2378,7 +2315,6 @@ template <class T> T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T &bas
if (mod->charges > 0 )
{
- if( !(spellInfo->SpellFamilyName == 8 && spellInfo->SpellFamilyFlags & 0x200000000LL) )
--mod->charges;
if (mod->charges == 0)
{
diff --git a/src/game/PlayerDump.cpp b/src/game/PlayerDump.cpp
index b061b63a06a..5218d9c4a54 100644
--- a/src/game/PlayerDump.cpp
+++ b/src/game/PlayerDump.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -26,7 +26,7 @@
#include "ObjectMgr.h"
// Character Dump tables
-#define DUMP_TABLE_COUNT 18
+#define DUMP_TABLE_COUNT 20
struct DumpTable
{
@@ -36,24 +36,27 @@ struct DumpTable
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_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 },
+ { "characters", DTT_CHARACTER },
+ { "character_achievement", DTT_CHAR_TABLE },
+ { "character_achievement_progress", DTT_CHAR_TABLE },
+ { "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
@@ -90,7 +93,7 @@ bool findnth(std::string &str, int n, std::string::size_type &s, std::string::si
if (e == std::string::npos) return false;
} while(str[e-1] == '\\');
- for(int i = 1; i < n; i++)
+ for(int i = 1; i < n; ++i)
{
do
{
@@ -154,7 +157,7 @@ bool changetoknth(std::string &str, int n, const char *with, bool insert = false
uint32 registerNewGuid(uint32 oldGuid, std::map<uint32, uint32> &guidMap, uint32 hiGuid)
{
- std::map<uint32, uint32>::iterator itr = guidMap.find(oldGuid);
+ std::map<uint32, uint32>::const_iterator itr = guidMap.find(oldGuid);
if(itr != guidMap.end())
return itr->second;
@@ -195,7 +198,7 @@ std::string CreateDumpString(char const* tableName, QueryResult *result)
std::ostringstream ss;
ss << "INSERT INTO "<< _TABLE_SIM_ << tableName << _TABLE_SIM_ << " VALUES (";
Field *fields = result->Fetch();
- for(uint32 i = 0; i < result->GetFieldCount(); i++)
+ for(uint32 i = 0; i < result->GetFieldCount(); ++i)
{
if (i == 0) ss << "'";
else ss << ", '";
@@ -329,7 +332,39 @@ void PlayerDumpWriter::DumpTable(std::string& dump, uint32 guid, char const*tabl
std::string PlayerDumpWriter::GetDump(uint32 guid)
{
std::string dump;
- for(int i = 0; i < DUMP_TABLE_COUNT; i++)
+
+ dump += "IMPORTANT NOTE: This sql queries not created for apply directly, use '.pdump load' command in console or client chat instead.\n";
+ dump += "IMPORTANT NOTE: NOT APPLY ITS DIRECTLY to character DB or you will DAMAGE and CORRUPT character DB\n\n";
+
+ // revision check guard
+ QueryResult* result = CharacterDatabase.Query("SELECT * FROM character_db_version LIMIT 1");
+ if(result)
+ {
+ QueryResult::FieldNames const& namesMap = result->GetFieldNames();
+ std::string reqName;
+ for(QueryResult::FieldNames::const_iterator itr = namesMap.begin(); itr != namesMap.end(); ++itr)
+ {
+ if(itr->second.substr(0,9)=="required_")
+ {
+ reqName = itr->second;
+ break;
+ }
+ }
+
+ if(!reqName.empty())
+ {
+ // this will fail at wrong character DB version
+ dump += "UPDATE character_db_version SET "+reqName+" = 1 WHERE FALSE;\n\n";
+ }
+ else
+ sLog.outError("Table 'character_db_version' not have revision guard field, revision guard query not added to pdump.");
+
+ delete result;
+ }
+ else
+ sLog.outError("Character DB not have 'character_db_version' table, revision guard query not added to pdump.");
+
+ 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..
@@ -436,9 +471,23 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
std::string line; line.assign(buf);
// skip empty strings
- if(line.find_first_not_of(" \t\n\r\7")==std::string::npos)
+ size_t nw_pos = line.find_first_not_of(" \t\n\r\7");
+ if(nw_pos==std::string::npos)
+ continue;
+
+ // skip NOTE
+ if(line.substr(nw_pos,15)=="IMPORTANT NOTE:")
continue;
+ // add required_ check
+ if(line.substr(nw_pos,41)=="UPDATE character_db_version SET required_")
+ {
+ if(!CharacterDatabase.Execute(line.c_str()))
+ ROLLBACK(DUMP_FILE_BROKEN);
+
+ continue;
+ }
+
// determine table name and load type
std::string tn = gettablename(line);
if(tn.empty())
@@ -449,7 +498,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
DumpTableType type;
uint8 i;
- for(i = 0; i < DUMP_TABLE_COUNT; i++)
+ for(i = 0; i < DUMP_TABLE_COUNT; ++i)
{
if (tn == dumpTables[i].name)
{
diff --git a/src/game/PlayerDump.h b/src/game/PlayerDump.h
index 211a000103d..e3dfd192efb 100644
--- a/src/game/PlayerDump.h
+++ b/src/game/PlayerDump.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -20,6 +20,7 @@
#ifndef _PLAYER_DUMP_H
#define _PLAYER_DUMP_H
+
#include <string>
#include <map>
#include <set>
@@ -28,10 +29,10 @@ enum DumpTableType
{
DTT_CHARACTER, // // characters
- DTT_CHAR_TABLE, // // character_action, character_aura, character_homebind,
- // character_queststatus, character_reputation,
- // character_spell, character_spell_cooldown, character_ticket,
- // character_tutorial
+ DTT_CHAR_TABLE, // // character_achievement, character_achievement_progress,
+ // character_action, character_aura, character_homebind,
+ // character_queststatus, character_reputation, character_spell,
+ // character_spell_cooldown, character_ticket, character_tutorial
DTT_INVENTORY, // -> item guids collection // character_inventory
diff --git a/src/game/PointMovementGenerator.cpp b/src/game/PointMovementGenerator.cpp
index 6117dbf903d..084dad7cfa8 100644
--- a/src/game/PointMovementGenerator.cpp
+++ b/src/game/PointMovementGenerator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,16 +22,16 @@
#include "Errors.h"
#include "Creature.h"
#include "CreatureAI.h"
-#include "MapManager.h"
#include "DestinationHolderImp.h"
//----- Point Movement Generator
template<class T>
void PointMovementGenerator<T>::Initialize(T &unit)
{
- unit.StopMoving();
+ //unit.StopMoving();
+ unit.clearUnitState(UNIT_STAT_MOVING);
Traveller<T> traveller(unit);
- i_destinationHolder.SetDestination(traveller,i_x,i_y,i_z);
+ i_destinationHolder.SetDestination(traveller,i_x,i_y,i_z, !unit.hasUnitState(UNIT_STAT_JUMPING));
if (unit.GetTypeId() == TYPEID_UNIT && ((Creature*)&unit)->canFly())
unit.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
@@ -68,7 +68,7 @@ template<class T>
void PointMovementGenerator<T>:: Finalize(T &unit)
{
if(unit.hasUnitState(UNIT_STAT_CHARGING))
- unit.clearUnitState(UNIT_STAT_CHARGING);
+ unit.clearUnitState(UNIT_STAT_CHARGING | UNIT_STAT_JUMPING);
else if(arrived)
MovementInform(unit);
}
diff --git a/src/game/PointMovementGenerator.h b/src/game/PointMovementGenerator.h
index 5f1bf33c348..6dfb1d6f8ec 100644
--- a/src/game/PointMovementGenerator.h
+++ b/src/game/PointMovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/PoolHandler.cpp b/src/game/PoolHandler.cpp
new file mode 100644
index 00000000000..bb2276a6d24
--- /dev/null
+++ b/src/game/PoolHandler.cpp
@@ -0,0 +1,719 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://www.mangosproject.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 "PoolHandler.h"
+#include "ObjectMgr.h"
+#include "ProgressBar.h"
+#include "Log.h"
+#include "MapManager.h"
+#include "Policies/SingletonImp.h"
+
+INSTANTIATE_SINGLETON_1(PoolHandler);
+
+////////////////////////////////////////////////////////////
+// Methods of template class PoolGroup
+
+template <class T>
+PoolGroup<T>::PoolGroup()
+{
+ Spawned = 0;
+}
+
+// Method to add a gameobject/creature guid to the proper list depending on pool type and chance value
+template <class T>
+void PoolGroup<T>::AddEntry(PoolObject& poolitem, uint32 maxentries)
+{
+ if (poolitem.chance != 0 && maxentries == 1)
+ ExplicitlyChanced.push_back(poolitem);
+ else
+ EqualChanced.push_back(poolitem);
+}
+
+// Method to check the chances are proper in this object pool
+template <class T>
+bool PoolGroup<T>::CheckPool(void)
+{
+ if (EqualChanced.size() == 0)
+ {
+ float chance = 0;
+ for (uint32 i=0; i<ExplicitlyChanced.size(); ++i)
+ chance += ExplicitlyChanced[i].chance;
+ if (chance != 100 && chance != 0)
+ return false;
+ }
+ return true;
+}
+
+// Method that tell if the gameobject, creature or pool is spawned currently
+template <class T>
+bool PoolGroup<T>::IsSpawnedObject(uint32 guid)
+{
+ for (uint32 i=0; i<ExplicitlyChanced.size(); ++i)
+ if (ExplicitlyChanced[i].guid == guid)
+ return ExplicitlyChanced[i].spawned;
+ for (uint32 i=0; i<EqualChanced.size(); ++i)
+ if (EqualChanced[i].guid == guid)
+ return EqualChanced[i].spawned;
+ return false;
+}
+
+// Method that return a guid of a rolled creature or gameobject
+// Note: Copy from loot system because it's very similar and only few things change
+template <class T>
+uint32 PoolGroup<T>::RollOne(void)
+{
+ if (!ExplicitlyChanced.empty()) // First explicitly chanced entries are checked
+ {
+ float roll = rand_chance();
+
+ for (uint32 i=0; i<ExplicitlyChanced.size(); ++i)
+ {
+ roll -= ExplicitlyChanced[i].chance;
+ if (roll < 0)
+ return ExplicitlyChanced[i].guid;
+ }
+ }
+ if (!EqualChanced.empty())
+ return EqualChanced[irand(0, EqualChanced.size()-1)].guid;
+
+ return 0; // None found
+}
+
+// Main method to despawn a creature or gameobject in a pool
+// If no guid is passed, the pool is just removed (event end case)
+// If guid is filled, cache will be used and no removal will occur, it just fill the cache
+template<class T>
+void PoolGroup<T>::DespawnObject(uint32 guid)
+{
+ for (int i=0; i<EqualChanced.size(); ++i)
+ {
+ if (EqualChanced[i].spawned)
+ {
+ if (!guid || EqualChanced[i].guid == guid)
+ {
+ if (guid)
+ CacheValue = EqualChanced[i].guid;
+ else
+ Despawn1Object(EqualChanced[i].guid);
+
+ EqualChanced[i].spawned = false;
+ Spawned--;
+ }
+ }
+ }
+}
+
+// Method that is actualy doing the removal job on one creature
+template<>
+void PoolGroup<Creature>::Despawn1Object(uint32 guid)
+{
+ if (CreatureData const* data = objmgr.GetCreatureData(guid))
+ {
+ objmgr.RemoveCreatureFromGrid(guid, data);
+
+ if (Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_UNIT), (Creature*)NULL))
+ {
+ pCreature->CleanupsBeforeDelete();
+ pCreature->AddObjectToRemoveList();
+ }
+ }
+}
+
+// Same on one gameobject
+template<>
+void PoolGroup<GameObject>::Despawn1Object(uint32 guid)
+{
+ if (GameObjectData const* data = objmgr.GetGOData(guid))
+ {
+ objmgr.RemoveGameobjectFromGrid(guid, data);
+
+ if (GameObject* pGameobject = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL))
+ pGameobject->AddObjectToRemoveList();
+ }
+}
+
+// Same on one pool
+template<>
+void PoolGroup<Pool>::Despawn1Object(uint32 child_pool_id)
+{
+ poolhandler.DespawnPool(child_pool_id);
+}
+
+// Method for a pool only to remove any found record causing a circular dependency loop
+template<>
+void PoolGroup<Pool>::RemoveOneRelation(uint16 child_pool_id)
+{
+ for (PoolObjectList::iterator itr = ExplicitlyChanced.begin(); itr != ExplicitlyChanced.end(); ++itr)
+ {
+ if(itr->guid == child_pool_id)
+ {
+ ExplicitlyChanced.erase(itr);
+ break;
+ }
+ }
+ for (PoolObjectList::iterator itr = EqualChanced.begin(); itr != EqualChanced.end(); ++itr)
+ {
+ if(itr->guid == child_pool_id)
+ {
+ EqualChanced.erase(itr);
+ break;
+ }
+ }
+}
+
+// Method that Spawn 1+ creatures or gameobject
+// if cache is false (initialization or event start), X creatures are spawned with X <= limit (< if limit higher that the number of creatures in pool)
+// if cache is true, this means only one has to be spawned (or respawned if the rolled one is same as cached one)
+template <class T>
+void PoolGroup<T>::SpawnObject(uint32 limit, bool cache)
+{
+ if (limit == 1) // This is the only case where explicit chance is used
+ {
+ uint32 roll = RollOne();
+ if (cache && CacheValue != roll)
+ Despawn1Object(CacheValue);
+ CacheValue = Spawn1Object(roll);
+ }
+ else if (limit < EqualChanced.size() && Spawned < limit)
+ {
+ std::vector<uint32> IndexList;
+ for (int i=0; i<EqualChanced.size(); ++i)
+ if (!EqualChanced[i].spawned)
+ IndexList.push_back(i);
+
+ while (Spawned < limit && IndexList.size() > 0)
+ {
+ uint32 roll = urand(1, IndexList.size()) - 1;
+ uint32 index = IndexList[roll];
+ if (!cache || (cache && EqualChanced[index].guid != CacheValue))
+ {
+ if (cache)
+ Despawn1Object(CacheValue);
+ EqualChanced[index].spawned = Spawn1Object(EqualChanced[index].guid);
+ }
+ else
+ EqualChanced[index].spawned = ReSpawn1Object(EqualChanced[index].guid);
+
+ if (EqualChanced[index].spawned)
+ ++Spawned; // limited group use the Spawned variable to store the number of actualy spawned creatures
+ std::vector<uint32>::iterator itr = IndexList.begin()+roll;
+ IndexList.erase(itr);
+ }
+ CacheValue = 0;
+ }
+ else // Not enough objects in pool, so spawn all
+ {
+ for (int i=0; i<EqualChanced.size(); ++i)
+ EqualChanced[i].spawned = Spawn1Object(EqualChanced[i].guid);
+ }
+}
+
+// Method that is actualy doing the spawn job on 1 creature
+template <>
+bool PoolGroup<Creature>::Spawn1Object(uint32 guid)
+{
+ CreatureData const* data = objmgr.GetCreatureData(guid);
+ if (data)
+ {
+ objmgr.AddCreatureToGrid(guid, data);
+
+ // Spawn if necessary (loaded grids only)
+ Map* map = const_cast<Map*>(MapManager::Instance().GetBaseMap(data->mapid));
+ // We use spawn coords to spawn
+ if (!map->Instanceable() && !map->IsRemovalGrid(data->posX, data->posY))
+ {
+ Creature* pCreature = new Creature;
+ //sLog.outDebug("Spawning creature %u",guid);
+ if (!pCreature->LoadFromDB(guid, map))
+ {
+ delete pCreature;
+ }
+ else
+ {
+ map->Add(pCreature);
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+// Same for 1 gameobject
+template <>
+bool PoolGroup<GameObject>::Spawn1Object(uint32 guid)
+{
+ GameObjectData const* data = objmgr.GetGOData(guid);
+ if (data)
+ {
+ objmgr.AddGameobjectToGrid(guid, data);
+ // Spawn if necessary (loaded grids only)
+ // this base map checked as non-instanced and then only existed
+ Map* map = const_cast<Map*>(MapManager::Instance().GetBaseMap(data->mapid));
+ // We use current coords to unspawn, not spawn coords since creature can have changed grid
+ if (!map->Instanceable() && !map->IsRemovalGrid(data->posX, data->posY))
+ {
+ GameObject* pGameobject = new GameObject;
+ //sLog.outDebug("Spawning gameobject %u", guid);
+ if (!pGameobject->LoadFromDB(guid, map))
+ {
+ delete pGameobject;
+ }
+ else
+ {
+ if (pGameobject->isSpawnedByDefault())
+ map->Add(pGameobject);
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+// Same for 1 pool
+template <>
+bool PoolGroup<Pool>::Spawn1Object(uint32 child_pool_id)
+{
+ poolhandler.SpawnPool(child_pool_id);
+ return true;
+}
+
+// Method that does the respawn job on the specified creature
+template <>
+bool PoolGroup<Creature>::ReSpawn1Object(uint32 guid)
+{
+ CreatureData const* data = objmgr.GetCreatureData(guid);
+ if (data)
+ {
+ if (Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_UNIT), (Creature*)NULL))
+ pCreature->GetMap()->Add(pCreature);
+ return true;
+ }
+ return false;
+}
+
+// Same for 1 gameobject
+template <>
+bool PoolGroup<GameObject>::ReSpawn1Object(uint32 guid)
+{
+ GameObjectData const* data = objmgr.GetGOData(guid);
+ if (data)
+ {
+ if (GameObject* pGameobject = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL))
+ pGameobject->GetMap()->Add(pGameobject);
+ return true;
+ }
+ return false;
+}
+
+// Nothing to do for a child Pool
+template <>
+bool PoolGroup<Pool>::ReSpawn1Object(uint32 guid)
+{
+ return true;
+}
+
+
+////////////////////////////////////////////////////////////
+// Methods of class PoolHandler
+
+PoolHandler::PoolHandler()
+{
+ isSystemInit = false;
+}
+
+void PoolHandler::LoadFromDB()
+{
+ QueryResult *result = WorldDatabase.Query("SELECT MAX(entry) FROM pool_template");
+ if (!result)
+ {
+ sLog.outString(">> Table pool_template is empty.");
+ sLog.outString();
+ return;
+ }
+ else
+ {
+ Field *fields = result->Fetch();
+ max_pool_id = fields[0].GetUInt16();
+ delete result;
+ }
+
+ mPoolTemplate.resize(max_pool_id + 1);
+
+ result = WorldDatabase.Query("SELECT entry,max_limit FROM pool_template");
+ if (!result)
+ {
+ mPoolTemplate.clear();
+ sLog.outString(">> Table pool_template is empty:");
+ sLog.outString();
+ return;
+ }
+
+ uint32 count = 0;
+
+ barGoLink bar(result->GetRowCount());
+ do
+ {
+ ++count;
+ Field *fields = result->Fetch();
+
+ bar.step();
+
+ uint16 pool_id = fields[0].GetUInt16();
+
+ PoolTemplateData& pPoolTemplate = mPoolTemplate[pool_id];
+ pPoolTemplate.MaxLimit = fields[1].GetUInt32();
+
+ } while (result->NextRow());
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u objects pools", count );
+ delete result;
+
+ // Creatures
+
+ mPoolCreatureGroups.resize(max_pool_id + 1);
+ mCreatureSearchMap.clear();
+ // 1 2 3
+ result = WorldDatabase.Query("SELECT guid, pool_entry, chance FROM pool_creature");
+
+ count = 0;
+ if (!result)
+ {
+ barGoLink bar2(1);
+ bar2.step();
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u creatures in pools", count );
+ }
+ else
+ {
+
+ barGoLink bar2(result->GetRowCount());
+ do
+ {
+ Field *fields = result->Fetch();
+
+ bar2.step();
+
+ uint32 guid = fields[0].GetUInt32();
+ uint16 pool_id = fields[1].GetUInt16();
+ float chance = fields[2].GetFloat();
+
+ CreatureData const* data = objmgr.GetCreatureData(guid);
+ if (!data)
+ {
+ sLog.outErrorDb("`pool_creature` has a non existing creature spawn (GUID: %u) defined for pool id (%u), skipped.", guid, pool_id );
+ continue;
+ }
+ if (pool_id > max_pool_id)
+ {
+ sLog.outErrorDb("`pool_creature` pool id (%i) is out of range compared to max pool id in `pool_template`, skipped.",pool_id);
+ continue;
+ }
+ if (chance < 0 || chance > 100)
+ {
+ sLog.outErrorDb("`pool_creature` has an invalid chance (%f) for creature guid (%u) in pool id (%i), skipped.", chance, guid, pool_id);
+ continue;
+ }
+ PoolTemplateData *pPoolTemplate = &mPoolTemplate[pool_id];
+ ++count;
+
+ PoolObject plObject = PoolObject(guid, chance);
+ PoolGroup<Creature>& cregroup = mPoolCreatureGroups[pool_id];
+ cregroup.AddEntry(plObject, pPoolTemplate->MaxLimit);
+ SearchPair p(guid, pool_id);
+ mCreatureSearchMap.insert(p);
+
+ } while (result->NextRow());
+ sLog.outString();
+ sLog.outString( ">> Loaded %u creatures in pools", count );
+ delete result;
+ }
+
+ // Gameobjects
+
+ mPoolGameobjectGroups.resize(max_pool_id + 1);
+ mGameobjectSearchMap.clear();
+ // 1 2 3
+ result = WorldDatabase.Query("SELECT guid, pool_entry, chance FROM pool_gameobject");
+
+ count = 0;
+ if (!result)
+ {
+ barGoLink bar2(1);
+ bar2.step();
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u gameobject in pools", count );
+ }
+ else
+ {
+
+ barGoLink bar2(result->GetRowCount());
+ do
+ {
+ Field *fields = result->Fetch();
+
+ bar2.step();
+
+ uint32 guid = fields[0].GetUInt32();
+ uint16 pool_id = fields[1].GetUInt16();
+ float chance = fields[2].GetFloat();
+
+ GameObjectData const* data = objmgr.GetGOData(guid);
+ if (!data)
+ {
+ sLog.outErrorDb("`pool_gameobject` has a non existing gameobject spawn (GUID: %u) defined for pool id (%u), skipped.", guid, pool_id );
+ continue;
+ }
+ GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(data->id);
+ if (goinfo->type != GAMEOBJECT_TYPE_CHEST &&
+ goinfo->type != GAMEOBJECT_TYPE_GOOBER &&
+ goinfo->type != GAMEOBJECT_TYPE_FISHINGHOLE)
+ {
+ sLog.outErrorDb("`pool_gameobject` has a not lootable gameobject spawn (GUID: %u, type: %u) defined for pool id (%u), skipped.", guid, goinfo->type, pool_id );
+ continue;
+ }
+ if (pool_id > max_pool_id)
+ {
+ sLog.outErrorDb("`pool_gameobject` pool id (%i) is out of range compared to max pool id in `pool_template`, skipped.",pool_id);
+ continue;
+ }
+ if (chance < 0 || chance > 100)
+ {
+ sLog.outErrorDb("`pool_gameobject` has an invalid chance (%f) for gameobject guid (%u) in pool id (%i), skipped.", chance, guid, pool_id);
+ continue;
+ }
+ PoolTemplateData *pPoolTemplate = &mPoolTemplate[pool_id];
+
+ ++count;
+
+ PoolObject plObject = PoolObject(guid, chance);
+ PoolGroup<GameObject>& gogroup = mPoolGameobjectGroups[pool_id];
+ gogroup.AddEntry(plObject, pPoolTemplate->MaxLimit);
+ SearchPair p(guid, pool_id);
+ mGameobjectSearchMap.insert(p);
+
+ } while( result->NextRow() );
+ sLog.outString();
+ sLog.outString( ">> Loaded %u gameobject in pools", count );
+ delete result;
+ }
+
+ // Pool of pools
+ mPoolPoolGroups.resize(max_pool_id + 1);
+ // 1 2 3
+ result = WorldDatabase.Query("SELECT pool_id, mother_pool, chance FROM pool_pool");
+
+ count = 0;
+ if( !result )
+ {
+ barGoLink bar2(1);
+ bar2.step();
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u pools in pools", count );
+ }
+ else
+ {
+
+ barGoLink bar2( result->GetRowCount() );
+ do
+ {
+ Field *fields = result->Fetch();
+
+ bar2.step();
+
+ uint16 child_pool_id = fields[0].GetUInt16();
+ uint16 mother_pool_id = fields[1].GetUInt16();
+ float chance = fields[2].GetFloat();
+
+ if (mother_pool_id > max_pool_id)
+ {
+ sLog.outErrorDb("`pool_pool` mother_pool id (%i) is out of range compared to max pool id in `pool_template`, skipped.",mother_pool_id);
+ continue;
+ }
+ if (child_pool_id > max_pool_id)
+ {
+ sLog.outErrorDb("`pool_pool` included pool_id (%i) is out of range compared to max pool id in `pool_template`, skipped.",child_pool_id);
+ continue;
+ }
+ if (mother_pool_id == child_pool_id)
+ {
+ sLog.outErrorDb("`pool_pool` pool_id (%i) includes itself, dead-lock detected, skipped.",child_pool_id);
+ continue;
+ }
+ if (chance < 0 || chance > 100)
+ {
+ sLog.outErrorDb("`pool_pool` has an invalid chance (%f) for pool id (%u) in mother pool id (%i), skipped.", chance, child_pool_id, mother_pool_id);
+ continue;
+ }
+ PoolTemplateData *pPoolTemplateMother = &mPoolTemplate[mother_pool_id];
+
+ ++count;
+
+ PoolObject plObject = PoolObject(child_pool_id, chance);
+ PoolGroup<Pool>& plgroup = mPoolPoolGroups[mother_pool_id];
+ plgroup.AddEntry(plObject, pPoolTemplateMother->MaxLimit);
+ SearchPair p(child_pool_id, mother_pool_id);
+ mPoolSearchMap.insert(p);
+
+ } while( result->NextRow() );
+
+ // Now check for circular reference
+ for(uint16 i=0; i<max_pool_id; ++i)
+ {
+ std::set<uint16> checkedPools;
+ for(SearchMap::iterator poolItr = mPoolSearchMap.find(i); poolItr != mPoolSearchMap.end(); poolItr = mPoolSearchMap.find(poolItr->second))
+ {
+ checkedPools.insert(poolItr->first);
+ if(checkedPools.find(poolItr->second) != checkedPools.end())
+ {
+ std::ostringstream ss;
+ ss<< "The pool(s) ";
+ for (std::set<uint16>::const_iterator itr=checkedPools.begin(); itr!=checkedPools.end(); ++itr)
+ ss << *itr << " ";
+ ss << "create(s) a circular reference, which can cause the server to freeze.\nRemoving the last link between mother pool "
+ << poolItr->first << " and child pool " << poolItr->second;
+ sLog.outErrorDb(ss.str().c_str());
+ mPoolPoolGroups[poolItr->second].RemoveOneRelation(poolItr->first);
+ mPoolSearchMap.erase(poolItr);
+ --count;
+ break;
+ }
+ }
+ }
+ sLog.outString();
+ sLog.outString( ">> Loaded %u pools in mother pools", count );
+ delete result;
+ }
+}
+
+// The initialize method will spawn all pools not in an event and not in another pool, this is why there is 2 left joins with 2 null checks
+void PoolHandler::Initialize()
+{
+ QueryResult *result = WorldDatabase.Query("SELECT DISTINCT pool_template.entry FROM pool_template LEFT JOIN game_event_pool ON pool_template.entry=game_event_pool.pool_entry LEFT JOIN pool_pool ON pool_template.entry=pool_pool.pool_id WHERE game_event_pool.pool_entry IS NULL AND pool_pool.pool_id IS NULL");
+ uint32 count=0;
+ if (result)
+ {
+ do
+ {
+ Field *fields = result->Fetch();
+ uint16 pool_entry = fields[0].GetUInt16();
+ if (!CheckPool(pool_entry))
+ {
+ sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", pool_entry);
+ continue;
+ }
+ SpawnPool(pool_entry);
+ count++;
+ } while (result->NextRow());
+ }
+
+ sLog.outBasic("Pool handling system initialized, %u pools spawned.", count);
+ isSystemInit = true;
+}
+
+// Call to spawn a pool, if cache if true the method will spawn only if cached entry is different
+// If it's same, the gameobject/creature is respawned only (added back to map)
+void PoolHandler::SpawnPool(uint16 pool_id, bool cache)
+{
+ if (!mPoolPoolGroups[pool_id].isEmpty())
+ mPoolPoolGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, cache);
+ if (!mPoolGameobjectGroups[pool_id].isEmpty())
+ mPoolGameobjectGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, cache);
+ if (!mPoolCreatureGroups[pool_id].isEmpty())
+ mPoolCreatureGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, cache);
+}
+
+// Call to despawn a pool, all gameobjects/creatures in this pool are removed
+void PoolHandler::DespawnPool(uint16 pool_id)
+{
+ if (!mPoolPoolGroups[pool_id].isEmpty())
+ mPoolPoolGroups[pool_id].DespawnObject();
+ if (!mPoolGameobjectGroups[pool_id].isEmpty())
+ mPoolGameobjectGroups[pool_id].DespawnObject();
+ if (!mPoolCreatureGroups[pool_id].isEmpty())
+ mPoolCreatureGroups[pool_id].DespawnObject();
+}
+
+// Call to update the pool when a gameobject/creature part of pool [pool_id] is ready to respawn
+// Here we cache only the creature/gameobject whose guid is passed as parameter
+// Then the spawn pool call will use this cache to decide
+void PoolHandler::UpdatePool(uint16 pool_id, uint32 guid, uint32 type)
+{
+ uint16 motherpoolid = IsPartOfAPool(pool_id, 0);
+
+ if (motherpoolid)
+ mPoolPoolGroups[motherpoolid].DespawnObject(pool_id);
+ else if (type == TYPEID_GAMEOBJECT && !mPoolGameobjectGroups[pool_id].isEmpty())
+ mPoolGameobjectGroups[pool_id].DespawnObject(guid);
+ else if (type != TYPEID_GAMEOBJECT && !mPoolCreatureGroups[pool_id].isEmpty())
+ mPoolCreatureGroups[pool_id].DespawnObject(guid);
+
+ if (motherpoolid)
+ SpawnPool(motherpoolid, true);
+ else
+ SpawnPool(pool_id, true);
+}
+
+// Method that tell if the gameobject/creature is part of a pool and return the pool id if yes
+uint16 PoolHandler::IsPartOfAPool(uint32 guid, uint32 type)
+{
+ if (type == 0) // pool of pool
+ {
+ SearchMap::const_iterator itr = mPoolSearchMap.find(guid);
+ if (itr != mPoolSearchMap.end())
+ return itr->second;
+ }
+ else if (type == TYPEID_GAMEOBJECT)
+ {
+ SearchMap::const_iterator itr = mGameobjectSearchMap.find(guid);
+ if (itr != mGameobjectSearchMap.end())
+ return itr->second;
+ }
+ else // creature
+ {
+ SearchMap::const_iterator itr = mCreatureSearchMap.find(guid);
+ if (itr != mCreatureSearchMap.end())
+ return itr->second;
+ }
+ return 0;
+}
+
+// Method that check chance integrity of the creatures and gameobjects in this pool
+bool PoolHandler::CheckPool(uint16 pool_id)
+{
+ return pool_id <= max_pool_id &&
+ mPoolGameobjectGroups[pool_id].CheckPool() &&
+ mPoolCreatureGroups[pool_id].CheckPool() &&
+ mPoolPoolGroups[pool_id].CheckPool();
+}
+
+// Method that tell if a creature or gameobject in pool_id is spawned currently
+bool PoolHandler::IsSpawnedObject(uint16 pool_id, uint32 guid, uint32 type)
+{
+ if (pool_id > max_pool_id)
+ return false;
+ if (type == 0)
+ return mPoolPoolGroups[pool_id].IsSpawnedObject(guid);
+ else if (type == TYPEID_GAMEOBJECT)
+ return mPoolGameobjectGroups[pool_id].IsSpawnedObject(guid);
+ else
+ return mPoolCreatureGroups[pool_id].IsSpawnedObject(guid);
+}
diff --git a/src/game/PoolHandler.h b/src/game/PoolHandler.h
new file mode 100644
index 00000000000..35e18c2d58c
--- /dev/null
+++ b/src/game/PoolHandler.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://www.mangosproject.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 MANGOS_POOLHANDLER_H
+#define MANGOS_POOLHANDLER_H
+
+#include "Platform/Define.h"
+#include "Policies/Singleton.h"
+#include "Creature.h"
+#include "GameObject.h"
+
+struct PoolTemplateData
+{
+ uint32 MaxLimit;
+};
+
+struct PoolObject
+{
+ uint32 guid;
+ float chance;
+ bool spawned;
+ PoolObject(uint32 _guid, float _chance): guid(_guid), chance(fabs(_chance)), spawned(false) {}
+};
+
+template <class T>
+class PoolGroup
+{
+ public:
+ PoolGroup();
+ ~PoolGroup() {};
+ bool isEmpty() { return ExplicitlyChanced.size()==0 && EqualChanced.size()==0; }
+ void AddEntry(PoolObject& poolitem, uint32 maxentries);
+ bool CheckPool(void);
+ uint32 RollOne(void);
+ bool IsSpawnedObject(uint32 guid);
+ void DespawnObject(uint32 guid=0);
+ void Despawn1Object(uint32 guid);
+ void SpawnObject(uint32 limit, bool cache=false);
+ bool Spawn1Object(uint32 guid);
+ bool ReSpawn1Object(uint32 guid);
+ void RemoveOneRelation(uint16 child_pool_id);
+ private:
+ typedef std::vector<PoolObject> PoolObjectList;
+ uint32 CacheValue; // Store the guid of the removed creature/gameobject during a pool update
+ PoolObjectList ExplicitlyChanced;
+ PoolObjectList EqualChanced;
+ uint32 Spawned; // Used to know the number of spawned objects
+};
+
+class Pool // for Pool of Pool case
+{
+};
+
+class PoolHandler
+{
+ public:
+ PoolHandler();
+ ~PoolHandler() {};
+ void LoadFromDB();
+ uint16 IsPartOfAPool(uint32 guid, uint32 type);
+ bool IsSpawnedObject(uint16 pool_id, uint32 guid, uint32 type);
+ bool CheckPool(uint16 pool_id);
+ void SpawnPool(uint16 pool_id, bool cache=false);
+ void DespawnPool(uint16 pool_id);
+ void UpdatePool(uint16 pool_id, uint32 guid, uint32 type);
+ void Initialize();
+
+ protected:
+ bool isSystemInit;
+ uint16 max_pool_id;
+ typedef std::vector<PoolTemplateData> PoolTemplateDataMap;
+ typedef std::vector<PoolGroup<Creature> > PoolGroupCreatureMap;
+ typedef std::vector<PoolGroup<GameObject> > PoolGroupGameObjectMap;
+ typedef std::vector<PoolGroup<Pool> > PoolGroupPoolMap;
+ typedef std::pair<uint32, uint16> SearchPair;
+ typedef std::map<uint32, uint16> SearchMap;
+
+ PoolTemplateDataMap mPoolTemplate;
+ PoolGroupCreatureMap mPoolCreatureGroups;
+ PoolGroupGameObjectMap mPoolGameobjectGroups;
+ PoolGroupPoolMap mPoolPoolGroups;
+ SearchMap mCreatureSearchMap;
+ SearchMap mGameobjectSearchMap;
+ SearchMap mPoolSearchMap;
+
+};
+
+#define poolhandler MaNGOS::Singleton<PoolHandler>::Instance()
+#endif
diff --git a/src/game/PossessedAI.cpp b/src/game/PossessedAI.cpp
index bda0de88882..8fd2e5ca014 100644
--- a/src/game/PossessedAI.cpp
+++ b/src/game/PossessedAI.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/game/PossessedAI.h b/src/game/PossessedAI.h
index bbfacb6454c..bef7853246e 100644
--- a/src/game/PossessedAI.h
+++ b/src/game/PossessedAI.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/game/QueryHandler.cpp b/src/game/QueryHandler.cpp
index 6a99703dbc4..bdb02913f59 100644
--- a/src/game/QueryHandler.cpp
+++ b/src/game/QueryHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -31,8 +31,8 @@
#include "Player.h"
#include "UpdateMask.h"
#include "NPCHandler.h"
-#include "ObjectAccessor.h"
#include "Pet.h"
+#include "MapManager.h"
void WorldSession::SendNameQueryOpcode(Player *p)
{
@@ -102,20 +102,20 @@ void WorldSession::SendNameQueryOpcodeFromDBCallBack(QueryResult *result, uint32
WorldPacket data( SMSG_NAME_QUERY_RESPONSE, (8+1+4+4+4+10) );
data << MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER);
data << name;
- data << (uint8)0;
- data << (uint32)(field & 0xFF);
- data << (uint32)((field >> 16) & 0xFF);
- data << (uint32)((field >> 8) & 0xFF);
+ data << uint8(0);
+ data << uint32(field & 0xFF);
+ data << uint32((field >> 16) & 0xFF);
+ data << uint32((field >> 8) & 0xFF);
// if the first declined name field (3) is empty, the rest must be too
if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) && fields[3].GetCppString() != "")
{
- data << (uint8)1; // is declined
+ data << uint8(1); // is declined
for(int i = 3; i < MAX_DECLINED_NAME_CASES+3; ++i)
data << fields[i].GetCppString();
}
else
- data << (uint8)0; // is declined
+ data << uint8(0); // is declined
session->SendPacket( &data );
delete result;
@@ -123,7 +123,7 @@ void WorldSession::SendNameQueryOpcodeFromDBCallBack(QueryResult *result, uint32
void WorldSession::HandleNameQueryOpcode( WorldPacket & recv_data )
{
- CHECK_PACKET_SIZE(recv_data,8);
+ CHECK_PACKET_SIZE(recv_data, 8);
uint64 guid;
@@ -176,24 +176,22 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data )
sLog.outDetail("WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name, entry);
// guess size
WorldPacket data( SMSG_CREATURE_QUERY_RESPONSE, 100 );
- data << (uint32)entry; // creature entry
+ data << uint32(entry); // creature entry
data << Name;
data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty
data << SubName;
data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0
- data << (uint32)ci->type_flags; // flags wdbFeild7=wad flags1
- data << (uint32)ci->type;
- data << (uint32)ci->family; // family wdbFeild9
- data << (uint32)ci->rank; // rank wdbFeild10
- data << (uint32)0; // unknown wdbFeild11
- data << (uint32)ci->PetSpellDataId; // Id from CreatureSpellData.dbc wdbField12
+ data << uint32(ci->type_flags); // flags wdbFeild7=wad flags1
+ data << uint32(ci->type);
+ data << uint32(ci->family); // family wdbFeild9
+ data << uint32(ci->rank); // rank wdbFeild10
+ data << uint32(ci->PetSpellDataId); // Id from CreatureSpellData.dbc wdbField12
data << (uint32)ci->Modelid_A1; // Modelid_A1
data << (uint32)ci->Modelid_A2; // Modelid_A2
data << (uint32)ci->Modelid_H1; // Modelid_H1
data << (uint32)ci->Modelid_H2; // Modelid_H2
- data << (float)1.0f; // unk
- data << (float)1.0f; // unk
- data << (uint8)ci->RacialLeader;
+ data << float(ci->unk17); // unk
+ data << uint8(ci->RacialLeader);
SendPacket( &data );
sLog.outDebug( "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE " );
}
@@ -207,7 +205,7 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data )
WorldPacket data( SMSG_CREATURE_QUERY_RESPONSE, 4 );
data << uint32(entry | 0x80000000);
SendPacket( &data );
- sLog.outDebug( "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE " );
+ sLog.outDebug( "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE " );
}
}
@@ -224,9 +222,11 @@ void WorldSession::HandleGameObjectQueryOpcode( WorldPacket & recv_data )
{
std::string Name;
+ std::string IconName;
std::string CastBarCaption;
Name = info->name;
+ IconName = info->IconName;
CastBarCaption = info->castBarCaption;
int loc_idx = GetSessionDbLocaleIndex();
@@ -243,15 +243,16 @@ void WorldSession::HandleGameObjectQueryOpcode( WorldPacket & recv_data )
}
sLog.outDetail("WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name, entryID);
WorldPacket data ( SMSG_GAMEOBJECT_QUERY_RESPONSE, 150 );
- data << entryID;
- data << (uint32)info->type;
- data << (uint32)info->displayId;
+ data << uint32(entryID);
+ data << uint32(info->type);
+ data << uint32(info->displayId);
data << Name;
data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4
- data << uint8(0); // 2.0.3, string
+ data << IconName; // 2.0.3, string. Icon name to use instead of default icon for go's (ex: "Attack" makes sword)
data << CastBarCaption; // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting")
- data << uint8(0); // 2.0.3, probably string
- data.append(info->raw.data,24);
+ data << uint8(0); // 2.0.3, string
+ data.append(info->raw.data, 24);
+ data << float(info->size); // go size
SendPacket( &data );
sLog.outDebug( "WORLD: Sent CMSG_GAMEOBJECT_QUERY " );
}
@@ -276,20 +277,43 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/)
Corpse *corpse = GetPlayer()->GetCorpse();
- uint8 found = 1;
if(!corpse)
- found = 0;
+ {
+ WorldPacket data(MSG_CORPSE_QUERY, 1);
+ data << uint8(0); // corpse not found
+ SendPacket(&data);
+ return;
+ }
- WorldPacket data(MSG_CORPSE_QUERY, (1+found*(5*4)));
- data << uint8(found);
- if(found)
+ int32 mapid = corpse->GetMapId();
+ float x = corpse->GetPositionX();
+ float y = corpse->GetPositionY();
+ float z = corpse->GetPositionZ();
+ int32 corpsemapid = _player->GetMapId();
+
+ if(Map *map = MapManager::Instance().FindMap(corpse->GetMapId(), corpse->GetInstanceId()))
{
- data << corpse->GetMapId();
- data << corpse->GetPositionX();
- data << corpse->GetPositionY();
- data << corpse->GetPositionZ();
- data << _player->GetMapId();
+ if(map->IsDungeon())
+ {
+ if(!map->GetEntrancePos(mapid, x, y))
+ return;
+
+ Map *entrance_map = MapManager::Instance().GetMap(mapid, _player);
+ if(!entrance_map)
+ return;
+
+ z = entrance_map->GetHeight(x, y, MAX_HEIGHT);
+ corpsemapid = corpse->GetMapId();
+ }
}
+
+ WorldPacket data(MSG_CORPSE_QUERY, 1+(5*4));
+ data << uint8(1); // corpse found
+ data << int32(mapid);
+ data << float(x);
+ data << float(y);
+ data << float(z);
+ data << int32(corpsemapid);
SendPacket(&data);
}
@@ -299,8 +323,6 @@ void WorldSession::HandleNpcTextQueryOpcode( WorldPacket & recv_data )
uint32 textID;
uint64 guid;
- GossipText *pGossip;
- std::string GossipStr;
recv_data >> textID;
sLog.outDetail("WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID);
@@ -308,7 +330,7 @@ void WorldSession::HandleNpcTextQueryOpcode( WorldPacket & recv_data )
recv_data >> guid;
GetPlayer()->SetUInt64Value(UNIT_FIELD_TARGET, guid);
- pGossip = objmgr.GetGossipText(textID);
+ GossipText const* pGossip = objmgr.GetGossipText(textID);
WorldPacket data( SMSG_NPC_TEXT_UPDATE, 100 ); // guess size
data << textID;
@@ -332,7 +354,7 @@ void WorldSession::HandleNpcTextQueryOpcode( WorldPacket & recv_data )
else
{
std::string Text_0[8], Text_1[8];
- for (int i=0;i<8;i++)
+ for (int i=0;i<8;++i)
{
Text_0[i]=pGossip->Options[i].Text_0;
Text_1[i]=pGossip->Options[i].Text_1;
@@ -344,7 +366,7 @@ void WorldSession::HandleNpcTextQueryOpcode( WorldPacket & recv_data )
NpcTextLocale const *nl = objmgr.GetNpcTextLocale(textID);
if (nl)
{
- for (int i=0;i<8;i++)
+ for (int i=0;i<8;++i)
{
if (nl->Text_0[i].size() > loc_idx && !nl->Text_0[i][loc_idx].empty())
Text_0[i]=nl->Text_0[i][loc_idx];
@@ -354,7 +376,7 @@ void WorldSession::HandleNpcTextQueryOpcode( WorldPacket & recv_data )
}
}
- for (int i=0; i<8; i++)
+ for (int i=0; i<8; ++i)
{
data << pGossip->Options[i].Probability;
@@ -370,14 +392,11 @@ void WorldSession::HandleNpcTextQueryOpcode( WorldPacket & recv_data )
data << pGossip->Options[i].Language;
- data << pGossip->Options[i].Emotes[0]._Delay;
- data << pGossip->Options[i].Emotes[0]._Emote;
-
- data << pGossip->Options[i].Emotes[1]._Delay;
- data << pGossip->Options[i].Emotes[1]._Emote;
-
- data << pGossip->Options[i].Emotes[2]._Delay;
- data << pGossip->Options[i].Emotes[2]._Emote;
+ for(int j = 0; j < 3; ++j)
+ {
+ data << pGossip->Options[i].Emotes[j]._Delay;
+ data << pGossip->Options[i].Emotes[j]._Emote;
+ }
}
}
diff --git a/src/game/QuestDef.cpp b/src/game/QuestDef.cpp
index 3e190d67220..8099bf40e88 100644
--- a/src/game/QuestDef.cpp
+++ b/src/game/QuestDef.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -44,88 +44,87 @@ Quest::Quest(Field * questRecord)
QuestFlags = questRecord[17].GetUInt16();
uint32 SpecialFlags = questRecord[18].GetUInt16();
CharTitleId = questRecord[19].GetUInt32();
- PrevQuestId = questRecord[20].GetInt32();
- NextQuestId = questRecord[21].GetInt32();
- ExclusiveGroup = questRecord[22].GetInt32();
- NextQuestInChain = questRecord[23].GetUInt32();
- SrcItemId = questRecord[24].GetUInt32();
- SrcItemCount = questRecord[25].GetUInt32();
- SrcSpell = questRecord[26].GetUInt32();
- Title = questRecord[27].GetCppString();
- Details = questRecord[28].GetCppString();
- Objectives = questRecord[29].GetCppString();
- OfferRewardText = questRecord[30].GetCppString();
- RequestItemsText = questRecord[31].GetCppString();
- EndText = questRecord[32].GetCppString();
+ PlayersSlain = questRecord[20].GetUInt32();
+ BonusTalents = questRecord[21].GetUInt32();
+ PrevQuestId = questRecord[22].GetInt32();
+ NextQuestId = questRecord[23].GetInt32();
+ ExclusiveGroup = questRecord[24].GetInt32();
+ NextQuestInChain = questRecord[25].GetUInt32();
+ SrcItemId = questRecord[26].GetUInt32();
+ SrcItemCount = questRecord[27].GetUInt32();
+ SrcSpell = questRecord[28].GetUInt32();
+ Title = questRecord[29].GetCppString();
+ Details = questRecord[30].GetCppString();
+ Objectives = questRecord[31].GetCppString();
+ OfferRewardText = questRecord[32].GetCppString();
+ RequestItemsText = questRecord[33].GetCppString();
+ EndText = questRecord[34].GetCppString();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ObjectiveText[i] = questRecord[33+i].GetCppString();
+ ObjectiveText[i] = questRecord[35+i].GetCppString();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ReqItemId[i] = questRecord[37+i].GetUInt32();
+ ReqItemId[i] = questRecord[39+i].GetUInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ReqItemCount[i] = questRecord[41+i].GetUInt32();
+ ReqItemCount[i] = questRecord[43+i].GetUInt32();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
- ReqSourceId[i] = questRecord[45+i].GetUInt32();
+ ReqSourceId[i] = questRecord[47+i].GetUInt32();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
- ReqSourceCount[i] = questRecord[49+i].GetUInt32();
-
- for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
- ReqSourceRef[i] = questRecord[53+i].GetUInt32();
+ ReqSourceCount[i] = questRecord[51+i].GetUInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ReqCreatureOrGOId[i] = questRecord[57+i].GetInt32();
+ ReqCreatureOrGOId[i] = questRecord[55+i].GetInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ReqCreatureOrGOCount[i] = questRecord[61+i].GetUInt32();
+ ReqCreatureOrGOCount[i] = questRecord[59+i].GetUInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ReqSpell[i] = questRecord[65+i].GetUInt32();
+ ReqSpell[i] = questRecord[63+i].GetUInt32();
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
- RewChoiceItemId[i] = questRecord[69+i].GetUInt32();
+ RewChoiceItemId[i] = questRecord[67+i].GetUInt32();
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
- RewChoiceItemCount[i] = questRecord[75+i].GetUInt32();
+ RewChoiceItemCount[i] = questRecord[73+i].GetUInt32();
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
- RewItemId[i] = questRecord[81+i].GetUInt32();
+ RewItemId[i] = questRecord[79+i].GetUInt32();
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
- RewItemCount[i] = questRecord[85+i].GetUInt32();
+ RewItemCount[i] = questRecord[83+i].GetUInt32();
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
- RewRepFaction[i] = questRecord[89+i].GetUInt32();
+ RewRepFaction[i] = questRecord[87+i].GetUInt32();
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
- RewRepValue[i] = questRecord[94+i].GetInt32();
-
- RewHonorableKills = questRecord[99].GetUInt32();
- RewOrReqMoney = questRecord[100].GetInt32();
- RewMoneyMaxLevel = questRecord[101].GetUInt32();
- RewSpell = questRecord[102].GetUInt32();
- RewSpellCast = questRecord[103].GetUInt32();
- RewMailTemplateId = questRecord[104].GetUInt32();
- RewMailDelaySecs = questRecord[105].GetUInt32();
- PointMapId = questRecord[106].GetUInt32();
- PointX = questRecord[107].GetFloat();
- PointY = questRecord[108].GetFloat();
- PointOpt = questRecord[109].GetUInt32();
+ RewRepValue[i] = questRecord[92+i].GetInt32();
+
+ RewHonorableKills = questRecord[97].GetUInt32();
+ RewOrReqMoney = questRecord[98].GetInt32();
+ RewMoneyMaxLevel = questRecord[99].GetUInt32();
+ RewSpell = questRecord[100].GetUInt32();
+ RewSpellCast = questRecord[101].GetUInt32();
+ RewMailTemplateId = questRecord[102].GetUInt32();
+ RewMailDelaySecs = questRecord[103].GetUInt32();
+ PointMapId = questRecord[104].GetUInt32();
+ PointX = questRecord[105].GetFloat();
+ PointY = questRecord[106].GetFloat();
+ PointOpt = questRecord[107].GetUInt32();
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
- DetailsEmote[i] = questRecord[110+i].GetUInt32();
+ DetailsEmote[i] = questRecord[108+i].GetUInt32();
- IncompleteEmote = questRecord[114].GetUInt32();
- CompleteEmote = questRecord[115].GetUInt32();
+ IncompleteEmote = questRecord[112].GetUInt32();
+ CompleteEmote = questRecord[113].GetUInt32();
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
- OfferRewardEmote[i] = questRecord[116+i].GetInt32();
+ OfferRewardEmote[i] = questRecord[114+i].GetInt32();
- QuestStartScript = questRecord[120].GetUInt32();
- QuestCompleteScript = questRecord[121].GetUInt32();
+ QuestStartScript = questRecord[118].GetUInt32();
+ QuestCompleteScript = questRecord[119].GetUInt32();
QuestFlags |= SpecialFlags << 16;
@@ -134,7 +133,7 @@ Quest::Quest(Field * questRecord)
m_rewitemscount = 0;
m_rewchoiceitemscount = 0;
- for (int i=0; i < QUEST_OBJECTIVES_COUNT; i++)
+ for (int i=0; i < QUEST_OBJECTIVES_COUNT; ++i)
{
if ( ReqItemId[i] )
++m_reqitemscount;
@@ -142,13 +141,13 @@ Quest::Quest(Field * questRecord)
++m_reqCreatureOrGOcount;
}
- for (int i=0; i < QUEST_REWARDS_COUNT; i++)
+ for (int i=0; i < QUEST_REWARDS_COUNT; ++i)
{
if ( RewItemId[i] )
++m_rewitemscount;
}
- for (int i=0; i < QUEST_REWARD_CHOICES_COUNT; i++)
+ for (int i=0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
{
if (RewChoiceItemId[i])
++m_rewchoiceitemscount;
@@ -164,18 +163,20 @@ uint32 Quest::XPValue( Player *pPlayer ) const
uint32 pLevel = pPlayer->getLevel();
uint32 qLevel = QuestLevel;
float fullxp = 0;
- if (qLevel >= 65)
+ if (qLevel >= 15)
fullxp = RewMoneyMaxLevel / 6.0f;
- else if (qLevel == 64)
+ else if (qLevel == 14)
fullxp = RewMoneyMaxLevel / 4.8f;
- else if (qLevel == 63)
- fullxp = RewMoneyMaxLevel / 3.6f;
- else if (qLevel == 62)
+ else if (qLevel == 13)
+ fullxp = RewMoneyMaxLevel / 3.666f;
+ else if (qLevel == 12)
fullxp = RewMoneyMaxLevel / 2.4f;
- else if (qLevel == 61)
+ else if (qLevel == 11)
fullxp = RewMoneyMaxLevel / 1.2f;
- else if (qLevel > 0 && qLevel <= 60)
+ else if (qLevel >= 1 && qLevel <= 10)
fullxp = RewMoneyMaxLevel / 0.6f;
+ else if (qLevel == 0)
+ fullxp = RewMoneyMaxLevel;
if( pLevel <= qLevel + 5 )
return (uint32)fullxp;
diff --git a/src/game/QuestDef.h b/src/game/QuestDef.h
index 7b447c611c2..242c10bf48f 100644
--- a/src/game/QuestDef.h
+++ b/src/game/QuestDef.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -44,30 +44,33 @@ class ObjectMgr;
enum QuestFailedReasons
{
INVALIDREASON_DONT_HAVE_REQ = 0,
- INVALIDREASON_QUEST_FAILED_LOW_LEVEL = 1, //You are not high enough level for that quest.
- INVALIDREASON_QUEST_FAILED_WRONG_RACE = 6, //That quest is not available to your race.
- INVALIDREASON_QUEST_ALREADY_DONE = 7, //You have completed that quest.
- INVALIDREASON_QUEST_ONLY_ONE_TIMED = 12, //You can only be on one timed quest at a time.
- INVALIDREASON_QUEST_ALREADY_ON = 13, //You are already on that quest
- INVALIDREASON_QUEST_FAILED_EXPANSION = 16, //This quest requires an expansion enabled account.
- INVALIDREASON_QUEST_ALREADY_ON2 = 18, //You are already on that quest
- INVALIDREASON_QUEST_FAILED_MISSING_ITEMS = 21, //You don't have the required items with you. Check storage.
- INVALIDREASON_QUEST_FAILED_NOT_ENOUGH_MONEY = 23, //You don't have enough money for that quest.
- INVALIDREASON_DAILY_QUESTS_REMAINING = 26, //You have already completed 10 daily quests today
- INVALIDREASON_QUEST_FAILED_CAIS = 27, //You cannot complete quests once you have reached tired time
+ INVALIDREASON_QUEST_FAILED_LOW_LEVEL = 1, // You are not high enough level for that quest.
+ INVALIDREASON_QUEST_FAILED_WRONG_RACE = 6, // That quest is not available to your race.
+ INVALIDREASON_QUEST_ALREADY_DONE = 7, // You have completed that quest.
+ INVALIDREASON_QUEST_ONLY_ONE_TIMED = 12, // You can only be on one timed quest at a time.
+ INVALIDREASON_QUEST_ALREADY_ON = 13, // You are already on that quest.
+ INVALIDREASON_QUEST_FAILED_EXPANSION = 16, // This quest requires an expansion enabled account.
+ INVALIDREASON_QUEST_ALREADY_ON2 = 18, // You are already on that quest.
+ INVALIDREASON_QUEST_FAILED_MISSING_ITEMS = 21, // You don't have the required items with you. Check storage.
+ INVALIDREASON_QUEST_FAILED_NOT_ENOUGH_MONEY = 23, // You don't have enough money for that quest.
+ INVALIDREASON_DAILY_QUESTS_REMAINING = 26, // You have already completed 25 daily quests today.
+ INVALIDREASON_QUEST_FAILED_CAIS = 27, // You cannot complete quests once you have reached tired time.
+ INVALIDREASON_DAILY_QUEST_COMPLETED_TODAY = 29 // You have completed that daily quest today.
};
enum QuestShareMessages
{
- QUEST_PARTY_MSG_SHARING_QUEST = 0,
- QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1,
- QUEST_PARTY_MSG_ACCEPT_QUEST = 2,
- QUEST_PARTY_MSG_REFUSE_QUEST = 3,
- QUEST_PARTY_MSG_TOO_FAR = 4,
- QUEST_PARTY_MSG_BUSY = 5,
- QUEST_PARTY_MSG_LOG_FULL = 6,
- QUEST_PARTY_MSG_HAVE_QUEST = 7,
- QUEST_PARTY_MSG_FINISH_QUEST = 8,
+ QUEST_PARTY_MSG_SHARING_QUEST = 0,
+ QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1,
+ QUEST_PARTY_MSG_ACCEPT_QUEST = 2,
+ QUEST_PARTY_MSG_DECLINE_QUEST = 3,
+ QUEST_PARTY_MSG_BUSY = 4,
+ QUEST_PARTY_MSG_LOG_FULL = 5,
+ QUEST_PARTY_MSG_HAVE_QUEST = 6,
+ QUEST_PARTY_MSG_FINISH_QUEST = 7,
+ QUEST_PARTY_MSG_CANT_BE_SHARED_TODAY = 8,
+ QUEST_PARTY_MSG_SHARING_TIMER_EXPIRED = 9,
+ QUEST_PARTY_MSG_NOT_IN_PARTY = 10
};
enum __QuestTradeSkill
@@ -122,7 +125,7 @@ enum __QuestFlags
//QUEST_FLAGS_NONE2 = 0x00000010, // Not used currently
QUEST_FLAGS_EPIC = 0x00000020, // Not used currently: Unsure of content
QUEST_FLAGS_RAID = 0x00000040, // Not used currently
- QUEST_FLAGS_TBC = 0x00000080, // Not used currently: Available if TBC expension enabled only
+ QUEST_FLAGS_TBC = 0x00000080, // Not used currently: Available if TBC expansion enabled only
QUEST_FLAGS_UNK2 = 0x00000100, // Not used currently: _DELIVER_MORE Quest needs more than normal _q-item_ drops from mobs
QUEST_FLAGS_HIDDEN_REWARDS = 0x00000200, // Items and money rewarded only sent in SMSG_QUESTGIVER_OFFER_REWARD (not in SMSG_QUESTGIVER_QUEST_DETAILS or in client quest log(SMSG_QUEST_QUERY_RESPONSE))
QUEST_FLAGS_AUTO_REWARDED = 0x00000400, // These quests are automatically rewarded on quest complete and they will never appear in quest log client side.
@@ -190,6 +193,8 @@ class Quest
int32 GetExclusiveGroup() const { return ExclusiveGroup; }
uint32 GetNextQuestInChain() const { return NextQuestInChain; }
uint32 GetCharTitleId() const { return CharTitleId; }
+ uint32 GetPlayersSlain() const { return PlayersSlain; }
+ uint32 GetBonusTalents() const { return BonusTalents; }
uint32 GetSrcItemId() const { return SrcItemId; }
uint32 GetSrcItemCount() const { return SrcItemCount; }
uint32 GetSrcSpell() const { return SrcSpell; }
@@ -226,7 +231,6 @@ class Quest
uint32 ReqItemCount[QUEST_OBJECTIVES_COUNT];
uint32 ReqSourceId[QUEST_SOURCE_ITEM_IDS_COUNT];
uint32 ReqSourceCount[QUEST_SOURCE_ITEM_IDS_COUNT];
- uint32 ReqSourceRef[QUEST_SOURCE_ITEM_IDS_COUNT];
int32 ReqCreatureOrGOId[QUEST_OBJECTIVES_COUNT]; // >0 Creature <0 Gameobject
uint32 ReqCreatureOrGOCount[QUEST_OBJECTIVES_COUNT];
uint32 ReqSpell[QUEST_OBJECTIVES_COUNT];
@@ -277,6 +281,8 @@ class Quest
uint32 LimitTime;
uint32 QuestFlags;
uint32 CharTitleId;
+ uint32 PlayersSlain;
+ uint32 BonusTalents;
int32 PrevQuestId;
int32 NextQuestId;
int32 ExclusiveGroup;
diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp
index c447b170d4c..7decc561779 100644
--- a/src/game/QuestHandler.cpp
+++ b/src/game/QuestHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -91,7 +91,7 @@ void WorldSession::HandleQuestgiverHelloOpcode( WorldPacket & recv_data )
sLog.outDebug ("WORLD: Received CMSG_QUESTGIVER_HELLO npc = %u", GUID_LOPART(guid));
- Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_NONE);
+ Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_NONE);
if (!pCreature)
{
sLog.outDebug ("WORLD: HandleQuestgiverHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.",
@@ -101,7 +101,7 @@ void WorldSession::HandleQuestgiverHelloOpcode( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
// Stop the npc if moving
pCreature->StopMoving();
@@ -178,9 +178,9 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data )
// destroy not required for quest finish quest starting item
bool destroyItem = true;
- for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
+ for(int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
{
- if ((qInfo->ReqItemId[i] == ((Item*)pObject)->GetEntry()) && (((Item*)pObject)->GetProto()->MaxCount != 0))
+ if ((qInfo->ReqItemId[i] == ((Item*)pObject)->GetEntry()) && (((Item*)pObject)->GetProto()->MaxCount > 0))
{
destroyItem = false;
break;
@@ -451,12 +451,6 @@ void WorldSession::HandleQuestPushToParty(WorldPacket& recvPacket)
_player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_SHARING_QUEST);
- if( _player->GetDistance( pPlayer ) > 10 )
- {
- _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_TOO_FAR );
- continue;
- }
-
if( !pPlayer->SatisfyQuestStatus( pQuest, false ) )
{
_player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_HAVE_QUEST );
@@ -586,7 +580,7 @@ uint32 WorldSession::getDialogStatus(Player *pPlayer, Object* questgiver, uint32
{
if ( pQuest->IsAutoComplete() || (pQuest->IsRepeatable() && pPlayer->getQuestStatusMap()[quest_id].m_rewarded))
result2 = DIALOG_STATUS_REWARD_REP;
- else if (pPlayer->getLevel() <= pQuest->GetQuestLevel() + sWorld.getConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF) )
+ else if (pPlayer->getLevel() <= pPlayer->GetQuestLevel(pQuest) + sWorld.getConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF) )
{
if (pQuest->HasFlag(QUEST_FLAGS_DAILY))
result2 = DIALOG_STATUS_AVAILABLE_REP;
@@ -620,14 +614,14 @@ void WorldSession::HandleQuestgiverStatusQueryMultipleOpcode(WorldPacket& /*recv
WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 4);
data << uint32(count); // placeholder
- for(Player::ClientGUIDs::iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr)
+ for(Player::ClientGUIDs::const_iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr)
{
uint8 questStatus = DIALOG_STATUS_NONE;
uint8 defstatus = DIALOG_STATUS_NONE;
if(IS_CREATURE_GUID(*itr))
{
- Creature *questgiver = ObjectAccessor::GetCreature(*_player, *itr);
+ Creature *questgiver = GetPlayer()->GetMap()->GetCreature(*itr);
if(!questgiver || questgiver->IsHostileTo(_player))
continue;
if(!questgiver->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER))
@@ -642,7 +636,7 @@ void WorldSession::HandleQuestgiverStatusQueryMultipleOpcode(WorldPacket& /*recv
}
else if(IS_GAMEOBJECT_GUID(*itr))
{
- GameObject *questgiver = ObjectAccessor::GetGameObject(*_player, *itr);
+ GameObject *questgiver = GetPlayer()->GetMap()->GetGameObject(*itr);
if(!questgiver)
continue;
if(questgiver->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER)
diff --git a/src/game/RandomMovementGenerator.cpp b/src/game/RandomMovementGenerator.cpp
index cb748883772..0081c702abd 100644
--- a/src/game/RandomMovementGenerator.cpp
+++ b/src/game/RandomMovementGenerator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -26,6 +26,7 @@
#include "DestinationHolderImp.h"
#include "Map.h"
#include "Util.h"
+#include "CreatureGroups.h"
#define RUNNING_CHANCE_RANDOMMV 20 //will be "1 / RUNNING_CHANCE_RANDOMMV"
@@ -114,6 +115,12 @@ RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(),5000+i_destinationHolder.GetTotalTravelTime()));
creature.SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
}
+
+ //Call for creature group update
+ if(creature.GetFormation() && creature.GetFormation()->getLeader() == &creature)
+ {
+ creature.GetFormation()->LeaderMoveTo(nx, ny, nz);
+ }
}
template<>
diff --git a/src/game/RandomMovementGenerator.h b/src/game/RandomMovementGenerator.h
index a7105284ac6..20afe23d375 100644
--- a/src/game/RandomMovementGenerator.h
+++ b/src/game/RandomMovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/ReactorAI.cpp b/src/game/ReactorAI.cpp
index d15c71b28ef..362a8c9fe56 100644
--- a/src/game/ReactorAI.cpp
+++ b/src/game/ReactorAI.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -50,18 +50,18 @@ ReactorAI::IsVisible(Unit *) const
void
ReactorAI::UpdateAI(const uint32 /*time_diff*/)
{
- // update i_victimGuid if i_creature.getVictim() !=0 and changed
+ // update i_victimGuid if m_creature->getVictim() !=0 and changed
if(!UpdateVictim())
return;
- i_victimGuid = i_creature.getVictim()->GetGUID();
+ i_victimGuid = m_creature->getVictim()->GetGUID();
- if( i_creature.isAttackReady() )
+ if( m_creature->isAttackReady() )
{
- if( i_creature.IsWithinMeleeRange(i_creature.getVictim()))
+ if( m_creature->IsWithinMeleeRange(m_creature->getVictim()))
{
- i_creature.AttackerStateUpdate(i_creature.getVictim());
- i_creature.resetAttackTimer();
+ m_creature->AttackerStateUpdate(m_creature->getVictim());
+ m_creature->resetAttackTimer();
}
}
}
@@ -69,49 +69,49 @@ ReactorAI::UpdateAI(const uint32 /*time_diff*/)
void
ReactorAI::EnterEvadeMode()
{
- if( !i_creature.isAlive() )
+ if( !m_creature->isAlive() )
{
- DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", i_creature.GetGUIDLow());
- i_creature.GetMotionMaster()->MovementExpired();
- i_creature.GetMotionMaster()->MoveIdle();
+ DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow());
+ m_creature->GetMotionMaster()->MovementExpired();
+ m_creature->GetMotionMaster()->MoveIdle();
i_victimGuid = 0;
- i_creature.CombatStop();
- i_creature.DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->DeleteThreatList();
return;
}
- Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid );
+ Unit* victim = ObjectAccessor::GetUnit(*m_creature, i_victimGuid );
if( !victim )
{
- DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", m_creature->GetGUIDLow());
}
else if( victim->HasStealthAura() )
{
- DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", m_creature->GetGUIDLow());
}
else if( victim->isInFlight() )
{
- DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", m_creature->GetGUIDLow());
}
else
{
- DEBUG_LOG("Creature stopped attacking due to target %s [guid=%u]", victim->isAlive() ? "out run him" : "is dead", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking due to target %s [guid=%u]", victim->isAlive() ? "out run him" : "is dead", m_creature->GetGUIDLow());
}
- i_creature.RemoveAllAuras();
- i_creature.DeleteThreatList();
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
i_victimGuid = 0;
- i_creature.CombatStop();
- i_creature.SetLootRecipient(NULL);
+ m_creature->CombatStop(true);
+ m_creature->SetLootRecipient(NULL);
- if(!i_creature.GetCharmerOrOwner())
+ if(!m_creature->GetCharmerOrOwner())
{
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
- if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
- i_creature.GetMotionMaster()->MoveTargetedHome();
+ if( m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
+ m_creature->GetMotionMaster()->MoveTargetedHome();
}
- else if (i_creature.GetOwner() && i_creature.GetOwner()->isAlive())
- i_creature.GetMotionMaster()->MoveFollow(i_creature.GetOwner(),PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
+ else if (m_creature->GetOwner() && m_creature->GetOwner()->isAlive())
+ m_creature->GetMotionMaster()->MoveFollow(m_creature->GetOwner(),PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
}
diff --git a/src/game/ReactorAI.h b/src/game/ReactorAI.h
index a1c99707736..baed6a8e6e1 100644
--- a/src/game/ReactorAI.h
+++ b/src/game/ReactorAI.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -29,7 +29,7 @@ class TRINITY_DLL_DECL ReactorAI : public CreatureAI
{
public:
- ReactorAI(Creature *c) : CreatureAI(c), i_creature(*c), i_victimGuid(0) {}
+ explicit ReactorAI(Creature *c) : CreatureAI(c), i_victimGuid(0) {}
void MoveInLineOfSight(Unit *);
void EnterEvadeMode();
@@ -39,7 +39,6 @@ class TRINITY_DLL_DECL ReactorAI : public CreatureAI
static int Permissible(const Creature *);
private:
- Creature &i_creature;
uint64 i_victimGuid;
};
#endif
diff --git a/src/game/ReputationMgr.cpp b/src/game/ReputationMgr.cpp
new file mode 100644
index 00000000000..62b9504daff
--- /dev/null
+++ b/src/game/ReputationMgr.cpp
@@ -0,0 +1,473 @@
+/*
+ * Copyright (C) 2005-2009 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 "ReputationMgr.h"
+#include "DBCStores.h"
+#include "Player.h"
+#include "WorldPacket.h"
+
+const int32 ReputationMgr::PointsInRank[MAX_REPUTATION_RANK] = {36000, 3000, 3000, 3000, 6000, 12000, 21000, 1000};
+
+ReputationRank ReputationMgr::ReputationToRank(int32 standing)
+{
+ int32 limit = Reputation_Cap + 1;
+ for (int i = MAX_REPUTATION_RANK-1; i >= MIN_REPUTATION_RANK; --i)
+ {
+ limit -= PointsInRank[i];
+ if (standing >= limit )
+ return ReputationRank(i);
+ }
+ return MIN_REPUTATION_RANK;
+}
+
+int32 ReputationMgr::GetReputation(uint32 faction_id) const
+{
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry(faction_id);
+
+ if (!factionEntry)
+ {
+ sLog.outError("ReputationMgr::GetReputation: Can't get reputation of %s for unknown faction (faction id) #%u.",m_player->GetName(), faction_id);
+ return 0;
+ }
+
+ return GetReputation(factionEntry);
+}
+
+int32 ReputationMgr::GetBaseReputation(FactionEntry const* factionEntry) const
+{
+ if (!factionEntry)
+ return 0;
+
+ uint32 raceMask = m_player->getRaceMask();
+ uint32 classMask = m_player->getClassMask();
+ for (int i=0; i < 4; i++)
+ {
+ if( (factionEntry->BaseRepRaceMask[i] & raceMask) &&
+ (factionEntry->BaseRepClassMask[i]==0 ||
+ (factionEntry->BaseRepClassMask[i] & classMask) ) )
+ return factionEntry->BaseRepValue[i];
+ }
+
+ // in faction.dbc exist factions with (RepListId >=0, listed in character reputation list) with all BaseRepRaceMask[i]==0
+ return 0;
+}
+
+int32 ReputationMgr::GetReputation(FactionEntry const* factionEntry) const
+{
+ // Faction without recorded reputation. Just ignore.
+ if(!factionEntry)
+ return 0;
+
+ if(FactionState const* state = GetState(factionEntry))
+ return GetBaseReputation(factionEntry) + state->Standing;
+
+ return 0;
+}
+
+ReputationRank ReputationMgr::GetRank(FactionEntry const* factionEntry) const
+{
+ int32 reputation = GetReputation(factionEntry);
+ return ReputationToRank(reputation);
+}
+
+ReputationRank ReputationMgr::GetBaseRank(FactionEntry const* factionEntry) const
+{
+ int32 reputation = GetBaseReputation(factionEntry);
+ return ReputationToRank(reputation);
+}
+
+void ReputationMgr::ApplyForceReaction( uint32 faction_id,ReputationRank rank,bool apply )
+{
+ if(apply)
+ m_forcedReactions[faction_id] = rank;
+ else
+ m_forcedReactions.erase(faction_id);
+}
+
+uint32 ReputationMgr::GetDefaultStateFlags(FactionEntry const* factionEntry) const
+{
+ if (!factionEntry)
+ return 0;
+
+ uint32 raceMask = m_player->getRaceMask();
+ uint32 classMask = m_player->getClassMask();
+ for (int i=0; i < 4; i++)
+ {
+ if( (factionEntry->BaseRepRaceMask[i] & raceMask) &&
+ (factionEntry->BaseRepClassMask[i]==0 ||
+ (factionEntry->BaseRepClassMask[i] & classMask) ) )
+ return factionEntry->ReputationFlags[i];
+ }
+ return 0;
+}
+
+void ReputationMgr::SendForceReactions()
+{
+ WorldPacket data;
+ data.Initialize(SMSG_SET_FORCED_REACTIONS, 4+m_forcedReactions.size()*(4+4));
+ data << uint32(m_forcedReactions.size());
+ for(ForcedReactions::const_iterator itr = m_forcedReactions.begin(); itr != m_forcedReactions.end(); ++itr)
+ {
+ data << uint32(itr->first); // faction_id (Faction.dbc)
+ data << uint32(itr->second); // reputation rank
+ }
+ m_player->SendDirectMessage(&data);
+}
+
+void ReputationMgr::SendState(FactionState const* faction) const
+{
+ if(faction->Flags & FACTION_FLAG_VISIBLE) //If faction is visible then update it
+ {
+ WorldPacket data(SMSG_SET_FACTION_STANDING, (16)); // last check 2.4.0
+ data << (float) 0; // unk 2.4.0
+ data << (uint8) 0; // wotlk 8634
+ data << (uint32) 1; // count
+ // for
+ data << (uint32) faction->ReputationListID;
+ data << (uint32) faction->Standing;
+ // end for
+ m_player->SendDirectMessage(&data);
+ }
+}
+
+void ReputationMgr::SendInitialReputations()
+{
+ WorldPacket data(SMSG_INITIALIZE_FACTIONS, (4+128*5));
+ data << uint32 (0x00000080);
+
+ RepListID a = 0;
+
+ for (FactionStateList::const_iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr)
+ {
+ // fill in absent fields
+ for (; a != itr->first; a++)
+ {
+ data << uint8 (0x00);
+ data << uint32 (0x00000000);
+ }
+
+ // fill in encountered data
+ data << uint8 (itr->second.Flags);
+ data << uint32 (itr->second.Standing);
+
+ ++a;
+ }
+
+ // fill in absent fields
+ for (; a != 128; a++)
+ {
+ data << uint8 (0x00);
+ data << uint32 (0x00000000);
+ }
+
+ m_player->SendDirectMessage(&data);
+}
+
+void ReputationMgr::SendStates() const
+{
+ for(FactionStateList::const_iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr)
+ SendState(&(itr->second));
+}
+
+void ReputationMgr::SendVisible(FactionState const* faction) const
+{
+ if(m_player->GetSession()->PlayerLoading())
+ return;
+
+ // make faction visible in reputation list at client
+ WorldPacket data(SMSG_SET_FACTION_VISIBLE, 4);
+ data << faction->ReputationListID;
+ m_player->SendDirectMessage(&data);
+}
+
+void ReputationMgr::Initilize()
+{
+ m_factions.clear();
+ m_visibleFactionCount = 0;
+ m_honoredFactionCount = 0;
+ m_reveredFactionCount = 0;
+ m_exaltedFactionCount = 0;
+
+ for(unsigned int i = 1; i < sFactionStore.GetNumRows(); i++)
+ {
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry(i);
+
+ if( factionEntry && (factionEntry->reputationListID >= 0))
+ {
+ FactionState newFaction;
+ newFaction.ID = factionEntry->ID;
+ newFaction.ReputationListID = factionEntry->reputationListID;
+ newFaction.Standing = 0;
+ newFaction.Flags = GetDefaultStateFlags(factionEntry);
+ newFaction.Changed = true;
+
+ if( newFaction.Flags & FACTION_FLAG_VISIBLE )
+ ++m_visibleFactionCount;
+
+ UpdateRankCounters(REP_HOSTILE,GetBaseRank(factionEntry));
+
+ m_factions[newFaction.ReputationListID] = newFaction;
+ }
+ }
+}
+
+bool ReputationMgr::SetReputation(FactionEntry const* factionEntry, int32 standing, bool incremental)
+{
+ SimpleFactionsList const* flist = GetFactionTeamList(factionEntry->ID);
+ if (flist)
+ {
+ bool res = false;
+ for (SimpleFactionsList::const_iterator itr = flist->begin();itr != flist->end();++itr)
+ {
+ FactionEntry const *factionEntryCalc = sFactionStore.LookupEntry(*itr);
+ if(factionEntryCalc)
+ res = SetOneFactionReputation(factionEntryCalc, standing, incremental);
+ }
+ return res;
+ }
+ else
+ return SetOneFactionReputation(factionEntry, standing, incremental);
+}
+
+bool ReputationMgr::SetOneFactionReputation(FactionEntry const* factionEntry, int32 standing, bool incremental)
+{
+ FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID);
+ if (itr != m_factions.end())
+ {
+ int32 BaseRep = GetBaseReputation(factionEntry);
+
+ if(incremental)
+ standing += itr->second.Standing + BaseRep;
+
+ if (standing > Reputation_Cap)
+ standing = Reputation_Cap;
+ else if (standing < Reputation_Bottom)
+ standing = Reputation_Bottom;
+
+ ReputationRank old_rank = ReputationToRank(itr->second.Standing + BaseRep);
+ ReputationRank new_rank = ReputationToRank(standing);
+
+ itr->second.Standing = standing - BaseRep;
+ itr->second.Changed = true;
+
+ SetVisible(&itr->second);
+
+ if(new_rank <= REP_HOSTILE)
+ SetAtWar(&itr->second,true);
+
+ SendState(&itr->second);
+
+ UpdateRankCounters(old_rank, new_rank);
+
+ m_player->ReputationChanged(factionEntry);
+ m_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS, factionEntry->ID);
+ m_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION, factionEntry->ID);
+ m_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION,factionEntry->ID);
+ m_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION,factionEntry->ID);
+ m_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION,factionEntry->ID);
+
+ return true;
+ }
+ return false;
+}
+
+void ReputationMgr::SetVisible(FactionTemplateEntry const*factionTemplateEntry)
+{
+ if(!factionTemplateEntry->faction)
+ return;
+
+ if(FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionTemplateEntry->faction))
+ SetVisible(factionEntry);
+}
+
+void ReputationMgr::SetVisible(FactionEntry const *factionEntry)
+{
+ if(factionEntry->reputationListID < 0)
+ return;
+
+ FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID);
+ if (itr == m_factions.end())
+ return;
+
+ SetVisible(&itr->second);
+}
+
+void ReputationMgr::SetVisible(FactionState* faction)
+{
+ // always invisible or hidden faction can't be make visible
+ if(faction->Flags & (FACTION_FLAG_INVISIBLE_FORCED|FACTION_FLAG_HIDDEN))
+ return;
+
+ // already set
+ if(faction->Flags & FACTION_FLAG_VISIBLE)
+ return;
+
+ faction->Flags |= FACTION_FLAG_VISIBLE;
+ faction->Changed = true;
+
+ ++m_visibleFactionCount;
+
+ SendVisible(faction);
+}
+
+void ReputationMgr::SetAtWar( RepListID repListID, bool on )
+{
+ FactionStateList::iterator itr = m_factions.find(repListID);
+ if (itr == m_factions.end())
+ return;
+
+ // always invisible or hidden faction can't change war state
+ if(itr->second.Flags & (FACTION_FLAG_INVISIBLE_FORCED|FACTION_FLAG_HIDDEN) )
+ return;
+
+ SetAtWar(&itr->second,on);
+}
+
+void ReputationMgr::SetAtWar(FactionState* faction, bool atWar)
+{
+ // not allow declare war to own faction
+ if(atWar && (faction->Flags & FACTION_FLAG_PEACE_FORCED) )
+ return;
+
+ // already set
+ if(((faction->Flags & FACTION_FLAG_AT_WAR) != 0) == atWar)
+ return;
+
+ if( atWar )
+ faction->Flags |= FACTION_FLAG_AT_WAR;
+ else
+ faction->Flags &= ~FACTION_FLAG_AT_WAR;
+
+ faction->Changed = true;
+}
+
+void ReputationMgr::SetInactive( RepListID repListID, bool on )
+{
+ FactionStateList::iterator itr = m_factions.find(repListID);
+ if (itr == m_factions.end())
+ return;
+
+ SetInactive(&itr->second,on);
+}
+
+void ReputationMgr::SetInactive(FactionState* faction, bool inactive)
+{
+ // always invisible or hidden faction can't be inactive
+ if(inactive && ((faction->Flags & (FACTION_FLAG_INVISIBLE_FORCED|FACTION_FLAG_HIDDEN)) || !(faction->Flags & FACTION_FLAG_VISIBLE) ) )
+ return;
+
+ // already set
+ if(((faction->Flags & FACTION_FLAG_INACTIVE) != 0) == inactive)
+ return;
+
+ if(inactive)
+ faction->Flags |= FACTION_FLAG_INACTIVE;
+ else
+ faction->Flags &= ~FACTION_FLAG_INACTIVE;
+
+ faction->Changed = true;
+}
+
+void ReputationMgr::LoadFromDB(QueryResult *result)
+{
+ // Set initial reputations (so everything is nifty before DB data load)
+ Initilize();
+
+ //QueryResult *result = CharacterDatabase.PQuery("SELECT faction,standing,flags FROM character_reputation WHERE guid = '%u'",GetGUIDLow());
+
+ if(result)
+ {
+ do
+ {
+ Field *fields = result->Fetch();
+
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry(fields[0].GetUInt32());
+ if( factionEntry && (factionEntry->reputationListID >= 0))
+ {
+ FactionState* faction = &m_factions[factionEntry->reputationListID];
+
+ // update standing to current
+ faction->Standing = int32(fields[1].GetUInt32());
+
+ // update counters
+ int32 BaseRep = GetBaseReputation(factionEntry);
+ ReputationRank old_rank = ReputationToRank(BaseRep);
+ ReputationRank new_rank = ReputationToRank(BaseRep + faction->Standing);
+ UpdateRankCounters(old_rank,new_rank);
+
+ uint32 dbFactionFlags = fields[2].GetUInt32();
+
+ if( dbFactionFlags & FACTION_FLAG_VISIBLE )
+ SetVisible(faction); // have internal checks for forced invisibility
+
+ if( dbFactionFlags & FACTION_FLAG_INACTIVE)
+ SetInactive(faction,true); // have internal checks for visibility requirement
+
+ if( dbFactionFlags & FACTION_FLAG_AT_WAR ) // DB at war
+ SetAtWar(faction,true); // have internal checks for FACTION_FLAG_PEACE_FORCED
+ else // DB not at war
+ {
+ // allow remove if visible (and then not FACTION_FLAG_INVISIBLE_FORCED or FACTION_FLAG_HIDDEN)
+ if( faction->Flags & FACTION_FLAG_VISIBLE )
+ SetAtWar(faction,false); // have internal checks for FACTION_FLAG_PEACE_FORCED
+ }
+
+ // set atWar for hostile
+ if(GetRank(factionEntry) <= REP_HOSTILE)
+ SetAtWar(faction,true);
+
+ // reset changed flag if values similar to saved in DB
+ if(faction->Flags==dbFactionFlags)
+ faction->Changed = false;
+ }
+ }
+ while( result->NextRow() );
+
+ delete result;
+ }
+}
+
+void ReputationMgr::SaveToDB()
+{
+ for(FactionStateList::iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr)
+ {
+ if (itr->second.Changed)
+ {
+ CharacterDatabase.PExecute("DELETE FROM character_reputation WHERE guid = '%u' AND faction='%u'", m_player->GetGUIDLow(), itr->second.ID);
+ CharacterDatabase.PExecute("INSERT INTO character_reputation (guid,faction,standing,flags) VALUES ('%u', '%u', '%i', '%u')", m_player->GetGUIDLow(), itr->second.ID, itr->second.Standing, itr->second.Flags);
+ itr->second.Changed = false;
+ }
+ }
+}
+
+void ReputationMgr::UpdateRankCounters( ReputationRank old_rank, ReputationRank new_rank )
+{
+ if(old_rank >= REP_EXALTED)
+ --m_exaltedFactionCount;
+ if(old_rank >= REP_REVERED)
+ --m_reveredFactionCount;
+ if(old_rank >= REP_HONORED)
+ --m_honoredFactionCount;
+
+ if(new_rank >= REP_EXALTED)
+ ++m_exaltedFactionCount;
+ if(new_rank >= REP_REVERED)
+ ++m_reveredFactionCount;
+ if(new_rank >= REP_HONORED)
+ ++m_honoredFactionCount;
+} \ No newline at end of file
diff --git a/src/game/ReputationMgr.h b/src/game/ReputationMgr.h
new file mode 100644
index 00000000000..b81634119df
--- /dev/null
+++ b/src/game/ReputationMgr.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2005-2009 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 __MANGOS_REPUTATION_MGR_H
+#define __MANGOS_REPUTATION_MGR_H
+
+#include "Common.h"
+#include "SharedDefines.h"
+#include "DBCStructure.h"
+#include <map>
+
+enum FactionFlags
+{
+ FACTION_FLAG_VISIBLE = 0x01, // makes visible in client (set or can be set at interaction with target of this faction)
+ FACTION_FLAG_AT_WAR = 0x02, // enable AtWar-button in client. player controlled (except opposition team always war state), Flag only set on initial creation
+ FACTION_FLAG_HIDDEN = 0x04, // hidden faction from reputation pane in client (player can gain reputation, but this update not sent to client)
+ FACTION_FLAG_INVISIBLE_FORCED = 0x08, // always overwrite FACTION_FLAG_VISIBLE and hide faction in rep.list, used for hide opposite team factions
+ FACTION_FLAG_PEACE_FORCED = 0x10, // always overwrite FACTION_FLAG_AT_WAR, used for prevent war with own team factions
+ FACTION_FLAG_INACTIVE = 0x20, // player controlled, state stored in characters.data ( CMSG_SET_FACTION_INACTIVE )
+ FACTION_FLAG_RIVAL = 0x40 // flag for the two competing outland factions
+};
+
+typedef uint32 RepListID;
+struct FactionState
+{
+ uint32 ID;
+ RepListID ReputationListID;
+ uint32 Flags;
+ int32 Standing;
+ bool Changed;
+};
+
+typedef std::map<RepListID,FactionState> FactionStateList;
+typedef std::pair<FactionStateList::const_iterator,FactionStateList::const_iterator> FactionStateListPair;
+
+typedef std::map<uint32,ReputationRank> ForcedReactions;
+
+class Player;
+class QueryResult;
+
+class ReputationMgr
+{
+ public: // constructors and global modifiers
+ explicit ReputationMgr(Player* owner) : m_player(owner),
+ m_visibleFactionCount(0), m_honoredFactionCount(0), m_reveredFactionCount(0), m_exaltedFactionCount(0) {}
+ ~ReputationMgr() {}
+
+ void SaveToDB();
+ void LoadFromDB(QueryResult *result);
+ public: // statics
+ static const int32 PointsInRank[MAX_REPUTATION_RANK];
+ static const int32 Reputation_Cap = 42999;
+ static const int32 Reputation_Bottom = -42000;
+
+ static ReputationRank ReputationToRank(int32 standing);
+ public: // accessors
+ uint8 GetVisibleFactionCount() const { return m_visibleFactionCount; }
+ uint8 GetHonoredFactionCount() const { return m_honoredFactionCount; }
+ uint8 GetReveredFactionCount() const { return m_reveredFactionCount; }
+ uint8 GetExaltedFactionCount() const { return m_exaltedFactionCount; }
+
+ FactionStateList const& GetStateList() const { return m_factions; }
+
+ FactionState const* GetState(FactionEntry const* factionEntry) const
+ {
+ return factionEntry->reputationListID >= 0 ? GetState(factionEntry->reputationListID) : NULL;
+ }
+
+ FactionState const* GetState(RepListID id) const
+ {
+ FactionStateList::const_iterator repItr = m_factions.find (id);
+ return repItr != m_factions.end() ? &repItr->second : NULL;
+ }
+
+ int32 GetReputation(uint32 faction_id) const;
+ int32 GetReputation(FactionEntry const* factionEntry) const;
+ int32 GetBaseReputation(FactionEntry const* factionEntry) const;
+
+ ReputationRank GetRank(FactionEntry const* factionEntry) const;
+ ReputationRank GetBaseRank(FactionEntry const* factionEntry) const;
+
+ ReputationRank const* GetForcedRankIfAny(FactionTemplateEntry const* factionTemplateEntry) const
+ {
+ ForcedReactions::const_iterator forceItr = m_forcedReactions.find(factionTemplateEntry->faction);
+ return forceItr != m_forcedReactions.end() ? &forceItr->second : NULL;
+ }
+
+ public: // modifiers
+ bool SetReputation(FactionEntry const* factionEntry, int32 standing)
+ {
+ return SetReputation(factionEntry, standing, false);
+ }
+ bool ModifyReputation(FactionEntry const* factionEntry, int32 standing)
+ {
+ return SetReputation(factionEntry, standing, true);
+ }
+
+ void SetVisible(FactionTemplateEntry const* factionTemplateEntry);
+ void SetVisible(FactionEntry const* factionEntry);
+ void SetAtWar(RepListID repListID, bool on);
+ void SetInactive(RepListID repListID, bool on);
+
+ void ApplyForceReaction(uint32 faction_id,ReputationRank rank,bool apply);
+
+ public: // senders
+ void SendInitialReputations();
+ void SendForceReactions();
+ void SendState(FactionState const* faction) const;
+ void SendStates() const;
+
+ private: // internal helper functions
+ void Initilize();
+ uint32 GetDefaultStateFlags(const FactionEntry *factionEntry) const;
+ bool SetReputation(FactionEntry const* factionEntry, int32 standing, bool incremental);
+ bool SetOneFactionReputation(FactionEntry const* factionEntry, int32 standing, bool incremental);
+ void SetVisible(FactionState* faction);
+ void SetAtWar(FactionState* faction, bool atWar);
+ void SetInactive(FactionState* faction, bool inactive);
+ void SendVisible(FactionState const* faction) const;
+ void UpdateRankCounters( ReputationRank old_rank, ReputationRank new_rank );
+ private:
+ Player* m_player;
+ FactionStateList m_factions;
+ ForcedReactions m_forcedReactions;
+ uint8 m_visibleFactionCount :8;
+ uint8 m_honoredFactionCount :8;
+ uint8 m_reveredFactionCount :8;
+ uint8 m_exaltedFactionCount :8;
+};
+
+#endif
diff --git a/src/game/ScriptCalls.cpp b/src/game/ScriptCalls.cpp
index 5f3b8a96b0d..fec1afb08ae 100644
--- a/src/game/ScriptCalls.cpp
+++ b/src/game/ScriptCalls.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -78,8 +78,10 @@ bool LoadScriptingModule(char const* libName)
||!(testScript->scriptAreaTrigger =(scriptCallAreaTrigger )TRINITY_GET_PROC_ADDR(testScript->hScriptsLib,"AreaTrigger" ))
||!(testScript->ItemQuestAccept =(scriptCallItemQuestAccept )TRINITY_GET_PROC_ADDR(testScript->hScriptsLib,"ItemQuestAccept" ))
||!(testScript->GOQuestAccept =(scriptCallGOQuestAccept )TRINITY_GET_PROC_ADDR(testScript->hScriptsLib,"GOQuestAccept" ))
- ||!(testScript->ReceiveEmote =(scriptCallReceiveEmote )TRINITY_GET_PROC_ADDR(testScript->hScriptsLib,"ReceiveEmote" ))
||!(testScript->ItemUse =(scriptCallItemUse )TRINITY_GET_PROC_ADDR(testScript->hScriptsLib,"ItemUse" ))
+ ||!(testScript->EffectDummyGameObj =(scriptCallEffectDummyGameObj )TRINITY_GET_PROC_ADDR(testScript->hScriptsLib,"EffectDummyGameObj" ))
+ ||!(testScript->EffectDummyCreature =(scriptCallEffectDummyCreature )TRINITY_GET_PROC_ADDR(testScript->hScriptsLib,"EffectDummyCreature" ))
+ ||!(testScript->EffectDummyItem =(scriptCallEffectDummyItem )TRINITY_GET_PROC_ADDR(testScript->hScriptsLib,"EffectDummyItem" ))
||!(testScript->GetAI =(scriptCallGetAI )TRINITY_GET_PROC_ADDR(testScript->hScriptsLib,"GetAI" ))
||!(testScript->CreateInstanceData =(scriptCallCreateInstanceData )TRINITY_GET_PROC_ADDR(testScript->hScriptsLib,"CreateInstanceData" ))
)
@@ -90,7 +92,8 @@ bool LoadScriptingModule(char const* libName)
return false;
}
- printf("Scripts Library %s was successfully loaded.\n",name.c_str());
+ sLog.outString();
+ sLog.outString( ">>> Scripts Library %s was successfully loaded.\n", name.c_str() );
//heh we are still there :P we have a valid library
//we reload script
diff --git a/src/game/ScriptCalls.h b/src/game/ScriptCalls.h
index 68f6c5dac01..4e23f9f576d 100644
--- a/src/game/ScriptCalls.h
+++ b/src/game/ScriptCalls.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -58,8 +58,10 @@ typedef bool(TRINITY_IMPORT * scriptCallAreaTrigger)( Player *player, AreaTrigge
typedef bool(TRINITY_IMPORT * scriptCallItemQuestAccept)(Player *player, Item *, Quest const*);
typedef bool(TRINITY_IMPORT * scriptCallGOQuestAccept)(Player *player, GameObject *, Quest const*);
typedef bool(TRINITY_IMPORT * scriptCallGOChooseReward)(Player *player, GameObject *, Quest const*, uint32 opt );
-typedef bool(TRINITY_IMPORT * scriptCallReceiveEmote) ( Player *player, Creature *_Creature, uint32 emote );
typedef bool(TRINITY_IMPORT * scriptCallItemUse) (Player *player, Item *_Item, SpellCastTargets const& targets);
+typedef bool(TRINITY_IMPORT * scriptCallEffectDummyGameObj) (Unit *caster, uint32 spellId, uint32 effIndex, GameObject *gameObjTarget);
+typedef bool(TRINITY_IMPORT * scriptCallEffectDummyCreature) (Unit *caster, uint32 spellId, uint32 effIndex, Creature *crTarget);
+typedef bool(TRINITY_IMPORT * scriptCallEffectDummyItem) (Unit *caster, uint32 spellId, uint32 effIndex, Item *itemTarget);
typedef CreatureAI* (TRINITY_IMPORT * scriptCallGetAI) ( Creature *_Creature );
typedef InstanceData* (TRINITY_IMPORT * scriptCallCreateInstanceData) (Map *map);
@@ -86,8 +88,10 @@ typedef struct
scriptCallAreaTrigger scriptAreaTrigger;
scriptCallItemQuestAccept ItemQuestAccept;
scriptCallGOQuestAccept GOQuestAccept;
- scriptCallReceiveEmote ReceiveEmote;
scriptCallItemUse ItemUse;
+ scriptCallEffectDummyGameObj EffectDummyGameObj;
+ scriptCallEffectDummyCreature EffectDummyCreature;
+ scriptCallEffectDummyItem EffectDummyItem;
scriptCallGetAI GetAI;
scriptCallCreateInstanceData CreateInstanceData;
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index 61cbcaa35ad..e6aaf8619bc 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -24,6 +24,9 @@
#include "Platform/Define.h"
#include <cassert>
+#define MaNGOS Trinity
+#define GetMangosString GetTrinityString
+
enum Gender
{
GENDER_MALE = 0,
@@ -88,7 +91,8 @@ enum Classes
#define CLASSMASK_ALL_PLAYABLE \
((1<<(CLASS_WARRIOR-1))|(1<<(CLASS_PALADIN-1))|(1<<(CLASS_HUNTER-1))| \
(1<<(CLASS_ROGUE-1)) |(1<<(CLASS_PRIEST-1)) |(1<<(CLASS_SHAMAN-1))| \
- (1<<(CLASS_MAGE-1)) |(1<<(CLASS_WARLOCK-1))|(1<<(CLASS_DRUID-1)) )
+ (1<<(CLASS_MAGE-1)) |(1<<(CLASS_WARLOCK-1))|(1<<(CLASS_DRUID-1)) | \
+ (1<<(CLASS_DEATH_KNIGHT-1)) )
#define CLASSMASK_WAND_USERS ((1<<(CLASS_PRIEST-1))|(1<<(CLASS_MAGE-1))|(1<<(CLASS_WARLOCK-1)))
@@ -134,12 +138,13 @@ enum Powers
POWER_FOCUS = 2,
POWER_ENERGY = 3,
POWER_HAPPINESS = 4,
- POWER_RUNES = 5,
+ POWER_RUNE = 5,
+ POWER_RUNIC_POWER = 6,
+ MAX_POWERS = 7,
+ POWER_ALL = 127, // default for class?
POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value)
};
-#define MAX_POWERS 5 // not count POWER_RUNES for now
-
enum SpellSchools
{
SPELL_SCHOOL_NORMAL = 0,
@@ -199,10 +204,11 @@ enum ItemQualities
ITEM_QUALITY_RARE = 3, //BLUE
ITEM_QUALITY_EPIC = 4, //PURPLE
ITEM_QUALITY_LEGENDARY = 5, //ORANGE
- ITEM_QUALITY_ARTIFACT = 6 //LIGHT YELLOW
+ ITEM_QUALITY_ARTIFACT = 6, //LIGHT YELLOW
+ ITEM_QUALITY_HEIRLOOM = 7
};
-#define MAX_ITEM_QUALITY 7
+#define MAX_ITEM_QUALITY 8
enum SpellCategory
{
@@ -217,7 +223,7 @@ enum SpellCategory
#define SPELL_ATTR_UNK0 0x00000001 // 0
#define SPELL_ATTR_RANGED 0x00000002 // 1 All ranged abilities have this flag
#define SPELL_ATTR_ON_NEXT_SWING_1 0x00000004 // 2 on next swing
-#define SPELL_ATTR_UNK3 0x00000008 // 3 not set in 2.4.2
+#define SPELL_ATTR_UNK3 0x00000008 // 3 not set in 3.0.3
#define SPELL_ATTR_UNK4 0x00000010 // 4
#define SPELL_ATTR_UNK5 0x00000020 // 5 trade spells?
#define SPELL_ATTR_PASSIVE 0x00000040 // 6 Passive spell
@@ -257,7 +263,7 @@ enum SpellCategory
#define SPELL_ATTR_EX_NEGATIVE 0x00000080 // 7
#define SPELL_ATTR_EX_NOT_IN_COMBAT_TARGET 0x00000100 // 8 Spell req target not to be in combat state
#define SPELL_ATTR_EX_UNK9 0x00000200 // 9
-#define SPELL_ATTR_EX_UNK10 0x00000400 // 10
+#define SPELL_ATTR_EX_NO_INITIAL_AGGRO 0x00000400 // 10 no generates threat on cast 100%
#define SPELL_ATTR_EX_UNK11 0x00000800 // 11
#define SPELL_ATTR_EX_UNK12 0x00001000 // 12
#define SPELL_ATTR_EX_UNK13 0x00002000 // 13
@@ -272,7 +278,7 @@ enum SpellCategory
#define SPELL_ATTR_EX_REQ_COMBO_POINTS2 0x00400000 // 22 Req combo points on target
#define SPELL_ATTR_EX_UNK23 0x00800000 // 23
#define SPELL_ATTR_EX_UNK24 0x01000000 // 24 Req fishing pole??
-#define SPELL_ATTR_EX_UNK25 0x02000000 // 25 not set in 2.4.2
+#define SPELL_ATTR_EX_UNK25 0x02000000 // 25
#define SPELL_ATTR_EX_UNK26 0x04000000 // 26
#define SPELL_ATTR_EX_UNK27 0x08000000 // 27
#define SPELL_ATTR_EX_UNK28 0x10000000 // 28
@@ -282,35 +288,35 @@ enum SpellCategory
#define SPELL_ATTR_EX2_UNK0 0x00000001 // 0
#define SPELL_ATTR_EX2_UNK1 0x00000002 // 1
-#define SPELL_ATTR_EX2_UNK2 0x00000004 // 2 boss spells?
+#define SPELL_ATTR_EX2_CANT_REFLECTED 0x00000004 // 2 ? used for detect can or not spell reflected
#define SPELL_ATTR_EX2_UNK3 0x00000008 // 3
#define SPELL_ATTR_EX2_UNK4 0x00000010 // 4
-#define SPELL_ATTR_EX2_UNK5 0x00000020 // 5
+#define SPELL_ATTR_EX2_AUTOREPEAT_FLAG 0x00000020 // 5
#define SPELL_ATTR_EX2_UNK6 0x00000040 // 6
#define SPELL_ATTR_EX2_UNK7 0x00000080 // 7
-#define SPELL_ATTR_EX2_UNK8 0x00000100 // 8 not set in 2.4.2
+#define SPELL_ATTR_EX2_UNK8 0x00000100 // 8 not set in 3.0.3
#define SPELL_ATTR_EX2_UNK9 0x00000200 // 9
#define SPELL_ATTR_EX2_UNK10 0x00000400 // 10
#define SPELL_ATTR_EX2_HEALTH_FUNNEL 0x00000800 // 11
#define SPELL_ATTR_EX2_UNK12 0x00001000 // 12
#define SPELL_ATTR_EX2_UNK13 0x00002000 // 13
#define SPELL_ATTR_EX2_UNK14 0x00004000 // 14
-#define SPELL_ATTR_EX2_UNK15 0x00008000 // 15 not set in 2.4.2
+#define SPELL_ATTR_EX2_UNK15 0x00008000 // 15 not set in 3.0.3
#define SPELL_ATTR_EX2_TAME_BEAST 0x00010000 // 16
#define SPELL_ATTR_EX2_NOT_RESET_AUTOSHOT 0x00020000 // 17 Hunters Shot and Stings only have this flag
#define SPELL_ATTR_EX2_UNK18 0x00040000 // 18 Only Revive pet - possible req dead pet
#define SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT 0x00080000 // 19 does not necessarly need shapeshift
#define SPELL_ATTR_EX2_UNK20 0x00100000 // 20
-#define SPELL_ATTR_EX2_UNK21 0x00200000 // 21
-#define SPELL_ATTR_EX2_UNK22 0x00400000 // 22
+#define SPELL_ATTR_EX2_DAMAGE_REDUCED_SHIELD 0x00200000 // 21 for ice blocks, pala immunity buffs, priest absorb shields, but used also for other spells -> not sure!
+#define SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER 0x00400000 // 22 spell can trigger even if triggered
#define SPELL_ATTR_EX2_UNK23 0x00800000 // 23 Only mage Arcane Concentration have this flag
#define SPELL_ATTR_EX2_UNK24 0x01000000 // 24
#define SPELL_ATTR_EX2_UNK25 0x02000000 // 25
#define SPELL_ATTR_EX2_UNK26 0x04000000 // 26 unaffected by school immunity
#define SPELL_ATTR_EX2_UNK27 0x08000000 // 27
-#define SPELL_ATTR_EX2_UNK28 0x10000000 // 28
+#define SPELL_ATTR_EX2_UNK28 0x10000000 // 28 no breaks stealth if it fails??
#define SPELL_ATTR_EX2_CANT_CRIT 0x20000000 // 29 Spell can't crit
-#define SPELL_ATTR_EX2_UNK30 0x40000000 // 30
+#define SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER_2 0x40000000 // 30 spell can trigger even if triggered
#define SPELL_ATTR_EX2_FOOD 0x80000000 // 31 food, well-fed, and a few others
#define SPELL_ATTR_EX3_UNK0 0x00000001 // 0
@@ -329,8 +335,8 @@ enum SpellCategory
#define SPELL_ATTR_EX3_UNK13 0x00002000 // 13
#define SPELL_ATTR_EX3_UNK14 0x00004000 // 14 "Honorless Target" only this spells have this flag
#define SPELL_ATTR_EX3_UNK15 0x00008000 // 15 Auto Shoot, Shoot, Throw, - this is autoshot flag
-#define SPELL_ATTR_EX3_UNK16 0x00010000 // 16
-#define SPELL_ATTR_EX3_NO_INITIAL_AGGRO 0x00020000 // 17 no initial aggro
+#define SPELL_ATTR_EX3_UNK16 0x00010000 // 16 no triggers effects that trigger on casting a spell??
+#define SPELL_ATTR_EX3_UNK17 0x00020000 // 17 no triggers effects that trigger on casting a spell??
#define SPELL_ATTR_EX3_UNK18 0x00040000 // 18
#define SPELL_ATTR_EX3_UNK19 0x00080000 // 19
#define SPELL_ATTR_EX3_DEATH_PERSISTENT 0x00100000 // 20 Death persistent spells
@@ -338,8 +344,8 @@ enum SpellCategory
#define SPELL_ATTR_EX3_REQ_WAND 0x00400000 // 22 Req wand
#define SPELL_ATTR_EX3_UNK23 0x00800000 // 23
#define SPELL_ATTR_EX3_REQ_OFFHAND 0x01000000 // 24 Req offhand weapon
-#define SPELL_ATTR_EX3_UNK25 0x02000000 // 25
-#define SPELL_ATTR_EX3_UNK26 0x04000000 // 26
+#define SPELL_ATTR_EX3_UNK25 0x02000000 // 25 no cause spell pushback ?
+#define SPELL_ATTR_EX3_CAN_PROC_TRIGGERED 0x04000000 // 26
#define SPELL_ATTR_EX3_UNK27 0x08000000 // 27
#define SPELL_ATTR_EX3_UNK28 0x10000000 // 28
#define SPELL_ATTR_EX3_UNK29 0x20000000 // 29
@@ -350,9 +356,9 @@ enum SpellCategory
#define SPELL_ATTR_EX4_UNK1 0x00000002 // 1 proc on finishing move?
#define SPELL_ATTR_EX4_UNK2 0x00000004 // 2
#define SPELL_ATTR_EX4_UNK3 0x00000008 // 3
-#define SPELL_ATTR_EX4_UNK4 0x00000010 // 4
+#define SPELL_ATTR_EX4_UNK4 0x00000010 // 4 This will no longer cause guards to attack on use??
#define SPELL_ATTR_EX4_UNK5 0x00000020 // 5
-#define SPELL_ATTR_EX4_UNK6 0x00000040 // 6
+#define SPELL_ATTR_EX4_NOT_STEALABLE 0x00000040 // 6 although such auras might be dispellable, they cannot be stolen
#define SPELL_ATTR_EX4_UNK7 0x00000080 // 7
#define SPELL_ATTR_EX4_UNK8 0x00000100 // 8
#define SPELL_ATTR_EX4_UNK9 0x00000200 // 9
@@ -388,7 +394,7 @@ enum SpellCategory
#define SPELL_ATTR_EX5_UNK6 0x00000040 // 6
#define SPELL_ATTR_EX5_UNK7 0x00000080 // 7
#define SPELL_ATTR_EX5_UNK8 0x00000100 // 8
-#define SPELL_ATTR_EX5_UNK9 0x00000200 // 9
+#define SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY 0x00000200 // 9 begin periodic tick at aura apply
#define SPELL_ATTR_EX5_UNK10 0x00000400 // 10
#define SPELL_ATTR_EX5_UNK11 0x00000800 // 11
#define SPELL_ATTR_EX5_UNK12 0x00001000 // 12
@@ -413,37 +419,39 @@ enum SpellCategory
#define SPELL_ATTR_EX5_UNK31 0x80000000 // 31 Forces all nearby enemies to focus attacks caster
#define SPELL_ATTR_EX6_UNK0 0x00000001 // 0 Only Move spell have this flag
-#define SPELL_ATTR_EX6_UNK1 0x00000002 // 1 not set in 2.4.2
+#define SPELL_ATTR_EX6_UNK1 0x00000002 // 1 not set in 3.0.3
#define SPELL_ATTR_EX6_UNK2 0x00000004 // 2
#define SPELL_ATTR_EX6_UNK3 0x00000008 // 3
-#define SPELL_ATTR_EX6_UNK4 0x00000010 // 4 not set in 2.4.2
+#define SPELL_ATTR_EX6_UNK4 0x00000010 // 4
#define SPELL_ATTR_EX6_UNK5 0x00000020 // 5
#define SPELL_ATTR_EX6_UNK6 0x00000040 // 6
#define SPELL_ATTR_EX6_UNK7 0x00000080 // 7
#define SPELL_ATTR_EX6_UNK8 0x00000100 // 8
-#define SPELL_ATTR_EX6_UNK9 0x00000200 // 9 not set in 2.4.2
+#define SPELL_ATTR_EX6_UNK9 0x00000200 // 9
#define SPELL_ATTR_EX6_UNK10 0x00000400 // 10
#define SPELL_ATTR_EX6_UNK11 0x00000800 // 11
-#define SPELL_ATTR_EX6_UNK12 0x00001000 // 12 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK13 0x00002000 // 13 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK14 0x00004000 // 14 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK15 0x00008000 // 15 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK16 0x00010000 // 16 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK17 0x00020000 // 17 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK18 0x00040000 // 18 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK19 0x00080000 // 19 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK20 0x00100000 // 20 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK21 0x00200000 // 21 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK22 0x00400000 // 22 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK23 0x00800000 // 23 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK24 0x01000000 // 24 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK25 0x02000000 // 25 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK26 0x04000000 // 26 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK27 0x08000000 // 27 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK28 0x10000000 // 28 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK29 0x20000000 // 29 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK30 0x40000000 // 30 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK31 0x80000000 // 31 not set in 2.4.2
+#define SPELL_ATTR_EX6_UNK12 0x00001000 // 12
+#define SPELL_ATTR_EX6_UNK13 0x00002000 // 13
+#define SPELL_ATTR_EX6_UNK14 0x00004000 // 14
+#define SPELL_ATTR_EX6_UNK15 0x00008000 // 15 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK16 0x00010000 // 16
+#define SPELL_ATTR_EX6_UNK17 0x00020000 // 17
+#define SPELL_ATTR_EX6_UNK18 0x00040000 // 18
+#define SPELL_ATTR_EX6_UNK19 0x00080000 // 19
+#define SPELL_ATTR_EX6_UNK20 0x00100000 // 20
+#define SPELL_ATTR_EX6_UNK21 0x00200000 // 21
+#define SPELL_ATTR_EX6_UNK22 0x00400000 // 22
+#define SPELL_ATTR_EX6_UNK23 0x00800000 // 23 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK24 0x01000000 // 24 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK25 0x02000000 // 25 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK26 0x04000000 // 26 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK27 0x08000000 // 27 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK28 0x10000000 // 28 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK29 0x20000000 // 29 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK30 0x40000000 // 30 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK31 0x80000000 // 31 not set in 3.0.3
+
+#define MAX_GLYPH_SLOT_INDEX 6
enum SheathTypes
{
@@ -562,11 +570,11 @@ enum SpellEffects
SPELL_EFFECT_DISPEL = 38,
SPELL_EFFECT_LANGUAGE = 39,
SPELL_EFFECT_DUAL_WIELD = 40,
- SPELL_EFFECT_SUMMON_WILD = 41,
- SPELL_EFFECT_SUMMON_GUARDIAN = 42,
+ SPELL_EFFECT_JUMP = 41,
+ SPELL_EFFECT_JUMP2 = 42,
SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER= 43,
SPELL_EFFECT_SKILL_STEP = 44,
- SPELL_EFFECT_UNDEFINED_45 = 45,
+ SPELL_EFFECT_ADD_HONOR = 45,
SPELL_EFFECT_SPAWN = 46,
SPELL_EFFECT_TRADE_SKILL = 47,
SPELL_EFFECT_STEALTH = 48,
@@ -586,16 +594,16 @@ enum SpellEffects
SPELL_EFFECT_POWER_BURN = 62,
SPELL_EFFECT_THREAT = 63,
SPELL_EFFECT_TRIGGER_SPELL = 64,
- SPELL_EFFECT_HEALTH_FUNNEL = 65,
- SPELL_EFFECT_POWER_FUNNEL = 66,
+ SPELL_EFFECT_APPLY_AREA_AURA_RAID = 65,
+ SPELL_EFFECT_CREATE_MANA_GEM = 66,
SPELL_EFFECT_HEAL_MAX_HEALTH = 67,
SPELL_EFFECT_INTERRUPT_CAST = 68,
SPELL_EFFECT_DISTRACT = 69,
SPELL_EFFECT_PULL = 70,
SPELL_EFFECT_PICKPOCKET = 71,
SPELL_EFFECT_ADD_FARSIGHT = 72,
- SPELL_EFFECT_SUMMON_POSSESSED = 73,
- SPELL_EFFECT_SUMMON_TOTEM = 74,
+ SPELL_EFFECT_UNTRAIN_TALENTS = 73,
+ SPELL_EFFECT_APPLY_GLYPH = 74,
SPELL_EFFECT_HEAL_MECHANICAL = 75,
SPELL_EFFECT_SUMMON_OBJECT_WILD = 76,
SPELL_EFFECT_SCRIPT_EFFECT = 77,
@@ -608,17 +616,17 @@ enum SpellEffects
SPELL_EFFECT_STUCK = 84,
SPELL_EFFECT_SUMMON_PLAYER = 85,
SPELL_EFFECT_ACTIVATE_OBJECT = 86,
- SPELL_EFFECT_SUMMON_TOTEM_SLOT1 = 87,
- SPELL_EFFECT_SUMMON_TOTEM_SLOT2 = 88,
- SPELL_EFFECT_SUMMON_TOTEM_SLOT3 = 89,
- SPELL_EFFECT_SUMMON_TOTEM_SLOT4 = 90,
+ SPELL_EFFECT_WMO_DAMAGE = 87,
+ SPELL_EFFECT_WMO_REPAIR = 88,
+ SPELL_EFFECT_WMO_CHANGE = 89,
+ SPELL_EFFECT_KILL_CREDIT = 90,
SPELL_EFFECT_THREAT_ALL = 91,
SPELL_EFFECT_ENCHANT_HELD_ITEM = 92,
SPELL_EFFECT_SUMMON_PHANTASM = 93, //unused
SPELL_EFFECT_SELF_RESURRECT = 94,
SPELL_EFFECT_SKINNING = 95,
SPELL_EFFECT_CHARGE = 96,
- SPELL_EFFECT_SUMMON_CRITTER = 97,
+ SPELL_EFFECT_97 = 97,
SPELL_EFFECT_KNOCK_BACK = 98,
SPELL_EFFECT_DISENCHANT = 99,
SPELL_EFFECT_INEBRIATE = 100,
@@ -633,7 +641,7 @@ enum SpellEffects
SPELL_EFFECT_SUMMON_DEAD_PET = 109,
SPELL_EFFECT_DESTROY_ALL_TOTEMS = 110,
SPELL_EFFECT_DURABILITY_DAMAGE = 111,
- SPELL_EFFECT_SUMMON_DEMON = 112,
+ SPELL_EFFECT_112 = 112,
SPELL_EFFECT_RESURRECT_NEW = 113,
SPELL_EFFECT_ATTACK_ME = 114,
SPELL_EFFECT_DURABILITY_DAMAGE_PCT = 115,
@@ -655,19 +663,19 @@ enum SpellEffects
SPELL_EFFECT_131 = 131,
SPELL_EFFECT_132 = 132,
SPELL_EFFECT_UNLEARN_SPECIALIZATION = 133,
- SPELL_EFFECT_KILL_CREDIT = 134,
+ SPELL_EFFECT_KILL_CREDIT2 = 134,
SPELL_EFFECT_135 = 135,
SPELL_EFFECT_HEAL_PCT = 136,
SPELL_EFFECT_ENERGIZE_PCT = 137,
SPELL_EFFECT_138 = 138,
- SPELL_EFFECT_139 = 139,
+ SPELL_EFFECT_CLEAR_QUEST = 139,
SPELL_EFFECT_FORCE_CAST = 140,
SPELL_EFFECT_141 = 141,
SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE = 142,
SPELL_EFFECT_APPLY_AREA_AURA_OWNER = 143,
SPELL_EFFECT_KNOCK_BACK_2 = 144,
SPELL_EFFECT_145 = 145,
- SPELL_EFFECT_146 = 146,
+ SPELL_EFFECT_ACTIVATE_RUNE = 146,
SPELL_EFFECT_QUEST_FAIL = 147,
SPELL_EFFECT_148 = 148,
SPELL_EFFECT_149 = 149,
@@ -675,7 +683,201 @@ enum SpellEffects
SPELL_EFFECT_TRIGGER_SPELL_2 = 151,
SPELL_EFFECT_152 = 152,
SPELL_EFFECT_153 = 153,
- TOTAL_SPELL_EFFECTS = 154
+ SPELL_EFFECT_154 = 154,
+ SPELL_EFFECT_TITAN_GRIP = 155,
+ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC = 156,
+ SPELL_EFFECT_CREATE_ITEM_2 = 157,
+ SPELL_EFFECT_MILLING = 158,
+ SPELL_EFFECT_ALLOW_RENAME_PET = 159,
+ TOTAL_SPELL_EFFECTS = 160
+};
+
+enum SpellCastResult
+{
+ SPELL_FAILED_AFFECTING_COMBAT = 0,
+ SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 1,
+ SPELL_FAILED_ALREADY_AT_FULL_MANA = 2,
+ SPELL_FAILED_ALREADY_AT_FULL_POWER = 3,
+ SPELL_FAILED_ALREADY_BEING_TAMED = 4,
+ SPELL_FAILED_ALREADY_HAVE_CHARM = 5,
+ SPELL_FAILED_ALREADY_HAVE_SUMMON = 6,
+ SPELL_FAILED_ALREADY_OPEN = 7,
+ SPELL_FAILED_AURA_BOUNCED = 8,
+ SPELL_FAILED_AUTOTRACK_INTERRUPTED = 9,
+ SPELL_FAILED_BAD_IMPLICIT_TARGETS = 10,
+ SPELL_FAILED_BAD_TARGETS = 11,
+ SPELL_FAILED_CANT_BE_CHARMED = 12,
+ SPELL_FAILED_CANT_BE_DISENCHANTED = 13,
+ SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 14,
+ SPELL_FAILED_CANT_BE_MILLED = 15,
+ SPELL_FAILED_CANT_BE_PROSPECTED = 16,
+ SPELL_FAILED_CANT_CAST_ON_TAPPED = 17,
+ SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 18,
+ SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 19,
+ SPELL_FAILED_CANT_STEALTH = 20,
+ SPELL_FAILED_CASTER_AURASTATE = 21,
+ SPELL_FAILED_CASTER_DEAD = 22,
+ SPELL_FAILED_CHARMED = 23,
+ SPELL_FAILED_CHEST_IN_USE = 24,
+ SPELL_FAILED_CONFUSED = 25,
+ SPELL_FAILED_DONT_REPORT = 26,
+ SPELL_FAILED_EQUIPPED_ITEM = 27,
+ SPELL_FAILED_EQUIPPED_ITEM_CLASS = 28,
+ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 29,
+ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 30,
+ SPELL_FAILED_ERROR = 31,
+ SPELL_FAILED_FIZZLE = 32,
+ SPELL_FAILED_FLEEING = 33,
+ SPELL_FAILED_FOOD_LOWLEVEL = 34,
+ SPELL_FAILED_HIGHLEVEL = 35,
+ SPELL_FAILED_HUNGER_SATIATED = 36,
+ SPELL_FAILED_IMMUNE = 37,
+ SPELL_FAILED_INCORRECT_AREA = 38,
+ SPELL_FAILED_INTERRUPTED = 39,
+ SPELL_FAILED_INTERRUPTED_COMBAT = 40,
+ SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 41,
+ SPELL_FAILED_ITEM_GONE = 42,
+ SPELL_FAILED_ITEM_NOT_FOUND = 43,
+ SPELL_FAILED_ITEM_NOT_READY = 44,
+ SPELL_FAILED_LEVEL_REQUIREMENT = 45,
+ SPELL_FAILED_LINE_OF_SIGHT = 46,
+ SPELL_FAILED_LOWLEVEL = 47,
+ SPELL_FAILED_LOW_CASTLEVEL = 48,
+ SPELL_FAILED_MAINHAND_EMPTY = 49,
+ SPELL_FAILED_MOVING = 50,
+ SPELL_FAILED_NEED_AMMO = 51,
+ SPELL_FAILED_NEED_AMMO_POUCH = 52,
+ SPELL_FAILED_NEED_EXOTIC_AMMO = 53,
+ SPELL_FAILED_NEED_MORE_ITEMS = 54,
+ SPELL_FAILED_NOPATH = 55,
+ SPELL_FAILED_NOT_BEHIND = 56,
+ SPELL_FAILED_NOT_FISHABLE = 57,
+ SPELL_FAILED_NOT_FLYING = 58,
+ SPELL_FAILED_NOT_HERE = 59,
+ SPELL_FAILED_NOT_INFRONT = 60,
+ SPELL_FAILED_NOT_IN_CONTROL = 61,
+ SPELL_FAILED_NOT_KNOWN = 62,
+ SPELL_FAILED_NOT_MOUNTED = 63,
+ SPELL_FAILED_NOT_ON_TAXI = 64,
+ SPELL_FAILED_NOT_ON_TRANSPORT = 65,
+ SPELL_FAILED_NOT_READY = 66,
+ SPELL_FAILED_NOT_SHAPESHIFT = 67,
+ SPELL_FAILED_NOT_STANDING = 68,
+ SPELL_FAILED_NOT_TRADEABLE = 69,
+ SPELL_FAILED_NOT_TRADING = 70,
+ SPELL_FAILED_NOT_UNSHEATHED = 71,
+ SPELL_FAILED_NOT_WHILE_GHOST = 72,
+ SPELL_FAILED_NOT_WHILE_LOOTING = 73,
+ SPELL_FAILED_NO_AMMO = 74,
+ SPELL_FAILED_NO_CHARGES_REMAIN = 75,
+ SPELL_FAILED_NO_CHAMPION = 76,
+ SPELL_FAILED_NO_COMBO_POINTS = 77,
+ SPELL_FAILED_NO_DUELING = 78,
+ SPELL_FAILED_NO_ENDURANCE = 79,
+ SPELL_FAILED_NO_FISH = 80,
+ SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 81,
+ SPELL_FAILED_NO_MOUNTS_ALLOWED = 82,
+ SPELL_FAILED_NO_PET = 83,
+ SPELL_FAILED_NO_POWER = 84,
+ SPELL_FAILED_NOTHING_TO_DISPEL = 85,
+ SPELL_FAILED_NOTHING_TO_STEAL = 86,
+ SPELL_FAILED_ONLY_ABOVEWATER = 87,
+ SPELL_FAILED_ONLY_DAYTIME = 88,
+ SPELL_FAILED_ONLY_INDOORS = 89,
+ SPELL_FAILED_ONLY_MOUNTED = 90,
+ SPELL_FAILED_ONLY_NIGHTTIME = 91,
+ SPELL_FAILED_ONLY_OUTDOORS = 92,
+ SPELL_FAILED_ONLY_SHAPESHIFT = 93,
+ SPELL_FAILED_ONLY_STEALTHED = 94,
+ SPELL_FAILED_ONLY_UNDERWATER = 95,
+ SPELL_FAILED_OUT_OF_RANGE = 96,
+ SPELL_FAILED_PACIFIED = 97,
+ SPELL_FAILED_POSSESSED = 98,
+ SPELL_FAILED_REAGENTS = 99,
+ SPELL_FAILED_REQUIRES_AREA = 100,
+ SPELL_FAILED_REQUIRES_SPELL_FOCUS = 101,
+ SPELL_FAILED_ROOTED = 102,
+ SPELL_FAILED_SILENCED = 103,
+ SPELL_FAILED_SPELL_IN_PROGRESS = 104,
+ SPELL_FAILED_SPELL_LEARNED = 105,
+ SPELL_FAILED_SPELL_UNAVAILABLE = 106,
+ SPELL_FAILED_STUNNED = 107,
+ SPELL_FAILED_TARGETS_DEAD = 108,
+ SPELL_FAILED_TARGET_AFFECTING_COMBAT = 109,
+ SPELL_FAILED_TARGET_AURASTATE = 110,
+ SPELL_FAILED_TARGET_DUELING = 111,
+ SPELL_FAILED_TARGET_ENEMY = 112,
+ SPELL_FAILED_TARGET_ENRAGED = 113,
+ SPELL_FAILED_TARGET_FRIENDLY = 114,
+ SPELL_FAILED_TARGET_IN_COMBAT = 115,
+ SPELL_FAILED_TARGET_IS_PLAYER = 116,
+ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 117,
+ SPELL_FAILED_TARGET_NOT_DEAD = 118,
+ SPELL_FAILED_TARGET_NOT_IN_PARTY = 119,
+ SPELL_FAILED_TARGET_NOT_LOOTED = 120,
+ SPELL_FAILED_TARGET_NOT_PLAYER = 121,
+ SPELL_FAILED_TARGET_NO_POCKETS = 122,
+ SPELL_FAILED_TARGET_NO_WEAPONS = 123,
+ SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 124,
+ SPELL_FAILED_TARGET_UNSKINNABLE = 125,
+ SPELL_FAILED_THIRST_SATIATED = 126,
+ SPELL_FAILED_TOO_CLOSE = 127,
+ SPELL_FAILED_TOO_MANY_OF_ITEM = 128,
+ SPELL_FAILED_TOTEM_CATEGORY = 129,
+ SPELL_FAILED_TOTEMS = 130,
+ SPELL_FAILED_TRY_AGAIN = 131,
+ SPELL_FAILED_UNIT_NOT_BEHIND = 132,
+ SPELL_FAILED_UNIT_NOT_INFRONT = 133,
+ SPELL_FAILED_WRONG_PET_FOOD = 134,
+ SPELL_FAILED_NOT_WHILE_FATIGUED = 135,
+ SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 136,
+ SPELL_FAILED_NOT_WHILE_TRADING = 137,
+ SPELL_FAILED_TARGET_NOT_IN_RAID = 138,
+ SPELL_FAILED_TARGET_FREEFORALL = 139,
+ SPELL_FAILED_NO_EDIBLE_CORPSES = 140,
+ SPELL_FAILED_ONLY_BATTLEGROUNDS = 141,
+ SPELL_FAILED_TARGET_NOT_GHOST = 142,
+ SPELL_FAILED_TRANSFORM_UNUSABLE = 143,
+ SPELL_FAILED_WRONG_WEATHER = 144,
+ SPELL_FAILED_DAMAGE_IMMUNE = 145,
+ SPELL_FAILED_PREVENTED_BY_MECHANIC = 146,
+ SPELL_FAILED_PLAY_TIME = 147,
+ SPELL_FAILED_REPUTATION = 148,
+ SPELL_FAILED_MIN_SKILL = 149,
+ SPELL_FAILED_NOT_IN_ARENA = 150,
+ SPELL_FAILED_NOT_ON_SHAPESHIFT = 151,
+ SPELL_FAILED_NOT_ON_STEALTHED = 152,
+ SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 153,
+ SPELL_FAILED_NOT_ON_MOUNTED = 154,
+ SPELL_FAILED_TOO_SHALLOW = 155,
+ SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 156,
+ SPELL_FAILED_TARGET_IS_TRIVIAL = 157,
+ SPELL_FAILED_BM_OR_INVISGOD = 158,
+ SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 159,
+ SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 160,
+ SPELL_FAILED_NOT_IDLE = 161,
+ SPELL_FAILED_NOT_INACTIVE = 162,
+ SPELL_FAILED_PARTIAL_PLAYTIME = 163,
+ SPELL_FAILED_NO_PLAYTIME = 164,
+ SPELL_FAILED_NOT_IN_BATTLEGROUND = 165,
+ SPELL_FAILED_NOT_IN_RAID_INSTANCE = 166,
+ SPELL_FAILED_ONLY_IN_ARENA = 167,
+ SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 168,
+ SPELL_FAILED_ON_USE_ENCHANT = 169,
+ SPELL_FAILED_NOT_ON_GROUND = 170,
+ SPELL_FAILED_CUSTOM_ERROR = 171,
+ SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 172,
+ SPELL_FAILED_TOO_MANY_SOCKETS = 173,
+ SPELL_FAILED_INVALID_GLYPH = 174,
+ SPELL_FAILED_UNIQUE_GLYPH = 175,
+ SPELL_FAILED_GLYPH_SOCKET_LOCKED = 176,
+ SPELL_FAILED_NO_VALID_TARGETS = 177,
+ SPELL_FAILED_ITEM_AT_MAX_CHARGES = 178,
+ SPELL_FAILED_NOT_IN_BARBERSHOP = 179,
+ SPELL_FAILED_FISHING_TOO_LOW = 180,
+ SPELL_FAILED_UNKNOWN = 181,
+
+ SPELL_CAST_OK = 255 //custom value, don't must be send to client
};
// Spell aura states
@@ -685,25 +887,28 @@ enum AuraState
AURA_STATE_DEFENSE = 1, // C |
AURA_STATE_HEALTHLESS_20_PERCENT = 2, // CcT |
AURA_STATE_BERSERKING = 3, // C T |
- //AURA_STATE_UNKNOWN4 = 4, // c t| some limitation to charge spells (?) and target test spells
+ AURA_STATE_FROZEN = 4, // c t| frozen target
AURA_STATE_JUDGEMENT = 5, // C |
//AURA_STATE_UNKNOWN6 = 6, // | not used
AURA_STATE_HUNTER_PARRY = 7, // C |
AURA_STATE_ROGUE_ATTACK_FROM_STEALTH = 7, // C | FIX ME: not implemented yet!
- //AURA_STATE_UNKNOWN7c = 7, // c | random/focused bursts spells (?)
+ //AURA_STATE_UNKNOWN7 = 7, // c | random/focused bursts spells (?)
//AURA_STATE_UNKNOWN8 = 8, // | not used
//AURA_STATE_UNKNOWN9 = 9, // | not used
AURA_STATE_WARRIOR_VICTORY_RUSH = 10, // C | warrior victory rush
- AURA_STATE_HUNTER_CRIT_STRIKE = 10, // C | hunter crit strike
- AURA_STATE_CRIT = 11, // C |
+ //AURA_STATE_UNKNOWN11 = 11, // t|
AURA_STATE_FAERIE_FIRE = 12, // c t|
AURA_STATE_HEALTHLESS_35_PERCENT = 13, // C T |
AURA_STATE_IMMOLATE = 14, // T |
AURA_STATE_SWIFTMEND = 15, // T |
AURA_STATE_DEADLY_POISON = 16, // T |
- AURA_STATE_FORBEARANCE = 17, // c t|
- AURA_STATE_WEAKENED_SOUL = 18, // t|
- AURA_STATE_HYPOTHERMIA = 19 // c |
+ AURA_STATE_ENRAGE = 17, // C |
+ //AURA_STATE_UNKNOWN18 = 18, // C t|
+ //AURA_STATE_UNKNOWN19 = 19, // | not used
+ //AURA_STATE_UNKNOWN20 = 20, // c | only (45317 Suicide)
+ //AURA_STATE_UNKNOWN21 = 21, // | not used
+ //AURA_STATE_UNKNOWN22 = 22, // C | not implemented yet (Requires Evasive Charges to use)
+ AURA_STATE_HEALTH_ABOVE_75_PERCENT = 23, // C |
};
// Spell mechanics
@@ -711,11 +916,11 @@ enum Mechanics
{
MECHANIC_NONE = 0,
MECHANIC_CHARM = 1,
- MECHANIC_CONFUSED = 2,
+ MECHANIC_DISORIENTED = 2,
MECHANIC_DISARM = 3,
MECHANIC_DISTRACT = 4,
MECHANIC_FEAR = 5,
- MECHANIC_FUMBLE = 6,
+ MECHANIC_GRIP = 6,
MECHANIC_ROOT = 7,
MECHANIC_PACIFY = 8, //0 spells use this mechanic
MECHANIC_SILENCE = 9,
@@ -731,7 +936,7 @@ enum Mechanics
MECHANIC_SHIELD = 19,
MECHANIC_SHACKLE = 20,
MECHANIC_MOUNT = 21,
- MECHANIC_PERSUADE = 22, //0 spells use this mechanic
+ MECHANIC_INFECTED = 22,
MECHANIC_TURN = 23,
MECHANIC_HORROR = 24,
MECHANIC_INVULNERABILITY = 25,
@@ -739,12 +944,13 @@ enum Mechanics
MECHANIC_DAZE = 27,
MECHANIC_DISCOVERY = 28,
MECHANIC_IMMUNE_SHIELD = 29, // Divine (Blessing) Shield/Protection and Ice Block
- MECHANIC_SAPPED = 30
+ MECHANIC_SAPPED = 30,
+ MECHANIC_ENRAGED = 31
};
// Used for spell 42292 Immune Movement Impairment and Loss of Control (0x49967da6)
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK ( \
- (1<<MECHANIC_CHARM )|(1<<MECHANIC_CONFUSED )|(1<<MECHANIC_FEAR )| \
+ (1<<MECHANIC_CHARM )|(1<<MECHANIC_DISORIENTED )|(1<<MECHANIC_FEAR )| \
(1<<MECHANIC_ROOT )|(1<<MECHANIC_PACIFY )|(1<<MECHANIC_SLEEP )| \
(1<<MECHANIC_SNARE )|(1<<MECHANIC_STUN )|(1<<MECHANIC_FREEZE)| \
(1<<MECHANIC_KNOCKOUT)|(1<<MECHANIC_POLYMORPH)|(1<<MECHANIC_BANISH)| \
@@ -764,7 +970,8 @@ enum DispelType
DISPEL_ALL = 7,
DISPEL_SPE_NPC_ONLY = 8,
DISPEL_ENRAGE = 9,
- DISPEL_ZG_TICKET = 10
+ DISPEL_ZG_TICKET = 10,
+ DESPEL_OLD_UNUSED = 11
};
#define DISPEL_ALL_MASK ( (1<<DISPEL_MAGIC) | (1<<DISPEL_CURSE) | (1<<DISPEL_DISEASE) | (1<<DISPEL_POISON) )
@@ -790,10 +997,9 @@ enum Targets
{
TARGET_SELF = 1,
TARGET_UNIT_CASTER = 1,
- TARGET_RANDOM_ENEMY_CHAIN_IN_AREA = 2, // only one spell has that, but regardless, it's a target type after all
- //TARGET_UNIT_NEARBY_ENEMY
- TARGET_UNIT_SINGLE_UNKNOWN = 3,
- TARGET_UNIT_NEARBY_ALLY = 4,
+ TARGET_UNIT_NEARBY_ENEMY = 2,
+ TARGET_UNIT_NEARBY_ALLY = 3,
+ TARGET_UNIT_NEARBY_ALLY_UNK = 4,
TARGET_PET = 5,
TARGET_UNIT_PET = 5,
TARGET_CHAIN_DAMAGE = 6,
@@ -816,7 +1022,6 @@ enum Targets
TARGET_UNIT_PARTY_CASTER = 20,
TARGET_SINGLE_FRIEND = 21,
TARGET_UNIT_TARGET_ALLY = 21,
- TARGET_ALL_AROUND_CASTER = 22, // used only in TargetA, target selection dependent from TargetB
TARGET_DEST_CASTER = 22,
TARGET_GAMEOBJECT = 23,
//TARGET_OBJECT_OPEN
@@ -986,9 +1191,10 @@ enum GameobjectTypes
GAMEOBJECT_TYPE_BARBER_CHAIR = 32,
GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING = 33,
GAMEOBJECT_TYPE_GUILD_BANK = 34,
+ GAMEOBJECT_TYPE_TRAPDOOR = 35
};
-#define MAX_GAMEOBJECT_TYPE 35 // sending to client this or greater value can crash client.
+#define MAX_GAMEOBJECT_TYPE 36 // sending to client this or greater value can crash client.
#define GAMEOBJECT_FISHINGNODE_ENTRY 35591 // Better to define it somewhere instead of hardcoding everywhere
@@ -1207,7 +1413,7 @@ enum Emote
EMOTE_ONESHOT_POINT = 25,
EMOTE_STATE_STAND = 26,
EMOTE_STATE_READYUNARMED = 27,
- EMOTE_STATE_WORK = 28,
+ EMOTE_STATE_WORK_SHEATHED = 28,
EMOTE_STATE_POINT = 29,
EMOTE_STATE_NONE = 30,
EMOTE_ONESHOT_WOUND = 33,
@@ -1240,13 +1446,13 @@ enum Emote
EMOTE_ONESHOT_SALUTE_NOSHEATH = 113,
EMOTE_STATE_USESTANDING_NOSHEATHE = 133,
EMOTE_ONESHOT_LAUGH_NOSHEATHE = 153,
- EMOTE_STATE_WORK_NOSHEATHE = 173,
+ EMOTE_STATE_WORK = 173,
EMOTE_STATE_SPELLPRECAST = 193,
EMOTE_ONESHOT_READYRIFLE = 213,
EMOTE_STATE_READYRIFLE = 214,
- EMOTE_STATE_WORK_NOSHEATHE_MINING = 233,
- EMOTE_STATE_WORK_NOSHEATHE_CHOPWOOD= 234,
- EMOTE_zzOLDONESHOT_LIFTOFF = 253,
+ EMOTE_STATE_WORK_MINING = 233,
+ EMOTE_STATE_WORK_CHOPWOOD = 234,
+ EMOTE_STATE_APPLAUD = 253,
EMOTE_ONESHOT_LIFTOFF = 254,
EMOTE_ONESHOT_YES = 273,
EMOTE_ONESHOT_NO = 274,
@@ -1295,8 +1501,57 @@ enum Emote
EMOTE_ONESHOT_CUSTOMSPELL09 = 410,
EMOTE_ONESHOT_CUSTOMSPELL10 = 411,
EMOTE_STATE_EXCLAIM = 412,
+ EMOTE_STATE_DANCE_CUSTOM = 413,
EMOTE_STATE_SIT_CHAIR_MED = 415,
- EMOTE_STATE_SPELLEFFECT_HOLD = 422
+ EMOTE_STATE_CUSTOM_SPELL_01 = 416,
+ EMOTE_STATE_CUSTOM_SPELL_02 = 417,
+ EMOTE_STATE_EAT = 418,
+ EMOTE_STATE_CUSTOM_SPELL_04 = 419,
+ EMOTE_STATE_CUSTOM_SPELL_03 = 420,
+ EMOTE_STATE_CUSTOM_SPELL_05 = 421,
+ EMOTE_STATE_SPELLEFFECT_HOLD = 422,
+ EMOTE_STATE_EAT_NO_SHEATHE = 423,
+ EMOTE_STATE_MOUNT = 424,
+ EMOTE_STATE_READY2HL = 425,
+ EMOTE_STATE_SIT_CHAIR_HIGH = 426,
+ EMOTE_STATE_FALL = 427,
+ EMOTE_STATE_LOOT = 428,
+ EMOTE_STATE_SUBMERGED_NEW = 429,
+ EMOTE_ONESHOT_COWER = 430,
+ EMOTE_STATE_COWER = 431,
+ EMOTE_ONESHOT_USESTANDING = 432,
+ EMOTE_STATE_STEALTH_STAND = 433,
+ EMOTE_ONESHOT_OMNICAST_GHOUL = 434,
+ EMOTE_ONESHOT_ATTACKBOW = 435,
+ EMOTE_ONESHOT_ATTACKRIFLE = 436,
+ EMOTE_STATE_SWIM_IDLE = 437,
+ EMOTE_STATE_ATTACK_UNARMED = 438,
+ EMOTE_ONESHOT_SPELLCAST_W_SOUND = 439,
+ EMOTE_ONESHOT_DODGE = 440,
+ EMOTE_ONESHOT_PARRY1H = 441,
+ EMOTE_ONESHOT_PARRY2H = 442,
+ EMOTE_ONESHOT_PARRY2HL = 443,
+ EMOTE_STATE_FLYFALL = 444,
+ EMOTE_ONESHOT_FLYDEATH = 445,
+ EMOTE_STATE_FLY_FALL = 446,
+ EMOTE_ONESHOT_FLY_SIT_GROUND_DOWN = 447,
+ EMOTE_ONESHOT_FLY_SIT_GROUND_UP = 448,
+ EMOTE_ONESHOT_EMERGE = 449,
+ EMOTE_ONESHOT_DRAGONSPIT = 450,
+ EMOTE_STATE_SPECIALUNARMED = 451,
+ EMOTE_ONESHOT_FLYGRAB = 452,
+ EMOTE_STATE_FLYGRABCLOSED = 453,
+ EMOTE_ONESHOT_FLYGRABTHROWN = 454,
+ EMOTE_STATE_FLY_SIT_GROUND = 455,
+ EMOTE_STATE_WALKBACKWARDS = 456,
+ EMOTE_ONESHOT_FLYTALK = 457,
+ EMOTE_ONESHOT_FLYATTACK1H = 458,
+ EMOTE_STATE_CUSTOMSPELL08 = 459,
+ EMOTE_ONESHOT_FLY_DRAGONSPIT = 460,
+ EMOTE_STATE_SIT_CHAIR_LOW = 461,
+ EMOTE_ONE_SHOT_STUN = 462,
+ EMOTE_ONESHOT_SPELLCAST_OMNI = 463,
+ EMOTE_STATE_READYTHROWN = 464
};
enum Anim
@@ -1555,7 +1810,9 @@ enum LockType
LOCKTYPE_BLASTING = 16,
LOCKTYPE_SLOW_OPEN = 17,
LOCKTYPE_SLOW_CLOSE = 18,
- LOCKTYPE_FISHING = 19
+ LOCKTYPE_FISHING = 19,
+ LOCKTYPE_INSCRIPTION = 20,
+ LOCKTYPE_OPEN_FROM_VEHICLE = 21
};
enum TrainerType // this is important type for npcs!
@@ -1568,6 +1825,7 @@ enum TrainerType // this is important
#define MAX_TRAINER_TYPE 4
+// CreatureType.dbc
enum CreatureType
{
CREATURE_TYPE_BEAST = 1,
@@ -1587,6 +1845,7 @@ enum CreatureType
uint32 const CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD = (1 << (CREATURE_TYPE_HUMANOID-1)) | (1 << (CREATURE_TYPE_UNDEAD-1));
+// CreatureFamily.dbc
enum CreatureFamily
{
CREATURE_FAMILY_WOLF = 1,
@@ -1598,6 +1857,7 @@ enum CreatureFamily
CREATURE_FAMILY_CARRION_BIRD = 7,
CREATURE_FAMILY_CRAB = 8,
CREATURE_FAMILY_GORILLA = 9,
+ CREATURE_FAMILY_HORSE_CUSTOM = 10, // not exist in DBC but used for horse like beasts in DB
CREATURE_FAMILY_RAPTOR = 11,
CREATURE_FAMILY_TALLSTRIDER = 12,
CREATURE_FAMILY_FELHUNTER = 15,
@@ -1609,7 +1869,7 @@ enum CreatureFamily
CREATURE_FAMILY_IMP = 23,
CREATURE_FAMILY_BAT = 24,
CREATURE_FAMILY_HYENA = 25,
- CREATURE_FAMILY_OWL = 26,
+ CREATURE_FAMILY_BIRD_OF_PREY = 26,
CREATURE_FAMILY_WIND_SERPENT = 27,
CREATURE_FAMILY_REMOTE_CONTROL = 28,
CREATURE_FAMILY_FELGUARD = 29,
@@ -1619,14 +1879,24 @@ enum CreatureFamily
CREATURE_FAMILY_SPOREBAT = 33,
CREATURE_FAMILY_NETHER_RAY = 34,
CREATURE_FAMILY_SERPENT = 35,
- CREATURE_FAMILY_SEA_LION = 36
+ CREATURE_FAMILY_MOTH = 37,
+ CREATURE_FAMILY_CHIMAERA = 38,
+ CREATURE_FAMILY_DEVILSAUR = 39,
+ CREATURE_FAMILY_GHOUL = 40,
+ CREATURE_FAMILY_SILITHID = 41,
+ CREATURE_FAMILY_WORM = 42,
+ CREATURE_FAMILY_RHINO = 43,
+ CREATURE_FAMILY_WASP = 44,
+ CREATURE_FAMILY_CORE_HOUND = 45,
+ CREATURE_FAMILY_SPIRIT_BEAST = 46
};
enum CreatureTypeFlags
{
- CREATURE_TYPEFLAGS_TAMEABLE = 0x0001,
- CREATURE_TYPEFLAGS_HERBLOOT = 0x0100,
- CREATURE_TYPEFLAGS_MININGLOOT = 0x0200
+ CREATURE_TYPEFLAGS_TAMEABLE = 0x0001,
+ CREATURE_TYPEFLAGS_HERBLOOT = 0x0100,
+ CREATURE_TYPEFLAGS_MININGLOOT = 0x0200,
+ CREATURE_TYPEFLAGS_ENGINEERLOOT = 0x8000
};
enum CreatureEliteType
@@ -1639,6 +1909,31 @@ enum CreatureEliteType
CREATURE_UNKNOWN = 5 // found in 2.2.3 for 2 mobs
};
+// values based at Holidays.dbc
+enum HolidayIds
+{
+ HOLIDAY_FIREWORKS_SPECTACULAR = 62,
+ HOLIDAY_FEAST_OF_WINTER_VEIL = 141,
+ HOLIDAY_NOBLEGARDEN = 181,
+ HOLIDAY_CHILDRENS_WEEK = 201,
+ HOLIDAY_CALL_TO_ARMS_AV = 283,
+ HOLIDAY_CALL_TO_ARMS_WG = 284,
+ HOLIDAY_CALL_TO_ARMS_AB = 285,
+ HOLIDAY_FISHING_EXTRAVAGANZA = 301,
+ HOLIDAY_HARVEST_FESTIVAL = 321,
+ HOLIDAY_HALLOWS_END = 324,
+ HOLIDAY_LUNAR_FESTIVAL = 327,
+ HOLIDAY_LOVE_IS_IN_THE_AIR = 335,
+ HOLIDAY_FIRE_FESTIVAL = 341,
+ HOLIDAY_CALL_TO_ARMS_ES = 353,
+ HOLIDAY_BREWFEST = 372,
+ HOLIDAY_DARKMOON_FAIRE_ELWYNN = 374,
+ HOLIDAY_DARKMOON_FAIRE_THUNDER = 375,
+ HOLIDAY_DARKMOON_FAIRE_SHATTRATH = 376,
+ HOLIDAY_CALL_TO_ARMS_SA = 400,
+ HOLIDAY_WOTLK_LAUNCH = 406
+};
+
// values based at QuestInfo.dbc
enum QuestTypes
{
@@ -1651,6 +1946,8 @@ enum QuestTypes
QUEST_TYPE_LEGENDARY = 83,
QUEST_TYPE_ESCORT = 84,
QUEST_TYPE_HEROIC = 85,
+ QUEST_TYPE_RAID_10 = 88,
+ QUEST_TYPE_RAID_25 = 89
};
// values based at QuestSort.dbc
@@ -1661,7 +1958,7 @@ enum QuestSort
QUEST_SORT_SEASONAL = 22,
QUEST_SORT_UNDERCITY_OLD = 23,
QUEST_SORT_HERBALISM = 24,
- QUEST_SORT_SCARLET_MONASTERY_OLD= 25,
+ QUEST_SORT_BATTLEGROUNDS = 25,
QUEST_SORT_ULDAMN_OLD = 41,
QUEST_SORT_WARLOCK = 61,
QUEST_SORT_WARRIOR = 81,
@@ -1690,34 +1987,39 @@ enum QuestSort
QUEST_SORT_REPUTATION = 367,
QUEST_SORT_INVASION = 368,
QUEST_SORT_MIDSUMMER = 369,
- QUEST_SORT_BREWFEST = 370
+ QUEST_SORT_BREWFEST = 370,
+ QUEST_SORT_INSCRIPTION = 371,
+ QUEST_SORT_DEATH_KNIGHT = 372,
+ QUEST_SORT_JEWELCRAFTING = 373
};
inline uint8 ClassByQuestSort(int32 QuestSort)
{
switch(QuestSort)
{
- case QUEST_SORT_WARLOCK: return CLASS_WARLOCK;
- case QUEST_SORT_WARRIOR: return CLASS_WARRIOR;
- case QUEST_SORT_SHAMAN: return CLASS_SHAMAN;
- case QUEST_SORT_PALADIN: return CLASS_PALADIN;
- case QUEST_SORT_MAGE: return CLASS_MAGE;
- case QUEST_SORT_ROGUE: return CLASS_ROGUE;
- case QUEST_SORT_HUNTER: return CLASS_HUNTER;
- case QUEST_SORT_PRIEST: return CLASS_PRIEST;
- case QUEST_SORT_DRUID: return CLASS_DRUID;
+ case QUEST_SORT_WARLOCK: return CLASS_WARLOCK;
+ case QUEST_SORT_WARRIOR: return CLASS_WARRIOR;
+ case QUEST_SORT_SHAMAN: return CLASS_SHAMAN;
+ case QUEST_SORT_PALADIN: return CLASS_PALADIN;
+ case QUEST_SORT_MAGE: return CLASS_MAGE;
+ case QUEST_SORT_ROGUE: return CLASS_ROGUE;
+ case QUEST_SORT_HUNTER: return CLASS_HUNTER;
+ case QUEST_SORT_PRIEST: return CLASS_PRIEST;
+ case QUEST_SORT_DRUID: return CLASS_DRUID;
+ case QUEST_SORT_DEATH_KNIGHT: return CLASS_DEATH_KNIGHT;
}
return 0;
}
enum SkillType
{
+ SKILL_NONE = 0,
+
SKILL_FROST = 6,
SKILL_FIRE = 8,
SKILL_ARMS = 26,
SKILL_COMBAT = 38,
SKILL_SUBTLETY = 39,
- SKILL_POISONS = 40,
SKILL_SWORDS = 43,
SKILL_AXES = 44,
SKILL_BOWS = 45,
@@ -1725,8 +2027,8 @@ enum SkillType
SKILL_BEAST_MASTERY = 50,
SKILL_SURVIVAL = 51,
SKILL_MACES = 54,
- SKILL_HOLY = 56,
SKILL_2H_SWORDS = 55,
+ SKILL_HOLY = 56,
SKILL_SHADOW = 78,
SKILL_DEFENSE = 95,
SKILL_LANG_COMMON = 98,
@@ -1782,24 +2084,20 @@ enum SkillType
SKILL_PET_BOAR = 211,
SKILL_PET_CROCILISK = 212,
SKILL_PET_CARRION_BIRD = 213,
- SKILL_PET_GORILLA = 215,
SKILL_PET_CRAB = 214,
+ SKILL_PET_GORILLA = 215,
SKILL_PET_RAPTOR = 217,
SKILL_PET_TALLSTRIDER = 218,
SKILL_RACIAL_UNDED = 220,
- SKILL_WEAPON_TALENTS = 222,
SKILL_CROSSBOWS = 226,
- SKILL_SPEARS = 227,
SKILL_WANDS = 228,
SKILL_POLEARMS = 229,
SKILL_PET_SCORPID = 236,
SKILL_ARCANE = 237,
- SKILL_OPEN_LOCK = 242,
SKILL_PET_TURTLE = 251,
SKILL_ASSASSINATION = 253,
SKILL_FURY = 256,
SKILL_PROTECTION = 257,
- SKILL_BEAST_TRAINING = 261,
SKILL_PROTECTION2 = 267,
SKILL_PET_TALENTS = 270,
SKILL_PLATE_MAIL = 293,
@@ -1829,7 +2127,7 @@ enum SkillType
SKILL_LOCKPICKING = 633,
SKILL_PET_BAT = 653,
SKILL_PET_HYENA = 654,
- SKILL_PET_OWL = 655,
+ SKILL_PET_BIRD_OF_PREY = 655,
SKILL_PET_WIND_SERPENT = 656,
SKILL_LANG_GUTTERSPEAK = 673,
SKILL_RIDING_KODO = 713,
@@ -1849,10 +2147,41 @@ enum SkillType
SKILL_PET_WARP_STALKER = 766,
SKILL_PET_RAVAGER = 767,
SKILL_PET_SERPENT = 768,
- SKILL_INTERNAL = 769
+ SKILL_INTERNAL = 769,
+ SKILL_DK_BLOOD = 770,
+ SKILL_DK_FROST = 771,
+ SKILL_DK_UNHOLY = 772,
+ SKILL_INSCRIPTION = 773,
+ SKILL_PET_MOTH = 775,
+ SKILL_RUNEFORGING = 776,
+ SKILL_MOUNTS = 777,
+ SKILL_COMPANIONS = 778,
+ SKILL_PET_EXOTIC_CHIMAERA = 780,
+ SKILL_PET_EXOTIC_DEVILSAUR = 781,
+ SKILL_PET_GHOUL = 782,
+ SKILL_PET_EXOTIC_SILITHID = 783,
+ SKILL_PET_EXOTIC_WORM = 784,
+ SKILL_PET_WASP = 785,
+ SKILL_PET_EXOTIC_RHINO = 786,
+ SKILL_PET_EXOTIC_CORE_HOUND = 787,
+ SKILL_PET_EXOTIC_SPIRIT_BEAST = 788
};
-#define MAX_SKILL_TYPE 770
+#define MAX_SKILL_TYPE 789
+
+inline SkillType SkillByLockType(LockType locktype)
+{
+ switch(locktype)
+ {
+ case LOCKTYPE_PICKLOCK: return SKILL_LOCKPICKING;
+ case LOCKTYPE_HERBALISM: return SKILL_HERBALISM;
+ case LOCKTYPE_MINING: return SKILL_MINING;
+ case LOCKTYPE_FISHING: return SKILL_FISHING;
+ case LOCKTYPE_INSCRIPTION: return SKILL_INSCRIPTION;
+ default: break;
+ }
+ return SKILL_NONE;
+}
inline uint32 SkillByQuestSort(int32 QuestSort)
{
@@ -1867,25 +2196,27 @@ inline uint32 SkillByQuestSort(int32 QuestSort)
case QUEST_SORT_TAILORING: return SKILL_TAILORING;
case QUEST_SORT_COOKING: return SKILL_COOKING;
case QUEST_SORT_FIRST_AID: return SKILL_FIRST_AID;
+ case QUEST_SORT_JEWELCRAFTING: return SKILL_JEWELCRAFTING;
+ case QUEST_SORT_INSCRIPTION: return SKILL_INSCRIPTION;
}
return 0;
}
enum SkillCategory
{
- SKILL_CATEGORY_ATTRIBUTES = 5,
- SKILL_CATEGORY_WEAPON = 6,
- SKILL_CATEGORY_CLASS = 7,
- SKILL_CATEGORY_ARMOR = 8,
- SKILL_CATEGORY_SECONDARY = 9, // secondary professions
+ SKILL_CATEGORY_ATTRIBUTES = 5,
+ SKILL_CATEGORY_WEAPON = 6,
+ SKILL_CATEGORY_CLASS = 7,
+ SKILL_CATEGORY_ARMOR = 8,
+ SKILL_CATEGORY_SECONDARY = 9, // secondary professions
SKILL_CATEGORY_LANGUAGES = 10,
SKILL_CATEGORY_PROFESSION = 11, // primary professions
- SKILL_CATEGORY_NOT_DISPLAYED = 12
+ SKILL_CATEGORY_GENERIC = 12
};
enum TotemCategory
{
- TC_SKINNING_SKIFE = 1,
+ TC_SKINNING_SKIFE_OLD = 1,
TC_EARTH_TOTEM = 2,
TC_AIR_TOTEM = 3,
TC_FIRE_TOTEM = 4,
@@ -1895,15 +2226,28 @@ enum TotemCategory
TC_GOLDEN_ROD = 8,
TC_TRUESILVER_ROD = 9,
TC_ARCANITE_ROD = 10,
- TC_MINING_PICK = 11,
+ TC_MINING_PICK_OLD = 11,
TC_PHILOSOPHERS_STONE = 12,
- TC_BLACKSMITH_HAMMER = 13,
+ TC_BLACKSMITH_HAMMER_OLD = 13,
TC_ARCLIGHT_SPANNER = 14,
TC_GYROMATIC_MA = 15,
TC_MASTER_TOTEM = 21,
TC_FEL_IRON_ROD = 41,
TC_ADAMANTITE_ROD = 62,
- TC_ETERNIUM_ROD = 63
+ TC_ETERNIUM_ROD = 63,
+ TC_HOLLOW_QUILL = 81,
+ TC_RUNED_AZURITE_ROD = 101,
+ TC_VIRTUOSO_INKING_SET = 121,
+ TC_DRUMS = 141,
+ TC_GNOMISH_ARMY_KNIFE = 161,
+ TC_BLACKSMITH_HAMMER = 162,
+ TC_MINING_PICK = 165,
+ TC_SKINNING_KNIFE = 166,
+ TC_HAMMER_PICK = 167,
+ TC_BLADED_PICKAXE = 168,
+ TC_FLINT_AND_TINDER = 169,
+ TC_RUNED_COBALT_ROD = 189,
+ TC_RUNED_TITANIUM_ROD = 190
};
enum UnitDynFlags
@@ -1913,7 +2257,8 @@ enum UnitDynFlags
UNIT_DYNFLAG_OTHER_TAGGER = 0x0004,
UNIT_DYNFLAG_ROOTED = 0x0008,
UNIT_DYNFLAG_SPECIALINFO = 0x0010,
- UNIT_DYNFLAG_DEAD = 0x0020
+ UNIT_DYNFLAG_DEAD = 0x0020,
+ UNIT_DYNFLAG_REFER_A_FRIEND = 0x0040
};
enum CorpseDynFlags
@@ -1922,11 +2267,14 @@ enum CorpseDynFlags
};
// Passive Spell codes explicit used in code
-#define SPELL_ID_GENERIC_LEARN 483
-#define SPELL_ID_PASSIVE_BATTLE_STANCE 2457
-#define SPELL_ID_PASSIVE_RESURRECTION_SICKNESS 15007
-#define SPELL_ID_WEAPON_SWITCH_COOLDOWN_1_5s 6119
-#define SPELL_ID_WEAPON_SWITCH_COOLDOWN_1_0s 6123
+#define SPELL_ID_GENERIC_LEARN 483
+#define SPELL_ID_GENERIC_LEARN_PET 55884 // used for learning mounts and companions
+#define SPELL_ID_PASSIVE_BATTLE_STANCE 2457
+#define SPELL_ID_PASSIVE_RESURRECTION_SICKNESS 15007
+#define SPELL_ID_WEAPON_SWITCH_COOLDOWN_1_5s 6119
+#define SPELL_ID_WEAPON_SWITCH_COOLDOWN_1_0s 6123
+#define SPELL_ID_AUTOSHOT 75 // used for checks in other spells interruption
+#define SPELL_ID_SHADOWMELD 58984 // used for check ignore stealth stance state
enum WeatherType
{
@@ -1990,9 +2338,12 @@ enum ChatMsg
CHAT_MSG_BATTLEGROUND = 0x2C,
CHAT_MSG_BATTLEGROUND_LEADER = 0x2D,
CHAT_MSG_RESTRICTED = 0x2E,
+ CHAT_MSG_BN = 0x2F,
+ CHAT_MSG_ACHIEVEMENT = 0x30,
+ CHAT_MSG_GUILD_ACHIEVEMENT = 0x31
};
-#define MAX_CHAT_MSG_TYPE 0x2F
+#define MAX_CHAT_MSG_TYPE 0x32
// Values from ItemPetFood (power of (value-1) used for compare with CreatureFamilyEntry.petDietMask
enum PetDiet
@@ -2072,27 +2423,29 @@ enum DungeonDifficulties
TOTAL_DIFFICULTIES
};
+enum SummonCategory
+{
+ SUMMON_CATEGORY_WILD = 0,
+ SUMMON_CATEGORY_ALLY = 1,
+ SUMMON_CATEGORY_PET = 2,
+ SUMMON_CATEGORY_POSSESSED = 3,
+ SUMMON_CATEGORY_VEHICLE = 4,
+};
+
enum SummonType
{
- SUMMON_TYPE_CRITTER = 41,
- SUMMON_TYPE_GUARDIAN = 61,
- SUMMON_TYPE_TOTEM_SLOT1 = 63,
- SUMMON_TYPE_WILD = 64,
- SUMMON_TYPE_POSESSED = 65,
- SUMMON_TYPE_DEMON = 66,
- SUMMON_TYPE_SUMMON = 67,
- SUMMON_TYPE_TOTEM_SLOT2 = 81,
- SUMMON_TYPE_TOTEM_SLOT3 = 82,
- SUMMON_TYPE_TOTEM_SLOT4 = 83,
- SUMMON_TYPE_TOTEM = 121,
- SUMMON_TYPE_UNKNOWN3 = 181,
- SUMMON_TYPE_UNKNOWN4 = 187,
- SUMMON_TYPE_UNKNOWN1 = 247,
- SUMMON_TYPE_CRITTER2 = 407,
- SUMMON_TYPE_CRITTER3 = 307,
- SUMMON_TYPE_UNKNOWN5 = 409,
- SUMMON_TYPE_POSESSED3 = 427,
- SUMMON_TYPE_POSESSED2 = 428
+ SUMMON_TYPE_NONE = 0,
+ SUMMON_TYPE_PET = 1,
+ SUMMON_TYPE_GUARDIAN = 2,
+ SUMMON_TYPE_MINION = 3,
+ SUMMON_TYPE_TOTEM = 4,
+ SUMMON_TYPE_MINIPET = 5,
+ SUMMON_TYPE_GUARDIAN2 = 6,
+ SUMMON_TYPE_WILD2 = 7,
+ SUMMON_TYPE_WILD3 = 8,
+ SUMMON_TYPE_VEHICLE = 9,
+ SUMMON_TYPE_VEHICLE2 = 10,
+ SUMMON_TYPE_OBJECT = 11,
};
enum ResponseCodes
@@ -2161,42 +2514,45 @@ enum ResponseCodes
CHAR_CREATE_SERVER_QUEUE = 0x37,
CHAR_CREATE_ONLY_EXISTING = 0x38,
CHAR_CREATE_EXPANSION = 0x39,
-
- CHAR_DELETE_IN_PROGRESS = 0x3A,
- CHAR_DELETE_SUCCESS = 0x3B,
- CHAR_DELETE_FAILED = 0x3C,
- CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 0x3D,
- CHAR_DELETE_FAILED_GUILD_LEADER = 0x3E,
- CHAR_DELETE_FAILED_ARENA_CAPTAIN = 0x3F,
-
- CHAR_LOGIN_IN_PROGRESS = 0x40,
- CHAR_LOGIN_SUCCESS = 0x41,
- CHAR_LOGIN_NO_WORLD = 0x42,
- CHAR_LOGIN_DUPLICATE_CHARACTER = 0x43,
- CHAR_LOGIN_NO_INSTANCES = 0x44,
- CHAR_LOGIN_FAILED = 0x45,
- CHAR_LOGIN_DISABLED = 0x46,
- CHAR_LOGIN_NO_CHARACTER = 0x47,
- CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x48,
- CHAR_LOGIN_LOCKED_BY_BILLING = 0x49,
-
- CHAR_NAME_SUCCESS = 0x4A,
- CHAR_NAME_FAILURE = 0x4B,
- CHAR_NAME_NO_NAME = 0x4C,
- CHAR_NAME_TOO_SHORT = 0x4D,
- CHAR_NAME_TOO_LONG = 0x4E,
- CHAR_NAME_INVALID_CHARACTER = 0x4F,
- CHAR_NAME_MIXED_LANGUAGES = 0x50,
- CHAR_NAME_PROFANE = 0x51,
- CHAR_NAME_RESERVED = 0x52,
- CHAR_NAME_INVALID_APOSTROPHE = 0x53,
- CHAR_NAME_MULTIPLE_APOSTROPHES = 0x54,
- CHAR_NAME_THREE_CONSECUTIVE = 0x55,
- CHAR_NAME_INVALID_SPACE = 0x56,
- CHAR_NAME_CONSECUTIVE_SPACES = 0x57,
- CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x58,
- CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x59,
- CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x5A,
+ CHAR_CREATE_EXPANSION_CLASS = 0x3A,
+ CHAR_CREATE_LEVEL_REQUIREMENT = 0x3B,
+ CHAR_CREATE_UNIQUE_CLASS_LIMIT = 0x3C,
+
+ CHAR_DELETE_IN_PROGRESS = 0x3D,
+ CHAR_DELETE_SUCCESS = 0x3E,
+ CHAR_DELETE_FAILED = 0x3F,
+ CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 0x40,
+ CHAR_DELETE_FAILED_GUILD_LEADER = 0x41,
+ CHAR_DELETE_FAILED_ARENA_CAPTAIN = 0x42,
+
+ CHAR_LOGIN_IN_PROGRESS = 0x43,
+ CHAR_LOGIN_SUCCESS = 0x44,
+ CHAR_LOGIN_NO_WORLD = 0x45,
+ CHAR_LOGIN_DUPLICATE_CHARACTER = 0x46,
+ CHAR_LOGIN_NO_INSTANCES = 0x47,
+ CHAR_LOGIN_FAILED = 0x48,
+ CHAR_LOGIN_DISABLED = 0x49,
+ CHAR_LOGIN_NO_CHARACTER = 0x4A,
+ CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x4B,
+ CHAR_LOGIN_LOCKED_BY_BILLING = 0x4C,
+
+ CHAR_NAME_SUCCESS = 0x4D,
+ CHAR_NAME_FAILURE = 0x4E,
+ CHAR_NAME_NO_NAME = 0x4F,
+ CHAR_NAME_TOO_SHORT = 0x50,
+ CHAR_NAME_TOO_LONG = 0x51,
+ CHAR_NAME_INVALID_CHARACTER = 0x52,
+ CHAR_NAME_MIXED_LANGUAGES = 0x53,
+ CHAR_NAME_PROFANE = 0x54,
+ CHAR_NAME_RESERVED = 0x55,
+ CHAR_NAME_INVALID_APOSTROPHE = 0x56,
+ CHAR_NAME_MULTIPLE_APOSTROPHES = 0x57,
+ CHAR_NAME_THREE_CONSECUTIVE = 0x58,
+ CHAR_NAME_INVALID_SPACE = 0x59,
+ CHAR_NAME_CONSECUTIVE_SPACES = 0x5A,
+ CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x5B,
+ CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x5C,
+ CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x5D
};
/// Ban function modes
@@ -2214,5 +2570,24 @@ enum BanReturn
BAN_SYNTAX_ERROR,
BAN_NOTFOUND
};
+
+// indexes of BattlemasterList.dbc
+enum BattleGroundTypeId
+{
+ BATTLEGROUND_TYPE_NONE = 0,
+ BATTLEGROUND_AV = 1,
+ BATTLEGROUND_WS = 2,
+ BATTLEGROUND_AB = 3,
+ BATTLEGROUND_NA = 4,
+ BATTLEGROUND_BE = 5,
+ BATTLEGROUND_AA = 6,
+ BATTLEGROUND_EY = 7,
+ BATTLEGROUND_RL = 8,
+ BATTLEGROUND_SA = 9,
+ BATTLEGROUND_DS = 10,
+ BATTLEGROUND_RV = 11
+};
+#define MAX_BATTLEGROUND_TYPE_ID 12
+
#endif
diff --git a/src/game/SkillDiscovery.cpp b/src/game/SkillDiscovery.cpp
index 5a5869047a5..7bd7b2347b1 100644
--- a/src/game/SkillDiscovery.cpp
+++ b/src/game/SkillDiscovery.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,7 +22,6 @@
#include "Log.h"
#include "ProgressBar.h"
#include "Policies/SingletonImp.h"
-#include "ObjectAccessor.h"
#include "World.h"
#include "Util.h"
#include "SkillDiscovery.h"
@@ -31,14 +30,15 @@
struct SkillDiscoveryEntry
{
- uint32 spellId;
- float chance;
+ uint32 spellId; // discavered spell
+ uint32 reqSkillValue; // skill level limitation
+ float chance; // chance
SkillDiscoveryEntry()
- : spellId(0), chance(0) {}
+ : spellId(0), reqSkillValue(0), chance(0) {}
- SkillDiscoveryEntry(uint16 _spellId, float _chance)
- : spellId(_spellId), chance(_chance) {}
+ SkillDiscoveryEntry(uint16 _spellId, uint32 req_skill_val, float _chance)
+ : spellId(_spellId), reqSkillValue(req_skill_val), chance(_chance) {}
};
typedef std::list<SkillDiscoveryEntry> SkillDiscoveryList;
@@ -53,8 +53,8 @@ void LoadSkillDiscoveryTable()
uint32 count = 0;
- // 0 1 2
- QueryResult *result = WorldDatabase.Query("SELECT spellId, reqSpell, chance FROM skill_discovery_template");
+ // 0 1 2 3
+ QueryResult *result = WorldDatabase.Query("SELECT spellId, reqSpell, reqSkillValue, chance FROM skill_discovery_template");
if (result)
{
@@ -69,11 +69,13 @@ void LoadSkillDiscoveryTable()
uint32 spellId = fields[0].GetUInt32();
int32 reqSkillOrSpell = fields[1].GetInt32();
- float chance = fields[2].GetFloat();
+ uint32 reqSkillValue = fields[2].GetInt32();
+ float chance = fields[3].GetFloat();
if( chance <= 0 ) // chance
{
- ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell << " chance = " << chance << "\n";
+ ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell
+ << " reqSkillValue = " << reqSkillValue << " chance = " << chance << "(chance problem)\n";
continue;
}
@@ -86,13 +88,16 @@ void LoadSkillDiscoveryTable()
continue;
}
- if( spellEntry->Mechanic != MECHANIC_DISCOVERY )
+ // mechanic discovery
+ if (spellEntry->Mechanic != MECHANIC_DISCOVERY &&
+ // explicit discovery ability
+ !IsExplicitDiscoverySpell(spellEntry))
{
- sLog.outErrorDb("Spell (ID: %u) not have have MECHANIC_DISCOVERY (28) value in Mechanic field in spell.dbc but listed in `skill_discovery_template` table",spellId);
+ sLog.outErrorDb("Spell (ID: %u) not have have MECHANIC_DISCOVERY (28) value in Mechanic field in spell.dbc and not 100% chance random discovery ability but listed in `skill_discovery_template` table",spellId);
continue;
}
- SkillDiscoveryStore[reqSkillOrSpell].push_back( SkillDiscoveryEntry(spellId, chance) );
+ SkillDiscoveryStore[reqSkillOrSpell].push_back( SkillDiscoveryEntry(spellId, reqSkillValue, chance) );
}
else if( reqSkillOrSpell == 0 ) // skill case
{
@@ -107,7 +112,7 @@ void LoadSkillDiscoveryTable()
for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
{
- SkillDiscoveryStore[-int32(_spell_idx->second->skillId)].push_back( SkillDiscoveryEntry(spellId, chance) );
+ SkillDiscoveryStore[-int32(_spell_idx->second->skillId)].push_back( SkillDiscoveryEntry(spellId, reqSkillValue, chance) );
}
}
else
@@ -115,6 +120,7 @@ void LoadSkillDiscoveryTable()
sLog.outErrorDb("Spell (ID: %u) have negative value in `reqSpell` field in `skill_discovery_template` table",spellId);
continue;
}
+
++count;
} while (result->NextRow());
@@ -132,16 +138,57 @@ void LoadSkillDiscoveryTable()
}
}
+uint32 GetExplicitDiscoverySpell(uint32 spellId, Player* player)
+{
+ // explicit discovery spell chances (always success if case exist)
+ // in this case we have both skill and spell
+ SkillDiscoveryMap::const_iterator tab = SkillDiscoveryStore.find(spellId);
+ if(tab == SkillDiscoveryStore.end())
+ return 0;
+
+ SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spellId);
+ SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spellId);
+ uint32 skillvalue = lower != upper ? player->GetSkillValue(lower->second->skillId) : 0;
+
+ float full_chance = 0;
+ for(SkillDiscoveryList::const_iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
+ if(item_iter->reqSkillValue <= skillvalue)
+ if(!player->HasSpell(item_iter->spellId))
+ full_chance += item_iter->chance;
+
+ float rate = full_chance / 100.0f;
+ float roll = rand_chance() * rate; // roll now in range 0..full_chance
+
+ for(SkillDiscoveryList::const_iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
+ {
+ if(item_iter->reqSkillValue > skillvalue)
+ continue;
+
+ if(player->HasSpell(item_iter->spellId))
+ continue;
+
+ if(item_iter->chance > roll)
+ return item_iter->spellId;
+
+ roll -= item_iter->chance;
+ }
+
+ return 0;
+}
+
uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player)
{
+ uint32 skillvalue = skillId ? player->GetSkillValue(skillId) : 0;
+
// check spell case
- SkillDiscoveryMap::iterator tab = SkillDiscoveryStore.find(spellId);
+ SkillDiscoveryMap::const_iterator tab = SkillDiscoveryStore.find(spellId);
if(tab != SkillDiscoveryStore.end())
{
- for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
+ for(SkillDiscoveryList::const_iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
{
if( roll_chance_f(item_iter->chance * sWorld.getRate(RATE_SKILL_DISCOVERY))
+ && item_iter->reqSkillValue <= skillvalue
&& !player->HasSpell(item_iter->spellId) )
return item_iter->spellId;
}
@@ -149,13 +196,17 @@ uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player)
return 0;
}
+ if(!skillId)
+ return 0;
+
// check skill line case
tab = SkillDiscoveryStore.find(-(int32)skillId);
if(tab != SkillDiscoveryStore.end())
{
- for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
+ for(SkillDiscoveryList::const_iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
{
if( roll_chance_f(item_iter->chance * sWorld.getRate(RATE_SKILL_DISCOVERY))
+ && item_iter->reqSkillValue <= skillvalue
&& !player->HasSpell(item_iter->spellId) )
return item_iter->spellId;
}
diff --git a/src/game/SkillDiscovery.h b/src/game/SkillDiscovery.h
index 350062101fe..9981eb133f6 100644
--- a/src/game/SkillDiscovery.h
+++ b/src/game/SkillDiscovery.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -27,5 +27,6 @@ class Player;
void LoadSkillDiscoveryTable();
uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player);
+uint32 GetExplicitDiscoverySpell(uint32 spellId, Player* player);
#endif
diff --git a/src/game/SkillExtraItems.cpp b/src/game/SkillExtraItems.cpp
index d89cbbdcddf..f0061f97c00 100644
--- a/src/game/SkillExtraItems.cpp
+++ b/src/game/SkillExtraItems.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/SkillExtraItems.h b/src/game/SkillExtraItems.h
index 38684b9933a..3a44619a862 100644
--- a/src/game/SkillExtraItems.h
+++ b/src/game/SkillExtraItems.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/SkillHandler.cpp b/src/game/SkillHandler.cpp
index 973d0bf9c39..2e1f09aaf5a 100644
--- a/src/game/SkillHandler.cpp
+++ b/src/game/SkillHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -23,12 +23,10 @@
#include "Opcodes.h"
#include "Log.h"
#include "Player.h"
-#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "ObjectAccessor.h"
#include "UpdateMask.h"
-#include "SpellAuras.h"
void WorldSession::HandleLearnTalentOpcode( WorldPacket & recv_data )
{
@@ -37,107 +35,7 @@ void WorldSession::HandleLearnTalentOpcode( WorldPacket & recv_data )
uint32 talent_id, requested_rank;
recv_data >> talent_id >> requested_rank;
- uint32 CurTalentPoints = GetPlayer()->GetFreeTalentPoints();
-
- if(CurTalentPoints == 0)
- return;
-
- if (requested_rank > 4)
- return;
-
- TalentEntry const *talentInfo = sTalentStore.LookupEntry( talent_id );
-
- if(!talentInfo)
- return;
-
- TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
-
- if(!talentTabInfo)
- return;
-
- Player * player = GetPlayer();
-
- // prevent learn talent for different class (cheating)
- if( (player->getClassMask() & talentTabInfo->ClassMask) == 0 )
- return;
-
- // prevent skip talent ranks (cheating)
- if(requested_rank > 0 && !player->HasSpell(talentInfo->RankID[requested_rank-1]))
- return;
-
- // Check if it requires another talent
- if (talentInfo->DependsOn > 0)
- {
- if(TalentEntry const *depTalentInfo = sTalentStore.LookupEntry(talentInfo->DependsOn))
- {
- bool hasEnoughRank = false;
- for (int i = talentInfo->DependsOnRank; i <= 4; i++)
- {
- if (depTalentInfo->RankID[i] != 0)
- if (player->HasSpell(depTalentInfo->RankID[i]))
- hasEnoughRank = true;
- }
- if (!hasEnoughRank)
- return;
- }
- }
-
- // Check if it requires spell
- if( talentInfo->DependsOnSpell && !player->HasSpell(talentInfo->DependsOnSpell) )
- return;
-
- // Find out how many points we have in this field
- uint32 spentPoints = 0;
-
- uint32 tTab = talentInfo->TalentTab;
- if (talentInfo->Row > 0)
- {
- unsigned int numRows = sTalentStore.GetNumRows();
- for (unsigned int i = 0; i < numRows; i++) // Loop through all talents.
- {
- // Someday, someone needs to revamp
- const TalentEntry *tmpTalent = sTalentStore.LookupEntry(i);
- if (tmpTalent) // the way talents are tracked
- {
- if (tmpTalent->TalentTab == tTab)
- {
- for (int j = 0; j <= 4; j++)
- {
- if (tmpTalent->RankID[j] != 0)
- {
- if (player->HasSpell(tmpTalent->RankID[j]))
- {
- spentPoints += j + 1;
- }
- }
- }
- }
- }
- }
- }
-
- // not have required min points spent in talent tree
- if(spentPoints < (talentInfo->Row * 5))
- return;
-
- // spell not set in talent.dbc
- uint32 spellid = talentInfo->RankID[requested_rank];
- if( spellid == 0 )
- {
- sLog.outError("Talent.dbc have for talent: %u Rank: %u spell id = 0", talent_id, requested_rank);
- return;
- }
-
- // already known
- if(GetPlayer( )->HasSpell(spellid))
- return;
-
- // learn! (other talent ranks will unlearned at learning)
- GetPlayer( )->learnSpell(spellid);
- sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talent_id, requested_rank, spellid);
-
- // update free talent points
- GetPlayer()->SetFreeTalentPoints(CurTalentPoints - 1);
+ _player->LearnTalent(talent_id, requested_rank);
}
void WorldSession::HandleTalentWipeOpcode( WorldPacket & recv_data )
@@ -148,7 +46,7 @@ void WorldSession::HandleTalentWipeOpcode( WorldPacket & recv_data )
uint64 guid;
recv_data >> guid;
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_TRAINER);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_TRAINER);
if (!unit)
{
sLog.outDebug( "WORLD: HandleTalentWipeOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
@@ -157,7 +55,7 @@ void WorldSession::HandleTalentWipeOpcode( WorldPacket & recv_data )
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
if(!(_player->resetTalents()))
{
diff --git a/src/game/SocialMgr.cpp b/src/game/SocialMgr.cpp
index 8f9db3e469d..1fc3f83ab1b 100644
--- a/src/game/SocialMgr.cpp
+++ b/src/game/SocialMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -23,7 +23,6 @@
#include "Database/DatabaseEnv.h"
#include "Opcodes.h"
#include "WorldPacket.h"
-#include "WorldSession.h"
#include "Player.h"
#include "ObjectMgr.h"
#include "World.h"
@@ -44,10 +43,10 @@ PlayerSocial::~PlayerSocial()
uint32 PlayerSocial::GetNumberOfSocialsWithFlag(SocialFlag flag)
{
uint32 counter = 0;
- for(PlayerSocialMap::iterator itr = m_playerSocialMap.begin(); itr != m_playerSocialMap.end(); ++itr)
+ for(PlayerSocialMap::const_iterator itr = m_playerSocialMap.begin(); itr != m_playerSocialMap.end(); ++itr)
{
if(itr->second.Flags & flag)
- counter++;
+ ++counter;
}
return counter;
}
@@ -70,7 +69,7 @@ bool PlayerSocial::AddToSocialList(uint32 friend_guid, bool ignore)
if(ignore)
flag = SOCIAL_FLAG_IGNORED;
- PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
+ PlayerSocialMap::const_iterator itr = m_playerSocialMap.find(friend_guid);
if(itr != m_playerSocialMap.end())
{
CharacterDatabase.PExecute("UPDATE character_social SET flags = (flags | %u) WHERE guid = '%u' AND friend = '%u'", flag, GetPlayerGUID(), friend_guid);
@@ -110,7 +109,7 @@ void PlayerSocial::RemoveFromSocialList(uint32 friend_guid, bool ignore)
void PlayerSocial::SetFriendNote(uint32 friend_guid, std::string note)
{
- PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
+ PlayerSocialMap::const_iterator itr = m_playerSocialMap.find(friend_guid);
if(itr == m_playerSocialMap.end()) // not exist
return;
@@ -158,7 +157,7 @@ void PlayerSocial::SendSocialList()
bool PlayerSocial::HasFriend(uint32 friend_guid)
{
- PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
+ PlayerSocialMap::const_iterator itr = m_playerSocialMap.find(friend_guid);
if(itr != m_playerSocialMap.end())
return itr->second.Flags & SOCIAL_FLAG_FRIEND;
return false;
@@ -166,7 +165,7 @@ bool PlayerSocial::HasFriend(uint32 friend_guid)
bool PlayerSocial::HasIgnore(uint32 ignore_guid)
{
- PlayerSocialMap::iterator itr = m_playerSocialMap.find(ignore_guid);
+ PlayerSocialMap::const_iterator itr = m_playerSocialMap.find(ignore_guid);
if(itr != m_playerSocialMap.end())
return itr->second.Flags & SOCIAL_FLAG_IGNORED;
return false;
@@ -182,13 +181,6 @@ SocialMgr::~SocialMgr()
}
-void SocialMgr::RemovePlayerSocial(uint32 guid)
-{
- SocialMap::iterator itr = m_socialMap.find(guid);
- if(itr != m_socialMap.end())
- m_socialMap.erase(itr);
-}
-
void SocialMgr::GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &friendInfo)
{
if(!player)
@@ -204,7 +196,7 @@ void SocialMgr::GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &fri
return;
uint32 team = player->GetTeam();
- uint32 security = player->GetSession()->GetSecurity();
+ AccountTypes security = player->GetSession()->GetSecurity();
bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST) || security > SEC_PLAYER;
@@ -275,14 +267,14 @@ void SocialMgr::BroadcastToFriendListers(Player *player, WorldPacket *packet)
return;
uint32 team = player->GetTeam();
- uint32 security = player->GetSession()->GetSecurity();
+ AccountTypes security = player->GetSession()->GetSecurity();
uint32 guid = player->GetGUIDLow();
bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST);
bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
- for(SocialMap::iterator itr = m_socialMap.begin(); itr != m_socialMap.end(); ++itr)
+ for(SocialMap::const_iterator itr = m_socialMap.begin(); itr != m_socialMap.end(); ++itr)
{
- PlayerSocialMap::iterator itr2 = itr->second.m_playerSocialMap.find(guid);
+ PlayerSocialMap::const_iterator itr2 = itr->second.m_playerSocialMap.find(guid);
if(itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND))
{
Player *pFriend = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));
diff --git a/src/game/SocialMgr.h b/src/game/SocialMgr.h
index f5bf3c8600c..1ca04d69707 100644
--- a/src/game/SocialMgr.h
+++ b/src/game/SocialMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -143,7 +143,8 @@ class SocialMgr
SocialMgr();
~SocialMgr();
// Misc
- void RemovePlayerSocial(uint32 guid);
+ void RemovePlayerSocial(uint32 guid) { m_socialMap.erase(guid); }
+
void GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &friendInfo);
// Packet management
void MakeFriendStatusPacket(FriendsResult result, uint32 friend_guid, WorldPacket *data);
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 27667f0ddc3..5ffb17d05ac 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -33,9 +33,9 @@
#include "Player.h"
#include "Pet.h"
#include "Unit.h"
+#include "Totem.h"
#include "Spell.h"
#include "DynamicObject.h"
-#include "SpellAuras.h"
#include "Group.h"
#include "UpdateData.h"
#include "MapManager.h"
@@ -43,14 +43,13 @@
#include "CellImpl.h"
#include "Policies/SingletonImp.h"
#include "SharedDefines.h"
-#include "Tools.h"
#include "LootMgr.h"
#include "VMapFactory.h"
#include "BattleGround.h"
#include "Util.h"
#include "TemporarySummon.h"
-#define SPELL_CHANNEL_UPDATE_INTERVAL 1000
+#define SPELL_CHANNEL_UPDATE_INTERVAL (1*IN_MILISECONDS)
extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS];
@@ -120,6 +119,14 @@ void SpellCastTargets::setDestination(Unit *target, bool send)
m_targetMask |= TARGET_FLAG_DEST_LOCATION;
}
+void SpellCastTargets::setSource(float x, float y, float z)
+{
+ m_srcX = x;
+ m_srcY = y;
+ m_srcZ = z;
+ m_targetMask |= TARGET_FLAG_SOURCE_LOCATION;
+}
+
void SpellCastTargets::setGOTarget(GameObject *target)
{
m_GOTarget = target;
@@ -145,7 +152,7 @@ void SpellCastTargets::setCorpseTarget(Corpse* corpse)
void SpellCastTargets::Update(Unit* caster)
{
- m_GOTarget = m_GOTargetGUID ? ObjectAccessor::GetGameObject(*caster,m_GOTargetGUID) : NULL;
+ m_GOTarget = m_GOTargetGUID ? caster->GetMap()->GetGameObject(m_GOTargetGUID) : NULL;
m_unitTarget = m_unitTargetGUID ?
( m_unitTargetGUID==caster->GetGUID() ? caster : ObjectAccessor::GetUnit(*caster, m_unitTargetGUID) ) :
NULL;
@@ -171,6 +178,8 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )
if(data->rpos()+4 > data->size())
return false;
+ //data->hexlike();
+
*data >> m_targetMask;
sLog.outDebug("Spell read, target mask = %u", m_targetMask);
@@ -178,19 +187,23 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )
return true;
// TARGET_FLAG_UNK2 is used for non-combat pets, maybe other?
- if( m_targetMask & (TARGET_FLAG_UNIT|TARGET_FLAG_UNK2) )
- if(!readGUID(*data, m_unitTargetGUID))
+ if( m_targetMask & ( TARGET_FLAG_UNIT | TARGET_FLAG_UNK2 ))
+ if(!data->readPackGUID(m_unitTargetGUID))
return false;
- if( m_targetMask & ( TARGET_FLAG_OBJECT | TARGET_FLAG_OBJECT_UNK ))
- if(!readGUID(*data, m_GOTargetGUID))
+ if( m_targetMask & ( TARGET_FLAG_OBJECT ))
+ if(!data->readPackGUID(m_GOTargetGUID))
return false;
if(( m_targetMask & ( TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM )) && caster->GetTypeId() == TYPEID_PLAYER)
- if(!readGUID(*data, m_itemTargetGUID))
+ if(!data->readPackGUID(m_itemTargetGUID))
+ return false;
+
+ if( m_targetMask & (TARGET_FLAG_CORPSE | TARGET_FLAG_PVP_CORPSE ) )
+ if(!data->readPackGUID(m_CorpseTargetGUID))
return false;
- /*if( m_targetMask & TARGET_FLAG_SOURCE_LOCATION )
+ if( m_targetMask & TARGET_FLAG_SOURCE_LOCATION )
{
if(data->rpos()+4+4+4 > data->size())
return false;
@@ -198,17 +211,23 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )
*data >> m_srcX >> m_srcY >> m_srcZ;
if(!Trinity::IsValidMapCoord(m_srcX, m_srcY, m_srcZ))
return false;
- }*/
- if( m_targetMask & (TARGET_FLAG_SOURCE_LOCATION | TARGET_FLAG_DEST_LOCATION) )
+ m_hasDest = true;
+ }
+
+ if( m_targetMask & TARGET_FLAG_DEST_LOCATION )
{
- if(data->rpos()+4+4+4 > data->size())
+ if(data->rpos()+1+4+4+4 > data->size())
+ return false;
+
+ if(!data->readPackGUID(m_unitTargetGUID))
return false;
*data >> m_destX >> m_destY >> m_destZ;
- m_hasDest = true;
if(!Trinity::IsValidMapCoord(m_destX, m_destY, m_destZ))
return false;
+
+ m_hasDest = true;
}
if( m_targetMask & TARGET_FLAG_STRING )
@@ -219,10 +238,6 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )
*data >> m_strTarget;
}
- if( m_targetMask & (TARGET_FLAG_CORPSE | TARGET_FLAG_PVP_CORPSE ) )
- if(!readGUID(*data, m_CorpseTargetGUID))
- return false;
-
// find real units/GOs
Update(caster);
return true;
@@ -242,7 +257,7 @@ void SpellCastTargets::write ( WorldPacket * data )
else
*data << uint8(0);
}
- else if( m_targetMask & ( TARGET_FLAG_OBJECT | TARGET_FLAG_OBJECT_UNK ) )
+ else if( m_targetMask & TARGET_FLAG_OBJECT )
{
if(m_GOTarget)
data->append(m_GOTarget->GetPackGUID());
@@ -267,7 +282,14 @@ void SpellCastTargets::write ( WorldPacket * data )
*data << m_srcX << m_srcY << m_srcZ;
if( m_targetMask & TARGET_FLAG_DEST_LOCATION )
+ {
+ if(m_unitTarget)
+ data->append(m_unitTarget->GetPackGUID());
+ else
+ *data << uint8(0);
+
*data << m_destX << m_destY << m_destZ;
+ }
if( m_targetMask & TARGET_FLAG_STRING )
*data << m_strTarget;
@@ -283,6 +305,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
m_triggeringContainer = triggeringContainer;
m_referencedFromCurrentSpell = false;
m_executedCurrently = false;
+ m_needComboPoints = NeedsComboPoints(m_spellInfo);
m_delayStart = 0;
m_delayAtDamageCount = 0;
@@ -302,7 +325,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
break;
default:
// Wands
- if (m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_REQ_WAND)
+ if (m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG)
m_attackType = RANGED_ATTACK;
else
m_attackType = BASE_ATTACK;
@@ -317,7 +340,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
if((m_caster->getClassMask() & CLASSMASK_WAND_USERS) != 0 && m_caster->GetTypeId()==TYPEID_PLAYER)
{
if(Item* pItem = ((Player*)m_caster)->GetWeaponForAttack(RANGED_ATTACK))
- m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetProto()->Damage->DamageType);
+ m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetProto()->Damage[0].DamageType);
}
}
// Set health leech amount to zero
@@ -352,14 +375,15 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
gameObjTarget = NULL;
focusObject = NULL;
m_cast_count = 0;
+ m_glyphIndex = 0;
+ m_preCastSpell = 0;
m_triggeredByAuraSpell = NULL;
+ m_spellAura = NULL;
- //Auto Shot & Shoot
- if( m_spellInfo->AttributesEx2 == 0x000020 && !triggered )
- m_autoRepeat = true;
- else
- m_autoRepeat = false;
+ //Auto Shot & Shoot (wand)
+ m_autoRepeat = IsAutoRepeatRangedSpell(m_spellInfo);
+ m_runesState = 0;
m_powerCost = 0; // setup to correct value in Spell::prepare, don't must be used before.
m_casttime = 0; // setup to correct value in Spell::prepare, don't must be used before.
m_timer = 0; // will set to castime in prepare
@@ -369,7 +393,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
// determine reflection
m_canReflect = false;
- if(m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && (m_spellInfo->AttributesEx2 & 0x4)==0)
+ if(m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_CANT_REFLECTED))
{
for(int j=0;j<3;j++)
{
@@ -441,8 +465,20 @@ void Spell::FillTargetMap()
continue;
}
+ if(tmpUnitMap.empty() && m_spellInfo->Targets & TARGET_FLAG_CASTER)
+ {
+ AddUnitTarget(m_caster, i);
+ continue;
+ }
+
if(!targetA && !targetB)
{
+ if(!GetSpellMaxRangeForFriend(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex)))
+ {
+ AddUnitTarget(m_caster, i);
+ continue;
+ }
+
// add here custom effects that need default target.
// FOR EVERY TARGET TYPE THERE IS A DIFFERENT FILL!!
switch(m_spellInfo->Effect[i])
@@ -455,11 +491,11 @@ void Spell::FillTargetMap()
{
// non-standard target selection
SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex);
- float max_range = GetSpellMaxRange(srange);
+ float max_range = GetSpellMaxRangeForHostile(srange);
WorldObject* result = NULL;
Trinity::CannibalizeObjectCheck u_check(m_caster, max_range);
- Trinity::WorldObjectSearcher<Trinity::CannibalizeObjectCheck > searcher(result, u_check);
+ Trinity::WorldObjectSearcher<Trinity::CannibalizeObjectCheck > searcher(m_caster, result, u_check);
m_caster->VisitNearbyGridObject(max_range, searcher);
if(!result)
m_caster->VisitNearbyWorldObject(max_range, searcher);
@@ -509,12 +545,15 @@ void Spell::FillTargetMap()
case SPELL_EFFECT_CREATE_ITEM:
case SPELL_EFFECT_TRIGGER_SPELL:
case SPELL_EFFECT_SKILL_STEP:
+ case SPELL_EFFECT_PROFICIENCY:
+ case SPELL_EFFECT_SUMMON_OBJECT_WILD:
case SPELL_EFFECT_SELF_RESURRECT:
case SPELL_EFFECT_REPUTATION:
case SPELL_EFFECT_LEARN_SPELL:
if(m_targets.getUnitTarget())
tmpUnitMap.push_back(m_targets.getUnitTarget());
- else
+ // Triggered spells have additional spell targets - cast them even if no explicit unit target is given (required for spell 50516 for example)
+ else if(m_spellInfo->Effect[i] == SPELL_EFFECT_TRIGGER_SPELL)
tmpUnitMap.push_back(m_caster);
break;
case SPELL_EFFECT_SUMMON_PLAYER:
@@ -541,19 +580,22 @@ void Spell::FillTargetMap()
break;
case SPELL_EFFECT_SUMMON_CHANGE_ITEM:
case SPELL_EFFECT_ADD_FARSIGHT:
+ case SPELL_EFFECT_APPLY_GLYPH:
case SPELL_EFFECT_STUCK:
+ case SPELL_EFFECT_FEED_PET:
case SPELL_EFFECT_DESTROY_ALL_TOTEMS:
tmpUnitMap.push_back(m_caster);
break;
case SPELL_EFFECT_LEARN_PET_SPELL:
- if(Pet* pet = m_caster->GetPet())
+ if(Guardian* pet = m_caster->GetGuardianPet())
tmpUnitMap.push_back(pet);
break;
/*case SPELL_EFFECT_ENCHANT_ITEM:
case SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY:
+ case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC:
case SPELL_EFFECT_DISENCHANT:
- case SPELL_EFFECT_FEED_PET:
case SPELL_EFFECT_PROSPECTING:
+ case SPELL_EFFECT_MILLING:
if(m_targets.getItemTarget())
AddItemTarget(m_targets.getItemTarget(), i);
break;*/
@@ -594,13 +636,12 @@ void Spell::FillTargetMap()
}
}
-
if(IsChanneledSpell(m_spellInfo) && !tmpUnitMap.empty())
m_needAliveTargetMask |= (1<<i);
for (std::list<Unit*>::iterator itr = tmpUnitMap.begin() ; itr != tmpUnitMap.end();)
{
- if(!CheckTarget(*itr, i, false ))
+ if(!CheckTarget(*itr, i))
{
itr = tmpUnitMap.erase(itr);
continue;
@@ -627,42 +668,9 @@ void Spell::FillTargetMap()
void Spell::prepareDataForTriggerSystem()
{
//==========================================================================================
- // Now fill data for trigger system, need know:
- // Ñan spell trigger another or not ( m_canTrigger )
// Create base triggers flags for Attacker and Victim ( m_procAttacker and m_procVictim)
//==========================================================================================
- // Fill flag can spell trigger or not
- if (!m_IsTriggeredSpell)
- m_canTrigger = true; // Normal cast - can trigger
- else if (!m_triggeredByAuraSpell)
- m_canTrigger = true; // Triggered from SPELL_EFFECT_TRIGGER_SPELL - can trigger
- else // Exceptions (some periodic triggers)
- {
- m_canTrigger = false; // Triggered spells can`t trigger another
- switch (m_spellInfo->SpellFamilyName)
- {
- case SPELLFAMILY_MAGE: // Arcane Missles / Blizzard triggers need do it
- if (m_spellInfo->SpellFamilyFlags & 0x0000000000200080LL) m_canTrigger = true;
- break;
- case SPELLFAMILY_WARLOCK: // For Hellfire Effect / Rain of Fire / Seed of Corruption triggers need do it
- if (m_spellInfo->SpellFamilyFlags & 0x0000800000000060LL) m_canTrigger = true;
- break;
- case SPELLFAMILY_HUNTER: // Hunter Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect
- if (m_spellInfo->SpellFamilyFlags & 0x0000200000000014LL) m_canTrigger = true;
- break;
- case SPELLFAMILY_PALADIN: // For Holy Shock triggers need do it
- if (m_spellInfo->SpellFamilyFlags & 0x0001000000200000LL) m_canTrigger = true;
- break;
- case SPELLFAMILY_ROGUE: // mutilate mainhand + offhand
- if (m_spellInfo->SpellFamilyFlags & 0x600000000LL) m_canTrigger = true;
- break;
- }
- }
- // Do not trigger from item cast spell
- if (m_CastItem)
- m_canTrigger = false;
-
// Get data for type of attack and fill base info for trigger
switch (m_spellInfo->DmgClass)
{
@@ -671,21 +679,30 @@ void Spell::prepareDataForTriggerSystem()
m_procVictim = PROC_FLAG_TAKEN_MELEE_SPELL_HIT;
break;
case SPELL_DAMAGE_CLASS_RANGED:
- m_procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT;
- m_procVictim = PROC_FLAG_TAKEN_RANGED_SPELL_HIT;
+ // Auto attack
+ if (m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG)
+ {
+ m_procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_HIT;
+ m_procVictim = PROC_FLAG_TAKEN_RANGED_HIT;
+ }
+ else // Ranged spell attack
+ {
+ m_procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT;
+ m_procVictim = PROC_FLAG_TAKEN_RANGED_SPELL_HIT;
+ }
break;
default:
- if (IsPositiveSpell(m_spellInfo->Id)) // Check for positive spell
+ if (IsPositiveSpell(m_spellInfo->Id)) // Check for positive spell
{
m_procAttacker = PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL;
m_procVictim = PROC_FLAG_TAKEN_POSITIVE_SPELL;
}
- else if (m_spellInfo->Id == 5019) // Wands
+ else if (m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG) // Wands auto attack
{
- m_procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT;
- m_procVictim = PROC_FLAG_TAKEN_RANGED_SPELL_HIT;
+ m_procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_HIT;
+ m_procVictim = PROC_FLAG_TAKEN_RANGED_HIT;
}
- else
+ else // Negative spell
{
m_procAttacker = PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT;
m_procVictim = PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT;
@@ -694,7 +711,7 @@ void Spell::prepareDataForTriggerSystem()
}
// Hunter traps spells (for Entrapment trigger)
// Gives your Immolation Trap, Frost Trap, Explosive Trap, and Snake Trap ....
- if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && m_spellInfo->SpellFamilyFlags & 0x0000200000000014LL)
+ if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && (m_spellInfo->SpellFamilyFlags[1] & 0x00002000 || m_spellInfo->SpellFamilyFlags[0] & 0x1C))
m_procAttacker |= PROC_FLAG_ON_TRAP_ACTIVATION;
}
@@ -703,8 +720,6 @@ void Spell::CleanupTargetList()
m_UniqueTargetInfo.clear();
m_UniqueGOTargetInfo.clear();
m_UniqueItemInfo.clear();
- m_countOfHit = 0;
- m_countOfMiss = 0;
m_delayMoment = 0;
}
@@ -713,6 +728,9 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
if( m_spellInfo->Effect[effIndex]==0 )
return;
+ // Check for effect immune skip if immuned
+ bool immuned = pVictim->IsImmunedToSpellEffect(m_spellInfo, effIndex);
+
uint64 targetGUID = pVictim->GetGUID();
// Lookup target in already in list
@@ -720,7 +738,8 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
{
if (targetGUID == ihit->targetGUID) // Found in list
{
- ihit->effectMask |= 1<<effIndex; // Add only effect mask
+ if (!immuned)
+ ihit->effectMask |= 1<<effIndex; // Add only effect mask if not immuned
return;
}
}
@@ -730,7 +749,7 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
// Get spell hit result on target
TargetInfo target;
target.targetGUID = targetGUID; // Store target GUID
- target.effectMask = 1<<effIndex; // Store index of effect
+ target.effectMask = immuned ? 0 : 1<<effIndex; // Store index of effect if not immuned
target.processed = false; // Effects not apply on target
target.damage = 0;
@@ -744,11 +763,6 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
else
target.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
- if (target.missCondition == SPELL_MISS_NONE)
- ++m_countOfHit;
- else
- ++m_countOfMiss;
-
// Spell have speed - need calculate incoming time
if (m_spellInfo->speed > 0.0f)
{
@@ -829,15 +843,13 @@ void Spell::AddGOTarget(GameObject* pVictim, uint32 effIndex)
else
target.timeDelay = 0LL;
- ++m_countOfHit;
-
// Add target to list
m_UniqueGOTargetInfo.push_back(target);
}
void Spell::AddGOTarget(uint64 goGUID, uint32 effIndex)
{
- GameObject* go = ObjectAccessor::GetGameObject(*m_caster, goGUID);
+ GameObject* go = m_caster->GetMap()->GetGameObject(goGUID);
if (go)
AddGOTarget(go, effIndex);
}
@@ -864,83 +876,6 @@ void Spell::AddItemTarget(Item* pitem, uint32 effIndex)
target.effectMask = 1<<effIndex;
m_UniqueItemInfo.push_back(target);
}
-/*
-void Spell::doTriggers(SpellMissInfo missInfo, uint32 damage, SpellSchoolMask damageSchoolMask, uint32 block, uint32 absorb, bool crit)
-{
- // Do triggers depends from hit result (triggers on hit do in effects)
- // Set aura states depends from hit result
- if (missInfo!=SPELL_MISS_NONE)
- {
- // Miss/dodge/parry/block only for melee based spells
- // Resist only for magic based spells
- switch (missInfo)
- {
- case SPELL_MISS_MISS:
- if(m_caster->GetTypeId()== TYPEID_PLAYER)
- ((Player*)m_caster)->UpdateWeaponSkill(BASE_ATTACK);
-
- m_caster->CastMeleeProcDamageAndSpell(unitTarget, 0, damageSchoolMask, m_attackType, MELEE_HIT_MISS, m_spellInfo, m_IsTriggeredSpell);
- break;
- case SPELL_MISS_RESIST:
- m_caster->ProcDamageAndSpell(unitTarget, PROC_FLAG_TARGET_RESISTS, PROC_FLAG_RESIST_SPELL, 0, damageSchoolMask, m_spellInfo, m_IsTriggeredSpell);
- break;
- case SPELL_MISS_DODGE:
- if(unitTarget->GetTypeId() == TYPEID_PLAYER)
- ((Player*)unitTarget)->UpdateDefense();
-
- // Overpower
- if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->getClass() == CLASS_WARRIOR)
- {
- ((Player*) m_caster)->AddComboPoints(unitTarget, 1);
- m_caster->StartReactiveTimer( REACTIVE_OVERPOWER );
- }
-
- // Riposte
- if (unitTarget->getClass() != CLASS_ROGUE)
- {
- unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true);
- unitTarget->StartReactiveTimer( REACTIVE_DEFENSE );
- }
-
- m_caster->CastMeleeProcDamageAndSpell(unitTarget, 0, damageSchoolMask, m_attackType, MELEE_HIT_DODGE, m_spellInfo, m_IsTriggeredSpell);
- break;
- case SPELL_MISS_PARRY:
- // Update victim defense ?
- if(unitTarget->GetTypeId() == TYPEID_PLAYER)
- ((Player*)unitTarget)->UpdateDefense();
- // Mongoose bite - set only Counterattack here
- if (unitTarget->getClass() == CLASS_HUNTER)
- {
- unitTarget->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true);
- unitTarget->StartReactiveTimer( REACTIVE_HUNTER_PARRY );
- }
- else
- {
- unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true);
- unitTarget->StartReactiveTimer( REACTIVE_DEFENSE );
- }
- m_caster->CastMeleeProcDamageAndSpell(unitTarget, 0, damageSchoolMask, m_attackType, MELEE_HIT_PARRY, m_spellInfo, m_IsTriggeredSpell);
- break;
- case SPELL_MISS_BLOCK:
- unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true);
- unitTarget->StartReactiveTimer( REACTIVE_DEFENSE );
-
- m_caster->CastMeleeProcDamageAndSpell(unitTarget, 0, damageSchoolMask, m_attackType, MELEE_HIT_BLOCK, m_spellInfo, m_IsTriggeredSpell);
- break;
- // Trigger from this events not supported
- case SPELL_MISS_EVADE:
- case SPELL_MISS_IMMUNE:
- case SPELL_MISS_IMMUNE2:
- case SPELL_MISS_DEFLECT:
- case SPELL_MISS_ABSORB:
- // Trigger from reflects need do after get reflect result
- case SPELL_MISS_REFLECT:
- break;
- default:
- break;
- }
- }
-}*/
void Spell::DoAllEffectOnTarget(TargetInfo *target)
{
@@ -950,15 +885,13 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Get mask of effects for target
uint32 mask = target->effectMask;
- if (mask == 0) // No effects
- return;
Unit* unit = m_caster->GetGUID()==target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster,target->targetGUID);
if (!unit)
return;
// Get original caster (if exist) and calculate damage/healing from him data
- Unit *caster = m_originalCasterGUID ? m_originalCaster : m_caster;
+ Unit *caster = m_originalCaster ? m_originalCaster : m_caster;
// Skip if m_originalCaster not avaiable
if (!caster)
@@ -977,25 +910,36 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Fill base trigger info
uint32 procAttacker = m_procAttacker;
uint32 procVictim = m_procVictim;
- uint32 procEx = PROC_EX_NONE;
+ uint32 procEx = m_triggeredByAuraSpell
+ && !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER)
+ && !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER_2)
+ ? PROC_EX_INTERNAL_TRIGGERED : PROC_EX_NONE;
+ m_spellAura = NULL; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
+ Unit * spellHitTarget = NULL;
if (missInfo==SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
- DoSpellHitOnUnit(unit, mask);
+ spellHitTarget = unit;
else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
{
if (target->reflectResult == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
- DoSpellHitOnUnit(m_caster, mask);
+ spellHitTarget = m_caster;
}
- /*else //TODO: This is a hack. need fix
+
+ if(spellHitTarget)
{
- uint32 tempMask = 0;
- for(uint32 i = 0; i < 3; ++i)
- if(m_spellInfo->Effect[i] == SPELL_EFFECT_DUMMY
- || m_spellInfo->Effect[i] == SPELL_EFFECT_TRIGGER_SPELL)
- tempMask |= 1<<i;
- if(tempMask &= mask)
- DoSpellHitOnUnit(unit, tempMask);
- }*/
+ SpellMissInfo missInfo = DoSpellHitOnUnit(spellHitTarget, mask);
+ if(missInfo != SPELL_MISS_NONE)
+ {
+ m_caster->SendSpellMiss(unit, m_spellInfo->Id, missInfo);
+ m_damage = 0;
+ spellHitTarget = NULL;
+ }
+ }
+
+ // Do not take combo points on dodge
+ if (m_needComboPoints && m_targets.getUnitTargetGUID() == target->targetGUID)
+ if( missInfo != SPELL_MISS_NONE && missInfo != SPELL_MISS_MISS)
+ m_needComboPoints = false;
// All calculated do it!
// Do healing and triggers
@@ -1006,23 +950,20 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
if (crit)
{
procEx |= PROC_EX_CRITICAL_HIT;
- addhealth = caster->SpellCriticalBonus(m_spellInfo, addhealth, NULL);
+ addhealth = caster->SpellCriticalHealingBonus(m_spellInfo, addhealth, NULL);
}
else
procEx |= PROC_EX_NORMAL_HIT;
- caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, crit);
-
// Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
- if (m_canTrigger && missInfo != SPELL_MISS_REFLECT)
+ if (missInfo != SPELL_MISS_REFLECT)
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo);
- int32 gain = unitTarget->ModifyHealth( int32(addhealth) );
+ if (m_spellAura)
+ m_spellAura->SetProcDamage(addhealth);
+ int32 gain = caster->DealHeal(unitTarget, addhealth, m_spellInfo, crit);
unitTarget->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
- if(caster->GetTypeId()==TYPEID_PLAYER)
- if(BattleGround *bg = ((Player*)caster)->GetBattleGround())
- bg->UpdatePlayerScore(((Player*)caster), SCORE_HEALING_DONE, gain);
}
// Do damage and triggers
else if (m_damage > 0)
@@ -1036,62 +977,33 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Send log damage message to client
caster->SendSpellNonMeleeDamageLog(&damageInfo);
- procEx = createProcExtendMask(&damageInfo, missInfo);
+ procEx |= createProcExtendMask(&damageInfo, missInfo);
procVictim |= PROC_FLAG_TAKEN_ANY_DAMAGE;
// Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
- if (m_canTrigger && missInfo != SPELL_MISS_REFLECT)
+ if (missInfo != SPELL_MISS_REFLECT)
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo);
+ if (m_spellAura)
+ m_spellAura->SetProcDamage(damageInfo.damage);
+
caster->DealSpellDamage(&damageInfo, true);
- // Shadow Word: Death - deals damage equal to damage done to caster if victim is not killed
- if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && m_spellInfo->SpellFamilyFlags&0x0000000200000000LL &&
- caster != unitTarget && unitTarget->isAlive())
- {
- // Redirect damage to caster if victim Alive
- damageInfo.target = caster;
- damageInfo.absorb = 0;
- damageInfo.resist = 0;
- damageInfo.blocked = 0;
- // Send log damage message to client
- caster->SendSpellNonMeleeDamageLog(&damageInfo);
- caster->DealSpellDamage(&damageInfo, true);
- }
// Judgement of Blood
- else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && m_spellInfo->SpellFamilyFlags & 0x0000000800000000LL && m_spellInfo->SpellIconID==153)
+ if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && m_spellInfo->SpellFamilyFlags[1] & 0x00000008 && m_spellInfo->SpellIconID==153)
{
int32 damagePoint = damageInfo.damage * 33 / 100;
m_caster->CastCustomSpell(m_caster, 32220, &damagePoint, NULL, NULL, true);
}
- // Bloodthirst
- else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellInfo->SpellFamilyFlags & 0x40000000000LL)
- {
- uint32 BTAura = 0;
- switch(m_spellInfo->Id)
- {
- case 23881: BTAura = 23885; break;
- case 23892: BTAura = 23886; break;
- case 23893: BTAura = 23887; break;
- case 23894: BTAura = 23888; break;
- case 25251: BTAura = 25252; break;
- case 30335: BTAura = 30339; break;
- default:
- sLog.outError("Spell::EffectSchoolDMG: Spell %u not handled in BTAura",m_spellInfo->Id);
- break;
- }
- if (BTAura)
- m_caster->CastSpell(m_caster,BTAura,true);
- }
}
// Passive spell hits/misses or active spells only misses (only triggers)
else
{
// Fill base damage struct (unitTarget - is real spell target)
SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
- procEx = createProcExtendMask(&damageInfo, missInfo);
+ procEx |= createProcExtendMask(&damageInfo, missInfo);
// Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
- if (m_canTrigger && missInfo != SPELL_MISS_REFLECT)
+ if (missInfo != SPELL_MISS_REFLECT)
caster->ProcDamageAndSpell(unit, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo);
}
@@ -1106,53 +1018,71 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
if( !m_caster->IsFriendlyTo(unit) && !IsPositiveSpell(m_spellInfo->Id))
{
- if( !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_NO_INITIAL_AGGRO) )
+ if( !(m_spellInfo->AttributesEx & SPELL_ATTR_EX_NO_INITIAL_AGGRO) )
{
m_caster->CombatStart(unit);
}
else if(m_customAttr & SPELL_ATTR_CU_AURA_CC)
{
if(!unit->IsStandState())
- unit->SetStandState(PLAYER_STATE_NONE);
+ unit->SetStandState(UNIT_STAND_STATE_STAND);
}
}
+
+ if(spellHitTarget)
+ {
+ //AI functions
+ if(spellHitTarget->GetTypeId() == TYPEID_UNIT && ((Creature*)spellHitTarget)->IsAIEnabled)
+ ((Creature*)spellHitTarget)->AI()->SpellHit(m_caster, m_spellInfo);
+
+ if(m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->IsAIEnabled)
+ ((Creature*)m_caster)->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
+
+ // Needs to be called after dealing damage/healing to not remove breaking on damage auras
+ DoTriggersOnSpellHit(spellHitTarget);
+ }
}
-void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
+SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
{
if(!unit || !effectMask)
- return;
+ return SPELL_MISS_EVADE;
// Recheck immune (only for delayed spells)
if( m_spellInfo->speed &&
- !(m_spellInfo->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)
- && (unit->IsImmunedToDamage(GetSpellSchoolMask(m_spellInfo),true) ||
- unit->IsImmunedToSpell(m_spellInfo,true) ))
+ (unit->IsImmunedToDamage(m_spellInfo) ||
+ unit->IsImmunedToSpell(m_spellInfo)))
{
- m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_IMMUNE);
- m_damage = 0;
- return;
+ return SPELL_MISS_IMMUNE;
+ }
+
+ if (unit->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)unit)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id);
+ ((Player*)unit)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id);
+ }
+
+ if(m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, unit);
}
if( m_caster != unit )
{
- if (unit->GetCharmerOrOwnerGUID() != m_caster->GetGUID())
+ // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
+ if (m_spellInfo->speed > 0.0f &&
+ unit->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE) &&
+ unit->GetCharmerOrOwnerGUID() != m_caster->GetGUID())
{
- if (unit->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- {
- m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE);
- m_damage = 0;
- return;
- }
+ return SPELL_MISS_EVADE;
}
+
if( !m_caster->IsFriendlyTo(unit) )
{
// for delayed spells ignore not visible explicit target
if(m_spellInfo->speed > 0.0f && unit==m_targets.getUnitTarget() && !unit->isVisibleForOrDetect(m_caster,false))
{
- m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE);
- m_damage = 0;
- return;
+ return SPELL_MISS_EVADE;
}
unit->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_HITBYSPELL);
@@ -1165,9 +1095,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
// TODO: this cause soul transfer bugged
if(m_spellInfo->speed > 0.0f && unit->GetTypeId() == TYPEID_PLAYER && !IsPositiveSpell(m_spellInfo->Id))
{
- m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE);
- m_damage = 0;
- return;
+ return SPELL_MISS_EVADE;
}
// assisting case, healing and resurrection
@@ -1176,7 +1104,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
m_caster->SetContestedPvP();
//m_caster->UpdatePvP(true);
}
- if( unit->isInCombat() && !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_NO_INITIAL_AGGRO) )
+ if( unit->isInCombat() && !(m_spellInfo->AttributesEx & SPELL_ATTR_EX_NO_INITIAL_AGGRO) )
{
m_caster->SetInCombatState(unit->GetCombatTimer() > 0);
unit->getHostilRefManager().threatAssist(m_caster, 0.0f);
@@ -1194,50 +1122,96 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
unit->IncrDiminishing(m_diminishGroup);
}
- for(uint32 effectNumber=0;effectNumber<3;effectNumber++)
+ uint8 aura_effmask = 0;
+ for (uint8 i = 0; i < 3; ++i)
+ if (effectMask & (1<<i) && (m_spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA || IsAreaAuraEffect(m_spellInfo->Effect[i])))
+ aura_effmask |= 1<<i;
+
+ uint8 t_effmask = effectMask & ~aura_effmask;
+ for(uint32 effectNumber = 0; effectNumber < 3; ++effectNumber)
{
- if (effectMask & (1<<effectNumber))
+ if (t_effmask & (1<<effectNumber))
+ HandleEffects(unit,NULL,NULL,effectNumber);
+ }
+
+ if (aura_effmask)
+ {
+ Unit * caster = m_originalCaster ? m_originalCaster : m_caster;
+ Aura * Aur= new Aura(m_spellInfo, aura_effmask, &m_currentBasePoints[0], unit, caster , m_CastItem, m_caster);
+
+ if (!Aur->IsAreaAura())
{
- HandleEffects(unit,NULL,NULL,effectNumber/*,m_damageMultipliers[effectNumber]*/);
- //Only damage and heal spells need this
- /*if ( m_applyMultiplierMask & (1 << effectNumber) )
+ // Now Reduce spell duration using data received at spell hit
+ int32 duration = Aur->GetAuraMaxDuration();
+ unit->ApplyDiminishingToDuration(m_diminishGroup,duration,caster,m_diminishLevel);
+ Aur->setDiminishGroup(m_diminishGroup);
+
+ duration = caster->ModSpellDuration(m_spellInfo, unit, duration, Aur->IsPositive());
+
+ //mod duration of channeled aura by spell haste
+ if (IsChanneledSpell(m_spellInfo))
+ caster->ModSpellCastTime(m_spellInfo, duration, this);
+
+ if(duration != Aur->GetAuraMaxDuration())
{
- // Get multiplier
- float multiplier = m_spellInfo->DmgMultiplier[effectNumber];
- // Apply multiplier mods
- if(m_originalCaster)
- if(Player* modOwner = m_originalCaster->GetSpellModOwner())
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_EFFECT_PAST_FIRST, multiplier,this);
- m_damageMultipliers[effectNumber] *= multiplier;
- }*/
+ Aur->SetAuraMaxDuration(duration);
+ Aur->SetAuraDuration(duration);
+ }
+
+ // Prayer of Mending (jump animation), we need formal caster instead original for correct animation
+ if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags[1] & 0x000020))
+ m_caster->CastSpell(unit, 41637, true, NULL, NULL, m_originalCasterGUID);
}
+ // Set aura only when successfully applied
+ if (unit->AddAura(Aur))
+ m_spellAura = Aur;
}
- if(unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->IsAIEnabled)
- ((Creature*)unit)->AI()->SpellHit(m_caster, m_spellInfo);
+ return SPELL_MISS_NONE;
+}
- if(m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->IsAIEnabled)
- ((Creature*)m_caster)->AI()->SpellHitTarget(unit, m_spellInfo);
+void Spell::DoTriggersOnSpellHit(Unit *unit)
+{
+ // Apply additional spell effects to target
+ if (m_preCastSpell)
+ {
+ // Special spell id
+ // TODO: Handle all of special spells in one place?
+ if(m_preCastSpell==61988)
+ {
+ //Cast Forbearance
+ m_caster->CastSpell(unit,25771, true, m_CastItem);
+ // Cast Avenging Wrath Marker
+ m_caster->CastSpell(unit,61987, true, m_CastItem);
+ }
+ else
+ m_caster->CastSpell(unit,m_preCastSpell, true, m_CastItem);
+ }
if (m_ChanceTriggerSpells.size())
{
int _duration=0;
for(ChanceTriggerSpells::const_iterator i = m_ChanceTriggerSpells.begin(); i != m_ChanceTriggerSpells.end(); ++i)
{
+ // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
+ // set duration equal to triggering spell
if(roll_chance_i(i->second))
{
m_caster->CastSpell(unit, i->first, true);
- // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
- // set duration equal to triggering spell
- if (GetSpellDuration(i->first)==-1)
+ sLog.outDebug("Spell %d triggered spell %d by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->first);
+ }
+ if (GetSpellDuration(i->first)==-1)
+ {
+ if (Aura * triggeredAur = unit->GetAura(i->first->Id, m_caster->GetGUID()))
{
// get duration from aura-only once
if (!_duration)
{
- Aura * aur = unit->GetAuraByCasterSpell(m_spellInfo->Id, m_caster->GetGUID());
+ Aura * aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
_duration = aur ? aur->GetAuraDuration() : -1;
}
- unit->SetAurasDurationByCasterSpell(i->first->Id, m_caster->GetGUID(), _duration);
+ triggeredAur->SetAuraDuration(_duration);
+ triggeredAur->SetPermanent(false);
}
}
}
@@ -1252,15 +1226,6 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
else
unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
}
-
- //This is not needed with procflag patch
- /*if(m_originalCaster)
- {
- if(m_customAttr & SPELL_ATTR_CU_EFFECT_HEAL)
- m_originalCaster->ProcDamageAndSpell(unit, PROC_FLAG_HEAL, PROC_FLAG_NONE, 0, GetSpellSchoolMask(m_spellInfo), m_spellInfo);
- if(m_originalCaster != unit && (m_customAttr & SPELL_ATTR_CU_EFFECT_DAMAGE))
- m_originalCaster->ProcDamageAndSpell(unit, PROC_FLAG_HIT_SPELL, PROC_FLAG_STRUCK_SPELL, 0, GetSpellSchoolMask(m_spellInfo), m_spellInfo);
- }*/
}
void Spell::DoAllEffectOnTarget(GOTargetInfo *target)
@@ -1273,7 +1238,7 @@ void Spell::DoAllEffectOnTarget(GOTargetInfo *target)
if(!effectMask)
return;
- GameObject* go = ObjectAccessor::GetGameObject(*m_caster, target->targetGUID);
+ GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
if(!go)
return;
@@ -1298,13 +1263,19 @@ void Spell::DoAllEffectOnTarget(ItemTargetInfo *target)
HandleEffects(NULL, target->item, NULL, effectNumber);
}
-bool Spell::IsAliveUnitPresentInTargetList()
+bool Spell::UpdateChanneledTargetList()
{
// Not need check return true
if (m_needAliveTargetMask == 0)
return true;
uint8 needAliveTargetMask = m_needAliveTargetMask;
+ uint8 needAuraMask = 0;
+ for (uint8 i=0;i<MAX_SPELL_EFFECTS;++i)
+ if (m_spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA)
+ needAuraMask |= 1<<i;
+
+ needAuraMask &= needAliveTargetMask;
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
{
@@ -1313,7 +1284,24 @@ bool Spell::IsAliveUnitPresentInTargetList()
Unit *unit = m_caster->GetGUID()==ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
if (unit && unit->isAlive())
+ {
+ if (needAuraMask & ihit->effectMask)
+ {
+ if(Aura * aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID()))
+ {
+ if (m_caster != unit && !m_caster->IsWithinDistInMap(unit,m_caster->GetSpellMaxRangeForTarget(unit,GetSpellRangeStore()->LookupEntry(m_spellInfo->rangeIndex))))
+ {
+ ihit->effectMask &= ~aur->GetEffectMask();
+ unit->RemoveAura(aur);
+ continue;
+ }
+ }
+ else
+ continue;
+ }
+
needAliveTargetMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
+ }
}
}
@@ -1371,6 +1359,16 @@ void Spell::SearchChainTarget(std::list<Unit*> &TagUnitMap, float max_range, uin
if(!cur)
return;
+ // Get spell max affected targets
+ /*uint32 unMaxTargets = m_spellInfo->MaxAffectedTargets;
+ Unit::AuraList const& mod = m_caster->GetAurasByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
+ for(Unit::AuraList::const_iterator m = mod.begin(); m != mod.end(); ++m)
+ {
+ if (!(*m)->isAffectedOnSpell(m_spellInfo))
+ continue;
+ unMaxTargets+=(*m)->GetAmount();
+ }*/
+
//FIXME: This very like horrible hack and wrong for most spells
if(m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MELEE)
max_range += num * CHAIN_SPELL_JUMP_RADIUS;
@@ -1431,7 +1429,7 @@ void Spell::SearchChainTarget(std::list<Unit*> &TagUnitMap, float max_range, uin
}
}
-void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, const uint32 &type, SpellTargets TargetType, uint32 entry)
+void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry)
{
float x, y, z;
if(type == PUSH_DEST_CENTER)
@@ -1483,7 +1481,7 @@ Unit* Spell::SearchNearbyTarget(float radius, SpellTargets TargetType, uint32 en
{
Creature* target = NULL;
Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster, entry, true, radius);
- Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(target, u_check);
+ Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(m_caster, target, u_check);
m_caster->VisitNearbyObject(radius, searcher);
return target;
}
@@ -1497,13 +1495,13 @@ Unit* Spell::SearchNearbyTarget(float radius, SpellTargets TargetType, uint32 en
case SPELL_TARGETS_ENEMY:
{
Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, radius);
- Trinity::UnitLastSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(target, u_check);
+ Trinity::UnitLastSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(m_caster, target, u_check);
m_caster->VisitNearbyObject(radius, searcher);
}break;
case SPELL_TARGETS_ALLY:
{
Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, radius);
- Trinity::UnitLastSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(target, u_check);
+ Trinity::UnitLastSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(m_caster, target, u_check);
m_caster->VisitNearbyObject(radius, searcher);
}break;
}
@@ -1512,24 +1510,36 @@ Unit* Spell::SearchNearbyTarget(float radius, SpellTargets TargetType, uint32 en
void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
{
- float radius;
+ float radius_h, radius_f;
if (m_spellInfo->EffectRadiusIndex[i])
- radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ {
+ radius_h = GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])) * m_spellValue->RadiusMod;
+ radius_f = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])) * m_spellValue->RadiusMod;
+ }
else
- radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
+ {
+ radius_h = GetSpellMaxRangeForHostile(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
+ radius_f = GetSpellMaxRangeForFriend(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
+ }
//Chain: 2, 6, 22, 25, 45, 77
uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[i];
uint32 unMaxTargets = m_spellValue->MaxAffectedTargets;
- if(m_originalCaster)
+ Unit::AuraEffectList const& Auras = m_caster->GetAurasByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
+ for(Unit::AuraEffectList::const_iterator j = Auras.begin();j != Auras.end(); ++j)
{
- if(Player* modOwner = m_originalCaster->GetSpellModOwner())
+ if((*j)->isAffectedOnSpell(m_spellInfo))
+ unMaxTargets+=(*j)->GetAmount();
+ }
+
+ if(m_originalCaster)
+ if (Player* modOwner = m_caster->GetSpellModOwner())
{
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius,this);
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius_f,this);
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius_h,this);
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, EffectChainTarget, this);
}
- }
if(EffectChainTarget > 1)
{
@@ -1553,17 +1563,17 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
TagUnitMap.push_back(owner);
break;
case TARGET_UNIT_PET:
- if(Pet* pet = m_caster->GetPet())
+ if(Guardian* pet = m_caster->GetGuardianPet())
TagUnitMap.push_back(pet);
break;
case TARGET_UNIT_PARTY_CASTER:
- m_caster->GetPartyMember(TagUnitMap, radius);
+ m_caster->GetPartyMember(TagUnitMap, radius_f);
break;
case TARGET_UNIT_RAID:
- if(Unit *target = m_targets.getUnitTarget())
- TagUnitMap.push_back(target);
- else
- m_caster->GetRaidMember(TagUnitMap, radius);
+ //if(Unit *target = m_targets.getUnitTarget())
+ // TagUnitMap.push_back(target);
+ //else
+ m_caster->GetRaidMember(TagUnitMap, radius_f);
break;
}
}break;
@@ -1577,33 +1587,37 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
break;
}
+ if(!IsPositiveSpell(m_spellInfo->Id))
+ if(Unit *magnet = m_caster->SelectMagnetTarget(target))
+ if(magnet != target)
+ m_targets.setUnitTarget(magnet);
+
switch(cur)
{
case TARGET_UNIT_MINIPET:
- if( target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isPet() && ((Pet*)target)->getPetType() == MINI_PET)
+ if(target->GetGUID() == m_caster->m_SummonSlot[4])
TagUnitMap.push_back(target);
break;
case TARGET_UNIT_TARGET_ALLY:
case TARGET_UNIT_TARGET_RAID:
- case TARGET_UNIT_TARGET_ANY: // SelectMagnetTarget()?
+ case TARGET_UNIT_TARGET_ANY:
case TARGET_UNIT_TARGET_PARTY:
- case TARGET_UNIT_SINGLE_UNKNOWN:
TagUnitMap.push_back(target);
break;
case TARGET_UNIT_PARTY_TARGET:
- target->GetPartyMember(TagUnitMap, radius);
+ target->GetPartyMember(TagUnitMap, radius_f);
break;
case TARGET_UNIT_TARGET_ENEMY:
if(EffectChainTarget <= 1)
- TagUnitMap.push_back(SelectMagnetTarget());
- else if(SelectMagnetTarget()) //TODO: chain target should also use magnet target
- SearchChainTarget(TagUnitMap, radius, EffectChainTarget, SPELL_TARGETS_ENEMY);
+ TagUnitMap.push_back(target);
+ else
+ SearchChainTarget(TagUnitMap, radius_h, EffectChainTarget, SPELL_TARGETS_ENEMY);
break;
case TARGET_UNIT_CHAINHEAL:
if(EffectChainTarget <= 1)
TagUnitMap.push_back(target);
else
- SearchChainTarget(TagUnitMap, radius, EffectChainTarget, SPELL_TARGETS_CHAINHEAL);
+ SearchChainTarget(TagUnitMap, radius_f, EffectChainTarget, SPELL_TARGETS_CHAINHEAL);
break;
}
}break;
@@ -1650,17 +1664,17 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
case TARGET_UNIT_AREA_ENEMY_GROUND:
m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
case TARGET_UNIT_AREA_ENEMY:
- SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_ENEMY);
+ SearchAreaTarget(TagUnitMap, radius_h, PUSH_DEST_CENTER, SPELL_TARGETS_ENEMY);
break;
case TARGET_UNIT_AREA_ALLY_GROUND:
m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
case TARGET_UNIT_AREA_ALLY:
- SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_ALLY);
+ SearchAreaTarget(TagUnitMap, radius_f, PUSH_DEST_CENTER, SPELL_TARGETS_ALLY);
break;
case TARGET_UNIT_AREA_PARTY_GROUND:
m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
case TARGET_UNIT_AREA_PARTY:
- m_caster->GetPartyMember(TagUnitMap, radius);
+ m_caster->GetPartyMember(TagUnitMap, radius_f);
break;
case TARGET_UNIT_AREA_ENTRY_GROUND:
m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
@@ -1670,7 +1684,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(m_spellInfo->Id);
if(lower==upper)
{
- SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_ENEMY);
+ SearchAreaTarget(TagUnitMap, radius_h, PUSH_DEST_CENTER, SPELL_TARGETS_ENEMY);
sLog.outErrorDb("Spell (ID: %u) (caster Entry: %u) does not have record in `spell_script_target`", m_spellInfo->Id, m_caster->GetEntry());
break;
}
@@ -1682,7 +1696,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
sLog.outError( "SPELL: spell ID %u requires non-creature target\n", m_spellInfo->Id );
continue;
}
- SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_ENTRY, i_spellST->second.targetEntry);
+ SearchAreaTarget(TagUnitMap, radius_f, PUSH_DEST_CENTER, SPELL_TARGETS_ENTRY, i_spellST->second.targetEntry);
}
}
break;
@@ -1726,41 +1740,41 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
m_targets.setDestination(((Player*)m_caster)->m_homebindX,((Player*)m_caster)->m_homebindY,((Player*)m_caster)->m_homebindZ, true, ((Player*)m_caster)->m_homebindMapId);
break;
-
case TARGET_IN_FRONT_OF_CASTER:
case TARGET_UNIT_CONE_ENEMY_UNKNOWN:
if(m_customAttr & SPELL_ATTR_CU_CONE_BACK)
- SearchAreaTarget(TagUnitMap, radius, PUSH_IN_BACK, SPELL_TARGETS_ENEMY);
+ SearchAreaTarget(TagUnitMap, radius_h, PUSH_IN_BACK, SPELL_TARGETS_ENEMY);
else if(m_customAttr & SPELL_ATTR_CU_CONE_LINE)
- SearchAreaTarget(TagUnitMap, radius, PUSH_IN_LINE, SPELL_TARGETS_ENEMY);
+ SearchAreaTarget(TagUnitMap, radius_h, PUSH_IN_LINE, SPELL_TARGETS_ENEMY);
else
- SearchAreaTarget(TagUnitMap, radius, PUSH_IN_FRONT, SPELL_TARGETS_ENEMY);
+ SearchAreaTarget(TagUnitMap, radius_h, PUSH_IN_FRONT, SPELL_TARGETS_ENEMY);
break;
case TARGET_UNIT_CONE_ALLY:
- SearchAreaTarget(TagUnitMap, radius, PUSH_IN_FRONT, SPELL_TARGETS_ALLY);
+ SearchAreaTarget(TagUnitMap, radius_f, PUSH_IN_FRONT, SPELL_TARGETS_ALLY);
break;
// nearby target
case TARGET_UNIT_NEARBY_ALLY:
+ case TARGET_UNIT_NEARBY_ALLY_UNK:
if(!m_targets.getUnitTarget())
- m_targets.setUnitTarget(SearchNearbyTarget(radius, SPELL_TARGETS_ALLY));
+ m_targets.setUnitTarget(SearchNearbyTarget(radius_f, SPELL_TARGETS_ALLY));
if(m_targets.getUnitTarget())
{
if(EffectChainTarget <= 1)
TagUnitMap.push_back(m_targets.getUnitTarget());
else
- SearchChainTarget(TagUnitMap, radius, EffectChainTarget, SPELL_TARGETS_ALLY);
+ SearchChainTarget(TagUnitMap, radius_f, EffectChainTarget, SPELL_TARGETS_ALLY);
}
break;
- case TARGET_RANDOM_ENEMY_CHAIN_IN_AREA:
+ case TARGET_UNIT_NEARBY_ENEMY:
if(!m_targets.getUnitTarget())
- m_targets.setUnitTarget(SearchNearbyTarget(radius, SPELL_TARGETS_ENEMY));
+ m_targets.setUnitTarget(SearchNearbyTarget(radius_h, SPELL_TARGETS_ENEMY));
if(m_targets.getUnitTarget())
{
if(EffectChainTarget <= 1)
TagUnitMap.push_back(m_targets.getUnitTarget());
else
- SearchChainTarget(TagUnitMap, radius, EffectChainTarget, SPELL_TARGETS_ENEMY);
+ SearchChainTarget(TagUnitMap, radius_h, EffectChainTarget, SPELL_TARGETS_ENEMY);
}
break;
case TARGET_SCRIPT:
@@ -1777,7 +1791,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
}
SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex);
- float range = GetSpellMaxRange(srange);
+ float range = GetSpellMaxRangeForHostile(srange);
Creature* creatureScriptTarget = NULL;
GameObject* goScriptTarget = NULL;
@@ -1793,7 +1807,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
if(i_spellST->second.targetEntry)
{
Trinity::NearestGameObjectEntryInObjectRangeCheck go_check(*m_caster,i_spellST->second.targetEntry,range);
- Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck> checker(p_GameObject,go_check);
+ Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck> checker(m_caster, p_GameObject,go_check);
m_caster->VisitNearbyGridObject(range, checker);
if(p_GameObject)
@@ -1823,7 +1837,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
Creature *p_Creature = NULL;
Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster,i_spellST->second.targetEntry,i_spellST->second.type!=SPELL_TARGET_TYPE_DEAD,range);
- Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(p_Creature, u_check);
+ Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(m_caster, p_Creature, u_check);
m_caster->VisitNearbyObject(range, searcher);
if(p_Creature )
@@ -1872,7 +1886,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
Player* Target = itr->getSource();
// IsHostileTo check duel and controlled by enemy
- if( Target && targetPlayer->IsWithinDistInMap(Target, radius) &&
+ if( Target && targetPlayer->IsWithinDistInMap(Target, radius_f) &&
targetPlayer->getClass() == Target->getClass() &&
!m_caster->IsHostileTo(Target) )
{
@@ -1903,7 +1917,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
float x, y, z, angle, dist;
float objSize = m_caster->GetObjectSize();
- dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ dist = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
if(dist < objSize)
dist = objSize;
else if(cur == TARGET_DEST_CASTER_RANDOM)
@@ -1946,7 +1960,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
float x, y, z, angle, dist;
float objSize = target->GetObjectSize();
- dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ dist = target->GetSpellRadiusForTarget(target, sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
if(dist < objSize)
dist = objSize;
else if(cur == TARGET_DEST_CASTER_RANDOM)
@@ -1982,7 +1996,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
float x, y, z, angle, dist;
- dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ dist = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
if (cur == TARGET_DEST_DEST_RANDOM)
dist *= rand_norm();
@@ -2016,10 +2030,71 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
TagUnitMap.remove(m_targets.getUnitTarget());
Trinity::RandomResizeList(TagUnitMap, unMaxTargets);
+
+ /*if(m_spellInfo->Id==57669) //Replenishment (special target selection)
+ {
+ if(pGroup)
+ {
+ typedef std::priority_queue<PrioritizeManaPlayerWraper, std::vector<PrioritizeManaPlayerWraper>, PrioritizeMana> Top10;
+ Top10 manaUsers;
+
+ for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL && manaUsers.size() < 10; itr = itr->next())
+ {
+ Player* Target = itr->getSource();
+ if (m_caster->GetGUID() != Target->GetGUID() && Target->getPowerType() == POWER_MANA &&
+ !Target->isDead() && m_caster->IsWithinDistInMap(Target, radius))
+ {
+ PrioritizeManaPlayerWraper WTarget(Target);
+ manaUsers.push(WTarget);
+ }
+ }
+
+ while(!manaUsers.empty())
+ {
+ TagUnitMap.push_back(manaUsers.top().getPlayer());
+ manaUsers.pop();
+ }
+ }
+ else
+ {
+ Unit* ownerOrSelf = pTarget ? pTarget : m_caster->GetCharmerOrOwnerOrSelf();
+ if ((ownerOrSelf==m_caster || m_caster->IsWithinDistInMap(ownerOrSelf, radius)) &&
+ ownerOrSelf->getPowerType() == POWER_MANA)
+ TagUnitMap.push_back(ownerOrSelf);
+
+ if(Pet* pet = ownerOrSelf->GetGuardianPet())
+ if( m_caster->IsWithinDistInMap(pet, radius) && pet->getPowerType() == POWER_MANA )
+ TagUnitMap.push_back(pet);
+ }
+ }*/
}
}
-void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura)
+class PrioritizeManaPlayerWraper
+{
+ friend struct PrioritizeMana;
+
+ public:
+ explicit PrioritizeManaPlayerWraper(Player* player) : player(player)
+ {
+ uint32 maxmana = player->GetMaxPower(POWER_MANA);
+ percentMana = maxmana ? player->GetPower(POWER_MANA) * 100 / maxmana : 101;
+ }
+ Player* getPlayer() const { return player; }
+ private:
+ Player* player;
+ uint32 percentMana;
+};
+
+struct PrioritizeMana
+{
+ int operator()( PrioritizeManaPlayerWraper const& x, PrioritizeManaPlayerWraper const& y ) const
+ {
+ return x.percentMana < y.percentMana;
+ }
+};
+
+void Spell::prepare(SpellCastTargets const* targets, AuraEffect* triggeredByAura)
{
if(m_CastItem)
m_castItemGUID = m_CastItem->GetGUID();
@@ -2028,6 +2103,13 @@ void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura)
m_targets = *targets;
+ if(!m_targets.getUnitTargetGUID() && m_spellInfo->Targets & TARGET_FLAG_UNIT)
+ {
+ if(Unit *target = ObjectAccessor::GetUnit(*m_caster, m_caster->GetUInt64Value(UNIT_FIELD_TARGET)))
+ if(IsValidSingleTargetSpell(target))
+ m_targets.setUnitTarget(target);
+ }
+
m_spellState = SPELL_STATE_PREPARING;
m_caster->GetPosition(m_castPositionX, m_castPositionY, m_castPositionZ);
@@ -2041,7 +2123,7 @@ void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura)
m_caster->m_Events.AddEvent(Event, m_caster->m_Events.CalculateTime(1));
//Prevent casting at cast another spell (ServerSide check)
- if(m_caster->IsNonMeleeSpellCasted(false, true) && m_cast_count)
+ if(m_caster->IsNonMeleeSpellCasted(false, true, true) && m_cast_count)
{
SendCastResult(SPELL_FAILED_SPELL_IN_PROGRESS);
finish(false);
@@ -2078,13 +2160,13 @@ void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura)
// Fill cost data
m_powerCost = CalculatePowerCost();
- uint8 result = CanCast(true);
- if(result != 0 && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
+ SpellCastResult result = CheckCast(true);
+ if(result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
{
if(triggeredByAura)
{
SendChannelUpdate(0);
- triggeredByAura->SetAuraDuration(0);
+ triggeredByAura->GetParentAura()->SetAuraDuration(0);
}
SendCastResult(result);
finish(false);
@@ -2094,13 +2176,18 @@ void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura)
// Prepare data for triggers
prepareDataForTriggerSystem();
- // calculate cast time (calculated after first CanCast check to prevent charge counting for first CanCast fail)
+ // Set combo point requirement
+ if (m_IsTriggeredSpell || m_CastItem || m_caster->GetTypeId()!=TYPEID_PLAYER)
+ m_needComboPoints = false;
+
+ // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
m_casttime = GetSpellCastTime(m_spellInfo, this);
// set timer base at cast time
ReSetTimer();
-
- if(m_IsTriggeredSpell)
+ //Containers for channeled spells have to be set
+ //TODO:Apply this to all casted spells if needed
+ if(m_IsTriggeredSpell && !IsChanneledSpell(m_spellInfo))
cast(true);
else
{
@@ -2150,11 +2237,10 @@ void Spell::cancel()
{
Unit* unit = m_caster->GetGUID()==(*ihit).targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
if( unit && unit->isAlive() )
- unit->RemoveAurasByCasterSpell(m_spellInfo->Id, m_caster->GetGUID());
+ unit->RemoveAurasDueToSpell(m_spellInfo->Id, m_caster->GetGUID(), AURA_REMOVE_BY_CANCEL);
}
}
-
- m_caster->RemoveAurasByCasterSpell(m_spellInfo->Id, m_caster->GetGUID());
+ m_caster->RemoveAurasDueToSpell(m_spellInfo->Id, m_caster->GetGUID(), AURA_REMOVE_BY_CANCEL);
SendChannelUpdate(0);
SendInterrupted(0);
SendCastResult(SPELL_FAILED_INTERRUPTED);
@@ -2178,8 +2264,6 @@ void Spell::cast(bool skipCheck)
{
SetExecutedCurrently(true);
- uint8 castResult = 0;
-
// update pointers base at GUIDs to prevent access to non-existed already object
UpdatePointers();
@@ -2194,23 +2278,12 @@ void Spell::cast(bool skipCheck)
if(m_caster->GetTypeId() != TYPEID_PLAYER && m_targets.getUnitTarget() && m_targets.getUnitTarget() != m_caster)
m_caster->SetInFront(m_targets.getUnitTarget());
- if(!m_IsTriggeredSpell)
- {
- castResult = CheckPower();
- if(castResult != 0)
- {
- SendCastResult(castResult);
- finish(false);
- SetExecutedCurrently(false);
- return;
- }
- }
// triggered cast called from Spell::prepare where it was already checked
- if(!skipCheck)
+ if(!m_IsTriggeredSpell || !skipCheck)
{
- castResult = CanCast(false);
- if(castResult != 0)
+ SpellCastResult castResult = CheckCast(false);
+ if(castResult != SPELL_CAST_OK)
{
SendCastResult(castResult);
finish(false);
@@ -2221,48 +2294,70 @@ void Spell::cast(bool skipCheck)
FillTargetMap();
- if(m_spellState == SPELL_STATE_FINISHED) // stop cast if spell marked as finish somewhere in Take*/FillTargetMap
+ if(m_spellInfo->SpellFamilyName)
{
- SetExecutedCurrently(false);
- return;
+ if (m_spellInfo->excludeCasterAuraSpell && !IsPositiveSpell(m_spellInfo->excludeCasterAuraSpell))
+ m_preCastSpell = m_spellInfo->excludeCasterAuraSpell;
+ else if (m_spellInfo->excludeTargetAuraSpell && !IsPositiveSpell(m_spellInfo->excludeTargetAuraSpell))
+ m_preCastSpell = m_spellInfo->excludeTargetAuraSpell;
+ }
+ switch (m_spellInfo->SpellFamilyName)
+ {
+ case SPELLFAMILY_GENERIC:
+ {
+ if (m_spellInfo->Mechanic == MECHANIC_BANDAGE) // Bandages
+ m_preCastSpell = 11196; // Recently Bandaged
+ else if(m_spellInfo->SpellIconID == 1662 && m_spellInfo->AttributesEx & 0x20)
+ m_preCastSpell = 23230; // Blood Fury - Healing Reduction
+ break;
+ }
}
-
// traded items have trade slot instead of guid in m_itemTargetGUID
// set to real guid to be sent later to the client
m_targets.updateTradeSlotItem();
- if(!m_IsTriggeredSpell)
+ if (m_caster->GetTypeId() == TYPEID_PLAYER)
{
- //TakePower();
- TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
- }
+ if (!m_IsTriggeredSpell && m_CastItem)
+ ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry());
- // CAST SPELL
- SendSpellCooldown();
- //SendCastResult(castResult);
- SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
-
- if(m_customAttr & SPELL_ATTR_CU_DIRECT_DAMAGE)
- CalculateDamageDoneForAllTargets();
+ ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id);
+ }
- //handle SPELL_AURA_ADD_TARGET_TRIGGER auras
- //are there any spells need to be triggered after hit?
- Unit::AuraList const& targetTriggers = m_caster->GetAurasByType(SPELL_AURA_ADD_TARGET_TRIGGER);
- for(Unit::AuraList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
+ // this is related to combo points so must be done before takepower
+ // are there any spells need to be triggered after hit?
+ // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
+ Unit::AuraEffectList const& targetTriggers = m_caster->GetAurasByType(SPELL_AURA_ADD_TARGET_TRIGGER);
+ for(Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
{
+ if (!(*i)->isAffectedOnSpell(m_spellInfo))
+ continue;
SpellEntry const *auraSpellInfo = (*i)->GetSpellProto();
uint32 auraSpellIdx = (*i)->GetEffIndex();
- if (IsAffectedBy(auraSpellInfo, auraSpellIdx))
+ if(SpellEntry const *spellInfo = sSpellStore.LookupEntry(auraSpellInfo->EffectTriggerSpell[auraSpellIdx]))
{
- if(SpellEntry const *spellInfo = sSpellStore.LookupEntry(auraSpellInfo->EffectTriggerSpell[auraSpellIdx]))
- {
- // Calculate chance at that moment (can be depend for example from combo points)
- int32 chance = m_caster->CalculateSpellDamage(auraSpellInfo, auraSpellIdx, (*i)->GetBasePoints(), NULL);
- m_ChanceTriggerSpells.push_back(std::make_pair(spellInfo, chance * (*i)->GetStackAmount()));
- }
+ // Calculate chance at that moment (can be depend for example from combo points)
+ int32 chance = m_caster->CalculateSpellDamage(auraSpellInfo, auraSpellIdx, (*i)->GetBasePoints(), NULL);
+ m_ChanceTriggerSpells.push_back(std::make_pair(spellInfo, chance * (*i)->GetParentAura()->GetStackAmount()));
}
}
+ // this is related to combo points so must be done before takepower
+ if(m_customAttr & SPELL_ATTR_CU_DIRECT_DAMAGE)
+ CalculateDamageDoneForAllTargets();
+
+ if(!m_IsTriggeredSpell)
+ {
+ // Powers have to be taken before SendSpellGo
+ TakePower();
+ TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
+ }
+
+ // CAST SPELL
+ SendSpellCooldown();
+ //SendCastResult(castResult);
+ SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
+
if(m_customAttr & SPELL_ATTR_CU_CHARGE)
EffectCharge(0);
@@ -2284,12 +2379,6 @@ void Spell::cast(bool skipCheck)
handle_immediate();
}
- // combo points should not be taken before SPELL_AURA_ADD_TARGET_TRIGGER auras are handled
- if(!m_IsTriggeredSpell)
- {
- TakePower();
- }
-
if(m_customAttr & SPELL_ATTR_CU_LINK_CAST)
{
if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(m_spellInfo->Id))
@@ -2308,9 +2397,18 @@ void Spell::handle_immediate()
// start channeling if applicable
if(IsChanneledSpell(m_spellInfo))
{
- m_spellState = SPELL_STATE_CASTING;
- m_caster->AddInterruptMask(m_spellInfo->ChannelInterruptFlags);
- SendChannelStart(GetSpellDuration(m_spellInfo));
+ int32 duration = GetSpellDuration(m_spellInfo);
+ if (duration)
+ {
+ //apply haste mods
+ m_caster->ModSpellCastTime(m_spellInfo, duration, this);
+ // Apply duration mod
+ if(Player* modOwner = m_caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
+ m_spellState = SPELL_STATE_CASTING;
+ m_caster->AddInterruptMask(m_spellInfo->ChannelInterruptFlags);
+ SendChannelStart(duration);
+ }
}
// process immediate effects (items, ground, etc.) also initialize some variables
@@ -2435,6 +2533,10 @@ void Spell::_handle_immediate_phase()
void Spell::_handle_finish_phase()
{
+ // Take for real after all targets are processed
+ if (m_needComboPoints)
+ ((Player*)m_caster)->ClearComboPoints();
+
// spell log
if(m_needSpellLog)
SendLogExecute();
@@ -2446,93 +2548,20 @@ void Spell::SendSpellCooldown()
return;
Player* _player = (Player*)m_caster;
- // Add cooldown for max (disable spell)
- // Cooldown started on SendCooldownEvent call
- if (m_spellInfo->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE)
- {
- _player->AddSpellCooldown(m_spellInfo->Id, 0, time(NULL) - 1);
- return;
- }
-
- // init cooldown values
- uint32 cat = 0;
- int32 rec = -1;
- int32 catrec = -1;
-
- // some special item spells without correct cooldown in SpellInfo
- // cooldown information stored in item prototype
- // This used in same way in WorldSession::HandleItemQuerySingleOpcode data sending to client.
-
- if(m_CastItem)
- {
- ItemPrototype const* proto = m_CastItem->GetProto();
- if(proto)
- {
- for(int idx = 0; idx < 5; ++idx)
- {
- if(proto->Spells[idx].SpellId == m_spellInfo->Id)
- {
- cat = proto->Spells[idx].SpellCategory;
- rec = proto->Spells[idx].SpellCooldown;
- catrec = proto->Spells[idx].SpellCategoryCooldown;
- break;
- }
- }
- }
- }
- // if no cooldown found above then base at DBC data
- if(rec < 0 && catrec < 0)
+ // mana/health/etc potions, disabled by client (until combat out as declarate)
+ if (m_CastItem && m_CastItem->IsPotion())
{
- cat = m_spellInfo->Category;
- rec = m_spellInfo->RecoveryTime;
- catrec = m_spellInfo->CategoryRecoveryTime;
+ // need in some way provided data for Spell::finish SendCooldownEvent
+ _player->SetLastPotionId(m_CastItem->GetEntry());
+ return;
}
- // shoot spells used equipped item cooldown values already assigned in GetAttackTime(RANGED_ATTACK)
- // prevent 0 cooldowns set by another way
- if (rec <= 0 && catrec <= 0 && (cat == 76 || cat == 351))
- rec = _player->GetAttackTime(RANGED_ATTACK);
-
- // Now we have cooldown data (if found any), time to apply mods
- if(rec > 0)
- _player->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COOLDOWN, rec, this);
-
- if(catrec > 0)
- _player->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COOLDOWN, catrec, this);
-
- // replace negative cooldowns by 0
- if (rec < 0) rec = 0;
- if (catrec < 0) catrec = 0;
-
- // no cooldown after applying spell mods
- if( rec == 0 && catrec == 0)
+ // have infinity cooldown but set at aura apply // do not set cooldown for triggered spells (needed by reincarnation)
+ if(m_spellInfo->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE || m_IsTriggeredSpell)
return;
- time_t curTime = time(NULL);
-
- time_t catrecTime = catrec ? curTime+catrec/1000 : 0; // in secs
- time_t recTime = rec ? curTime+rec/1000 : catrecTime;// in secs
-
- // self spell cooldown
- if(recTime > 0)
- _player->AddSpellCooldown(m_spellInfo->Id, m_CastItem ? m_CastItem->GetEntry() : 0, recTime);
-
- // category spells
- if (catrec > 0)
- {
- SpellCategoryStore::const_iterator i_scstore = sSpellCategoryStore.find(cat);
- if(i_scstore != sSpellCategoryStore.end())
- {
- for(SpellCategorySet::const_iterator i_scset = i_scstore->second.begin(); i_scset != i_scstore->second.end(); ++i_scset)
- {
- if(*i_scset == m_spellInfo->Id) // skip main spell, already handled above
- continue;
-
- _player->AddSpellCooldown(m_spellInfo->Id, m_CastItem ? m_CastItem->GetEntry() : 0, catrecTime);
- }
- }
- }
+ _player->AddSpellAndCategoryCooldowns(m_spellInfo,m_CastItem ? m_CastItem->GetEntry() : 0, this);
}
void Spell::update(uint32 difftime)
@@ -2591,8 +2620,9 @@ void Spell::update(uint32 difftime)
}
// check if there are alive targets left
- if (!IsAliveUnitPresentInTargetList())
+ if (!UpdateChanneledTargetList())
{
+ sLog.outDebug("Channeled spell %d is removed due to lack of targets", m_spellInfo->Id);
SendChannelUpdate(0);
finish();
}
@@ -2629,7 +2659,7 @@ void Spell::update(uint32 difftime)
{
GOTargetInfo* target = &*ihit;
- GameObject* go = ObjectAccessor::GetGameObject(*m_caster, target->targetGUID);
+ GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
if(!go)
continue;
@@ -2653,7 +2683,6 @@ void Spell::finish(bool ok)
if(m_spellState == SPELL_STATE_FINISHED)
return;
-
m_spellState = SPELL_STATE_FINISHED;
if(IsChanneledSpell(m_spellInfo))
@@ -2662,6 +2691,39 @@ void Spell::finish(bool ok)
if(!m_caster->IsNonMeleeSpellCasted(false, false, true))
m_caster->clearUnitState(UNIT_STAT_CASTING);
+ // Unsummon summon as possessed creatures on spell cancel
+ if(IsChanneledSpell(m_spellInfo)
+ && m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (Unit * charm = m_caster->GetCharm())
+ for(int i = 0; i < 3; ++i)
+ {
+ if(m_spellInfo->Effect[i] == SPELL_EFFECT_SUMMON)
+ if(SummonPropertiesEntry const *SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i]))
+ if(SummonProperties->Category == SUMMON_CATEGORY_POSSESSED)
+ {
+ if(charm->GetTypeId() == TYPEID_UNIT)
+ {
+ if(((Creature*)charm)->isPet() && ((Pet*)charm)->getPetType() == POSSESSED_PET)
+ ((Pet*)charm)->Remove(PET_SAVE_AS_DELETED);
+ break;
+ }
+ }
+ }
+ }
+ else if (m_caster->GetTypeId()==TYPEID_UNIT && ((Creature*)m_caster)->isSummon())
+ {
+ // Unsummon statue
+ uint32 spell = m_caster->GetUInt32Value(UNIT_CREATED_BY_SPELL);
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell );
+ if (spellInfo && spellInfo->SpellIconID==2056)
+ {
+ sLog.outDebug("Statue %d is unsummoned in spell %d finish", m_caster->GetGUIDLow(), m_spellInfo->Id);
+ m_caster->setDeathState(JUST_DIED);
+ return;
+ }
+ }
+
// other code related only to successfully finished spells
if(!ok)
return;
@@ -2672,10 +2734,7 @@ void Spell::finish(bool ok)
// Heal caster for all health leech from all targets
if (m_healthLeech)
- {
- m_caster->ModifyHealth(m_healthLeech);
- m_caster->SendHealSpellLog(m_caster, m_spellInfo->Id, uint32(m_healthLeech));
- }
+ m_caster->DealHeal(m_caster, uint32(m_healthLeech), m_spellInfo);
if (IsMeleeAttackResetSpell())
{
@@ -2686,6 +2745,10 @@ void Spell::finish(bool ok)
m_caster->resetAttackTimer(RANGED_ATTACK);
}
+ // potions disabled by client, send event "not in combat" if need
+ if (!m_triggeredByAuraSpell && m_caster->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)m_caster)->UpdatePotionCooldown(this);
+
// call triggered spell only at successful cast (after clear combo points -> for add some if need)
// I assume what he means is that some triggered spells may add combo points
if(!m_TriggerSpells.empty())
@@ -2696,72 +2759,65 @@ void Spell::finish(bool ok)
m_caster->AttackStop();
}
-void Spell::SendCastResult(uint8 result)
+void Spell::SendCastResult(SpellCastResult result)
{
+ if(result == SPELL_CAST_OK)
+ return;
+
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return;
if(((Player*)m_caster)->GetSession()->PlayerLoading()) // don't send cast results at loading time
return;
- if(result != 0)
- {
- WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
- data << uint32(m_spellInfo->Id);
- data << uint8(result); // problem
- data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
- switch (result)
- {
- case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
- data << uint32(m_spellInfo->RequiresSpellFocus);
- break;
- case SPELL_FAILED_REQUIRES_AREA:
- // hardcode areas limitation case
- switch(m_spellInfo->Id)
- {
- case 41617: // Cenarion Mana Salve
- case 41619: // Cenarion Healing Salve
- data << uint32(3905);
- break;
- case 41618: // Bottled Nethergon Energy
- case 41620: // Bottled Nethergon Vapor
- data << uint32(3842);
- break;
- case 45373: // Bloodberry Elixir
- data << uint32(4075);
- break;
- default: // default case
- data << uint32(m_spellInfo->AreaId);
- break;
- }
- break;
- case SPELL_FAILED_TOTEMS:
- if(m_spellInfo->Totem[0])
- data << uint32(m_spellInfo->Totem[0]);
- if(m_spellInfo->Totem[1])
- data << uint32(m_spellInfo->Totem[1]);
- break;
- case SPELL_FAILED_TOTEM_CATEGORY:
- if(m_spellInfo->TotemCategory[0])
- data << uint32(m_spellInfo->TotemCategory[0]);
- if(m_spellInfo->TotemCategory[1])
- data << uint32(m_spellInfo->TotemCategory[1]);
- break;
- case SPELL_FAILED_EQUIPPED_ITEM_CLASS:
- data << uint32(m_spellInfo->EquippedItemClass);
- data << uint32(m_spellInfo->EquippedItemSubClassMask);
- data << uint32(m_spellInfo->EquippedItemInventoryTypeMask);
- break;
- }
- ((Player*)m_caster)->GetSession()->SendPacket(&data);
- }
- else
+ WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
+ data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
+ data << uint32(m_spellInfo->Id);
+ data << uint8(result); // problem
+ switch (result)
{
- WorldPacket data(SMSG_CLEAR_EXTRA_AURA_INFO, (8+4));
- data.append(m_caster->GetPackGUID());
- data << uint32(m_spellInfo->Id);
- ((Player*)m_caster)->GetSession()->SendPacket(&data);
+ case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
+ data << uint32(m_spellInfo->RequiresSpellFocus);
+ break;
+ case SPELL_FAILED_REQUIRES_AREA:
+ // hardcode areas limitation case
+ switch(m_spellInfo->Id)
+ {
+ case 41617: // Cenarion Mana Salve
+ case 41619: // Cenarion Healing Salve
+ data << uint32(3905);
+ break;
+ case 41618: // Bottled Nethergon Energy
+ case 41620: // Bottled Nethergon Vapor
+ data << uint32(3842);
+ break;
+ case 45373: // Bloodberry Elixir
+ data << uint32(4075);
+ break;
+ default: // default case (don't must be)
+ data << uint32(0);
+ break;
+ }
+ break;
+ case SPELL_FAILED_TOTEMS:
+ if(m_spellInfo->Totem[0])
+ data << uint32(m_spellInfo->Totem[0]);
+ if(m_spellInfo->Totem[1])
+ data << uint32(m_spellInfo->Totem[1]);
+ break;
+ case SPELL_FAILED_TOTEM_CATEGORY:
+ if(m_spellInfo->TotemCategory[0])
+ data << uint32(m_spellInfo->TotemCategory[0]);
+ if(m_spellInfo->TotemCategory[1])
+ data << uint32(m_spellInfo->TotemCategory[1]);
+ break;
+ case SPELL_FAILED_EQUIPPED_ITEM_CLASS:
+ data << uint32(m_spellInfo->EquippedItemClass);
+ data << uint32(m_spellInfo->EquippedItemSubClassMask);
+ //data << uint32(m_spellInfo->EquippedItemInventoryTypeMask);
+ break;
}
+ ((Player*)m_caster)->GetSession()->SendPacket(&data);
}
void Spell::SendSpellStart()
@@ -2774,6 +2830,13 @@ void Spell::SendSpellStart()
uint32 castFlags = CAST_FLAG_UNKNOWN1;
if(IsRangedSpell())
castFlags |= CAST_FLAG_AMMO;
+ if ((m_caster->GetTypeId() == TYPEID_PLAYER ||
+ (m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->isPet()))
+ && m_spellInfo->powerType != POWER_HEALTH )
+ castFlags |= CAST_FLAG_POWER_LEFT_SELF;
+
+ if(m_spellInfo->runeCostID)
+ castFlags |= CAST_FLAG_UNKNOWN10;
Unit *target = m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster;
@@ -2784,14 +2847,17 @@ void Spell::SendSpellStart()
data.append(m_caster->GetPackGUID());
data.append(m_caster->GetPackGUID());
- data << uint32(m_spellInfo->Id);
- data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
- data << uint16(castFlags);
- data << uint32(m_timer);
+ data << uint8(m_cast_count); // pending spell cast?
+ data << uint32(m_spellInfo->Id); // spellId
+ data << uint32(castFlags); // cast flags
+ data << uint32(m_timer); // delay?
m_targets.write(&data);
- if( castFlags & CAST_FLAG_AMMO )
+ if(castFlags & CAST_FLAG_POWER_LEFT_SELF)
+ data << uint32(m_caster->GetPower((Powers)m_spellInfo->powerType));
+
+ if ( castFlags & CAST_FLAG_AMMO )
WriteAmmoToPacket(&data);
m_caster->SendMessageToSet(&data, true);
@@ -2810,25 +2876,72 @@ void Spell::SendSpellGo()
uint32 castFlags = CAST_FLAG_UNKNOWN3;
if(IsRangedSpell())
castFlags |= CAST_FLAG_AMMO; // arrows/bullets visual
+ if ((m_caster->GetTypeId() == TYPEID_PLAYER ||
+ (m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->isPet()))
+ && m_spellInfo->powerType != POWER_HEALTH )
+ castFlags |= CAST_FLAG_POWER_LEFT_SELF; // should only be sent to self, but the current messaging doesn't make that possible
+
+ if((m_caster->GetTypeId() == TYPEID_PLAYER) && (m_caster->getClass() == CLASS_DEATH_KNIGHT) && m_spellInfo->runeCostID)
+ {
+ castFlags |= CAST_FLAG_UNKNOWN10; // same as in SMSG_SPELL_START
+ castFlags |= CAST_FLAG_UNKNOWN7; // rune cooldowns list
+ }
WorldPacket data(SMSG_SPELL_GO, 50); // guess size
+
if(m_CastItem)
data.append(m_CastItem->GetPackGUID());
else
data.append(m_caster->GetPackGUID());
data.append(m_caster->GetPackGUID());
- data << uint32(m_spellInfo->Id);
- data << uint16(castFlags);
+ data << uint8(m_cast_count); // pending spell cast?
+ data << uint32(m_spellInfo->Id); // spellId
+ data << uint32(castFlags); // cast flags
data << uint32(getMSTime()); // timestamp
WriteSpellGoTargets(&data);
m_targets.write(&data);
- if( castFlags & CAST_FLAG_AMMO )
+ if(castFlags & CAST_FLAG_POWER_LEFT_SELF)
+ data << uint32(m_caster->GetPower((Powers)m_spellInfo->powerType));
+
+ if ( castFlags & CAST_FLAG_UNKNOWN7 ) // rune cooldowns list
+ {
+ uint8 v1 = m_runesState;
+ uint8 v2 = ((Player*)m_caster)->GetRunesState();
+ data << uint8(v1); // runes state before
+ data << uint8(v2); // runes state after
+ for(uint8 i = 0; i < MAX_RUNES; ++i)
+ {
+ uint8 m = (1 << i);
+ if(m & v1) // usable before...
+ if(!(m & v2)) // ...but on cooldown now...
+ data << uint8(0); // some unknown byte (time?)
+ }
+ }
+
+ if ( castFlags & CAST_FLAG_UNKNOWN4 ) // unknown wotlk
+ {
+ data << float(0);
+ data << uint32(0);
+ }
+
+ if ( castFlags & CAST_FLAG_AMMO )
WriteAmmoToPacket(&data);
+ if ( castFlags & CAST_FLAG_UNKNOWN5 ) // unknown wotlk
+ {
+ data << uint32(0);
+ data << uint32(0);
+ }
+
+ if ( m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION )
+ {
+ data << uint8(0);
+ }
+
m_caster->SendMessageToSet(&data, true);
}
@@ -2873,15 +2986,36 @@ void Spell::WriteAmmoToPacket( WorldPacket * data )
void Spell::WriteSpellGoTargets( WorldPacket * data )
{
- *data << (uint8)m_countOfHit;
+ // This function also fill data for channeled spells:
+ // m_needAliveTargetMask req for stop channelig if one target die
+ uint32 hit = m_UniqueGOTargetInfo.size(); // Always hits on GO
+ uint32 miss = 0;
+ for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
+ {
+ if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
+ {
+ // possibly SPELL_MISS_IMMUNE2 for this??
+ ihit->missCondition = SPELL_MISS_IMMUNE2;
+ miss++;
+ }
+ else if ((*ihit).missCondition == SPELL_MISS_NONE)
+ hit++;
+ else
+ miss++;
+ }
+
+ *data << (uint8)hit;
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
+ {
*data << uint64(ihit->targetGUID);
+ m_needAliveTargetMask |=ihit->effectMask;
+ }
for(std::list<GOTargetInfo>::iterator ighit= m_UniqueGOTargetInfo.begin();ighit != m_UniqueGOTargetInfo.end();++ighit)
*data << uint64(ighit->targetGUID); // Always hits
- *data << (uint8)m_countOfMiss;
+ *data << (uint8)miss;
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
{
if( ihit->missCondition != SPELL_MISS_NONE ) // Add only miss
@@ -2892,6 +3026,9 @@ void Spell::WriteSpellGoTargets( WorldPacket * data )
*data << uint8(ihit->reflectResult);
}
}
+ // Reset m_needAliveTargetMask for non channeled spell
+ if(!IsChanneledSpell(m_spellInfo))
+ m_needAliveTargetMask = 0;
}
void Spell::SendLogExecute()
@@ -2956,30 +3093,19 @@ void Spell::SendLogExecute()
data << uint8(0);
break;
case SPELL_EFFECT_CREATE_ITEM:
+ case SPELL_EFFECT_CREATE_ITEM_2:
data << uint32(m_spellInfo->EffectItemType[0]);
break;
case SPELL_EFFECT_SUMMON:
- case SPELL_EFFECT_SUMMON_WILD:
- case SPELL_EFFECT_SUMMON_GUARDIAN:
case SPELL_EFFECT_TRANS_DOOR:
case SPELL_EFFECT_SUMMON_PET:
- case SPELL_EFFECT_SUMMON_POSSESSED:
- case SPELL_EFFECT_SUMMON_TOTEM:
case SPELL_EFFECT_SUMMON_OBJECT_WILD:
case SPELL_EFFECT_CREATE_HOUSE:
case SPELL_EFFECT_DUEL:
- case SPELL_EFFECT_SUMMON_TOTEM_SLOT1:
- case SPELL_EFFECT_SUMMON_TOTEM_SLOT2:
- case SPELL_EFFECT_SUMMON_TOTEM_SLOT3:
- case SPELL_EFFECT_SUMMON_TOTEM_SLOT4:
- case SPELL_EFFECT_SUMMON_PHANTASM:
- case SPELL_EFFECT_SUMMON_CRITTER:
case SPELL_EFFECT_SUMMON_OBJECT_SLOT1:
case SPELL_EFFECT_SUMMON_OBJECT_SLOT2:
case SPELL_EFFECT_SUMMON_OBJECT_SLOT3:
case SPELL_EFFECT_SUMMON_OBJECT_SLOT4:
- case SPELL_EFFECT_SUMMON_DEMON:
- case SPELL_EFFECT_150:
if(Unit *unit = m_targets.getUnitTarget())
data.append(unit->GetPackGUID());
else if(m_targets.getItemTargetGUID())
@@ -2998,6 +3124,13 @@ void Spell::SendLogExecute()
else
data << uint8(0);
break;
+ case SPELL_EFFECT_RESURRECT:
+ case SPELL_EFFECT_RESURRECT_NEW:
+ if(Unit *unit = m_targets.getUnitTarget())
+ data.append(unit->GetPackGUID());
+ else
+ data << uint8(0);
+ break;
default:
return;
}
@@ -3011,13 +3144,16 @@ void Spell::SendInterrupted(uint8 result)
{
WorldPacket data(SMSG_SPELL_FAILURE, (8+4+1));
data.append(m_caster->GetPackGUID());
- data << m_spellInfo->Id;
- data << result;
+ data << uint8(m_cast_count);
+ data << uint32(m_spellInfo->Id);
+ data << uint8(result);
m_caster->SendMessageToSet(&data, true);
data.Initialize(SMSG_SPELL_FAILED_OTHER, (8+4));
data.append(m_caster->GetPackGUID());
- data << m_spellInfo->Id;
+ data << uint8(m_cast_count);
+ data << uint32(m_spellInfo->Id);
+ data << uint8(result);
m_caster->SendMessageToSet(&data, true);
}
@@ -3061,7 +3197,7 @@ void Spell::SendChannelStart(uint32 duration)
{
if(itr->effectMask & (1<<0) )
{
- target = ObjectAccessor::GetGameObject(*m_caster, itr->targetGUID);
+ target = m_caster->GetMap()->GetGameObject(itr->targetGUID);
break;
}
}
@@ -3085,10 +3221,19 @@ void Spell::SendChannelStart(uint32 duration)
void Spell::SendResurrectRequest(Player* target)
{
- WorldPacket data(SMSG_RESURRECT_REQUEST, (8+4+2+4));
- data << m_caster->GetGUID();
- data << uint32(1) << uint16(0) << uint32(1);
+ // Both players and NPCs can resurrect using spells - have a look at creature 28487 for example
+ // However, the packet structure differs slightly
+
+ const char* sentName = m_caster->GetTypeId()==TYPEID_PLAYER ?"":m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex());
+
+ WorldPacket data(SMSG_RESURRECT_REQUEST, (8+4+strlen(sentName)+1+1+1));
+ data << uint64(m_caster->GetGUID());
+ data << uint32(strlen(sentName)+1);
+
+ data << sentName;
+ data << uint8(0);
+ data << uint8(m_caster->GetTypeId()==TYPEID_PLAYER ?0:1);
target->GetSession()->SendPacket(&data);
}
@@ -3125,7 +3270,7 @@ void Spell::TakeCastItem()
bool expendable = false;
bool withoutCharges = false;
- for (int i = 0; i<5; i++)
+ for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
if (proto->Spells[i].SpellId)
{
@@ -3141,7 +3286,7 @@ void Spell::TakeCastItem()
if (charges)
{
(charges > 0) ? --charges : ++charges; // abs(charges) less at 1 after use
- if (proto->Stackable < 2)
+ if (proto->Stackable == 1)
m_CastItem->SetSpellCharges(i, charges);
m_CastItem->SetState(ITEM_CHANGED, (Player*)m_caster);
}
@@ -3167,7 +3312,7 @@ void Spell::TakeCastItem()
void Spell::TakePower()
{
- if(m_CastItem || m_triggeredByAuraSpell || !m_powerCost)
+ if(m_CastItem || m_triggeredByAuraSpell)
return;
bool hit = true;
@@ -3180,12 +3325,27 @@ void Spell::TakePower()
{
if(ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_MISS/* && ihit->targetGUID!=m_caster->GetGUID()*/)
hit = false;
+ if (ihit->missCondition != SPELL_MISS_NONE)
+ {
+ //lower spell cost on fail (by talent aura)
+ if(Player *modOwner = ((Player*)m_caster)->GetSpellModOwner())
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost);
+ }
break;
}
- if(hit && NeedsComboPoints(m_spellInfo))
- ((Player*)m_caster)->ClearComboPoints();
}
+ Powers powerType = Powers(m_spellInfo->powerType);
+
+ if(powerType == POWER_RUNE)
+ {
+ TakeRunePower();
+ return;
+ }
+
+ if (!m_powerCost)
+ return;
+
// health as power used
if(m_spellInfo->powerType == POWER_HEALTH)
{
@@ -3199,8 +3359,6 @@ void Spell::TakePower()
return;
}
- Powers powerType = Powers(m_spellInfo->powerType);
-
if(hit)
m_caster->ModifyPower(powerType, -m_powerCost);
else
@@ -3211,6 +3369,136 @@ void Spell::TakePower()
m_caster->SetLastManaUse(getMSTime());
}
+void Spell::TakeAmmo()
+{
+ if(m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ Item *pItem = ((Player*)m_caster)->GetWeaponForAttack( RANGED_ATTACK );
+
+ // wands don't have ammo
+ if(!pItem || pItem->IsBroken() || pItem->GetProto()->SubClass==ITEM_SUBCLASS_WEAPON_WAND)
+ return;
+
+ if( pItem->GetProto()->InventoryType == INVTYPE_THROWN )
+ {
+ if(pItem->GetMaxStackCount()==1)
+ {
+ // decrease durability for non-stackable throw weapon
+ ((Player*)m_caster)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_RANGED);
+ }
+ else
+ {
+ // decrease items amount for stackable throw weapon
+ uint32 count = 1;
+ ((Player*)m_caster)->DestroyItemCount( pItem, count, true);
+ }
+ }
+ else if(uint32 ammo = ((Player*)m_caster)->GetUInt32Value(PLAYER_AMMO_ID))
+ ((Player*)m_caster)->DestroyItemCount(ammo, 1, true);
+ }
+}
+
+SpellCastResult Spell::CheckRuneCost(uint32 runeCostID)
+{
+ if(m_caster->GetTypeId() != TYPEID_PLAYER)
+ return SPELL_CAST_OK;
+
+ Player *plr = (Player*)m_caster;
+
+ if(plr->getClass() != CLASS_DEATH_KNIGHT)
+ return SPELL_CAST_OK;
+
+ SpellRuneCostEntry const *src = sSpellRuneCostStore.LookupEntry(runeCostID);
+
+ if(!src)
+ return SPELL_CAST_OK;
+
+ if(src->NoRuneCost())
+ return SPELL_CAST_OK;
+
+ int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
+
+ for(uint32 i = 0; i < RUNE_DEATH; ++i)
+ runeCost[i] = src->RuneCost[i];
+
+ runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
+
+ for(uint32 i = 0; i < MAX_RUNES; ++i)
+ {
+ uint8 rune = plr->GetCurrentRune(i);
+ if((plr->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
+ runeCost[rune]--;
+ }
+
+ for(uint32 i = 0; i < RUNE_DEATH; ++i)
+ if(runeCost[i] > 0)
+ runeCost[RUNE_DEATH] += runeCost[i];
+
+ if(runeCost[RUNE_DEATH] > MAX_RUNES)
+ return SPELL_FAILED_NO_POWER; // not sure if result code is correct
+
+ return SPELL_CAST_OK;
+}
+
+void Spell::TakeRunePower()
+{
+ if(m_caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ Player *plr = (Player*)m_caster;
+
+ if(plr->getClass() != CLASS_DEATH_KNIGHT)
+ return;
+
+ SpellRuneCostEntry const *src = sSpellRuneCostStore.LookupEntry(m_spellInfo->runeCostID);
+
+ if(!src || (src->NoRuneCost() && src->NoRunicPowerGain()))
+ return;
+ m_runesState = plr->GetRunesState(); // store previous state
+
+ int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
+
+ for(uint32 i = 0; i < RUNE_DEATH; ++i)
+ {
+ runeCost[i] = src->RuneCost[i];
+ }
+
+ runeCost[RUNE_DEATH] = 0; // calculated later
+
+ for(uint32 i = 0; i < MAX_RUNES; ++i)
+ {
+ uint8 rune = plr->GetCurrentRune(i);
+ if((plr->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
+ {
+ plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec
+ runeCost[rune]--;
+ }
+ }
+
+ runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
+
+ if(runeCost[RUNE_DEATH] > 0)
+ {
+ for(uint32 i = 0; i < MAX_RUNES; ++i)
+ {
+ uint8 rune = plr->GetCurrentRune(i);
+ if((plr->GetRuneCooldown(i) == 0) && (rune == RUNE_DEATH))
+ {
+ plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec
+ runeCost[rune]--;
+ plr->ConvertRune(i, plr->GetBaseRune(i));
+ if(runeCost[RUNE_DEATH] == 0)
+ break;
+ }
+ }
+ }
+
+ // you can gain some runic power when use runes
+ float rp = src->runePowerGain;
+ rp *= sWorld.getRate(RATE_POWER_RUNICPOWER_INCOME);
+ plr->ModifyPower(POWER_RUNIC_POWER, (int32)rp);
+}
+
void Spell::TakeReagents()
{
if(m_IsTriggeredSpell) // reagents used in triggered spell removed by original spell or don't must be removed.
@@ -3219,11 +3507,9 @@ void Spell::TakeReagents()
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return;
- if (m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP &&
- m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION))
- return;
-
Player* p_caster = (Player*)m_caster;
+ if (p_caster->CanNoReagentCast(m_spellInfo))
+ return;
for(uint32 x=0;x<8;x++)
{
@@ -3239,7 +3525,7 @@ void Spell::TakeReagents()
ItemPrototype const *proto = m_CastItem->GetProto();
if( proto && proto->ItemId == itemid )
{
- for(int s=0;s<5;s++)
+ for(int s=0;s < MAX_ITEM_PROTO_SPELLS; ++s)
{
// CastItem will be used up and does not count as reagent
int32 charges = m_CastItem->GetSpellCharges(s);
@@ -3286,14 +3572,9 @@ void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTar
gameObjTarget = pGOTarget;
uint8 eff = m_spellInfo->Effect[i];
- uint32 mechanic = m_spellInfo->EffectMechanic[i];
sLog.outDebug( "Spell: Effect : %u", eff);
- //Simply return. Do not display "immune" in red text on client
- if(unitTarget && unitTarget->IsImmunedToSpellEffect(eff, mechanic))
- return;
-
//we do not need DamageMultiplier here.
damage = CalculateDamage(i, NULL);
@@ -3310,7 +3591,7 @@ void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTar
EffectEnchantItemTmp(i);
else
{
- sLog.outError("SPELL: unknown effect %u spell id %u\n",
+ sLog.outError("SPELL: unknown effect %u spell id %u",
eff, m_spellInfo->Id);
}
}
@@ -3326,11 +3607,14 @@ void Spell::TriggerSpell()
}
}
-uint8 Spell::CanCast(bool strict)
+SpellCastResult Spell::CheckCast(bool strict)
{
// check cooldowns to prevent cheating
if(m_caster->GetTypeId()==TYPEID_PLAYER && ((Player*)m_caster)->HasSpellCooldown(m_spellInfo->Id))
{
+ //can cast triggered (by aura only?) spells while have this flag
+ if (!m_IsTriggeredSpell && ((Player*)m_caster)->HasFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY))
+ return SPELL_FAILED_SPELL_IN_PROGRESS;
if(m_triggeredByAuraSpell)
return SPELL_FAILED_DONT_REPORT;
else
@@ -3344,22 +3628,62 @@ uint8 Spell::CanCast(bool strict)
return SPELL_FAILED_DONT_REPORT;
// only check at first call, Stealth auras are already removed at second call
- // for now, ignore triggered spells
- if( strict && !m_IsTriggeredSpell)
+ // for now, ignore triggered by aura spells
+ if( strict && !m_triggeredByAuraSpell)
{
- // Cannot be used in this stance/form
- if(uint8 shapeError = GetErrorAtShapeshiftedCast(m_spellInfo, m_caster->m_form))
- return shapeError;
+ bool checkForm = true;
+ // Ignore form req aura
+ Unit::AuraEffectList const& ignore = m_caster->GetAurasByType(SPELL_AURA_MOD_IGNORE_SHAPESHIFT);
+ for(Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
+ {
+ if (!(*i)->isAffectedOnSpell(m_spellInfo))
+ continue;
+ checkForm = false;
+ break;
+ }
+ if (checkForm)
+ {
+ // Cannot be used in this stance/form
+ SpellCastResult shapeError = GetErrorAtShapeshiftedCast(m_spellInfo, m_caster->m_form);
+ if(shapeError != SPELL_CAST_OK)
+ return shapeError;
- if ((m_spellInfo->Attributes & SPELL_ATTR_ONLY_STEALTHED) && !(m_caster->HasStealthAura()))
- return SPELL_FAILED_ONLY_STEALTHED;
+ if ((m_spellInfo->Attributes & SPELL_ATTR_ONLY_STEALTHED) && !(m_caster->HasStealthAura()))
+ return SPELL_FAILED_ONLY_STEALTHED;
+ }
}
- // caster state requirements
- if(m_spellInfo->CasterAuraState && !m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraState)))
- return SPELL_FAILED_CASTER_AURASTATE;
- if(m_spellInfo->CasterAuraStateNot && m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraStateNot)))
- return SPELL_FAILED_CASTER_AURASTATE;
+ bool reqCombat=true;
+ Unit::AuraEffectList const& stateAuras = m_caster->GetAurasByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
+ for(Unit::AuraEffectList::const_iterator j = stateAuras.begin();j != stateAuras.end(); ++j)
+ {
+ if((*j)->isAffectedOnSpell(m_spellInfo))
+ {
+ if ((*j)->GetMiscValue()==1)
+ {
+ reqCombat=false;
+ break;
+ }
+ }
+ }
+
+ // caster state requirements
+ // not for triggered spells (needed by execute)
+ if (!m_IsTriggeredSpell)
+ {
+ if(m_spellInfo->CasterAuraState && !m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraState), m_spellInfo, m_caster))
+ return SPELL_FAILED_CASTER_AURASTATE;
+ if(m_spellInfo->CasterAuraStateNot && m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraStateNot), m_spellInfo, m_caster))
+ return SPELL_FAILED_CASTER_AURASTATE;
+
+ if(m_spellInfo->casterAuraSpell && !m_caster->HasAura(m_spellInfo->casterAuraSpell))
+ return SPELL_FAILED_CASTER_AURASTATE;
+ if(m_spellInfo->excludeCasterAuraSpell && m_caster->HasAura(m_spellInfo->excludeCasterAuraSpell))
+ return SPELL_FAILED_CASTER_AURASTATE;
+
+ if(reqCombat && m_caster->isInCombat() && IsNonCombatSpell(m_spellInfo))
+ return SPELL_FAILED_AFFECTING_COMBAT;
+ }
// cancel autorepeat spells if cast start when moving
// (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
@@ -3371,22 +3695,26 @@ uint8 Spell::CanCast(bool strict)
return SPELL_FAILED_MOVING;
}
- Unit *target = m_targets.getUnitTarget();
-
- if(target)
+ if(Unit *target = m_targets.getUnitTarget())
{
// target state requirements (not allowed state), apply to self also
- if(m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot)))
+ if(!m_IsTriggeredSpell && m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot), m_spellInfo, m_caster))
+ return SPELL_FAILED_TARGET_AURASTATE;
+
+ if(m_spellInfo->targetAuraSpell && !target->HasAura(m_spellInfo->targetAuraSpell))
+ return SPELL_FAILED_TARGET_AURASTATE;
+
+ if(m_spellInfo->excludeTargetAuraSpell && target->HasAura(m_spellInfo->excludeTargetAuraSpell))
return SPELL_FAILED_TARGET_AURASTATE;
if(target != m_caster)
{
// target state requirements (apply to non-self only), to allow cast affects to self like Dirty Deeds
- if(m_spellInfo->TargetAuraState && !target->HasAuraState(AuraState(m_spellInfo->TargetAuraState)))
+ if(!m_IsTriggeredSpell && m_spellInfo->TargetAuraState && !target->HasAuraState(AuraState(m_spellInfo->TargetAuraState), m_spellInfo, m_caster))
return SPELL_FAILED_TARGET_AURASTATE;
// Not allow casting on flying player
- if (target->isInFlight())
+ if (target->hasUnitState(UNIT_STAT_UNATTACKABLE))
return SPELL_FAILED_BAD_TARGETS;
if(!m_IsTriggeredSpell && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOSInMap(target))
@@ -3395,13 +3723,23 @@ uint8 Spell::CanCast(bool strict)
// auto selection spell rank implemented in WorldSession::HandleCastSpellOpcode
// this case can be triggered if rank not found (too low-level target for first rank)
if(m_caster->GetTypeId() == TYPEID_PLAYER && !IsPassiveSpell(m_spellInfo->Id) && !m_CastItem)
- {
for(int i=0;i<3;i++)
- {
if(IsPositiveEffect(m_spellInfo->Id, i) && m_spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA)
if(target->getLevel() + 10 < m_spellInfo->spellLevel)
return SPELL_FAILED_LOWLEVEL;
- }
+ }
+ else if (m_caster->GetTypeId()==TYPEID_PLAYER) // Target - is player caster
+ {
+ // Additional check for some spells
+ // If 0 spell effect empty - client not send target data (need use selection)
+ // TODO: check it on next client version
+ if (m_targets.m_targetMask == TARGET_FLAG_SELF &&
+ m_spellInfo->EffectImplicitTargetA[1] == TARGET_CHAIN_DAMAGE)
+ {
+ if (target = m_caster->GetUnit(*m_caster, ((Player *)m_caster)->GetSelection()))
+ m_targets.setUnitTarget(target);
+ else
+ return SPELL_FAILED_BAD_TARGETS;
}
}
@@ -3410,7 +3748,7 @@ uint8 Spell::CanCast(bool strict)
{
if(m_spellInfo->EffectImplicitTargetA[j] == TARGET_PET)
{
- target = m_caster->GetPet();
+ target = m_caster->GetGuardianPet();
if(!target)
{
if(m_triggeredByAuraSpell) // not report pet not existence for triggered spells
@@ -3454,14 +3792,15 @@ uint8 Spell::CanCast(bool strict)
}
if(IsPositiveSpell(m_spellInfo->Id))
- {
- if(target->IsImmunedToSpell(m_spellInfo,false))
+ if(target->IsImmunedToSpell(m_spellInfo))
return SPELL_FAILED_TARGET_AURASTATE;
- }
//Must be behind the target.
if( m_spellInfo->AttributesEx2 == 0x100000 && (m_spellInfo->AttributesEx & 0x200) == 0x200 && target->HasInArc(M_PI, m_caster)
- && (m_spellInfo->SpellFamilyName != SPELLFAMILY_DRUID || m_spellInfo->SpellFamilyFlags != 0x0000000000020000LL))
+ //Exclusion for Pounce: Facing Limitation was removed in 2.0.1, but it still uses the same, old Ex-Flags
+ && (!(m_spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo->SpellFamilyFlags.IsEqual(0x20000,0,0)))
+ //Mutilate no longer requires you be behind the target as of patch 3.0.3
+ && (!(m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellInfo->SpellFamilyFlags[1] & 0x200000)))
{
SendInterrupted(2);
return SPELL_FAILED_NOT_BEHIND;
@@ -3476,10 +3815,9 @@ uint8 Spell::CanCast(bool strict)
// check if target is in combat
if (target != m_caster && (m_spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_IN_COMBAT_TARGET) && target->isInCombat())
- {
return SPELL_FAILED_TARGET_AFFECTING_COMBAT;
- }
}
+
// Spell casted only on battleground
if((m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_BATTLEGROUND) && m_caster->GetTypeId()==TYPEID_PLAYER)
if(!((Player*)m_caster)->InBattleGround())
@@ -3489,14 +3827,19 @@ uint8 Spell::CanCast(bool strict)
// - with greater than 15 min CD without SPELL_ATTR_EX4_USABLE_IN_ARENA flag
// - with SPELL_ATTR_EX4_NOT_USABLE_IN_ARENA flag
if( (m_spellInfo->AttributesEx4 & SPELL_ATTR_EX4_NOT_USABLE_IN_ARENA) ||
- GetSpellRecoveryTime(m_spellInfo) > 15 * MINUTE * 1000 && !(m_spellInfo->AttributesEx4 & SPELL_ATTR_EX4_USABLE_IN_ARENA) )
+ GetSpellRecoveryTime(m_spellInfo) > 15 * MINUTE * IN_MILISECONDS && !(m_spellInfo->AttributesEx4 & SPELL_ATTR_EX4_USABLE_IN_ARENA) )
if(MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
if(mapEntry->IsBattleArena())
return SPELL_FAILED_NOT_IN_ARENA;
// zone check
- if(!IsSpellAllowedInLocation(m_spellInfo,m_caster->GetMapId(),m_caster->GetZoneId(),m_caster->GetAreaId()))
- return SPELL_FAILED_REQUIRES_AREA;
+ uint32 zone, area;
+ m_caster->GetZoneAndAreaId(zone,area);
+
+ SpellCastResult locRes= spellmgr.GetSpellAllowedInLocationError(m_spellInfo,m_caster->GetMapId(),zone,area,
+ m_caster->GetTypeId()==TYPEID_PLAYER ? ((Player*)m_caster) : NULL);
+ if(locRes != SPELL_CAST_OK)
+ return locRes;
// not let players cast spells at mount (and let do it to creatures)
if( m_caster->IsMounted() && m_caster->GetTypeId()==TYPEID_PLAYER && !m_IsTriggeredSpell &&
@@ -3510,11 +3853,14 @@ uint8 Spell::CanCast(bool strict)
// always (except passive spells) check items (focus object can be required for any type casts)
if(!IsPassiveSpell(m_spellInfo->Id))
- if(uint8 castResult = CheckItems())
+ {
+ SpellCastResult castResult = CheckItems();
+ if(castResult != SPELL_CAST_OK)
return castResult;
+ }
/*//ImpliciteTargetA-B = 38, If fact there is 0 Spell with ImpliciteTargetB=38
- if(m_UniqueTargetInfo.empty()) // skip second canCast apply (for delayed spells for example)
+ if(m_UniqueTargetInfo.empty()) // skip second CheckCast apply (for delayed spells for example)
{
for(uint8 j = 0; j < 3; j++)
{
@@ -3549,7 +3895,7 @@ uint8 Spell::CanCast(bool strict)
cell.data.Part.reserved = ALL_DISTRICT;
MaNGOS::NearestGameObjectEntryInObjectRangeCheck go_check(*m_caster,i_spellST->second.targetEntry,range);
- MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck> checker(p_GameObject,go_check);
+ MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck> checker(m_caster, p_GameObject,go_check);
TypeContainerVisitor<MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -3587,7 +3933,7 @@ uint8 Spell::CanCast(bool strict)
cell.SetNoCreate(); // Really don't know what is that???
MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster,i_spellST->second.targetEntry,i_spellST->second.type!=SPELL_TARGET_TYPE_DEAD,range);
- MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(p_Creature, u_check);
+ MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(m_caster, p_Creature, u_check);
TypeContainerVisitor<MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
@@ -3650,13 +3996,16 @@ uint8 Spell::CanCast(bool strict)
if(!m_IsTriggeredSpell)
{
- if(uint8 castResult = CheckRange(strict))
+ SpellCastResult castResult = CheckRange(strict);
+ if(castResult != SPELL_CAST_OK)
return castResult;
- if(uint8 castResult = CheckPower())
+ castResult = CheckPower();
+ if(castResult != SPELL_CAST_OK)
return castResult;
- if(uint8 castResult = CheckCasterAuras())
+ castResult = CheckCasterAuras();
+ if(castResult != SPELL_CAST_OK)
return castResult;
}
@@ -3667,12 +4016,7 @@ uint8 Spell::CanCast(bool strict)
{
case SPELL_EFFECT_DUMMY:
{
- if(m_spellInfo->SpellIconID == 1648) // Execute
- {
- if(!m_targets.getUnitTarget() || m_targets.getUnitTarget()->GetHealth() > m_targets.getUnitTarget()->GetMaxHealth()*0.2)
- return SPELL_FAILED_BAD_TARGETS;
- }
- else if (m_spellInfo->Id == 51582) // Rocket Boots Engaged
+ if (m_spellInfo->Id == 51582) // Rocket Boots Engaged
{
if(m_caster->IsInWater())
return SPELL_FAILED_ONLY_ABOVEWATER;
@@ -3681,7 +4025,7 @@ uint8 Spell::CanCast(bool strict)
{
// spell different for friends and enemies
// hart version required facing
- if(m_targets.getUnitTarget() && !m_caster->IsFriendlyTo(m_targets.getUnitTarget()) && !m_caster->HasInArc( M_PI, target ))
+ if(m_targets.getUnitTarget() && !m_caster->IsFriendlyTo(m_targets.getUnitTarget()) && !m_caster->HasInArc( M_PI, m_targets.getUnitTarget() ))
return SPELL_FAILED_UNIT_NOT_INFRONT;
}
else if (m_spellInfo->Id == 19938) // Awaken Peon
@@ -3692,25 +4036,15 @@ uint8 Spell::CanCast(bool strict)
}
break;
}
- case SPELL_EFFECT_SCHOOL_DAMAGE:
- {
- // Hammer of Wrath
- if(m_spellInfo->SpellVisual == 7250)
- {
- if (!m_targets.getUnitTarget())
- return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
-
- if(m_targets.getUnitTarget()->GetHealth() > m_targets.getUnitTarget()->GetMaxHealth()*0.2)
- return SPELL_FAILED_BAD_TARGETS;
- }
- break;
- }
case SPELL_EFFECT_LEARN_SPELL:
{
+ if (m_caster->GetTypeId() != TYPEID_PLAYER)
+ return SPELL_FAILED_BAD_TARGETS;
+
if(m_spellInfo->EffectImplicitTargetA[i] != TARGET_PET)
break;
- Pet* pet = m_caster->GetPet();
+ Pet* pet = ((Player*)m_caster)->GetPet();
if(!pet)
return SPELL_FAILED_NO_PET;
@@ -3720,21 +4054,17 @@ uint8 Spell::CanCast(bool strict)
if(!learn_spellproto)
return SPELL_FAILED_NOT_KNOWN;
- if(!pet->CanTakeMoreActiveSpells(learn_spellproto->Id))
- return SPELL_FAILED_TOO_MANY_SKILLS;
-
if(m_spellInfo->spellLevel > pet->getLevel())
return SPELL_FAILED_LOWLEVEL;
- if(!pet->HasTPForSpell(learn_spellproto->Id))
- return SPELL_FAILED_TRAINING_POINTS;
-
break;
}
case SPELL_EFFECT_LEARN_PET_SPELL:
{
- Pet* pet = m_caster->GetPet();
+ if (m_caster->GetTypeId() != TYPEID_PLAYER)
+ return SPELL_FAILED_BAD_TARGETS;
+ Pet* pet = ((Player*)m_caster)->GetPet();
if(!pet)
return SPELL_FAILED_NO_PET;
@@ -3743,31 +4073,29 @@ uint8 Spell::CanCast(bool strict)
if(!learn_spellproto)
return SPELL_FAILED_NOT_KNOWN;
- if(!pet->CanTakeMoreActiveSpells(learn_spellproto->Id))
- return SPELL_FAILED_TOO_MANY_SKILLS;
-
if(m_spellInfo->spellLevel > pet->getLevel())
return SPELL_FAILED_LOWLEVEL;
- if(!pet->HasTPForSpell(learn_spellproto->Id))
- return SPELL_FAILED_TRAINING_POINTS;
-
break;
}
case SPELL_EFFECT_FEED_PET:
{
- if (m_caster->GetTypeId() != TYPEID_PLAYER || !m_targets.getItemTarget() )
+ if (m_caster->GetTypeId() != TYPEID_PLAYER)
return SPELL_FAILED_BAD_TARGETS;
- Pet* pet = m_caster->GetPet();
+ Item* foodItem = m_targets.getItemTarget();
+ if(!foodItem)
+ return SPELL_FAILED_BAD_TARGETS;
+
+ Pet* pet = ((Player*)m_caster)->GetPet();
if(!pet)
return SPELL_FAILED_NO_PET;
- if(!pet->HaveInDiet(m_targets.getItemTarget()->GetProto()))
+ if(!pet->HaveInDiet(foodItem->GetProto()))
return SPELL_FAILED_WRONG_PET_FOOD;
- if(!pet->GetCurrentFoodBenefitLevel(m_targets.getItemTarget()->GetProto()->ItemLevel))
+ if(!pet->GetCurrentFoodBenefitLevel(foodItem->GetProto()->ItemLevel))
return SPELL_FAILED_FOOD_LOWLEVEL;
if(m_caster->isInCombat() || pet->isInCombat())
@@ -3839,130 +4167,40 @@ uint8 Spell::CanCast(bool strict)
// In BattleGround players can use only flags and banners
if( ((Player*)m_caster)->InBattleGround() &&
- !((Player*)m_caster)->isAllowUseBattleGroundObject() )
+ !((Player*)m_caster)->CanUseBattleGroundObject() )
return SPELL_FAILED_TRY_AGAIN;
// get the lock entry
- LockEntry const *lockInfo = NULL;
+ uint32 lockId = 0;
if (GameObject* go=m_targets.getGOTarget())
- lockInfo = sLockStore.LookupEntry(go->GetLockId());
+ lockId = go->GetLockId();
else if(Item* itm=m_targets.getItemTarget())
- lockInfo = sLockStore.LookupEntry(itm->GetProto()->LockID);
-
- // check lock compatibility
- if (lockInfo)
- {
- // check for lock - key pair (checked by client also, just prevent cheating
- bool ok_key = false;
- for(int it = 0; it < 5; ++it)
- {
- switch(lockInfo->keytype[it])
- {
- case LOCK_KEY_NONE:
- break;
- case LOCK_KEY_ITEM:
- {
- if(lockInfo->key[it])
- {
- if(m_CastItem && m_CastItem->GetEntry()==lockInfo->key[it])
- ok_key =true;
- break;
- }
- }
- case LOCK_KEY_SKILL:
- {
- if(uint32(m_spellInfo->EffectMiscValue[i])!=lockInfo->key[it])
- break;
+ lockId = itm->GetProto()->LockID;
- switch(lockInfo->key[it])
- {
- case LOCKTYPE_HERBALISM:
- if(((Player*)m_caster)->HasSkill(SKILL_HERBALISM))
- ok_key =true;
- break;
- case LOCKTYPE_MINING:
- if(((Player*)m_caster)->HasSkill(SKILL_MINING))
- ok_key =true;
- break;
- default:
- ok_key =true;
- break;
- }
- }
- }
- if(ok_key)
- break;
- }
+ SkillType skillId =SKILL_NONE;
+ int32 reqSkillValue = 0;
+ int32 skillValue = 0;
- if(!ok_key)
- return SPELL_FAILED_BAD_TARGETS;
- }
+ // check lock compatibility
+ SpellCastResult res = CanOpenLock(i,lockId,skillId,reqSkillValue,skillValue);
+ if(res != SPELL_CAST_OK)
+ return res;
// chance for fail at orange mining/herb/LockPicking gathering attempt
- if (!m_selfContainer || ((*m_selfContainer) != this))
- break;
-
- // get the skill value of the player
- int32 SkillValue = 0;
- bool canFailAtMax = true;
- if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_HERBALISM)
- {
- SkillValue = ((Player*)m_caster)->GetSkillValue(SKILL_HERBALISM);
- canFailAtMax = false;
- }
- else if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_MINING)
- {
- SkillValue = ((Player*)m_caster)->GetSkillValue(SKILL_MINING);
- canFailAtMax = false;
- }
- else if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_PICKLOCK)
- SkillValue = ((Player*)m_caster)->GetSkillValue(SKILL_LOCKPICKING);
-
- // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
- if(m_CastItem)
- SkillValue = 0;
-
- // add the damage modifier from the spell casted (cheat lock / skeleton key etc.) (use m_currentBasePoints, CalculateDamage returns wrong value)
- // TODO: is this a hack?
- SkillValue += m_currentBasePoints[i]+1;
-
- // get the required lock value
- int32 ReqValue=0;
- if (lockInfo)
+ // second check prevent fail at rechecks
+ if(skillId != SKILL_NONE && (!m_selfContainer || ((*m_selfContainer) != this)))
{
- // check for lock - key pair
- bool ok = false;
- for(int it = 0; it < 5; ++it)
- {
- if(lockInfo->keytype[it]==LOCK_KEY_ITEM && lockInfo->key[it] && m_CastItem && m_CastItem->GetEntry()==lockInfo->key[it])
- {
- // if so, we're good to go
- ok = true;
- break;
- }
- }
- if(ok)
- break;
+ bool canFailAtMax = skillId != SKILL_HERBALISM && skillId != SKILL_MINING;
- if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_PICKLOCK)
- ReqValue = lockInfo->requiredlockskill;
- else
- ReqValue = lockInfo->requiredminingskill;
+ // chance for failure in orange gather / lockpick (gathering skill can't fail at maxskill)
+ if((canFailAtMax || skillValue < sWorld.GetConfigMaxSkillValue()) && reqSkillValue > irand(skillValue-25, skillValue+37))
+ return SPELL_FAILED_TRY_AGAIN;
}
-
- // skill doesn't meet the required value
- if (ReqValue > SkillValue)
- return SPELL_FAILED_LOW_CASTLEVEL;
-
- // chance for failure in orange gather / lockpick (gathering skill can't fail at maxskill)
- if((canFailAtMax || SkillValue < sWorld.GetConfigMaxSkillValue()) && ReqValue > irand(SkillValue-25, SkillValue+37))
- return SPELL_FAILED_TRY_AGAIN;
-
break;
}
case SPELL_EFFECT_SUMMON_DEAD_PET:
{
- Creature *pet = m_caster->GetPet();
+ Creature *pet = m_caster->GetGuardianPet();
if(!pet)
return SPELL_FAILED_NO_PET;
@@ -3971,18 +4209,16 @@ uint8 Spell::CanCast(bool strict)
break;
}
- // This is generic summon effect now and don't make this check for summon types similar
- // SPELL_EFFECT_SUMMON_CRITTER, SPELL_EFFECT_SUMMON_WILD or SPELL_EFFECT_SUMMON_GUARDIAN.
- // These won't show up in m_caster->GetPetGUID()
+ // This is generic summon effect
case SPELL_EFFECT_SUMMON:
{
- switch(m_spellInfo->EffectMiscValueB[i])
+ SummonPropertiesEntry const *SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i]);
+ if(!SummonProperties)
+ break;
+ switch(SummonProperties->Category)
{
- case SUMMON_TYPE_POSESSED:
- case SUMMON_TYPE_POSESSED2:
- case SUMMON_TYPE_POSESSED3:
- case SUMMON_TYPE_DEMON:
- case SUMMON_TYPE_SUMMON:
+ case SUMMON_CATEGORY_PET:
+ case SUMMON_CATEGORY_POSSESSED:
{
if(m_caster->GetPetGUID())
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
@@ -3994,11 +4230,8 @@ uint8 Spell::CanCast(bool strict)
}
break;
}
- // Don't make this check for SPELL_EFFECT_SUMMON_CRITTER, SPELL_EFFECT_SUMMON_WILD or SPELL_EFFECT_SUMMON_GUARDIAN.
- // These won't show up in m_caster->GetPetGUID()
- case SPELL_EFFECT_SUMMON_POSSESSED:
+ // Not used for summon?
case SPELL_EFFECT_SUMMON_PHANTASM:
- case SPELL_EFFECT_SUMMON_DEMON:
{
if(m_caster->GetPetGUID())
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
@@ -4012,13 +4245,11 @@ uint8 Spell::CanCast(bool strict)
{
if(m_caster->GetPetGUID()) //let warlock do a replacement summon
{
-
- Pet* pet = ((Player*)m_caster)->GetPet();
-
if (m_caster->GetTypeId()==TYPEID_PLAYER && m_caster->getClass()==CLASS_WARLOCK)
{
if (strict) //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
- pet->CastSpell(pet, 32752, true, NULL, NULL, pet->GetGUID());
+ if(Pet* pet = ((Player*)m_caster)->GetPet())
+ pet->CastSpell(pet, 32752, true, NULL, NULL, pet->GetGUID());
}
else
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
@@ -4054,7 +4285,7 @@ uint8 Spell::CanCast(bool strict)
case SPELL_EFFECT_LEAP:
case SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER:
{
- float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ float dis = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
float fx = m_caster->GetPositionX() + dis * cos(m_caster->GetOrientation());
float fy = m_caster->GetPositionY() + dis * sin(m_caster->GetOrientation());
// teleport a bit above terrain level to avoid falling below it
@@ -4090,25 +4321,38 @@ uint8 Spell::CanCast(bool strict)
{
case SPELL_AURA_DUMMY:
{
- if(m_spellInfo->Id == 1515)
+ //custom check
+ switch(m_spellInfo->Id)
{
- if (!m_targets.getUnitTarget() || m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER)
- return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
+ case 61336:
+ if(m_caster->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_caster)->IsInFeralForm())
+ return SPELL_FAILED_ONLY_SHAPESHIFT;
+ break;
+ case 1515:
+ {
+ if (!m_targets.getUnitTarget() || m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER)
+ return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
- if (m_targets.getUnitTarget()->getLevel() > m_caster->getLevel())
- return SPELL_FAILED_HIGHLEVEL;
+ if (m_targets.getUnitTarget()->getLevel() > m_caster->getLevel())
+ return SPELL_FAILED_HIGHLEVEL;
- // use SMSG_PET_TAME_FAILURE?
- if (!((Creature*)m_targets.getUnitTarget())->GetCreatureInfo()->isTameable ())
- return SPELL_FAILED_BAD_TARGETS;
+ // use SMSG_PET_TAME_FAILURE?
+ if (!((Creature*)m_targets.getUnitTarget())->GetCreatureInfo()->isTameable ())
+ return SPELL_FAILED_BAD_TARGETS;
- if(m_caster->GetPetGUID())
- return SPELL_FAILED_ALREADY_HAVE_SUMMON;
+ if(m_caster->GetPetGUID())
+ return SPELL_FAILED_ALREADY_HAVE_SUMMON;
- if(m_caster->GetCharmGUID())
- return SPELL_FAILED_ALREADY_HAVE_CHARM;
+ if(m_caster->GetCharmGUID())
+ return SPELL_FAILED_ALREADY_HAVE_CHARM;
+
+ break;
+ }
+ default:
+ break;
}
- }break;
+ break;
+ }
case SPELL_AURA_MOD_POSSESS:
case SPELL_AURA_MOD_CHARM:
{
@@ -4141,17 +4385,14 @@ uint8 Spell::CanCast(bool strict)
return SPELL_FAILED_NO_MOUNTS_ALLOWED;
// Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
- if (m_caster->GetTypeId()==TYPEID_PLAYER && !sMapStore.LookupEntry(m_caster->GetMapId())->IsMountAllowed() && !m_IsTriggeredSpell && !m_spellInfo->AreaId)
- return SPELL_FAILED_NO_MOUNTS_ALLOWED;
-
- if (m_caster->GetAreaId()==35)
+ if (m_caster->GetTypeId()==TYPEID_PLAYER && !sMapStore.LookupEntry(m_caster->GetMapId())->IsMountAllowed() && !m_IsTriggeredSpell && !m_spellInfo->AreaGroupId)
return SPELL_FAILED_NO_MOUNTS_ALLOWED;
ShapeshiftForm form = m_caster->m_form;
if( form == FORM_CAT || form == FORM_TREE || form == FORM_TRAVEL ||
form == FORM_AQUA || form == FORM_BEAR || form == FORM_DIREBEAR ||
form == FORM_CREATUREBEAR || form == FORM_GHOSTWOLF || form == FORM_FLIGHT ||
- form == FORM_FLIGHT_EPIC || form == FORM_MOONKIN )
+ form == FORM_FLIGHT_EPIC || form == FORM_MOONKIN || form == FORM_METAMORPHOSIS )
return SPELL_FAILED_NOT_SHAPESHIFT;
break;
@@ -4170,11 +4411,10 @@ uint8 Spell::CanCast(bool strict)
case SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED:
case SPELL_AURA_FLY:
{
- // not allow cast fly spells at old maps by players (all spells is self target)
+ // not allow cast fly spells at old maps by players (all spells is self target)
if(m_caster->GetTypeId()==TYPEID_PLAYER)
{
- if( !((Player*)m_caster)->isGameMaster() &&
- GetVirtualMapForMapAndZone(m_caster->GetMapId(),m_caster->GetZoneId()) != 530)
+ if( !((Player*)m_caster)->IsAllowUseFlyMountsHere() )
return SPELL_FAILED_NOT_HERE;
}
break;
@@ -4198,10 +4438,10 @@ uint8 Spell::CanCast(bool strict)
}
// all ok
- return 0;
+ return SPELL_CAST_OK;
}
-int16 Spell::PetCanCast(Unit* target)
+SpellCastResult Spell::CheckPetCast(Unit* target)
{
if(!m_caster->isAlive())
return SPELL_FAILED_CASTER_DEAD;
@@ -4249,20 +4489,16 @@ int16 Spell::PetCanCast(Unit* target)
return SPELL_FAILED_NOT_READY;
}
- uint16 result = CanCast(true);
- if(result != 0)
- return result;
- else
- return -1; //this allows to check spell fail 0, in combat
+ return CheckCast(true);
}
-uint8 Spell::CheckCasterAuras() const
+SpellCastResult Spell::CheckCasterAuras() const
{
// Flag drop spells totally immuned to caster auras
// FIXME: find more nice check for all totally immuned spells
// AttributesEx3 & 0x10000000?
if(m_spellInfo->Id==23336 || m_spellInfo->Id==23334 || m_spellInfo->Id==34991)
- return 0;
+ return SPELL_CAST_OK;
uint8 school_immune = 0;
uint32 mechanic_immune = 0;
@@ -4282,26 +4518,27 @@ uint8 Spell::CheckCasterAuras() const
dispel_immune |= GetDispellMask(DispelType(m_spellInfo->EffectMiscValue[i]));
}
//immune movement impairment and loss of control
- if(m_spellInfo->Id==(uint32)42292)
+ if(m_spellInfo->Id==42292 || m_spellInfo->Id==59752)
mechanic_immune = IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK;
}
//Check whether the cast should be prevented by any state you might have.
- uint8 prevented_reason = 0;
+ SpellCastResult prevented_reason = SPELL_CAST_OK;
// Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
- if(!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED) && m_caster->HasAuraType(SPELL_AURA_MOD_STUN))
+ uint32 unitflag = m_caster->GetUInt32Value(UNIT_FIELD_FLAGS); // Get unit state
+ if(unitflag & UNIT_FLAG_STUNNED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED))
prevented_reason = SPELL_FAILED_STUNNED;
- else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED) && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED))
+ else if(unitflag & UNIT_FLAG_CONFUSED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED))
prevented_reason = SPELL_FAILED_CONFUSED;
- else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING) && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED))
+ else if(unitflag & UNIT_FLAG_FLEEING && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED))
prevented_reason = SPELL_FAILED_FLEEING;
- else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED) && m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_SILENCE)
+ else if(unitflag & UNIT_FLAG_SILENCED && m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_SILENCE)
prevented_reason = SPELL_FAILED_SILENCED;
- else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) && m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_PACIFY)
+ else if(unitflag & UNIT_FLAG_PACIFIED && m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_PACIFY)
prevented_reason = SPELL_FAILED_PACIFIED;
// Attr must make flag drop spell totally immune from all effects
- if(prevented_reason)
+ if(prevented_reason != SPELL_CAST_OK)
{
if(school_immune || mechanic_immune || dispel_immune)
{
@@ -4311,7 +4548,7 @@ uint8 Spell::CheckCasterAuras() const
{
if(itr->second)
{
- if( GetSpellMechanicMask(itr->second->GetSpellProto(), itr->second->GetEffIndex()) & mechanic_immune )
+ if( GetAllSpellMechanicMask(itr->second->GetSpellProto()) & mechanic_immune )
continue;
if( GetSpellSchoolMask(itr->second->GetSpellProto()) & school_immune )
continue;
@@ -4320,28 +4557,34 @@ uint8 Spell::CheckCasterAuras() const
//Make a second check for spell failed so the right SPELL_FAILED message is returned.
//That is needed when your casting is prevented by multiple states and you are only immune to some of them.
- switch(itr->second->GetModifier()->m_auraname)
+ for (uint8 i=0;i<MAX_SPELL_EFFECTS;++i)
{
- case SPELL_AURA_MOD_STUN:
- if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED))
- return SPELL_FAILED_STUNNED;
- break;
- case SPELL_AURA_MOD_CONFUSE:
- if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED))
- return SPELL_FAILED_CONFUSED;
- break;
- case SPELL_AURA_MOD_FEAR:
- if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED))
- return SPELL_FAILED_FLEEING;
- break;
- case SPELL_AURA_MOD_SILENCE:
- case SPELL_AURA_MOD_PACIFY:
- case SPELL_AURA_MOD_PACIFY_SILENCE:
- if( m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_PACIFY)
- return SPELL_FAILED_PACIFIED;
- else if ( m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_SILENCE)
- return SPELL_FAILED_SILENCED;
- break;
+ if (AuraEffect * part = itr->second->GetPartAura(i))
+ {
+ switch(part->GetAuraName())
+ {
+ case SPELL_AURA_MOD_STUN:
+ if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED))
+ return SPELL_FAILED_STUNNED;
+ break;
+ case SPELL_AURA_MOD_CONFUSE:
+ if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED))
+ return SPELL_FAILED_CONFUSED;
+ break;
+ case SPELL_AURA_MOD_FEAR:
+ if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED))
+ return SPELL_FAILED_FLEEING;
+ break;
+ case SPELL_AURA_MOD_SILENCE:
+ case SPELL_AURA_MOD_PACIFY:
+ case SPELL_AURA_MOD_PACIFY_SILENCE:
+ if( m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_PACIFY)
+ return SPELL_FAILED_PACIFIED;
+ else if ( m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_SILENCE)
+ return SPELL_FAILED_SILENCED;
+ break;
+ }
+ }
}
}
}
@@ -4350,7 +4593,7 @@ uint8 Spell::CheckCasterAuras() const
else
return prevented_reason;
}
- return 0; // all ok
+ return SPELL_CAST_OK;
}
bool Spell::CanAutoCast(Unit* target)
@@ -4363,25 +4606,26 @@ bool Spell::CanAutoCast(Unit* target)
{
if( m_spellInfo->StackAmount <= 1)
{
- if( target->HasAura(m_spellInfo->Id, j) )
+ if( target->HasAuraEffect(m_spellInfo->Id, j) )
return false;
}
else
{
- if( target->GetAuras().count(Unit::spellEffectPair(m_spellInfo->Id, j)) >= m_spellInfo->StackAmount)
- return false;
+ if( AuraEffect * aureff = target->GetAuraEffect(m_spellInfo->Id, j))
+ if (aureff->GetParentAura()->GetStackAmount() >= m_spellInfo->StackAmount)
+ return false;
}
}
else if ( IsAreaAuraEffect( m_spellInfo->Effect[j] ))
{
- if( target->HasAura(m_spellInfo->Id, j) )
+ if( target->HasAuraEffect(m_spellInfo->Id, j) )
return false;
}
}
- int16 result = PetCanCast(target);
+ SpellCastResult result = CheckPetCast(target);
- if(result == -1 || result == SPELL_FAILED_UNIT_NOT_INFRONT)
+ if(result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
{
FillTargetMap();
//check if among target units, our WANTED target is as well (->only self cast spells return false)
@@ -4392,12 +4636,13 @@ bool Spell::CanAutoCast(Unit* target)
return false; //target invalid
}
-uint8 Spell::CheckRange(bool strict)
+SpellCastResult Spell::CheckRange(bool strict)
{
//float range_mod;
// self cast doesn't need range checking -- also for Starshards fix
- if (m_spellInfo->rangeIndex == 1) return 0;
+ if (m_spellInfo->rangeIndex == 1)
+ return SPELL_CAST_OK;
// i do not know why we need this
/*if (strict) //add radius of caster
@@ -4406,15 +4651,15 @@ uint8 Spell::CheckRange(bool strict)
range_mod = 6.25;*/
SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex);
- float max_range = GetSpellMaxRange(srange); // + range_mod;
- float min_range = GetSpellMinRange(srange);
+
+ Unit *target = m_targets.getUnitTarget();
+ float max_range = m_caster->GetSpellMaxRangeForTarget(target, srange); // + range_mod;
+ float min_range = m_caster->GetSpellMinRangeForTarget(target, srange);
uint32 range_type = GetSpellRangeType(srange);
if(Player* modOwner = m_caster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
- Unit *target = m_targets.getUnitTarget();
-
if(target && target != m_caster)
{
if(range_type == SPELL_RANGE_MELEE)
@@ -4448,7 +4693,7 @@ uint8 Spell::CheckRange(bool strict)
return SPELL_FAILED_TOO_CLOSE;
}
- return 0; // ok
+ return SPELL_CAST_OK;
}
int32 Spell::CalculatePowerCost()
@@ -4488,9 +4733,12 @@ int32 Spell::CalculatePowerCost()
case POWER_FOCUS:
case POWER_ENERGY:
case POWER_HAPPINESS:
- // case POWER_RUNES:
powerCost += m_spellInfo->ManaCostPercentage * m_caster->GetMaxPower(Powers(m_spellInfo->powerType)) / 100;
break;
+ case POWER_RUNE:
+ case POWER_RUNIC_POWER:
+ sLog.outDebug("Spell::CalculateManaCost: Not implemented yet!");
+ break;
default:
sLog.outError("Spell::CalculateManaCost: Unknown power type '%d' in spell %d", m_spellInfo->powerType, m_spellInfo->Id);
return 0;
@@ -4516,39 +4764,43 @@ int32 Spell::CalculatePowerCost()
return powerCost;
}
-uint8 Spell::CheckPower()
+SpellCastResult Spell::CheckPower()
{
// item cast not used power
if(m_CastItem)
- return 0;
+ return SPELL_CAST_OK;
// health as power used - need check health amount
if(m_spellInfo->powerType == POWER_HEALTH)
{
if(m_caster->GetHealth() <= m_powerCost)
return SPELL_FAILED_CASTER_AURASTATE;
- return 0;
+ return SPELL_CAST_OK;
}
// Check valid power type
if( m_spellInfo->powerType >= MAX_POWERS )
{
- sLog.outError("Spell::CheckMana: Unknown power type '%d'", m_spellInfo->powerType);
+ sLog.outError("Spell::CheckPower: Unknown power type '%d'", m_spellInfo->powerType);
return SPELL_FAILED_UNKNOWN;
}
+
+ SpellCastResult failReason = CheckRuneCost(m_spellInfo->runeCostID);
+ if(failReason != SPELL_CAST_OK)
+ return failReason;
+
// Check power amount
Powers powerType = Powers(m_spellInfo->powerType);
if(m_caster->GetPower(powerType) < m_powerCost)
return SPELL_FAILED_NO_POWER;
else
- return 0;
+ return SPELL_CAST_OK;
}
-uint8 Spell::CheckItems()
+SpellCastResult Spell::CheckItems()
{
if (m_caster->GetTypeId() != TYPEID_PLAYER)
- return 0;
+ return SPELL_CAST_OK;
- uint32 itemid, itemcount;
Player* p_caster = (Player*)m_caster;
if(!m_CastItem)
@@ -4558,77 +4810,72 @@ uint8 Spell::CheckItems()
}
else
{
- itemid = m_CastItem->GetEntry();
+ uint32 itemid = m_CastItem->GetEntry();
if( !p_caster->HasItemCount(itemid,1) )
return SPELL_FAILED_ITEM_NOT_READY;
- else
- {
- ItemPrototype const *proto = m_CastItem->GetProto();
- if(!proto)
- return SPELL_FAILED_ITEM_NOT_READY;
- for (int i = 0; i<5; i++)
+ ItemPrototype const *proto = m_CastItem->GetProto();
+ if(!proto)
+ return SPELL_FAILED_ITEM_NOT_READY;
+
+ for (int i = 0; i<5; i++)
+ if (proto->Spells[i].SpellCharges)
+ if(m_CastItem->GetSpellCharges(i)==0)
+ return SPELL_FAILED_NO_CHARGES_REMAIN;
+
+ // consumable cast item checks
+ if (proto->Class == ITEM_CLASS_CONSUMABLE && m_targets.getUnitTarget())
+ {
+ // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
+ SpellCastResult failReason = SPELL_CAST_OK;
+ for (int i = 0; i < 3; i++)
{
- if (proto->Spells[i].SpellCharges)
+ // skip check, pet not required like checks, and for TARGET_PET m_targets.getUnitTarget() is not the real target but the caster
+ if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_PET)
+ continue;
+
+ if (m_spellInfo->Effect[i] == SPELL_EFFECT_HEAL)
{
- if(m_CastItem->GetSpellCharges(i)==0)
- return SPELL_FAILED_NO_CHARGES_REMAIN;
+ if (m_targets.getUnitTarget()->GetHealth() == m_targets.getUnitTarget()->GetMaxHealth())
+ {
+ failReason = SPELL_FAILED_ALREADY_AT_FULL_HEALTH;
+ continue;
+ }
+ else
+ {
+ failReason = SPELL_CAST_OK;
+ break;
+ }
}
- }
- uint32 ItemClass = proto->Class;
- if (ItemClass == ITEM_CLASS_CONSUMABLE && m_targets.getUnitTarget())
- {
- // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
- uint8 failReason = 0;
- for (int i = 0; i < 3; i++)
+ // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
+ if (m_spellInfo->Effect[i] == SPELL_EFFECT_ENERGIZE)
{
- // skip check, pet not required like checks, and for TARGET_PET m_targets.getUnitTarget() is not the real target but the caster
- if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_PET)
+ if(m_spellInfo->EffectMiscValue[i] < 0 || m_spellInfo->EffectMiscValue[i] >= MAX_POWERS)
+ {
+ failReason = SPELL_FAILED_ALREADY_AT_FULL_POWER;
continue;
+ }
- if (m_spellInfo->Effect[i] == SPELL_EFFECT_HEAL)
+ Powers power = Powers(m_spellInfo->EffectMiscValue[i]);
+ if (m_targets.getUnitTarget()->GetPower(power) == m_targets.getUnitTarget()->GetMaxPower(power))
{
- if (m_targets.getUnitTarget()->GetHealth() == m_targets.getUnitTarget()->GetMaxHealth())
- {
- failReason = (uint8)SPELL_FAILED_ALREADY_AT_FULL_HEALTH;
- continue;
- }
- else
- {
- failReason = 0;
- break;
- }
+ failReason = SPELL_FAILED_ALREADY_AT_FULL_POWER;
+ continue;
}
-
- // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
- if (m_spellInfo->Effect[i] == SPELL_EFFECT_ENERGIZE)
+ else
{
- if(m_spellInfo->EffectMiscValue[i] < 0 || m_spellInfo->EffectMiscValue[i] >= MAX_POWERS)
- {
- failReason = (uint8)SPELL_FAILED_ALREADY_AT_FULL_POWER;
- continue;
- }
-
- Powers power = Powers(m_spellInfo->EffectMiscValue[i]);
- if (m_targets.getUnitTarget()->GetPower(power) == m_targets.getUnitTarget()->GetMaxPower(power))
- {
- failReason = (uint8)SPELL_FAILED_ALREADY_AT_FULL_POWER;
- continue;
- }
- else
- {
- failReason = 0;
- break;
- }
+ failReason = SPELL_CAST_OK;
+ break;
}
}
- if (failReason)
- return failReason;
}
+ if (failReason != SPELL_CAST_OK)
+ return failReason;
}
}
+ // check target item
if(m_targets.getItemTargetGUID())
{
if(m_caster->GetTypeId() != TYPEID_PLAYER)
@@ -4647,6 +4894,7 @@ uint8 Spell::CheckItems()
return SPELL_FAILED_EQUIPPED_ITEM_CLASS;
}
+ // check spell focus object
if(m_spellInfo->RequiresSpellFocus)
{
CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY()));
@@ -4654,29 +4902,29 @@ uint8 Spell::CheckItems()
cell.data.Part.reserved = ALL_DISTRICT;
GameObject* ok = NULL;
- Trinity::GameObjectFocusCheck go_check(m_caster,m_spellInfo->RequiresSpellFocus);
- Trinity::GameObjectSearcher<Trinity::GameObjectFocusCheck> checker(ok,go_check);
+ MaNGOS::GameObjectFocusCheck go_check(m_caster,m_spellInfo->RequiresSpellFocus);
+ MaNGOS::GameObjectSearcher<MaNGOS::GameObjectFocusCheck> checker(m_caster,ok,go_check);
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectFocusCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster));
if(!ok)
- return (uint8)SPELL_FAILED_REQUIRES_SPELL_FOCUS;
+ return SPELL_FAILED_REQUIRES_SPELL_FOCUS;
focusObject = ok; // game object found in range
}
- if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP &&
- m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION)))
+ // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
+ if (!m_IsTriggeredSpell && !p_caster->CanNoReagentCast(m_spellInfo))
{
for(uint32 i=0;i<8;i++)
{
if(m_spellInfo->Reagent[i] <= 0)
continue;
- itemid = m_spellInfo->Reagent[i];
- itemcount = m_spellInfo->ReagentCount[i];
+ uint32 itemid = m_spellInfo->Reagent[i];
+ uint32 itemcount = m_spellInfo->ReagentCount[i];
// if CastItem is also spell reagent
if( m_CastItem && m_CastItem->GetEntry() == itemid )
@@ -4684,7 +4932,7 @@ uint8 Spell::CheckItems()
ItemPrototype const *proto = m_CastItem->GetProto();
if(!proto)
return SPELL_FAILED_ITEM_NOT_READY;
- for(int s=0;s<5;s++)
+ for(int s=0; s < MAX_ITEM_PROTO_SPELLS; ++s)
{
// CastItem will be used up and does not count as reagent
int32 charges = m_CastItem->GetSpellCharges(s);
@@ -4696,10 +4944,11 @@ uint8 Spell::CheckItems()
}
}
if( !p_caster->HasItemCount(itemid,itemcount) )
- return (uint8)SPELL_FAILED_ITEM_NOT_READY; //0x54
+ return SPELL_FAILED_ITEM_NOT_READY; //0x54
}
}
+ // check totem-item requirements (items presence in inventory)
uint32 totems = 2;
for(int i=0;i<2;++i)
{
@@ -4714,9 +4963,9 @@ uint8 Spell::CheckItems()
totems -= 1;
}
if(totems != 0)
- return (uint8)SPELL_FAILED_TOTEMS; //0x7C
+ return SPELL_FAILED_TOTEMS; //0x7C
- //Check items for TotemCategory
+ // Check items for TotemCategory (items presence in inventory)
uint32 TotemCategory = 2;
for(int i=0;i<2;++i)
{
@@ -4732,8 +4981,9 @@ uint8 Spell::CheckItems()
TotemCategory -= 1;
}
if(TotemCategory != 0)
- return (uint8)SPELL_FAILED_TOTEM_CATEGORY; //0x7B
+ return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
+ // special checks for spell effects
for(int i = 0; i < 3; i++)
{
switch (m_spellInfo->Effect[i])
@@ -4753,6 +5003,7 @@ uint8 Spell::CheckItems()
break;
}
case SPELL_EFFECT_ENCHANT_ITEM:
+ case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC:
{
Item* targetItem = m_targets.getItemTarget();
if(!targetItem)
@@ -4836,13 +5087,36 @@ uint8 Spell::CheckItems()
return SPELL_FAILED_LOW_CASTLEVEL;
//make sure the player has the required ores in inventory
if(m_targets.getItemTarget()->GetCount() < 5)
- return SPELL_FAILED_PROSPECT_NEED_MORE;
+ return SPELL_FAILED_NEED_MORE_ITEMS;
if(!LootTemplates_Prospecting.HaveLootFor(m_targets.getItemTargetEntry()))
return SPELL_FAILED_CANT_BE_PROSPECTED;
break;
}
+ case SPELL_EFFECT_MILLING:
+ {
+ if(!m_targets.getItemTarget())
+ return SPELL_FAILED_CANT_BE_MILLED;
+ //ensure item is a millable herb
+ if(!(m_targets.getItemTarget()->GetProto()->BagFamily & BAG_FAMILY_MASK_HERBS) || m_targets.getItemTarget()->GetProto()->Class != ITEM_CLASS_TRADE_GOODS)
+ return SPELL_FAILED_CANT_BE_MILLED;
+ //prevent milling in trade slot
+ if( m_targets.getItemTarget()->GetOwnerGUID() != m_caster->GetGUID() )
+ return SPELL_FAILED_CANT_BE_MILLED;
+ //Check for enough skill in inscription
+ uint32 item_millingskilllevel = m_targets.getItemTarget()->GetProto()->RequiredSkillRank;
+ if(item_millingskilllevel >p_caster->GetSkillValue(SKILL_INSCRIPTION))
+ return SPELL_FAILED_LOW_CASTLEVEL;
+ //make sure the player has the required herbs in inventory
+ if(m_targets.getItemTarget()->GetCount() < 5)
+ return SPELL_FAILED_NEED_MORE_ITEMS;
+
+ if(!LootTemplates_Milling.HaveLootFor(m_targets.getItemTargetEntry()))
+ return SPELL_FAILED_CANT_BE_MILLED;
+
+ break;
+ }
case SPELL_EFFECT_WEAPON_DAMAGE:
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
{
@@ -4911,7 +5185,39 @@ uint8 Spell::CheckItems()
}
}
- return uint8(0);
+ // check weapon presence in slots for main/offhand weapons
+ if(m_spellInfo->EquippedItemClass >=0)
+ {
+ // main hand weapon required
+ if(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_MAIN_HAND)
+ {
+ Item* item = ((Player*)m_caster)->GetWeaponForAttack(BASE_ATTACK);
+
+ // skip spell if no weapon in slot or broken
+ if(!item || item->IsBroken() )
+ return SPELL_FAILED_EQUIPPED_ITEM_CLASS;
+
+ // skip spell if weapon not fit to triggered spell
+ if(!item->IsFitToSpellRequirements(m_spellInfo))
+ return SPELL_FAILED_EQUIPPED_ITEM_CLASS;
+ }
+
+ // offhand hand weapon required
+ if(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_REQ_OFFHAND)
+ {
+ Item* item = ((Player*)m_caster)->GetWeaponForAttack(OFF_ATTACK);
+
+ // skip spell if no weapon in slot or broken
+ if(!item || item->IsBroken() )
+ return m_IsTriggeredSpell ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_EQUIPPED_ITEM_CLASS;
+
+ // skip spell if weapon not fit to triggered spell
+ if(!item->IsFitToSpellRequirements(m_spellInfo))
+ return m_IsTriggeredSpell ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_EQUIPPED_ITEM_CLASS;
+ }
+ }
+
+ return SPELL_CAST_OK;
}
void Spell::Delayed() // only called in DealDamage()
@@ -4922,18 +5228,22 @@ void Spell::Delayed() // only called in DealDamage()
//if (m_spellState == SPELL_STATE_DELAYED)
// return; // spell is active and can't be time-backed
+ if(isDelayableNoMore()) // Spells may only be delayed twice
+ return;
+
// spells not loosing casting time ( slam, dynamites, bombs.. )
//if(!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
// return;
- //check resist chance
- int32 resistChance = 100; //must be initialized to 100 for percent modifiers
- ((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME,resistChance, this);
- resistChance += m_caster->GetTotalAuraModifier(SPELL_AURA_RESIST_PUSHBACK) - 100;
- if (roll_chance_i(resistChance))
+ //check pushback reduce
+ int32 delaytime = 500; // spellcasting delay is normally 500ms
+ int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
+ ((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this);
+ delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
+ if(delayReduce >= 100)
return;
- int32 delaytime = GetNextDelayAtDamageMsTime();
+ delaytime = delaytime * (100 - delayReduce) / 100;
if(int32(m_timer) + delaytime > m_casttime)
{
@@ -4957,14 +5267,18 @@ void Spell::DelayedChannel()
if(!m_caster || m_caster->GetTypeId() != TYPEID_PLAYER || getState() != SPELL_STATE_CASTING)
return;
- //check resist chance
- int32 resistChance = 100; //must be initialized to 100 for percent modifiers
- ((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME,resistChance, this);
- resistChance += m_caster->GetTotalAuraModifier(SPELL_AURA_RESIST_PUSHBACK) - 100;
- if (roll_chance_i(resistChance))
+ if(isDelayableNoMore()) // Spells may only be delayed twice
+ return;
+
+ //check pushback reduce
+ int32 delaytime = GetSpellDuration(m_spellInfo) * 25 / 100; // channeling delay is normally 25% of its time per hit
+ int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
+ ((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME,delayReduce, this);
+ delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
+ if(delayReduce >= 100)
return;
- int32 delaytime = GetNextDelayAtDamageMsTime();
+ delaytime = delaytime * (100 - delayReduce) / 100;
if(int32(m_timer) < delaytime)
{
@@ -4983,11 +5297,8 @@ void Spell::DelayedChannel()
Unit* unit = m_caster->GetGUID()==ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
if (unit)
{
- for (int j=0;j<3;j++)
- if( ihit->effectMask & (1<<j) )
- unit->DelayAura(m_spellInfo->Id, j, delaytime);
+ unit->DelayAura(m_spellInfo->Id, m_caster->GetGUID(), delaytime);
}
-
}
}
@@ -5018,17 +5329,12 @@ void Spell::UpdatePointers()
m_targets.Update(m_caster);
}
-bool Spell::IsAffectedBy(SpellEntry const *spellInfo, uint32 effectId)
-{
- return spellmgr.IsAffectedBySpell(m_spellInfo,spellInfo->Id,effectId,spellInfo->EffectItemType[effectId]);
-}
-
bool Spell::CheckTargetCreatureType(Unit* target) const
{
uint32 spellCreatureTargetMask = m_spellInfo->TargetCreatureType;
// Curse of Doom : not find another way to fix spell target check :/
- if(m_spellInfo->SpellFamilyName==SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags == 0x0200000000LL)
+ if(m_spellInfo->SpellFamilyName==SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags.IsEqual(0,0x02,0))
{
// not allow cast at player
if(target->GetTypeId()==TYPEID_PLAYER)
@@ -5062,7 +5368,7 @@ CurrentSpellTypes Spell::GetCurrentContainer()
return(CURRENT_GENERIC_SPELL);
}
-bool Spell::CheckTarget( Unit* target, uint32 eff, bool hitPhase )
+bool Spell::CheckTarget( Unit* target, uint32 eff )
{
// Check targets for creature type mask and remove not appropriate (skip explicit self target case, maybe need other explicit targets)
if(m_spellInfo->EffectImplicitTargetA[eff]!=TARGET_SELF)
@@ -5071,6 +5377,12 @@ bool Spell::CheckTarget( Unit* target, uint32 eff, bool hitPhase )
return false;
}
+ // Check Aura spell req (need for AoE spells)
+ if(m_spellInfo->targetAuraSpell && !target->HasAura(m_spellInfo->targetAuraSpell))
+ return false;
+ if (m_spellInfo->excludeTargetAuraSpell && target->HasAura(m_spellInfo->excludeTargetAuraSpell))
+ return false;
+
// Check targets for not_selectable unit flag and remove
// A player can cast spells on his pet (or other controlled unit) though in any state
if (target != m_caster && target->GetCharmerOrOwnerGUID() != m_caster->GetGUID())
@@ -5131,7 +5443,13 @@ bool Spell::CheckTarget( Unit* target, uint32 eff, bool hitPhase )
// all ok by some way or another, skip normal check
break;
default: // normal case
- if(target!=m_caster && !target->IsWithinLOSInMap(m_caster))
+ // Get GO cast coordinates if original caster -> GO
+ WorldObject *caster = NULL;
+ if (IS_GAMEOBJECT_GUID(m_originalCasterGUID))
+ caster = m_caster->GetMap()->GetGameObject(m_originalCasterGUID);
+ if (!caster)
+ caster = m_caster;
+ if(target!=m_caster && !target->IsWithinLOSInMap(caster))
return false;
break;
}
@@ -5139,44 +5457,9 @@ bool Spell::CheckTarget( Unit* target, uint32 eff, bool hitPhase )
return true;
}
-Unit* Spell::SelectMagnetTarget()
-{
- Unit* target = m_targets.getUnitTarget();
-
- if(target && m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && target->HasAuraType(SPELL_AURA_SPELL_MAGNET)) //Attributes & 0x10 what is this?
- {
- Unit::AuraList const& magnetAuras = target->GetAurasByType(SPELL_AURA_SPELL_MAGNET);
- for(Unit::AuraList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr)
- {
- if(Unit* magnet = (*itr)->GetCaster())
- {
- if((*itr)->m_procCharges>0)
- {
- (*itr)->SetAuraProcCharges((*itr)->m_procCharges-1);
- target = magnet;
- m_targets.setUnitTarget(target);
- AddUnitTarget(target, 0);
- uint64 targetGUID = target->GetGUID();
- for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
- {
- if (targetGUID == ihit->targetGUID) // Found in list
- {
- (*ihit).damage = target->GetHealth();
- break;
- }
- }
- break;
- }
- }
- }
- }
-
- return target;
-}
-
bool Spell::IsNeedSendToClient() const
{
- return m_spellInfo->SpellVisual!=0 || IsChanneledSpell(m_spellInfo) ||
+ return m_spellInfo->SpellVisual[0] || m_spellInfo->SpellVisual[1] || IsChanneledSpell(m_spellInfo) ||
m_spellInfo->speed > 0.0f || !m_triggeredByAuraSpell && !m_IsTriggeredSpell;
}
@@ -5255,9 +5538,6 @@ bool SpellEvent::Execute(uint64 e_time, uint32 p_time)
// another non-melee non-delayed spell is casted now, abort
m_Spell->cancel();
}
- // Check if target of channeled spell still in range
- else if (m_Spell->CheckRange(false))
- m_Spell->cancel();
else
{
// do the action (pass spell to channeling state)
@@ -5360,6 +5640,17 @@ void Spell::CalculateDamageDoneForAllTargets()
}
}
+ bool usesAmmo = !m_IsTriggeredSpell || m_autoRepeat;
+ if (usesAmmo)
+ {
+ Unit::AuraEffectList const& Auras = m_caster->GetAurasByType(SPELL_AURA_ABILITY_CONSUME_NO_AMMO);
+ for(Unit::AuraEffectList::const_iterator j = Auras.begin();j != Auras.end(); ++j)
+ {
+ if((*j)->isAffectedOnSpell(m_spellInfo))
+ usesAmmo=false;
+ }
+ }
+
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
TargetInfo &target = *ihit;
@@ -5372,6 +5663,28 @@ void Spell::CalculateDamageDoneForAllTargets()
if (!unit)
continue;
+ if (usesAmmo)
+ {
+ bool ammoTaken=false;
+ for (uint8 i=0;i<3;i++)
+ {
+ if (!(mask & 1<<i))
+ continue;
+ switch (m_spellInfo->Effect[i])
+ {
+ case SPELL_EFFECT_SCHOOL_DAMAGE:
+ case SPELL_EFFECT_WEAPON_DAMAGE:
+ case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
+ case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
+ case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
+ ammoTaken=true;
+ TakeAmmo();
+ }
+ if (ammoTaken)
+ break;
+ }
+ }
+
if (target.missCondition==SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
target.damage += CalculateDamageDone(unit, mask, multiplier);
else if (target.missCondition == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
@@ -5430,6 +5743,68 @@ int32 Spell::CalculateDamageDone(Unit *unit, const uint32 effectMask, float *mul
return damageDone;
}
+SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& skillId, int32& reqSkillValue, int32& skillValue)
+{
+ if(!lockId) // possible case for GO and maybe for items.
+ return SPELL_CAST_OK;
+
+ // Get LockInfo
+ LockEntry const *lockInfo = sLockStore.LookupEntry(lockId);
+
+ if (!lockInfo)
+ return SPELL_FAILED_BAD_TARGETS;
+
+ bool reqKey = false; // some locks not have reqs
+
+ for(int j = 0; j < 8; ++j)
+ {
+ switch(lockInfo->Type[j])
+ {
+ // check key item (many fit cases can be)
+ case LOCK_KEY_ITEM:
+ if(lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[j])
+ return SPELL_CAST_OK;
+ reqKey = true;
+ break;
+ // check key skill (only single first fit case can be)
+ case LOCK_KEY_SKILL:
+ {
+ reqKey = true;
+
+ // wrong locktype, skip
+ if(uint32(m_spellInfo->EffectMiscValue[effIndex]) != lockInfo->Index[j])
+ continue;
+
+ skillId = SkillByLockType(LockType(lockInfo->Index[j]));
+
+ if ( skillId != SKILL_NONE )
+ {
+ // skill bonus provided by casting spell (mostly item spells)
+ // add the damage modifier from the spell casted (cheat lock / skeleton key etc.) (use m_currentBasePoints, CalculateDamage returns wrong value)
+ uint32 spellSkillBonus = uint32(m_currentBasePoints[effIndex]+1);
+ reqSkillValue = lockInfo->Skill[j];
+
+ // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
+ skillValue = m_CastItem || m_caster->GetTypeId()!= TYPEID_PLAYER ?
+ 0 : ((Player*)m_caster)->GetSkillValue(skillId);
+
+ skillValue += spellSkillBonus;
+
+ if (skillValue < reqSkillValue)
+ return SPELL_FAILED_LOW_CASTLEVEL;
+ }
+
+ return SPELL_CAST_OK;
+ }
+ }
+ }
+
+ if(reqKey)
+ return SPELL_FAILED_BAD_TARGETS;
+
+ return SPELL_CAST_OK;
+}
+
void Spell::SetSpellValue(SpellValueMod mod, int32 value)
{
switch(mod)
@@ -5446,6 +5821,9 @@ void Spell::SetSpellValue(SpellValueMod mod, int32 value)
m_spellValue->EffectBasePoints[2] = value - int32(m_spellInfo->EffectBaseDice[2]);
m_currentBasePoints[2] = m_spellValue->EffectBasePoints[2];
break;
+ case SPELLVALUE_RADIUS_MOD:
+ m_spellValue->RadiusMod = (float)value / 10000;
+ break;
case SPELLVALUE_MAX_TARGETS:
m_spellValue->MaxAffectedTargets = (uint32)value;
break;
diff --git a/src/game/Spell.h b/src/game/Spell.h
index 824450061d3..64aa7f24eb0 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,6 +22,7 @@
#define __SPELL_H
#include "GridDefines.h"
+#include "SharedDefines.h"
class Unit;
class Player;
@@ -44,26 +45,51 @@ enum SpellCastTargetFlags
TARGET_FLAG_RESURRECTABLE = 0x8000*/
TARGET_FLAG_SELF = 0x00000000,
+ TARGET_FLAG_UNUSED1 = 0x00000001, // not used in any spells as of 3.0.3 (can be set dynamically)
TARGET_FLAG_UNIT = 0x00000002, // pguid
+ TARGET_FLAG_UNUSED2 = 0x00000004, // not used in any spells as of 3.0.3 (can be set dynamically)
+ TARGET_FLAG_UNUSED3 = 0x00000008, // not used in any spells as of 3.0.3 (can be set dynamically)
TARGET_FLAG_ITEM = 0x00000010, // pguid
TARGET_FLAG_SOURCE_LOCATION = 0x00000020, // 3 float
TARGET_FLAG_DEST_LOCATION = 0x00000040, // 3 float
- TARGET_FLAG_OBJECT_UNK = 0x00000080, // ?
+ TARGET_FLAG_OBJECT_UNK = 0x00000080, // used in 7 spells only
+ TARGET_FLAG_CASTER = 0x00000100, // looks like self target (480 spells)
TARGET_FLAG_PVP_CORPSE = 0x00000200, // pguid
- TARGET_FLAG_OBJECT = 0x00000800, // pguid
- TARGET_FLAG_TRADE_ITEM = 0x00001000, // pguid
- TARGET_FLAG_STRING = 0x00002000, // string
- TARGET_FLAG_UNK1 = 0x00004000, // ?
- TARGET_FLAG_CORPSE = 0x00008000, // pguid
- TARGET_FLAG_UNK2 = 0x00010000 // pguid
+ TARGET_FLAG_UNIT_CORPSE = 0x00000400, // 10 spells (gathering professions)
+ TARGET_FLAG_OBJECT = 0x00000800, // pguid, 2 spells
+ TARGET_FLAG_TRADE_ITEM = 0x00001000, // pguid, 0 spells
+ TARGET_FLAG_STRING = 0x00002000, // string, 0 spells
+ TARGET_FLAG_UNK1 = 0x00004000, // 199 spells, opening object/lock
+ TARGET_FLAG_CORPSE = 0x00008000, // pguid, resurrection spells
+ TARGET_FLAG_UNK2 = 0x00010000, // pguid, not used in any spells as of 3.0.3 (can be set dynamically)
+ TARGET_FLAG_GLYPH = 0x00020000 // used in glyph spells
};
enum SpellCastFlags
{
+ CAST_FLAG_NONE = 0x00000000,
+ CAST_FLAG_UNKNOWN0 = 0x00000001, // may be pending spell cast
CAST_FLAG_UNKNOWN1 = 0x00000002,
+ CAST_FLAG_UNKNOWN11 = 0x00000004,
+ CAST_FLAG_UNKNOWN12 = 0x00000008,
CAST_FLAG_UNKNOWN2 = 0x00000010,
- CAST_FLAG_AMMO = 0x00000020,
- CAST_FLAG_UNKNOWN3 = 0x00000100
+ CAST_FLAG_AMMO = 0x00000020, // Projectiles visual
+ CAST_FLAG_UNKNOWN8 = 0x00000040,
+ CAST_FLAG_UNKNOWN9 = 0x00000080,
+ CAST_FLAG_UNKNOWN3 = 0x00000100,
+ CAST_FLAG_UNKNOWN13 = 0x00000200,
+ CAST_FLAG_UNKNOWN14 = 0x00000400,
+ CAST_FLAG_POWER_LEFT_SELF = 0x00000800, // wotlk
+ CAST_FLAG_UNKNOWN15 = 0x00001000,
+ CAST_FLAG_UNKNOWN16 = 0x00002000,
+ CAST_FLAG_UNKNOWN17 = 0x00004000,
+ CAST_FLAG_UNKNOWN18 = 0x00008000,
+ CAST_FLAG_UNKNOWN19 = 0x00010000,
+ CAST_FLAG_UNKNOWN4 = 0x00020000, // wotlk
+ CAST_FLAG_UNKNOWN10 = 0x00040000,
+ CAST_FLAG_UNKNOWN5 = 0x00080000, // wotlk
+ CAST_FLAG_UNKNOWN20 = 0x00100000,
+ CAST_FLAG_UNKNOWN7 = 0x00200000 // wotlk, rune cooldown list
};
enum SpellRangeFlag
@@ -133,6 +159,7 @@ class SpellCastTargets
void setUnitTarget(Unit *target);
void setDestination(float x, float y, float z, bool send = true, int32 mapId = -1);
void setDestination(Unit *target, bool send = true);
+ void setSource(float x, float y, float z);
uint64 getGOTargetGUID() const { return m_GOTargetGUID; }
GameObject *getGOTarget() const { return m_GOTarget; }
@@ -186,9 +213,11 @@ struct SpellValue
for(uint32 i = 0; i < 3; ++i)
EffectBasePoints[i] = proto->EffectBasePoints[i];
MaxAffectedTargets = proto->MaxAffectedTargets;
+ RadiusMod = 1.0f;
}
int32 EffectBasePoints[3];
uint32 MaxAffectedTargets;
+ float RadiusMod;
};
enum SpellState
@@ -239,6 +268,7 @@ class Spell
void EffectHealthLeech(uint32 i);
void EffectQuestComplete(uint32 i);
void EffectCreateItem(uint32 i);
+ void EffectCreateItem2(uint32 i);
void EffectPersistentAA(uint32 i);
void EffectEnergize(uint32 i);
void EffectOpenLock(uint32 i);
@@ -247,16 +277,15 @@ class Spell
void EffectProficiency(uint32 i);
void EffectApplyAreaAura(uint32 i);
void EffectSummonType(uint32 i);
- void EffectSummon(uint32 i);
void EffectLearnSpell(uint32 i);
void EffectDispel(uint32 i);
void EffectDualWield(uint32 i);
void EffectPickPocket(uint32 i);
void EffectAddFarsight(uint32 i);
- void EffectSummonPossessed(uint32 i);
void EffectSummonWild(uint32 i);
- void EffectSummonGuardian(uint32 i);
void EffectHealMechanical(uint32 i);
+ void EffectJump(uint32 i);
+ void EffectJump2(uint32 i);
void EffectTeleUnitsFaceCaster(uint32 i);
void EffectLearnSkill(uint32 i);
void EffectAddHonor(uint32 i);
@@ -281,7 +310,7 @@ class Spell
void EffectStuck(uint32 i);
void EffectSummonPlayer(uint32 i);
void EffectActivateObject(uint32 i);
- void EffectSummonTotem(uint32 i);
+ void EffectApplyGlyph(uint32 i);
void EffectEnchantHeldItem(uint32 i);
void EffectSummonObject(uint32 i);
void EffectResurrect(uint32 i);
@@ -298,6 +327,8 @@ class Spell
void EffectSkinning(uint32 i);
void EffectCharge(uint32 i);
void EffectProspecting(uint32 i);
+ void EffectMilling(uint32 i);
+ void EffectRenamePet(uint32 i);
void EffectSendTaxi(uint32 i);
void EffectSummonCritter(uint32 i);
void EffectKnockBack(uint32 i);
@@ -324,22 +355,28 @@ class Spell
void EffectKillCredit(uint32 i);
void EffectQuestFail(uint32 i);
void EffectRedirectThreat(uint32 i);
+ void EffectActivateRune(uint32 i);
+ void EffectTitanGrip(uint32 i);
+ void EffectEnchantItemPrismatic(uint32 i);
Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID = 0, Spell** triggeringContainer = NULL, bool skipCheck = false );
~Spell();
- void prepare(SpellCastTargets * targets, Aura* triggeredByAura = NULL);
+ void prepare(SpellCastTargets const* targets, AuraEffect* triggeredByAura = NULL);
void cancel();
void update(uint32 difftime);
void cast(bool skipCheck = false);
void finish(bool ok = true);
void TakePower();
+ void TakeAmmo();
+
+ void TakeRunePower();
void TakeReagents();
void TakeCastItem();
void TriggerSpell();
- uint8 CanCast(bool strict);
- int16 PetCanCast(Unit* target);
- bool CanAutoCast(Unit* target);
+
+ SpellCastResult CheckCast(bool strict);
+ SpellCastResult CheckPetCast(Unit* target);
// handlers
void handle_immediate();
@@ -348,10 +385,11 @@ class Spell
void _handle_immediate_phase();
void _handle_finish_phase();
- uint8 CheckItems();
- uint8 CheckRange(bool strict);
- uint8 CheckPower();
- uint8 CheckCasterAuras() const;
+ SpellCastResult CheckItems();
+ SpellCastResult CheckRange(bool strict);
+ SpellCastResult CheckPower();
+ SpellCastResult CheckRuneCost(uint32 runeCostID);
+ SpellCastResult CheckCasterAuras() const;
int32 CalculateDamage(uint8 i, Unit* target) { return m_caster->CalculateSpellDamage(m_spellInfo,i,m_currentBasePoints[i],target); }
int32 CalculatePowerCost();
@@ -359,21 +397,20 @@ class Spell
bool HaveTargetsForEffect(uint8 effect) const;
void Delayed();
void DelayedChannel();
- inline uint32 getState() const { return m_spellState; }
+ uint32 getState() const { return m_spellState; }
void setState(uint32 state) { m_spellState = state; }
void DoCreateItem(uint32 i, uint32 itemtype);
-
void WriteSpellGoTargets( WorldPacket * data );
void WriteAmmoToPacket( WorldPacket * data );
void FillTargetMap();
void SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap);
- Unit* SelectMagnetTarget();
- bool CheckTarget( Unit* target, uint32 eff, bool hitPhase );
+ bool CheckTarget( Unit* target, uint32 eff );
+ bool CanAutoCast(Unit* target);
- void SendCastResult(uint8 result);
+ void SendCastResult(SpellCastResult result);
void SendSpellStart();
void SendSpellGo();
void SendSpellCooldown();
@@ -393,6 +430,8 @@ class Spell
Item* m_CastItem;
uint64 m_castItemGUID;
uint8 m_cast_count;
+ uint32 m_glyphIndex;
+ uint32 m_preCastSpell;
SpellCastTargets m_targets;
int32 GetCastTime() const { return m_casttime; }
@@ -429,8 +468,6 @@ class Spell
void UpdatePointers(); // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc)
- bool IsAffectedBy(SpellEntry const *spellInfo, uint32 effectId);
-
bool CheckTargetCreatureType(Unit* target) const;
void AddTriggeredSpell(SpellEntry const* spell) { m_TriggerSpells.push_back(spell); }
@@ -438,6 +475,7 @@ class Spell
void CleanupTargetList();
void SetSpellValue(SpellValueMod mod, int32 value);
+ //void SetSpellValue(SpellValueMod mod, float value);
protected:
void SendLoot(uint64 guid, LootType loottype);
@@ -460,9 +498,17 @@ class Spell
int32 m_casttime; // Calculated spell cast time initialized only in Spell::prepare
bool m_canReflect; // can reflect this spell?
bool m_autoRepeat;
+ uint8 m_runesState;
uint8 m_delayAtDamageCount;
- int32 GetNextDelayAtDamageMsTime() { return m_delayAtDamageCount < 5 ? 1000 - (m_delayAtDamageCount++)* 200 : 200; }
+ bool isDelayableNoMore()
+ {
+ if(m_delayAtDamageCount >= 2)
+ return true;
+
+ m_delayAtDamageCount++;
+ return false;
+ }
// Delayed spells system
uint64 m_delayStart; // time of spell delay start, filled by event handler, zero = just started
@@ -473,6 +519,7 @@ class Spell
bool m_referencedFromCurrentSpell; // mark as references to prevent deleted and access by dead pointers
bool m_executedCurrently; // mark as executed to prevent deleted and access by dead pointers
bool m_needSpellLog; // need to send spell log?
+ bool m_needComboPoints;
uint8 m_applyMultiplierMask; // by effect: damage multiplier needed?
float m_damageMultipliers[3]; // by effect: damage multiplier
@@ -481,6 +528,7 @@ class Spell
Item* itemTarget;
GameObject* gameObjTarget;
int32 damage;
+ Aura * m_spellAura; // only used in DoAllEffectOnTarget
// this is set in Spell Hit, but used in Apply Aura handler
DiminishingLevels m_diminishLevel;
@@ -497,7 +545,6 @@ class Spell
//******************************************
// Spell trigger system
//******************************************
- bool m_canTrigger; // Can start trigger (m_IsTriggeredSpell can`t use for this)
uint32 m_procAttacker; // Attacker trigger flags
uint32 m_procVictim; // Victim trigger flags
void prepareDataForTriggerSystem();
@@ -506,8 +553,6 @@ class Spell
// Spell target subsystem
//*****************************************
// Targets store structures and data
- uint32 m_countOfHit;
- uint32 m_countOfMiss;
struct TargetInfo
{
uint64 targetGUID;
@@ -543,11 +588,12 @@ class Spell
void AddGOTarget(uint64 goGUID, uint32 effIndex);
void AddItemTarget(Item* target, uint32 effIndex);
void DoAllEffectOnTarget(TargetInfo *target);
- void DoSpellHitOnUnit(Unit *unit, uint32 effectMask);
+ SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask);
+ void DoTriggersOnSpellHit(Unit *unit);
void DoAllEffectOnTarget(GOTargetInfo *target);
void DoAllEffectOnTarget(ItemTargetInfo *target);
- bool IsAliveUnitPresentInTargetList();
- void SearchAreaTarget(std::list<Unit*> &data, float radius, const uint32 &type,
+ bool UpdateChanneledTargetList();
+ void SearchAreaTarget(std::list<Unit*> &data, float radius, SpellNotifyPushType type,
SpellTargets TargetType, uint32 entry = 0);
void SearchChainTarget(std::list<Unit*> &data, float radius, uint32 unMaxTargets,
SpellTargets TargetType);
@@ -559,6 +605,11 @@ class Spell
void SpellDamageSchoolDmg(uint32 i);
void SpellDamageWeaponDmg(uint32 i);
void SpellDamageHeal(uint32 i);
+
+ void GetSummonPosition(float &x, float &y, float &z, float radius = 0.0f, uint32 count = 0);
+ void SummonGuardian (uint32 entry, SummonPropertiesEntry const *properties);
+
+ SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType& skillid, int32& reqSkillValue, int32& skillValue);
// -------------------------------------------
//List For Triggered Spells
@@ -591,84 +642,76 @@ namespace Trinity
{
std::list<Unit*> *i_data;
Spell &i_spell;
- const uint32& i_push_type;
+ SpellNotifyPushType i_push_type;
float i_radius, i_radiusSq;
SpellTargets i_TargetType;
- Unit* i_caster;
+ Unit* i_source;
uint32 i_entry;
float i_x, i_y, i_z;
- SpellNotifierCreatureAndPlayer(Spell &spell, std::list<Unit*> &data, float radius, const uint32 &type,
+ SpellNotifierCreatureAndPlayer(Spell &spell, std::list<Unit*> &data, float radius, SpellNotifyPushType type,
SpellTargets TargetType = SPELL_TARGETS_ENEMY, uint32 entry = 0, float x = 0, float y = 0, float z = 0)
: i_data(&data), i_spell(spell), i_push_type(type), i_radius(radius), i_radiusSq(radius*radius)
, i_TargetType(TargetType), i_entry(entry), i_x(x), i_y(y), i_z(z)
{
- i_caster = spell.GetCaster();
+ i_source = spell.GetCaster();
+ assert(i_source);
}
template<class T> inline void Visit(GridRefManager<T> &m)
{
- assert(i_data);
-
- if(!i_caster)
- return;
-
for(typename GridRefManager<T>::iterator itr = m.begin(); itr != m.end(); ++itr)
{
- if( !itr->getSource()->isAlive() || (itr->getSource()->GetTypeId() == TYPEID_PLAYER && ((Player*)itr->getSource())->isInFlight()))
- continue;
+ Unit *target = (Unit*)itr->getSource();
switch (i_TargetType)
{
- case SPELL_TARGETS_ALLY:
- if (!itr->getSource()->isAttackableByAOE() || !i_caster->IsFriendlyTo( itr->getSource() ))
- continue;
- break;
case SPELL_TARGETS_ENEMY:
- {
- if(itr->getSource()->GetTypeId()==TYPEID_UNIT && ((Creature*)itr->getSource())->isTotem())
+ if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem())
continue;
- if(!itr->getSource()->isAttackableByAOE())
+ if(!target->isAttackableByAOE())
continue;
-
- Unit* check = i_caster->GetCharmerOrOwnerOrSelf();
-
- if( check->GetTypeId()==TYPEID_PLAYER )
+ if(i_source->IsControlledByPlayer())
{
- if (check->IsFriendlyTo( itr->getSource() ))
+ if(i_source->IsFriendlyTo(target))
continue;
}
else
{
- if (!check->IsHostileTo( itr->getSource() ))
+ if(!i_source->IsHostileTo(target))
continue;
}
- }break;
+ break;
+ case SPELL_TARGETS_ALLY:
+ if(!target->isAttackableByAOE() || !i_source->IsFriendlyTo(target))
+ continue;
+ break;
case SPELL_TARGETS_ENTRY:
- {
- if(itr->getSource()->GetEntry()!= i_entry)
+ if(target->GetEntry()!= i_entry)
continue;
- }break;
- default: continue;
+ break;
+ default:
+ continue;
}
switch(i_push_type)
{
+ case PUSH_DEST_CENTER:
+ case PUSH_TARGET_CENTER:
+ if((target->GetDistanceSq(i_x, i_y, i_z) < i_radiusSq))
+ i_data->push_back(target);
+ break;
case PUSH_IN_FRONT:
- if(i_caster->isInFront((Unit*)(itr->getSource()), i_radius, M_PI/3 ))
- i_data->push_back(itr->getSource());
+ if(i_source->isInFront(target, i_radius, M_PI/3))
+ i_data->push_back(target);
break;
case PUSH_IN_BACK:
- if(i_caster->isInBack((Unit*)(itr->getSource()), i_radius, M_PI/3 ))
- i_data->push_back(itr->getSource());
+ if(i_source->isInBack(target, i_radius, M_PI/3))
+ i_data->push_back(target);
break;
case PUSH_IN_LINE:
- if(i_caster->isInLine((Unit*)(itr->getSource()), i_radius ))
- i_data->push_back(itr->getSource());
- break;
- default:
- if((itr->getSource()->GetDistanceSq(i_x, i_y, i_z) < i_radiusSq))
- i_data->push_back(itr->getSource());
+ if(i_source->isInLine(target, i_radius))
+ i_data->push_back(target);
break;
}
}
diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h
index d8a9d73cf46..5953ae9fb13 100644
--- a/src/game/SpellAuraDefines.h
+++ b/src/game/SpellAuraDefines.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -20,14 +20,20 @@
#ifndef TRINITY_SPELLAURADEFINES_H
#define TRINITY_SPELLAURADEFINES_H
-#define MAX_AURAS 56
-#define MAX_POSITIVE_AURAS 40
+#define MAX_AURAS 64 // client support up to 255, but it will cause problems with group auras updating
+#define FRIENDLY_AA_REMOVE_TIME 2*IN_MILISECONDS
enum AURA_FLAGS
{
- AFLAG_NEGATIVE = 0x09,
- AFLAG_POSITIVE = 0x1F,
- AFLAG_MASK = 0xFF
+ AFLAG_NONE = 0x00,
+ AFLAG_EFF_INDEX_0 = 0x01,
+ AFLAG_EFF_INDEX_1 = 0x02,
+ AFLAG_EFF_INDEX_2 = 0x04,
+ AFLAG_CASTER = 0x08,
+ AFLAG_POSITIVE = 0x10,
+ AFLAG_DURATION = 0x20,
+ AFLAG_UNK2 = 0x40,
+ AFLAG_NEGATIVE = 0x80
};
//m_schoolAbsorb
@@ -60,7 +66,7 @@ enum AuraType
SPELL_AURA_MOD_INVISIBILITY = 18,
SPELL_AURA_MOD_INVISIBILITY_DETECTION = 19,
SPELL_AURA_OBS_MOD_HEALTH = 20, //20,21 unofficial
- SPELL_AURA_OBS_MOD_MANA = 21,
+ SPELL_AURA_OBS_MOD_ENERGY = 21,
SPELL_AURA_MOD_RESISTANCE = 22,
SPELL_AURA_PERIODIC_TRIGGER_SPELL = 23,
SPELL_AURA_PERIODIC_ENERGIZE = 24,
@@ -85,11 +91,11 @@ enum AuraType
SPELL_AURA_PROC_TRIGGER_DAMAGE = 43,
SPELL_AURA_TRACK_CREATURES = 44,
SPELL_AURA_TRACK_RESOURCES = 45,
- SPELL_AURA_MOD_PARRY_SKILL = 46,
+ SPELL_AURA_46 = 46, // Ignore all Gear test spells
SPELL_AURA_MOD_PARRY_PERCENT = 47,
- SPELL_AURA_MOD_DODGE_SKILL = 48,
+ SPELL_AURA_48 = 48, // One periodic spell
SPELL_AURA_MOD_DODGE_PERCENT = 49,
- SPELL_AURA_MOD_BLOCK_SKILL = 50,
+ SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT = 50,
SPELL_AURA_MOD_BLOCK_PERCENT = 51,
SPELL_AURA_MOD_CRIT_PERCENT = 52,
SPELL_AURA_PERIODIC_LEECH = 53,
@@ -102,9 +108,9 @@ enum AuraType
SPELL_AURA_MOD_PACIFY_SILENCE = 60,
SPELL_AURA_MOD_SCALE = 61,
SPELL_AURA_PERIODIC_HEALTH_FUNNEL = 62,
- SPELL_AURA_PERIODIC_MANA_FUNNEL = 63,
+ SPELL_AURA_63 = 63, // old SPELL_AURA_PERIODIC_MANA_FUNNEL
SPELL_AURA_PERIODIC_MANA_LEECH = 64,
- SPELL_AURA_MOD_CASTING_SPEED = 65,
+ SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK = 65,
SPELL_AURA_FEIGN_DEATH = 66,
SPELL_AURA_MOD_DISARM = 67,
SPELL_AURA_MOD_STALKED = 68,
@@ -129,7 +135,7 @@ enum AuraType
SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN = 87,
SPELL_AURA_MOD_HEALTH_REGEN_PERCENT = 88,
SPELL_AURA_PERIODIC_DAMAGE_PERCENT = 89,
- SPELL_AURA_MOD_RESIST_CHANCE = 90,
+ SPELL_AURA_90 = 90, // old SPELL_AURA_MOD_RESIST_CHANCE
SPELL_AURA_MOD_DETECT_RANGE = 91,
SPELL_AURA_PREVENTS_FLEEING = 92,
SPELL_AURA_MOD_UNATTACKABLE = 93,
@@ -158,7 +164,7 @@ enum AuraType
SPELL_AURA_MOD_REGEN_DURING_COMBAT = 116,
SPELL_AURA_MOD_MECHANIC_RESISTANCE = 117,
SPELL_AURA_MOD_HEALING_PCT = 118,
- SPELL_AURA_SHARE_PET_TRACKING = 119,
+ SPELL_AURA_119 = 119, // old SPELL_AURA_SHARE_PET_TRACKING
SPELL_AURA_UNTRACKABLE = 120,
SPELL_AURA_EMPATHY = 121,
SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT = 122,
@@ -184,11 +190,11 @@ enum AuraType
SPELL_AURA_MOD_BASE_RESISTANCE_PCT = 142,
SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE = 143,
SPELL_AURA_SAFE_FALL = 144,
- SPELL_AURA_CHARISMA = 145,
- SPELL_AURA_PERSUADED = 146,
- SPELL_AURA_ADD_CREATURE_IMMUNITY = 147,
+ SPELL_AURA_MOD_PET_TALENT_POINTS = 145,
+ SPELL_AURA_ALLOW_TAME_PET_TYPE = 146,
+ SPELL_AURA_MECHANIC_IMMUNITY_MASK = 147,
SPELL_AURA_RETAIN_COMBO_POINTS = 148,
- SPELL_AURA_RESIST_PUSHBACK = 149, // Resist Pushback
+ SPELL_AURA_REDUCE_PUSHBACK = 149, // Reduce Pushback
SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT = 150,
SPELL_AURA_TRACK_STEALTHED = 151, // Track Stealthed
SPELL_AURA_MOD_DETECTED_RANGE = 152, // Mod Detected Range
@@ -212,15 +218,15 @@ enum AuraType
SPELL_AURA_DETECT_AMORE = 170,
SPELL_AURA_MOD_SPEED_NOT_STACK = 171,
SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK = 172,
- SPELL_AURA_ALLOW_CHAMPION_SPELLS = 173,
- SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT = 174, // by default intellect, dependent from SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT
+ SPELL_AURA_173 = 173, // old SPELL_AURA_ALLOW_CHAMPION_SPELLS
+ SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT = 174, // by defeult intelect, dependent from SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT
SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT = 175,
SPELL_AURA_SPIRIT_OF_REDEMPTION = 176,
SPELL_AURA_AOE_CHARM = 177,
SPELL_AURA_MOD_DEBUFF_RESISTANCE = 178,
SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE = 179,
SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS = 180,
- SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS = 181, // unused - possible flat spell crit damage versus
+ SPELL_AURA_181 = 181, // old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS - possible flat spell crit damage versus
SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT = 182,
SPELL_AURA_MOD_CRITICAL_THREAT = 183,
SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE = 184,
@@ -233,11 +239,11 @@ enum AuraType
SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED = 191,
SPELL_AURA_HASTE_MELEE = 192,
SPELL_AURA_MELEE_SLOW = 193,
- SPELL_AURA_MOD_DEPRICATED_1 = 194, // not used now, old SPELL_AURA_MOD_SPELL_DAMAGE_OF_INTELLECT
- SPELL_AURA_MOD_DEPRICATED_2 = 195, // not used now, old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT
+ SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL = 194,
+ SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL = 195,
SPELL_AURA_MOD_COOLDOWN = 196, // only 24818 Noxious Breath
SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE = 197,
- SPELL_AURA_MOD_ALL_WEAPON_SKILLS = 198,
+ SPELL_AURA_198 = 198, // old SPELL_AURA_MOD_ALL_WEAPON_SKILLS
SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT = 199,
SPELL_AURA_MOD_XP_PCT = 200,
SPELL_AURA_FLY = 201,
@@ -262,20 +268,20 @@ enum AuraType
SPELL_AURA_MOD_RATING_FROM_STAT = 220,
SPELL_AURA_221 = 221,
SPELL_AURA_222 = 222,
- SPELL_AURA_223 = 223,
+ SPELL_AURA_RAID_PROC_FROM_CHARGE = 223,
SPELL_AURA_224 = 224,
- SPELL_AURA_PRAYER_OF_MENDING = 225,
+ SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE = 225,
SPELL_AURA_PERIODIC_DUMMY = 226,
- SPELL_AURA_227 = 227,
+ SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE = 227,
SPELL_AURA_DETECT_STEALTH = 228,
SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE = 229,
SPELL_AURA_230 = 230,
- SPELL_AURA_231 = 231,
+ SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE = 231,
SPELL_AURA_MECHANIC_DURATION_MOD = 232,
SPELL_AURA_233 = 233,
SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK = 234,
SPELL_AURA_MOD_DISPEL_RESIST = 235,
- SPELL_AURA_236 = 236,
+ SPELL_AURA_CONTROL_VEHICLE = 236,
SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER = 237,
SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER = 238,
SPELL_AURA_MOD_SCALE_2 = 239,
@@ -284,29 +290,57 @@ enum AuraType
SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING = 242,
SPELL_AURA_243 = 243,
SPELL_AURA_COMPREHEND_LANGUAGE = 244,
- SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS = 245,
- SPELL_AURA_246 = 246,
+ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL = 245,
+ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK = 246,
SPELL_AURA_247 = 247,
SPELL_AURA_MOD_COMBAT_RESULT_CHANCE = 248,
- SPELL_AURA_249 = 249,
+ SPELL_AURA_CONVERT_RUNE = 249,
SPELL_AURA_MOD_INCREASE_HEALTH_2 = 250,
SPELL_AURA_MOD_ENEMY_DODGE = 251,
SPELL_AURA_252 = 252,
- SPELL_AURA_253 = 253,
- SPELL_AURA_254 = 254,
- SPELL_AURA_255 = 255,
- SPELL_AURA_256 = 256,
- SPELL_AURA_257 = 257,
+ SPELL_AURA_MOD_BLOCK_CRIT_CHANCE = 253,
+ SPELL_AURA_MOD_DISARM_OFFHAND = 254,
+ SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT = 255,
+ SPELL_AURA_NO_REAGENT_USE = 256,
+ SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS = 257,
SPELL_AURA_258 = 258,
- SPELL_AURA_259 = 259,
- SPELL_AURA_260 = 260,
- SPELL_AURA_261 = 261,
- TOTAL_AURAS=262
+ SPELL_AURA_MOD_HOT_PCT = 259,
+ SPELL_AURA_SCREEN_EFFECT = 260,
+ SPELL_AURA_PHASE = 261,
+ SPELL_AURA_ABILITY_IGNORE_AURASTATE = 262,
+ SPELL_AURA_ALLOW_ONLY_ABILITY = 263,
+ SPELL_AURA_264 = 264,
+ SPELL_AURA_265 = 265,
+ SPELL_AURA_266 = 266,
+ SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL = 267,
+ SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT = 268,
+ SPELL_AURA_MOD_IGNORE_TARGET_RESIST = 269,
+ SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST = 270, // Possibly need swap vs 195 aura used only in 1 spell Chaos Bolt Passive
+ SPELL_AURA_MOD_DAMAGE_FROM_CASTER = 271,
+ SPELL_AURA_272 = 272,
+ SPELL_AURA_273 = 273,
+ SPELL_AURA_ABILITY_CONSUME_NO_AMMO = 274,
+ SPELL_AURA_MOD_IGNORE_SHAPESHIFT = 275,
+ SPELL_AURA_276 = 276, // Only "Test Mod Damage % Mechanic" spell, possible mod damage done
+ SPELL_AURA_MOD_MAX_AFFECTED_TARGETS = 277,
+ SPELL_AURA_MOD_DISARM_RANGED = 278,
+ SPELL_AURA_279 = 279,
+ SPELL_AURA_MOD_WEAPONTYPE_IGNORE_TARGET_RESISTANCE = 280,
+ SPELL_AURA_MOD_HONOR_GAIN_PCT = 281,
+ SPELL_AURA_MOD_BASE_HEALTH_PCT = 282,
+ SPELL_AURA_MOD_HEALING_RECEIVED = 283, // Possibly only for some spell family class spells
+ SPELL_AURA_284,
+ SPELL_AURA_285,
+ SPELL_AURA_286,
+ SPELL_AURA_DEFLECT_SPELLS,
+ SPELL_AURA_288,
+ TOTAL_AURAS = 289
};
enum AreaAuraType
{
AREA_AURA_PARTY,
+ AREA_AURA_RAID,
AREA_AURA_FRIEND,
AREA_AURA_ENEMY,
AREA_AURA_PET,
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 0296f12a34b..fa3e6ef937a 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -31,11 +31,9 @@
#include "Player.h"
#include "Unit.h"
#include "Spell.h"
-#include "SpellAuras.h"
#include "DynamicObject.h"
#include "Group.h"
#include "UpdateData.h"
-#include "MapManager.h"
#include "ObjectAccessor.h"
#include "Policies/SingletonImp.h"
#include "Totem.h"
@@ -45,310 +43,323 @@
#include "OutdoorPvP.h"
#include "OutdoorPvPMgr.h"
#include "CreatureAI.h"
+#include "ScriptCalls.h"
#include "Util.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
-#define NULL_AURA_SLOT 0xFF
-
pAuraHandler AuraHandler[TOTAL_AURAS]=
{
- &Aura::HandleNULL, // 0 SPELL_AURA_NONE
- &Aura::HandleBindSight, // 1 SPELL_AURA_BIND_SIGHT
- &Aura::HandleModPossess, // 2 SPELL_AURA_MOD_POSSESS
- &Aura::HandlePeriodicDamage, // 3 SPELL_AURA_PERIODIC_DAMAGE
- &Aura::HandleAuraDummy, // 4 SPELL_AURA_DUMMY
- &Aura::HandleModConfuse, // 5 SPELL_AURA_MOD_CONFUSE
- &Aura::HandleModCharm, // 6 SPELL_AURA_MOD_CHARM
- &Aura::HandleModFear, // 7 SPELL_AURA_MOD_FEAR
- &Aura::HandlePeriodicHeal, // 8 SPELL_AURA_PERIODIC_HEAL
- &Aura::HandleModAttackSpeed, // 9 SPELL_AURA_MOD_ATTACKSPEED
- &Aura::HandleModThreat, // 10 SPELL_AURA_MOD_THREAT
- &Aura::HandleModTaunt, // 11 SPELL_AURA_MOD_TAUNT
- &Aura::HandleAuraModStun, // 12 SPELL_AURA_MOD_STUN
- &Aura::HandleModDamageDone, // 13 SPELL_AURA_MOD_DAMAGE_DONE
- &Aura::HandleNoImmediateEffect, // 14 SPELL_AURA_MOD_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
- &Aura::HandleNoImmediateEffect, // 15 SPELL_AURA_DAMAGE_SHIELD implemented in Unit::DoAttackDamage
- &Aura::HandleModStealth, // 16 SPELL_AURA_MOD_STEALTH
- &Aura::HandleNoImmediateEffect, // 17 SPELL_AURA_MOD_STEALTH_DETECT
- &Aura::HandleInvisibility, // 18 SPELL_AURA_MOD_INVISIBILITY
- &Aura::HandleInvisibilityDetect, // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION
- &Aura::HandleAuraModTotalHealthPercentRegen, // 20 SPELL_AURA_OBS_MOD_HEALTH
- &Aura::HandleAuraModTotalManaPercentRegen, // 21 SPELL_AURA_OBS_MOD_MANA
- &Aura::HandleAuraModResistance, // 22 SPELL_AURA_MOD_RESISTANCE
- &Aura::HandlePeriodicTriggerSpell, // 23 SPELL_AURA_PERIODIC_TRIGGER_SPELL
- &Aura::HandlePeriodicEnergize, // 24 SPELL_AURA_PERIODIC_ENERGIZE
- &Aura::HandleAuraModPacify, // 25 SPELL_AURA_MOD_PACIFY
- &Aura::HandleAuraModRoot, // 26 SPELL_AURA_MOD_ROOT
- &Aura::HandleAuraModSilence, // 27 SPELL_AURA_MOD_SILENCE
- &Aura::HandleNoImmediateEffect, // 28 SPELL_AURA_REFLECT_SPELLS implement in Unit::SpellHitResult
- &Aura::HandleAuraModStat, // 29 SPELL_AURA_MOD_STAT
- &Aura::HandleAuraModSkill, // 30 SPELL_AURA_MOD_SKILL
- &Aura::HandleAuraModIncreaseSpeed, // 31 SPELL_AURA_MOD_INCREASE_SPEED
- &Aura::HandleAuraModIncreaseMountedSpeed, // 32 SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED
- &Aura::HandleAuraModDecreaseSpeed, // 33 SPELL_AURA_MOD_DECREASE_SPEED
- &Aura::HandleAuraModIncreaseHealth, // 34 SPELL_AURA_MOD_INCREASE_HEALTH
- &Aura::HandleAuraModIncreaseEnergy, // 35 SPELL_AURA_MOD_INCREASE_ENERGY
- &Aura::HandleAuraModShapeshift, // 36 SPELL_AURA_MOD_SHAPESHIFT
- &Aura::HandleAuraModEffectImmunity, // 37 SPELL_AURA_EFFECT_IMMUNITY
- &Aura::HandleAuraModStateImmunity, // 38 SPELL_AURA_STATE_IMMUNITY
- &Aura::HandleAuraModSchoolImmunity, // 39 SPELL_AURA_SCHOOL_IMMUNITY
- &Aura::HandleAuraModDmgImmunity, // 40 SPELL_AURA_DAMAGE_IMMUNITY
- &Aura::HandleAuraModDispelImmunity, // 41 SPELL_AURA_DISPEL_IMMUNITY
- &Aura::HandleAuraProcTriggerSpell, // 42 SPELL_AURA_PROC_TRIGGER_SPELL implemented in Unit::ProcDamageAndSpellFor and Unit::HandleProcTriggerSpell
- &Aura::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor
- &Aura::HandleAuraTrackCreatures, // 44 SPELL_AURA_TRACK_CREATURES
- &Aura::HandleAuraTrackResources, // 45 SPELL_AURA_TRACK_RESOURCES
- &Aura::HandleUnused, // 46 SPELL_AURA_MOD_PARRY_SKILL obsolete?
- &Aura::HandleAuraModParryPercent, // 47 SPELL_AURA_MOD_PARRY_PERCENT
- &Aura::HandleUnused, // 48 SPELL_AURA_MOD_DODGE_SKILL obsolete?
- &Aura::HandleAuraModDodgePercent, // 49 SPELL_AURA_MOD_DODGE_PERCENT
- &Aura::HandleUnused, // 50 SPELL_AURA_MOD_BLOCK_SKILL obsolete?
- &Aura::HandleAuraModBlockPercent, // 51 SPELL_AURA_MOD_BLOCK_PERCENT
- &Aura::HandleAuraModCritPercent, // 52 SPELL_AURA_MOD_CRIT_PERCENT
- &Aura::HandlePeriodicLeech, // 53 SPELL_AURA_PERIODIC_LEECH
- &Aura::HandleModHitChance, // 54 SPELL_AURA_MOD_HIT_CHANCE
- &Aura::HandleModSpellHitChance, // 55 SPELL_AURA_MOD_SPELL_HIT_CHANCE
- &Aura::HandleAuraTransform, // 56 SPELL_AURA_TRANSFORM
- &Aura::HandleModSpellCritChance, // 57 SPELL_AURA_MOD_SPELL_CRIT_CHANCE
- &Aura::HandleAuraModIncreaseSwimSpeed, // 58 SPELL_AURA_MOD_INCREASE_SWIM_SPEED
- &Aura::HandleNoImmediateEffect, // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
- &Aura::HandleAuraModPacifyAndSilence, // 60 SPELL_AURA_MOD_PACIFY_SILENCE
- &Aura::HandleAuraModScale, // 61 SPELL_AURA_MOD_SCALE
- &Aura::HandleNULL, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL
- &Aura::HandleUnused, // 63 SPELL_AURA_PERIODIC_MANA_FUNNEL obsolete?
- &Aura::HandlePeriodicManaLeech, // 64 SPELL_AURA_PERIODIC_MANA_LEECH
- &Aura::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED
- &Aura::HandleFeignDeath, // 66 SPELL_AURA_FEIGN_DEATH
- &Aura::HandleAuraModDisarm, // 67 SPELL_AURA_MOD_DISARM
- &Aura::HandleAuraModStalked, // 68 SPELL_AURA_MOD_STALKED
- &Aura::HandleSchoolAbsorb, // 69 SPELL_AURA_SCHOOL_ABSORB implemented in Unit::CalcAbsorbResist
- &Aura::HandleUnused, // 70 SPELL_AURA_EXTRA_ATTACKS Useless, used by only one spell that has only visual effect
- &Aura::HandleModSpellCritChanceShool, // 71 SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL
- &Aura::HandleModPowerCostPCT, // 72 SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT
- &Aura::HandleModPowerCost, // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL
- &Aura::HandleNoImmediateEffect, // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL implemented in Unit::SpellHitResult
- &Aura::HandleNoImmediateEffect, // 75 SPELL_AURA_MOD_LANGUAGE
- &Aura::HandleFarSight, // 76 SPELL_AURA_FAR_SIGHT
- &Aura::HandleModMechanicImmunity, // 77 SPELL_AURA_MECHANIC_IMMUNITY
- &Aura::HandleAuraMounted, // 78 SPELL_AURA_MOUNTED
- &Aura::HandleModDamagePercentDone, // 79 SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
- &Aura::HandleModPercentStat, // 80 SPELL_AURA_MOD_PERCENT_STAT
- &Aura::HandleNoImmediateEffect, // 81 SPELL_AURA_SPLIT_DAMAGE_PCT
- &Aura::HandleWaterBreathing, // 82 SPELL_AURA_WATER_BREATHING
- &Aura::HandleModBaseResistance, // 83 SPELL_AURA_MOD_BASE_RESISTANCE
- &Aura::HandleModRegen, // 84 SPELL_AURA_MOD_REGEN
- &Aura::HandleModPowerRegen, // 85 SPELL_AURA_MOD_POWER_REGEN
- &Aura::HandleChannelDeathItem, // 86 SPELL_AURA_CHANNEL_DEATH_ITEM
- &Aura::HandleNoImmediateEffect, // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
- &Aura::HandleNoImmediateEffect, // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT
- &Aura::HandlePeriodicDamagePCT, // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT
- &Aura::HandleUnused, // 90 SPELL_AURA_MOD_RESIST_CHANCE Useless
- &Aura::HandleNoImmediateEffect, // 91 SPELL_AURA_MOD_DETECT_RANGE implemented in Creature::GetAttackDistance
- &Aura::HandlePreventFleeing, // 92 SPELL_AURA_PREVENTS_FLEEING
- &Aura::HandleModUnattackable, // 93 SPELL_AURA_MOD_UNATTACKABLE
- &Aura::HandleNoImmediateEffect, // 94 SPELL_AURA_INTERRUPT_REGEN implemented in Player::RegenerateAll
- &Aura::HandleAuraGhost, // 95 SPELL_AURA_GHOST
- &Aura::HandleNoImmediateEffect, // 96 SPELL_AURA_SPELL_MAGNET implemented in Spell::SelectMagnetTarget
- &Aura::HandleManaShield, // 97 SPELL_AURA_MANA_SHIELD implemented in Unit::CalcAbsorbResist
- &Aura::HandleAuraModSkill, // 98 SPELL_AURA_MOD_SKILL_TALENT
- &Aura::HandleAuraModAttackPower, // 99 SPELL_AURA_MOD_ATTACK_POWER
- &Aura::HandleUnused, //100 SPELL_AURA_AURAS_VISIBLE obsolete? all player can see all auras now
- &Aura::HandleModResistancePercent, //101 SPELL_AURA_MOD_RESISTANCE_PCT
- &Aura::HandleNoImmediateEffect, //102 SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
- &Aura::HandleAuraModTotalThreat, //103 SPELL_AURA_MOD_TOTAL_THREAT
- &Aura::HandleAuraWaterWalk, //104 SPELL_AURA_WATER_WALK
- &Aura::HandleAuraFeatherFall, //105 SPELL_AURA_FEATHER_FALL
- &Aura::HandleAuraHover, //106 SPELL_AURA_HOVER
- &Aura::HandleAddModifier, //107 SPELL_AURA_ADD_FLAT_MODIFIER
- &Aura::HandleAddModifier, //108 SPELL_AURA_ADD_PCT_MODIFIER
- &Aura::HandleNoImmediateEffect, //109 SPELL_AURA_ADD_TARGET_TRIGGER
- &Aura::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT
- &Aura::HandleNULL, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER
- &Aura::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
- &Aura::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
- &Aura::HandleNoImmediateEffect, //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
- &Aura::HandleNoImmediateEffect, //115 SPELL_AURA_MOD_HEALING implemented in Unit::SpellBaseHealingBonusForVictim
- &Aura::HandleNoImmediateEffect, //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT
- &Aura::HandleNoImmediateEffect, //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE implemented in Unit::MagicSpellHitResult
- &Aura::HandleNoImmediateEffect, //118 SPELL_AURA_MOD_HEALING_PCT implemented in Unit::SpellHealingBonus
- &Aura::HandleUnused, //119 SPELL_AURA_SHARE_PET_TRACKING useless
- &Aura::HandleAuraUntrackable, //120 SPELL_AURA_UNTRACKABLE
- &Aura::HandleAuraEmpathy, //121 SPELL_AURA_EMPATHY
- &Aura::HandleModOffhandDamagePercent, //122 SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT
- &Aura::HandleModTargetResistance, //123 SPELL_AURA_MOD_TARGET_RESISTANCE
- &Aura::HandleAuraModRangedAttackPower, //124 SPELL_AURA_MOD_RANGED_ATTACK_POWER
- &Aura::HandleNoImmediateEffect, //125 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
- &Aura::HandleNoImmediateEffect, //126 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
- &Aura::HandleNoImmediateEffect, //127 SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
- &Aura::HandleModPossessPet, //128 SPELL_AURA_MOD_POSSESS_PET
- &Aura::HandleAuraModIncreaseSpeed, //129 SPELL_AURA_MOD_SPEED_ALWAYS
- &Aura::HandleAuraModIncreaseMountedSpeed, //130 SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS
- &Aura::HandleNoImmediateEffect, //131 SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
- &Aura::HandleAuraModIncreaseEnergyPercent, //132 SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT
- &Aura::HandleAuraModIncreaseHealthPercent, //133 SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT
- &Aura::HandleAuraModRegenInterrupt, //134 SPELL_AURA_MOD_MANA_REGEN_INTERRUPT
- &Aura::HandleModHealingDone, //135 SPELL_AURA_MOD_HEALING_DONE
- &Aura::HandleNoImmediateEffect, //136 SPELL_AURA_MOD_HEALING_DONE_PERCENT implemented in Unit::SpellHealingBonus
- &Aura::HandleModTotalPercentStat, //137 SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE
- &Aura::HandleHaste, //138 SPELL_AURA_MOD_HASTE
- &Aura::HandleForceReaction, //139 SPELL_AURA_FORCE_REACTION
- &Aura::HandleAuraModRangedHaste, //140 SPELL_AURA_MOD_RANGED_HASTE
- &Aura::HandleRangedAmmoHaste, //141 SPELL_AURA_MOD_RANGED_AMMO_HASTE
- &Aura::HandleAuraModBaseResistancePCT, //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT
- &Aura::HandleAuraModResistanceExclusive, //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE
- &Aura::HandleNoImmediateEffect, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
- &Aura::HandleUnused, //145 SPELL_AURA_CHARISMA obsolete?
- &Aura::HandleUnused, //146 SPELL_AURA_PERSUADED obsolete?
- &Aura::HandleNULL, //147 SPELL_AURA_ADD_CREATURE_IMMUNITY
- &Aura::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS
- &Aura::HandleNoImmediateEffect, //149 SPELL_AURA_RESIST_PUSHBACK
- &Aura::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
- &Aura::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
- &Aura::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
- &Aura::HandleNoImmediateEffect, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT
- &Aura::HandleNoImmediateEffect, //154 SPELL_AURA_MOD_STEALTH_LEVEL
- &Aura::HandleNoImmediateEffect, //155 SPELL_AURA_MOD_WATER_BREATHING
- &Aura::HandleNoImmediateEffect, //156 SPELL_AURA_MOD_REPUTATION_GAIN
- &Aura::HandleNULL, //157 SPELL_AURA_PET_DAMAGE_MULTI
- &Aura::HandleShieldBlockValue, //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE
- &Aura::HandleNoImmediateEffect, //159 SPELL_AURA_NO_PVP_CREDIT only for Honorless Target spell
- &Aura::HandleNoImmediateEffect, //160 SPELL_AURA_MOD_AOE_AVOIDANCE implemented in Unit::MagicSpellHitResult
- &Aura::HandleNoImmediateEffect, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT
- &Aura::HandleAuraPowerBurn, //162 SPELL_AURA_POWER_BURN_MANA
- &Aura::HandleNoImmediateEffect, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE
- &Aura::HandleUnused, //164 useless, only one test spell
- &Aura::HandleNoImmediateEffect, //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
- &Aura::HandleAuraModAttackPowerPercent, //166 SPELL_AURA_MOD_ATTACK_POWER_PCT
- &Aura::HandleAuraModRangedAttackPowerPercent, //167 SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT
- &Aura::HandleNoImmediateEffect, //168 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus
- &Aura::HandleNoImmediateEffect, //169 SPELL_AURA_MOD_CRIT_PERCENT_VERSUS implemented in Unit::DealDamageBySchool, Unit::DoAttackDamage, Unit::SpellCriticalBonus
- &Aura::HandleNULL, //170 SPELL_AURA_DETECT_AMORE only for Detect Amore spell
- &Aura::HandleAuraModIncreaseSpeed, //171 SPELL_AURA_MOD_SPEED_NOT_STACK
- &Aura::HandleAuraModIncreaseMountedSpeed, //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK
- &Aura::HandleUnused, //173 SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell
- &Aura::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus (by default intellect, dependent from SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT)
- &Aura::HandleModSpellHealingPercentFromStat, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus
- &Aura::HandleSpiritOfRedemption, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end
- &Aura::HandleNULL, //177 SPELL_AURA_AOE_CHARM
- &Aura::HandleNoImmediateEffect, //178 SPELL_AURA_MOD_DEBUFF_RESISTANCE implemented in Unit::MagicSpellHitResult
- &Aura::HandleNoImmediateEffect, //179 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE implemented in Unit::SpellCriticalBonus
- &Aura::HandleNoImmediateEffect, //180 SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS implemented in Unit::SpellDamageBonus
- &Aura::HandleUnused, //181 SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS unused
- &Aura::HandleAuraModResistenceOfStatPercent, //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT
- &Aura::HandleNULL, //183 SPELL_AURA_MOD_CRITICAL_THREAT
- &Aura::HandleNoImmediateEffect, //184 SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
- &Aura::HandleNoImmediateEffect, //185 SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
- &Aura::HandleNoImmediateEffect, //186 SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE implemented in Unit::MagicSpellHitResult
- &Aura::HandleNoImmediateEffect, //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
- &Aura::HandleNoImmediateEffect, //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
- &Aura::HandleModRating, //189 SPELL_AURA_MOD_RATING
- &Aura::HandleNULL, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN
- &Aura::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
- &Aura::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE
- &Aura::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct)
- &Aura::HandleUnused, //194 SPELL_AURA_MOD_DEPRICATED_1 not used now (old SPELL_AURA_MOD_SPELL_DAMAGE_OF_INTELLECT)
- &Aura::HandleUnused, //195 SPELL_AURA_MOD_DEPRICATED_2 not used now (old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT)
- &Aura::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN
- &Aura::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance
- &Aura::HandleUnused, //198 SPELL_AURA_MOD_ALL_WEAPON_SKILLS
- &Aura::HandleNoImmediateEffect, //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT implemented in Unit::MagicSpellHitResult
- &Aura::HandleNoImmediateEffect, //200 SPELL_AURA_MOD_XP_PCT implemented in Player::GiveXP
- &Aura::HandleAuraAllowFlight, //201 SPELL_AURA_FLY this aura enable flight mode...
- &Aura::HandleNoImmediateEffect, //202 SPELL_AURA_CANNOT_BE_DODGED implemented in Unit::RollPhysicalOutcomeAgainst
- &Aura::HandleNoImmediateEffect, //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
- &Aura::HandleNoImmediateEffect, //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
- &Aura::HandleNULL, //205 vulnerable to school dmg?
- &Aura::HandleNULL, //206 SPELL_AURA_MOD_SPEED_MOUNTED
- &Aura::HandleAuraModIncreaseFlightSpeed, //207 SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED
- &Aura::HandleAuraModIncreaseFlightSpeed, //208 SPELL_AURA_MOD_SPEED_FLIGHT, used only in spell: Flight Form (Passive)
- &Aura::HandleAuraModIncreaseFlightSpeed, //209 SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS
- &Aura::HandleNULL, //210 Commentator's Command
- &Aura::HandleAuraModIncreaseFlightSpeed, //211 SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK
- &Aura::HandleAuraModRangedAttackPowerOfStatPercent, //212 SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT
- &Aura::HandleNoImmediateEffect, //213 SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT implemented in Player::RewardRage
- &Aura::HandleNULL, //214 Tamed Pet Passive
- &Aura::HandleArenaPreparation, //215 SPELL_AURA_ARENA_PREPARATION
- &Aura::HandleModCastingSpeed, //216 SPELL_AURA_HASTE_SPELLS
- &Aura::HandleUnused, //217 unused
- &Aura::HandleAuraModRangedHaste, //218 SPELL_AURA_HASTE_RANGED
- &Aura::HandleModManaRegen, //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT
- &Aura::HandleNULL, //220 SPELL_AURA_MOD_RATING_FROM_STAT
- &Aura::HandleNULL, //221 ignored
- &Aura::HandleUnused, //222 unused
- &Aura::HandleNULL, //223 Cold Stare
- &Aura::HandleUnused, //224 unused
- &Aura::HandleNoImmediateEffect, //225 SPELL_AURA_PRAYER_OF_MENDING
- &Aura::HandleAuraPeriodicDummy, //226 SPELL_AURA_PERIODIC_DUMMY
- &Aura::HandleNULL, //227 periodic trigger spell
- &Aura::HandleNoImmediateEffect, //228 stealth detection
- &Aura::HandleNULL, //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE
- &Aura::HandleAuraModIncreaseMaxHealth, //230 Commanding Shout
- &Aura::HandleNULL, //231
- &Aura::HandleNoImmediateEffect, //232 SPELL_AURA_MECHANIC_DURATION_MOD implement in Unit::CalculateSpellDuration
- &Aura::HandleNULL, //233 set model id to the one of the creature with id m_modifier.m_miscvalue
- &Aura::HandleNoImmediateEffect, //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration
- &Aura::HandleAuraModDispelResist, //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult
- &Aura::HandleUnused, //236 unused
- &Aura::HandleModSpellDamagePercentFromAttackPower, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonus
- &Aura::HandleModSpellHealingPercentFromAttackPower, //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus
- &Aura::HandleAuraModScale, //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61
- &Aura::HandleAuraModExpertise, //240 SPELL_AURA_MOD_EXPERTISE
- &Aura::HandleForceMoveForward, //241 Forces the player to move forward
- &Aura::HandleUnused, //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING
- &Aura::HandleUnused, //243 used by two test spells
- &Aura::HandleComprehendLanguage, //244 Comprehend language
- &Aura::HandleUnused, //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS
- &Aura::HandleUnused, //246 unused
- &Aura::HandleUnused, //247 unused
- &Aura::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
- &Aura::HandleNULL, //249
- &Aura::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2
- &Aura::HandleNULL, //251 SPELL_AURA_MOD_ENEMY_DODGE
- &Aura::HandleUnused, //252 unused
- &Aura::HandleUnused, //253 unused
- &Aura::HandleUnused, //254 unused
- &Aura::HandleUnused, //255 unused
- &Aura::HandleUnused, //256 unused
- &Aura::HandleUnused, //257 unused
- &Aura::HandleUnused, //258 unused
- &Aura::HandleUnused, //259 unused
- &Aura::HandleUnused, //260 unused
- &Aura::HandleNULL //261 SPELL_AURA_261 some phased state (44856 spell)
+ &AuraEffect::HandleNULL, // 0 SPELL_AURA_NONE
+ &AuraEffect::HandleBindSight, // 1 SPELL_AURA_BIND_SIGHT
+ &AuraEffect::HandleModPossess, // 2 SPELL_AURA_MOD_POSSESS
+ &AuraEffect::HandlePeriodicDamage, // 3 SPELL_AURA_PERIODIC_DAMAGE
+ &AuraEffect::HandleAuraDummy, // 4 SPELL_AURA_DUMMY
+ &AuraEffect::HandleModConfuse, // 5 SPELL_AURA_MOD_CONFUSE
+ &AuraEffect::HandleModCharm, // 6 SPELL_AURA_MOD_CHARM
+ &AuraEffect::HandleModFear, // 7 SPELL_AURA_MOD_FEAR
+ &AuraEffect::HandlePeriodicHeal, // 8 SPELL_AURA_PERIODIC_HEAL
+ &AuraEffect::HandleModAttackSpeed, // 9 SPELL_AURA_MOD_ATTACKSPEED
+ &AuraEffect::HandleModThreat, // 10 SPELL_AURA_MOD_THREAT
+ &AuraEffect::HandleModTaunt, // 11 SPELL_AURA_MOD_TAUNT
+ &AuraEffect::HandleAuraModStun, // 12 SPELL_AURA_MOD_STUN
+ &AuraEffect::HandleModDamageDone, // 13 SPELL_AURA_MOD_DAMAGE_DONE
+ &AuraEffect::HandleNoImmediateEffect, // 14 SPELL_AURA_MOD_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
+ &AuraEffect::HandleNoImmediateEffect, // 15 SPELL_AURA_DAMAGE_SHIELD implemented in Unit::DoAttackDamage
+ &AuraEffect::HandleModStealth, // 16 SPELL_AURA_MOD_STEALTH
+ &AuraEffect::HandleNoImmediateEffect, // 17 SPELL_AURA_MOD_STEALTH_DETECT
+ &AuraEffect::HandleInvisibility, // 18 SPELL_AURA_MOD_INVISIBILITY
+ &AuraEffect::HandleInvisibilityDetect, // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION
+ &AuraEffect::HandleAuraModTotalHealthPercentRegen, // 20 SPELL_AURA_OBS_MOD_HEALTH
+ &AuraEffect::HandleAuraModTotalEnergyPercentRegen, // 21 SPELL_AURA_OBS_MOD_ENERGY
+ &AuraEffect::HandleAuraModResistance, // 22 SPELL_AURA_MOD_RESISTANCE
+ &AuraEffect::HandlePeriodicTriggerSpell, // 23 SPELL_AURA_PERIODIC_TRIGGER_SPELL
+ &AuraEffect::HandlePeriodicEnergize, // 24 SPELL_AURA_PERIODIC_ENERGIZE
+ &AuraEffect::HandleAuraModPacify, // 25 SPELL_AURA_MOD_PACIFY
+ &AuraEffect::HandleAuraModRoot, // 26 SPELL_AURA_MOD_ROOT
+ &AuraEffect::HandleAuraModSilence, // 27 SPELL_AURA_MOD_SILENCE
+ &AuraEffect::HandleNoImmediateEffect, // 28 SPELL_AURA_REFLECT_SPELLS implement in Unit::SpellHitResult
+ &AuraEffect::HandleAuraModStat, // 29 SPELL_AURA_MOD_STAT
+ &AuraEffect::HandleAuraModSkill, // 30 SPELL_AURA_MOD_SKILL
+ &AuraEffect::HandleAuraModIncreaseSpeed, // 31 SPELL_AURA_MOD_INCREASE_SPEED
+ &AuraEffect::HandleAuraModIncreaseMountedSpeed, // 32 SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED
+ &AuraEffect::HandleAuraModDecreaseSpeed, // 33 SPELL_AURA_MOD_DECREASE_SPEED
+ &AuraEffect::HandleAuraModIncreaseHealth, // 34 SPELL_AURA_MOD_INCREASE_HEALTH
+ &AuraEffect::HandleAuraModIncreaseEnergy, // 35 SPELL_AURA_MOD_INCREASE_ENERGY
+ &AuraEffect::HandleAuraModShapeshift, // 36 SPELL_AURA_MOD_SHAPESHIFT
+ &AuraEffect::HandleAuraModEffectImmunity, // 37 SPELL_AURA_EFFECT_IMMUNITY
+ &AuraEffect::HandleAuraModStateImmunity, // 38 SPELL_AURA_STATE_IMMUNITY
+ &AuraEffect::HandleAuraModSchoolImmunity, // 39 SPELL_AURA_SCHOOL_IMMUNITY
+ &AuraEffect::HandleAuraModDmgImmunity, // 40 SPELL_AURA_DAMAGE_IMMUNITY
+ &AuraEffect::HandleAuraModDispelImmunity, // 41 SPELL_AURA_DISPEL_IMMUNITY
+ &AuraEffect::HandleAuraProcTriggerSpell, // 42 SPELL_AURA_PROC_TRIGGER_SPELL implemented in Unit::ProcDamageAndSpellFor and Unit::HandleProcTriggerSpell
+ &AuraEffect::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor
+ &AuraEffect::HandleAuraTrackCreatures, // 44 SPELL_AURA_TRACK_CREATURES
+ &AuraEffect::HandleAuraTrackResources, // 45 SPELL_AURA_TRACK_RESOURCES
+ &AuraEffect::HandleUnused, // 46 SPELL_AURA_46 (used in test spells 54054 and 54058, and spell 48050) (3.0.8a)
+ &AuraEffect::HandleAuraModParryPercent, // 47 SPELL_AURA_MOD_PARRY_PERCENT
+ &AuraEffect::HandleNULL, // 48 SPELL_AURA_48 spell Napalm (area damage spell with additional delayed damage effect)
+ &AuraEffect::HandleAuraModDodgePercent, // 49 SPELL_AURA_MOD_DODGE_PERCENT
+ &AuraEffect::HandleNoImmediateEffect, // 50 SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT implemented in Unit::SpellCriticalHealingBonus
+ &AuraEffect::HandleAuraModBlockPercent, // 51 SPELL_AURA_MOD_BLOCK_PERCENT
+ &AuraEffect::HandleAuraModCritPercent, // 52 SPELL_AURA_MOD_CRIT_PERCENT
+ &AuraEffect::HandlePeriodicLeech, // 53 SPELL_AURA_PERIODIC_LEECH
+ &AuraEffect::HandleModHitChance, // 54 SPELL_AURA_MOD_HIT_CHANCE
+ &AuraEffect::HandleModSpellHitChance, // 55 SPELL_AURA_MOD_SPELL_HIT_CHANCE
+ &AuraEffect::HandleAuraTransform, // 56 SPELL_AURA_TRANSFORM
+ &AuraEffect::HandleModSpellCritChance, // 57 SPELL_AURA_MOD_SPELL_CRIT_CHANCE
+ &AuraEffect::HandleAuraModIncreaseSwimSpeed, // 58 SPELL_AURA_MOD_INCREASE_SWIM_SPEED
+ &AuraEffect::HandleNoImmediateEffect, // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
+ &AuraEffect::HandleAuraModPacifyAndSilence, // 60 SPELL_AURA_MOD_PACIFY_SILENCE
+ &AuraEffect::HandleAuraModScale, // 61 SPELL_AURA_MOD_SCALE
+ &AuraEffect::HandlePeriodicHealthFunnel, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL
+ &AuraEffect::HandleUnused, // 63 unused (3.0.8a) old SPELL_AURA_PERIODIC_MANA_FUNNEL
+ &AuraEffect::HandlePeriodicManaLeech, // 64 SPELL_AURA_PERIODIC_MANA_LEECH
+ &AuraEffect::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK
+ &AuraEffect::HandleFeignDeath, // 66 SPELL_AURA_FEIGN_DEATH
+ &AuraEffect::HandleAuraModDisarm, // 67 SPELL_AURA_MOD_DISARM
+ &AuraEffect::HandleAuraModStalked, // 68 SPELL_AURA_MOD_STALKED
+ &AuraEffect::HandleSchoolAbsorb, // 69 SPELL_AURA_SCHOOL_ABSORB implemented in Unit::CalcAbsorbResist
+ &AuraEffect::HandleUnused, // 70 SPELL_AURA_EXTRA_ATTACKS Useless, used by only one spell that has only visual effect
+ &AuraEffect::HandleModSpellCritChanceShool, // 71 SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL
+ &AuraEffect::HandleModPowerCostPCT, // 72 SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT
+ &AuraEffect::HandleModPowerCost, // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL
+ &AuraEffect::HandleNoImmediateEffect, // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL implemented in Unit::SpellHitResult
+ &AuraEffect::HandleNoImmediateEffect, // 75 SPELL_AURA_MOD_LANGUAGE
+ &AuraEffect::HandleFarSight, // 76 SPELL_AURA_FAR_SIGHT
+ &AuraEffect::HandleModMechanicImmunity, // 77 SPELL_AURA_MECHANIC_IMMUNITY
+ &AuraEffect::HandleAuraMounted, // 78 SPELL_AURA_MOUNTED
+ &AuraEffect::HandleModDamagePercentDone, // 79 SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
+ &AuraEffect::HandleModPercentStat, // 80 SPELL_AURA_MOD_PERCENT_STAT
+ &AuraEffect::HandleNoImmediateEffect, // 81 SPELL_AURA_SPLIT_DAMAGE_PCT
+ &AuraEffect::HandleWaterBreathing, // 82 SPELL_AURA_WATER_BREATHING
+ &AuraEffect::HandleModBaseResistance, // 83 SPELL_AURA_MOD_BASE_RESISTANCE
+ &AuraEffect::HandleModRegen, // 84 SPELL_AURA_MOD_REGEN
+ &AuraEffect::HandleModPowerRegen, // 85 SPELL_AURA_MOD_POWER_REGEN
+ &AuraEffect::HandleChannelDeathItem, // 86 SPELL_AURA_CHANNEL_DEATH_ITEM
+ &AuraEffect::HandleNoImmediateEffect, // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
+ &AuraEffect::HandleNoImmediateEffect, // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT
+ &AuraEffect::HandlePeriodicDamagePCT, // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT
+ &AuraEffect::HandleUnused, // 90 unused (3.0.8a) old SPELL_AURA_MOD_RESIST_CHANCE
+ &AuraEffect::HandleNoImmediateEffect, // 91 SPELL_AURA_MOD_DETECT_RANGE implemented in Creature::GetAttackDistance
+ &AuraEffect::HandlePreventFleeing, // 92 SPELL_AURA_PREVENTS_FLEEING
+ &AuraEffect::HandleModUnattackable, // 93 SPELL_AURA_MOD_UNATTACKABLE
+ &AuraEffect::HandleNoImmediateEffect, // 94 SPELL_AURA_INTERRUPT_REGEN implemented in Player::RegenerateAll
+ &AuraEffect::HandleAuraGhost, // 95 SPELL_AURA_GHOST
+ &AuraEffect::HandleNoImmediateEffect, // 96 SPELL_AURA_SPELL_MAGNET implemented in Unit::SelectMagnetTarget
+ &AuraEffect::HandleManaShield, // 97 SPELL_AURA_MANA_SHIELD implemented in Unit::CalcAbsorbResist
+ &AuraEffect::HandleAuraModSkill, // 98 SPELL_AURA_MOD_SKILL_TALENT
+ &AuraEffect::HandleAuraModAttackPower, // 99 SPELL_AURA_MOD_ATTACK_POWER
+ &AuraEffect::HandleUnused, //100 SPELL_AURA_AURAS_VISIBLE obsolete? all player can see all auras now, but still have spells including GM-spell
+ &AuraEffect::HandleModResistancePercent, //101 SPELL_AURA_MOD_RESISTANCE_PCT
+ &AuraEffect::HandleNoImmediateEffect, //102 SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleAuraModTotalThreat, //103 SPELL_AURA_MOD_TOTAL_THREAT
+ &AuraEffect::HandleAuraWaterWalk, //104 SPELL_AURA_WATER_WALK
+ &AuraEffect::HandleAuraFeatherFall, //105 SPELL_AURA_FEATHER_FALL
+ &AuraEffect::HandleAuraHover, //106 SPELL_AURA_HOVER
+ &AuraEffect::HandleAddModifier, //107 SPELL_AURA_ADD_FLAT_MODIFIER
+ &AuraEffect::HandleAddModifier, //108 SPELL_AURA_ADD_PCT_MODIFIER
+ &AuraEffect::HandleAddTargetTrigger, //109 SPELL_AURA_ADD_TARGET_TRIGGER
+ &AuraEffect::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT
+ &AuraEffect::HandleNoImmediateEffect, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER implemented in Unit::SelectMagnetTarget
+ &AuraEffect::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
+ &AuraEffect::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleNoImmediateEffect, //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleNoImmediateEffect, //115 SPELL_AURA_MOD_HEALING implemented in Unit::SpellBaseHealingBonusForVictim
+ &AuraEffect::HandleNoImmediateEffect, //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT
+ &AuraEffect::HandleNoImmediateEffect, //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE implemented in Unit::MagicSpellHitResult
+ &AuraEffect::HandleNoImmediateEffect, //118 SPELL_AURA_MOD_HEALING_PCT implemented in Unit::SpellHealingBonus
+ &AuraEffect::HandleUnused, //119 unused (3.0.8a) old SPELL_AURA_SHARE_PET_TRACKING
+ &AuraEffect::HandleAuraUntrackable, //120 SPELL_AURA_UNTRACKABLE
+ &AuraEffect::HandleAuraEmpathy, //121 SPELL_AURA_EMPATHY
+ &AuraEffect::HandleModOffhandDamagePercent, //122 SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT
+ &AuraEffect::HandleModTargetResistance, //123 SPELL_AURA_MOD_TARGET_RESISTANCE
+ &AuraEffect::HandleAuraModRangedAttackPower, //124 SPELL_AURA_MOD_RANGED_ATTACK_POWER
+ &AuraEffect::HandleNoImmediateEffect, //125 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleNoImmediateEffect, //126 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleNoImmediateEffect, //127 SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleModPossessPet, //128 SPELL_AURA_MOD_POSSESS_PET
+ &AuraEffect::HandleAuraModIncreaseSpeed, //129 SPELL_AURA_MOD_SPEED_ALWAYS
+ &AuraEffect::HandleAuraModIncreaseMountedSpeed, //130 SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS
+ &AuraEffect::HandleNoImmediateEffect, //131 SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleAuraModIncreaseEnergyPercent, //132 SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT
+ &AuraEffect::HandleAuraModIncreaseHealthPercent, //133 SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT
+ &AuraEffect::HandleAuraModRegenInterrupt, //134 SPELL_AURA_MOD_MANA_REGEN_INTERRUPT
+ &AuraEffect::HandleModHealingDone, //135 SPELL_AURA_MOD_HEALING_DONE
+ &AuraEffect::HandleNoImmediateEffect, //136 SPELL_AURA_MOD_HEALING_DONE_PERCENT implemented in Unit::SpellHealingBonus
+ &AuraEffect::HandleModTotalPercentStat, //137 SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE
+ &AuraEffect::HandleHaste, //138 SPELL_AURA_MOD_HASTE
+ &AuraEffect::HandleForceReaction, //139 SPELL_AURA_FORCE_REACTION
+ &AuraEffect::HandleAuraModRangedHaste, //140 SPELL_AURA_MOD_RANGED_HASTE
+ &AuraEffect::HandleRangedAmmoHaste, //141 SPELL_AURA_MOD_RANGED_AMMO_HASTE
+ &AuraEffect::HandleAuraModBaseResistancePCT, //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT
+ &AuraEffect::HandleAuraModResistanceExclusive, //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE
+ &AuraEffect::HandleNoImmediateEffect, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
+ &AuraEffect::HandleAuraModPetTalentsPoints, //145 SPELL_AURA_MOD_PET_TALENT_POINTS
+ &AuraEffect::HandleNoImmediateEffect, //146 SPELL_AURA_ALLOW_TAME_PET_TYPE
+ &AuraEffect::HandleModStateImmunityMask, //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK
+ &AuraEffect::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS
+ &AuraEffect::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK
+ &AuraEffect::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
+ &AuraEffect::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
+ &AuraEffect::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
+ &AuraEffect::HandleNoImmediateEffect, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT
+ &AuraEffect::HandleNoImmediateEffect, //154 SPELL_AURA_MOD_STEALTH_LEVEL
+ &AuraEffect::HandleNoImmediateEffect, //155 SPELL_AURA_MOD_WATER_BREATHING
+ &AuraEffect::HandleNoImmediateEffect, //156 SPELL_AURA_MOD_REPUTATION_GAIN
+ &AuraEffect::HandleNULL, //157 SPELL_AURA_PET_DAMAGE_MULTI
+ &AuraEffect::HandleShieldBlockValue, //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE
+ &AuraEffect::HandleNoImmediateEffect, //159 SPELL_AURA_NO_PVP_CREDIT only for Honorless Target spell
+ &AuraEffect::HandleNoImmediateEffect, //160 SPELL_AURA_MOD_AOE_AVOIDANCE implemented in Unit::MagicSpellHitResult
+ &AuraEffect::HandleNoImmediateEffect, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT
+ &AuraEffect::HandleAuraPowerBurn, //162 SPELL_AURA_POWER_BURN_MANA
+ &AuraEffect::HandleNoImmediateEffect, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE
+ &AuraEffect::HandleUnused, //164 unused (3.0.8a), only one test spell
+ &AuraEffect::HandleNoImmediateEffect, //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleAuraModAttackPowerPercent, //166 SPELL_AURA_MOD_ATTACK_POWER_PCT
+ &AuraEffect::HandleAuraModRangedAttackPowerPercent, //167 SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT
+ &AuraEffect::HandleNoImmediateEffect, //168 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus
+ &AuraEffect::HandleNoImmediateEffect, //169 SPELL_AURA_MOD_CRIT_PERCENT_VERSUS implemented in Unit::DealDamageBySchool, Unit::DoAttackDamage, Unit::SpellCriticalBonus
+ &AuraEffect::HandleNULL, //170 SPELL_AURA_DETECT_AMORE different spells that ignore transformation effects
+ &AuraEffect::HandleAuraModIncreaseSpeed, //171 SPELL_AURA_MOD_SPEED_NOT_STACK
+ &AuraEffect::HandleAuraModIncreaseMountedSpeed, //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK
+ &AuraEffect::HandleUnused, //173 unused (3.0.8a) no spells, old SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell
+ &AuraEffect::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus
+ &AuraEffect::HandleModSpellHealingPercentFromStat, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus
+ &AuraEffect::HandleSpiritOfRedemption, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end
+ &AuraEffect::HandleNULL, //177 SPELL_AURA_AOE_CHARM
+ &AuraEffect::HandleNoImmediateEffect, //178 SPELL_AURA_MOD_DEBUFF_RESISTANCE implemented in Unit::MagicSpellHitResult
+ &AuraEffect::HandleNoImmediateEffect, //179 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE implemented in Unit::SpellCriticalBonus
+ &AuraEffect::HandleNoImmediateEffect, //180 SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS implemented in Unit::SpellDamageBonus
+ &AuraEffect::HandleUnused, //181 unused (3.0.8a) old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS
+ &AuraEffect::HandleAuraModResistenceOfStatPercent, //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT
+ &AuraEffect::HandleNULL, //183 SPELL_AURA_MOD_CRITICAL_THREAT only used in 28746
+ &AuraEffect::HandleNoImmediateEffect, //184 SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
+ &AuraEffect::HandleNoImmediateEffect, //185 SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
+ &AuraEffect::HandleNoImmediateEffect, //186 SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE implemented in Unit::MagicSpellHitResult
+ &AuraEffect::HandleNoImmediateEffect, //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
+ &AuraEffect::HandleNoImmediateEffect, //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
+ &AuraEffect::HandleModRating, //189 SPELL_AURA_MOD_RATING
+ &AuraEffect::HandleNULL, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN
+ &AuraEffect::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
+ &AuraEffect::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE
+ &AuraEffect::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct)
+ &AuraEffect::HandleNULL, //194 SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist
+ &AuraEffect::HandleNoImmediateEffect, //195 SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist
+ &AuraEffect::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN
+ &AuraEffect::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance
+ &AuraEffect::HandleUnused, //198 unused (3.0.8a) old SPELL_AURA_MOD_ALL_WEAPON_SKILLS
+ &AuraEffect::HandleNoImmediateEffect, //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT implemented in Unit::MagicSpellHitResult
+ &AuraEffect::HandleNoImmediateEffect, //200 SPELL_AURA_MOD_XP_PCT implemented in Player::GiveXP
+ &AuraEffect::HandleAuraAllowFlight, //201 SPELL_AURA_FLY this aura enable flight mode...
+ &AuraEffect::HandleNoImmediateEffect, //202 SPELL_AURA_CANNOT_BE_DODGED implemented in Unit::RollPhysicalOutcomeAgainst
+ &AuraEffect::HandleNoImmediateEffect, //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
+ &AuraEffect::HandleNoImmediateEffect, //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
+ &AuraEffect::HandleNULL, //205 vulnerable to school dmg?
+ &AuraEffect::HandleNULL, //206 SPELL_AURA_MOD_SPEED_MOUNTED
+ &AuraEffect::HandleAuraModIncreaseFlightSpeed, //207 SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED
+ &AuraEffect::HandleAuraModIncreaseFlightSpeed, //208 SPELL_AURA_MOD_SPEED_FLIGHT, used only in spell: Flight Form (Passive)
+ &AuraEffect::HandleAuraModIncreaseFlightSpeed, //209 SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS
+ &AuraEffect::HandleNULL, //210 Commentator's Command
+ &AuraEffect::HandleAuraModIncreaseFlightSpeed, //211 SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK
+ &AuraEffect::HandleAuraModRangedAttackPowerOfStatPercent, //212 SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT
+ &AuraEffect::HandleNoImmediateEffect, //213 SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT implemented in Player::RewardRage
+ &AuraEffect::HandleNULL, //214 Tamed Pet Passive
+ &AuraEffect::HandleArenaPreparation, //215 SPELL_AURA_ARENA_PREPARATION
+ &AuraEffect::HandleModCastingSpeed, //216 SPELL_AURA_HASTE_SPELLS
+ &AuraEffect::HandleUnused, //217 unused (3.0.8a)
+ &AuraEffect::HandleAuraModRangedHaste, //218 SPELL_AURA_HASTE_RANGED
+ &AuraEffect::HandleModManaRegen, //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT
+ &AuraEffect::HandleModRatingFromStat, //220 SPELL_AURA_MOD_RATING_FROM_STAT
+ &AuraEffect::HandleNULL, //221 ignored
+ &AuraEffect::HandleUnused, //222 unused (3.0.8a) only for spell 44586 that not used in real spell cast
+ &AuraEffect::HandleNoImmediateEffect, //223 SPELL_AURA_RAID_PROC_FROM_CHARGE
+ &AuraEffect::HandleUnused, //224 unused (3.0.8a)
+ &AuraEffect::HandleNoImmediateEffect, //225 SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE
+ &AuraEffect::HandleAuraPeriodicDummy, //226 SPELL_AURA_PERIODIC_DUMMY
+ &AuraEffect::HandlePeriodicTriggerSpellWithValue, //227 SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
+ &AuraEffect::HandleNoImmediateEffect, //228 stealth detection
+ &AuraEffect::HandleNULL, //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE
+ &AuraEffect::HandleAuraModIncreaseHealth, //230 SPELL_AURA_MOD_INCREASE_HEALTH_2
+ &AuraEffect::HandleNoImmediateEffect, //231 SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE
+ &AuraEffect::HandleNoImmediateEffect, //232 SPELL_AURA_MECHANIC_DURATION_MOD implement in Unit::CalculateSpellDuration
+ &AuraEffect::HandleNULL, //233 set model id to the one of the creature with id GetMiscValue()
+ &AuraEffect::HandleNoImmediateEffect, //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration
+ &AuraEffect::HandleAuraModDispelResist, //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult
+ &AuraEffect::HandleAuraControlVehicle, //236 SPELL_AURA_CONTROL_VEHICLE
+ &AuraEffect::HandleModSpellDamagePercentFromAttackPower, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonus
+ &AuraEffect::HandleModSpellHealingPercentFromAttackPower, //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus
+ &AuraEffect::HandleAuraModScale, //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61
+ &AuraEffect::HandleAuraModExpertise, //240 SPELL_AURA_MOD_EXPERTISE
+ &AuraEffect::HandleForceMoveForward, //241 Forces the player to move forward
+ &AuraEffect::HandleUnused, //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING
+ &AuraEffect::HandleNULL, //243 faction reaction override spells
+ &AuraEffect::HandleComprehendLanguage, //244 Comprehend language
+ &AuraEffect::HandleNoImmediateEffect, //245 SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL
+ &AuraEffect::HandleNoImmediateEffect, //246 SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK implemented in Spell::EffectApplyAura
+ &AuraEffect::HandleNULL, //247 target to become a clone of the caster
+ &AuraEffect::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
+ &AuraEffect::HandleAuraConvertRune, //249 SPELL_AURA_CONVERT_RUNE
+ &AuraEffect::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2
+ &AuraEffect::HandleNoImmediateEffect, //251 SPELL_AURA_MOD_ENEMY_DODGE
+ &AuraEffect::HandleNULL, //252 haste all?
+ &AuraEffect::HandleNoImmediateEffect, //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE implemented in Unit::isBlockCritical
+ &AuraEffect::HandleAuraModDisarm, //254 SPELL_AURA_MOD_DISARM_OFFHAND
+ &AuraEffect::HandleNoImmediateEffect, //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT implemented in Unit::SpellDamageBonus
+ &AuraEffect::HandleNoReagentUseAura, //256 SPELL_AURA_NO_REAGENT_USE Use SpellClassMask for spell select
+ &AuraEffect::HandleNULL, //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS Use SpellClassMask for spell select
+ &AuraEffect::HandleNULL, //258 SPELL_AURA_MOD_SPELL_VISUAL
+ &AuraEffect::HandleNoImmediateEffect, //259 SPELL_AURA_MOD_HOT_PCT implemented in Unit::SpellHealingBonus
+ &AuraEffect::HandleNoImmediateEffect, //260 SPELL_AURA_SCREEN_EFFECT (miscvalue = id in ScreenEffect.dbc) not required any code
+ &AuraEffect::HandlePhase, //261 SPELL_AURA_PHASE undetactable invisibility? implemented in Unit::isVisibleForOrDetect
+ &AuraEffect::HandleNoImmediateEffect, //262 SPELL_AURA_ABILITY_IGNORE_AURASTATE implemented in spell::cancast
+ &AuraEffect::HandleAuraAllowOnlyAbility, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilities set in SpellClassMask
+ &AuraEffect::HandleUnused, //264 unused (3.0.8a)
+ &AuraEffect::HandleUnused, //265 unused (3.0.8a)
+ &AuraEffect::HandleUnused, //266 unused (3.0.8a)
+ &AuraEffect::HandleNoImmediateEffect, //267 SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL implemented in Unit::IsImmunedToSpellEffect
+ &AuraEffect::HandleAuraModAttackPowerOfStatPercent, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT
+ &AuraEffect::HandleNoImmediateEffect, //269 SPELL_AURA_MOD_IGNORE_TARGET_RESIST implemented in Unit::CalcAbsorbResist and CalcArmorReducedDamage
+ &AuraEffect::HandleNoImmediateEffect, //270 SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST implemented in Unit::CalcAbsorbResist and CalcArmorReducedDamage
+ &AuraEffect::HandleNoImmediateEffect, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonus
+ &AuraEffect::HandleNULL, //272 reduce spell cast time?
+ &AuraEffect::HandleUnused, //273 clientside
+ &AuraEffect::HandleNoImmediateEffect, //274 SPELL_AURA_CONSUME_NO_AMMO implemented in spell::CalculateDamageDoneForAllTargets
+ &AuraEffect::HandleNoImmediateEffect, //275 SPELL_AURA_MOD_IGNORE_SHAPESHIFT Use SpellClassMask for spell select
+ &AuraEffect::HandleNULL, //276 mod damage % mechanic?
+ &AuraEffect::HandleNoImmediateEffect, //277 SPELL_AURA_MOD_ABILITY_AFFECTED_TARGETS implemented in spell::settargetmap
+ &AuraEffect::HandleAuraModDisarm, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon
+ &AuraEffect::HandleNULL, //279 visual effects? 58836 and 57507
+ &AuraEffect::HandleNoImmediateEffect, //280 SPELL_AURA_MOD_WEAPONTYPE_IGNORE_TARGET_RESISTANCE
+ &AuraEffect::HandleNoImmediateEffect, //281 SPELL_AURA_MOD_HONOR_GAIN_PCT implemented in Player::RewardHonor
+ &AuraEffect::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT
+ &AuraEffect::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus
+ &AuraEffect::HandleUnused, //284 not used by any spells (3.08a)
+ &AuraEffect::HandleUnused, //285 not used by any spells (3.08a)
+ &AuraEffect::HandleUnused, //286 not used by any spells (3.08a)
+ &AuraEffect::HandleNoImmediateEffect, //287 SPELL_AURA_DEFLECT_SPELLS implemented in Unit::MagicSpellHitResult and Unit::MeleeSpellHitResult
+ &AuraEffect::HandleUnused, //288 not used by any spells (3.09) except 1 test spell.
};
-Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) :
-m_procCharges(0), m_stackAmount(1), m_spellmod(NULL), m_effIndex(eff), m_caster_guid(0), m_target(target),
-m_timeCla(1000), m_castItemGuid(castItem?castItem->GetGUID():0), m_auraSlot(MAX_AURAS),
-m_positive(false), m_permanent(false), m_isPeriodic(false), m_isTrigger(false), m_isAreaAura(false),
-m_isPersistent(false), m_updated(false), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_isRemovedOnShapeLost(true), m_in_use(false),
-m_periodicTimer(0), m_PeriodicEventId(0), m_AuraDRGroup(DIMINISHING_NONE)
-,m_tickNumber(0)
+Aura::Aura(SpellEntry const* spellproto, uint32 effMask, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem, Unit * formalCaster) :
+m_caster_guid(0), m_castItemGuid(castItem?castItem->GetGUID():0), m_target(target),
+m_timeCla(1000), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE),
+m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),m_auraStateMask(0), m_updated(false), m_isRemoved(false)
{
assert(target);
assert(spellproto && spellproto == sSpellStore.LookupEntry( spellproto->Id ) && "`info` must be pointer to sSpellStore element");
- m_spellProto = spellproto;
+ m_auraFlags = effMask;
- int32 damage;
- if(currentBasePoints)
- {
- damage = *currentBasePoints;
- m_currentBasePoints = damage - 1;
- }
- else
- {
- m_currentBasePoints = m_spellProto->EffectBasePoints[eff];
- if(caster)
- damage = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, target);
- else
- damage = m_currentBasePoints + 1;
- }
+ m_spellProto = spellproto;
m_isPassive = IsPassiveSpell(GetId());
- m_positive = IsPositiveEffect(GetId(), m_effIndex);
+
+ m_auraStateMask = 0;
+
+ m_isSingleTargetAura = IsSingleTargetSpell(m_spellProto);
m_applyTime = time(NULL);
@@ -356,112 +367,193 @@ m_periodicTimer(0), m_PeriodicEventId(0), m_AuraDRGroup(DIMINISHING_NONE)
{
m_caster_guid = target->GetGUID();
//damage = m_currentBasePoints+1; // stored value-1
- m_maxduration = target->CalculateSpellDuration(m_spellProto, m_effIndex, target);
+ m_maxduration = target->CalcSpellDuration(m_spellProto);
}
else
{
m_caster_guid = caster->GetGUID();
//damage = caster->CalculateSpellDamage(m_spellProto,m_effIndex,m_currentBasePoints,target);
- m_maxduration = caster->CalculateSpellDuration(m_spellProto, m_effIndex, target);
-
- if (!damage && castItem && castItem->GetItemSuffixFactor())
- {
- ItemRandomSuffixEntry const *item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(castItem->GetItemRandomPropertyId()));
- if(item_rand_suffix)
- {
- for (int k=0; k<3; k++)
- {
- SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(item_rand_suffix->enchant_id[k]);
- if(pEnchant)
- {
- for (int t=0; t<3; t++)
- if(pEnchant->spellid[t] == m_spellProto->Id)
- {
- damage = uint32((item_rand_suffix->prefix[k]*castItem->GetItemSuffixFactor()) / 10000 );
- break;
- }
- }
-
- if(damage)
- break;
- }
- }
- }
+ m_maxduration = caster->CalcSpellDuration(m_spellProto);
}
if(m_maxduration == -1 || m_isPassive && m_spellProto->DurationIndex == 0)
m_permanent = true;
+ else
+ m_permanent = false;
Player* modOwner = caster ? caster->GetSpellModOwner() : NULL;
if(!m_permanent && modOwner)
+ {
modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, m_maxduration);
+ // Get zero duration aura after - need set m_maxduration > 0 for apply/remove aura work
+ if (m_maxduration<=0)
+ m_maxduration = 1;
+ }
m_duration = m_maxduration;
- if(modOwner)
- modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_periodicTimer);
-
- sLog.outDebug("Aura: construct Spellid : %u, Aura : %u Duration : %d Target : %d Damage : %d", m_spellProto->Id, m_spellProto->EffectApplyAuraName[eff], m_maxduration, m_spellProto->EffectImplicitTargetA[eff],damage);
+ m_isDeathPersist = IsDeathPersistentSpell(m_spellProto);
- m_effIndex = eff;
- SetModifier(AuraType(m_spellProto->EffectApplyAuraName[eff]), damage, m_spellProto->EffectAmplitude[eff], m_spellProto->EffectMiscValue[eff]);
+ m_procCharges = m_spellProto->procCharges;
+ if(modOwner)
+ modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges);
- m_isDeathPersist = IsDeathPersistentSpell(m_spellProto);
+ m_isRemovedOnShapeLost = (m_caster_guid==m_target->GetGUID() &&
+ m_spellProto->Stances &&
+ !(m_spellProto->AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) &&
+ !(m_spellProto->Attributes & SPELL_ATTR_NOT_SHAPESHIFT));
- if(m_spellProto->procCharges)
+ for (uint8 i=0 ;i<MAX_SPELL_EFFECTS;++i)
{
- m_procCharges = m_spellProto->procCharges;
-
- if(modOwner)
- modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges);
+ if (m_auraFlags & (uint8(1) << i))
+ {
+ if (&currentBasePoints[0])
+ m_partAuras[i]=CreateAuraEffect(this, i,&currentBasePoints[0]+i, caster, NULL, formalCaster);
+ else
+ m_partAuras[i]=CreateAuraEffect(this, i, NULL , caster, NULL, formalCaster);
+ // correct flags if aura couldn't be created
+ if (!m_partAuras[i])
+ m_auraFlags &= uint8(~(1<< i));
+ }
+ else
+ {
+ m_partAuras[i]=NULL;
+ }
}
- else
- m_procCharges = -1;
- m_isRemovedOnShapeLost = (m_caster_guid==m_target->GetGUID() && m_spellProto->Stances &&
- !(m_spellProto->AttributesEx2 & 0x80000) && !(m_spellProto->Attributes & 0x10000));
+ // Aura is positive when it is casted by friend and at least one aura is positive
+ // or when it is casted by enemy and at least one aura is negative
+ bool swap=false;
+ if (!caster || caster==target) // caster == target - 1 negative effect is enough for aura to be negative
+ m_positive = false;
+ else
+ m_positive = !caster->IsHostileTo(m_target);
+ for (uint8 i=0;i<MAX_SPELL_EFFECTS;++i)
+ {
+ if (!(1<<i & GetEffectMask()))
+ continue;
+ if (m_positive == IsPositiveEffect(GetId(), i))
+ {
+ swap = true;
+ break;
+ }
+ }
+ if (!swap)
+ m_positive=!m_positive;
}
Aura::~Aura()
{
+ // free part auras memory
+ for (uint8 i=0 ; i<MAX_SPELL_EFFECTS;++i)
+ if (m_partAuras[i])
+ delete m_partAuras[i];
+}
+
+AuraEffect::AuraEffect(Aura * parentAura, uint8 effIndex, int32 * currentBasePoints , Unit * caster, Item* castItem) :
+m_parentAura(parentAura), m_spellmod(NULL), m_periodicTimer(0), m_isPeriodic(false), m_isAreaAura(false), m_isPersistent(false),
+m_target(parentAura->GetTarget()), m_tickNumber(0)
+{
+ m_spellProto = parentAura->GetSpellProto();
+ m_effIndex = effIndex;
+ m_auraName = AuraType(m_spellProto->EffectApplyAuraName[m_effIndex]);
+
+ if(currentBasePoints)
+ m_currentBasePoints = *currentBasePoints;
+ else
+ m_currentBasePoints = m_spellProto->EffectBasePoints[m_effIndex];
+
+ if(caster)
+ m_amount = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, m_target);
+ else
+ m_amount = m_currentBasePoints + 1;
+
+ if (!m_amount && castItem && castItem->GetItemSuffixFactor())
+ {
+ ItemRandomSuffixEntry const *item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(castItem->GetItemRandomPropertyId()));
+ if(item_rand_suffix)
+ {
+ for (int k=0; k<3; k++)
+ {
+ SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(item_rand_suffix->enchant_id[k]);
+ if(pEnchant)
+ {
+ for (int t=0; t<3; t++)
+ if(pEnchant->spellid[t] == m_spellProto->Id)
+ {
+ m_amount = uint32((item_rand_suffix->prefix[k]*castItem->GetItemSuffixFactor()) / 10000 );
+ break;
+ }
+ }
+
+ if(m_amount)
+ break;
+ }
+ }
+ }
+
+ Player* modOwner = caster ? caster->GetSpellModOwner() : NULL;
+ m_amplitude = m_spellProto->EffectAmplitude[m_effIndex];
+
+ //apply casting time mods for channeled spells
+ if (modOwner && m_amplitude && IsChanneledSpell(m_spellProto))
+ modOwner->ModSpellCastTime(m_spellProto, m_amplitude);
+
+ // Apply periodic time mod
+ if(modOwner && m_amplitude)
+ modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_amplitude);
+
+ // Start periodic on next tick or at aura apply
+ if (!(m_spellProto->AttributesEx5 & SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY))
+ m_periodicTimer += m_amplitude;
}
-AreaAura::AreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target,
-Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem)
+AreaAuraEffect::AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * currentBasePoints, Unit * caster, Item * castItem, Unit * formalCaster)
+: AuraEffect(parentAura, effIndex, currentBasePoints, caster, castItem)
{
+ m_removeTime = FRIENDLY_AA_REMOVE_TIME;
m_isAreaAura = true;
- // caster==NULL in constructor args if target==caster in fact
- Unit* caster_ptr = caster ? caster : target;
+ Unit* caster_ptr = formalCaster ? formalCaster : caster ? caster : m_target;
+ m_formalCasterGUID = caster_ptr->GetGUID();
+
+ if (m_spellProto->Effect[effIndex] == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY)
+ m_radius = GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex]));
+ else
+ m_radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex]));
- m_radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex]));
if(Player* modOwner = caster_ptr->GetSpellModOwner())
modOwner->ApplySpellMod(GetId(), SPELLMOD_RADIUS, m_radius);
- switch(spellproto->Effect[eff])
+ switch(m_spellProto->Effect[effIndex])
{
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
m_areaAuraType = AREA_AURA_PARTY;
- if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem())
- m_modifier.m_auraname = SPELL_AURA_NONE;
+ if(m_target->GetTypeId() == TYPEID_UNIT && ((Creature*)m_target)->isTotem())
+ m_auraName = SPELL_AURA_NONE;
+ break;
+ case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
+ m_areaAuraType = AREA_AURA_RAID;
+ if(m_target->GetTypeId() == TYPEID_UNIT && ((Creature*)m_target)->isTotem())
+ m_auraName = SPELL_AURA_NONE;
break;
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
m_areaAuraType = AREA_AURA_FRIEND;
break;
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
m_areaAuraType = AREA_AURA_ENEMY;
- if(target == caster_ptr)
- m_modifier.m_auraname = SPELL_AURA_NONE; // Do not do any effect on self
+ if(m_target == caster_ptr)
+ m_auraName = SPELL_AURA_NONE; // Do not do any effect on self
break;
case SPELL_EFFECT_APPLY_AREA_AURA_PET:
m_areaAuraType = AREA_AURA_PET;
break;
case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
m_areaAuraType = AREA_AURA_OWNER;
- if(target == caster_ptr)
- m_modifier.m_auraname = SPELL_AURA_NONE;
+ if(m_target == caster_ptr)
+ m_auraName = SPELL_AURA_NONE;
break;
default:
sLog.outError("Wrong spell effect in AreaAura constructor");
@@ -470,26 +562,30 @@ Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target,
}
}
-AreaAura::~AreaAura()
+AreaAuraEffect::~AreaAuraEffect()
{
}
-PersistentAreaAura::PersistentAreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target,
-Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem)
+PersistentAreaAuraEffect::PersistentAreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * currentBasePoints, Unit * caster,Item * castItem)
+: AuraEffect(parentAura, effIndex, currentBasePoints, caster, castItem)
{
m_isPersistent = true;
}
-PersistentAreaAura::~PersistentAreaAura()
+PersistentAreaAuraEffect::~PersistentAreaAuraEffect()
{
}
-Aura* CreateAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem)
+AuraEffect* CreateAuraEffect(Aura * parentAura, uint32 effIndex, int32 *currentBasePoints, Unit * caster, Item * castItem, Unit* formalCaster)
{
- if (IsAreaAuraEffect(spellproto->Effect[eff]))
- return new AreaAura(spellproto, eff, currentBasePoints, target, caster, castItem);
-
- return new Aura(spellproto, eff, currentBasePoints, target, caster, castItem);
+ assert (parentAura);
+ if (IsAreaAuraEffect(parentAura->GetSpellProto()->Effect[effIndex]))
+ return new AreaAuraEffect(parentAura, effIndex, currentBasePoints, caster, castItem, formalCaster);
+ else if (parentAura->GetSpellProto()->Effect[effIndex] == SPELL_EFFECT_APPLY_AURA)
+ return new AuraEffect(parentAura, effIndex, currentBasePoints, caster, castItem);
+ else if (parentAura->GetSpellProto()->Effect[effIndex] == SPELL_EFFECT_PERSISTENT_AREA_AURA)
+ return new PersistentAreaAuraEffect(parentAura, effIndex, currentBasePoints, caster, castItem);
+ else return NULL;
}
Unit* Aura::GetCaster() const
@@ -503,12 +599,15 @@ Unit* Aura::GetCaster() const
return unit && unit->IsInWorld() ? unit : NULL;
}
-void Aura::SetModifier(AuraType t, int32 a, uint32 pt, int32 miscValue)
+Unit* AreaAuraEffect::GetFormalCaster() const
{
- m_modifier.m_auraname = t;
- m_modifier.m_amount = a;
- m_modifier.m_miscvalue = miscValue;
- m_modifier.periodictime = pt;
+ if(m_formalCasterGUID==m_target->GetGUID())
+ return m_target;
+
+ //return ObjectAccessor::GetUnit(*m_target,m_caster_guid);
+ //must return caster even if it's in another grid/map
+ Unit *unit = ObjectAccessor::GetObjectInWorld(m_formalCasterGUID, (Unit*)NULL);
+ return unit && unit->IsInWorld() ? unit : NULL;
}
void Aura::Update(uint32 diff)
@@ -518,97 +617,71 @@ void Aura::Update(uint32 diff)
m_duration -= diff;
if (m_duration < 0)
m_duration = 0;
- m_timeCla -= diff;
- // GetEffIndex()==0 prevent double/triple apply manaPerSecond/manaPerSecondPerLevel to same spell with many auras
// all spells with manaPerSecond/manaPerSecondPerLevel have aura in effect 0
- if(GetEffIndex()==0 && m_timeCla <= 0)
+ if(m_timeCla > 0)
+ m_timeCla -= diff;
+ if(m_timeCla <= 0)
{
if(Unit* caster = GetCaster())
{
- Powers powertype = Powers(m_spellProto->powerType);
- int32 manaPerSecond = m_spellProto->manaPerSecond + m_spellProto->manaPerSecondPerLevel * caster->getLevel();
- m_timeCla = 1000;
- if (manaPerSecond)
+ if(int32 manaPerSecond = m_spellProto->manaPerSecond + m_spellProto->manaPerSecondPerLevel * caster->getLevel())
{
- if(powertype==POWER_HEALTH)
- caster->ModifyHealth(-manaPerSecond);
+ m_timeCla = 1000;
+
+ Powers powertype = Powers(m_spellProto->powerType);
+ if(powertype == POWER_HEALTH)
+ {
+ if (caster->GetHealth() > manaPerSecond)
+ caster->ModifyHealth(-manaPerSecond);
+ else
+ {
+ m_target->RemoveAura(this);
+ return;
+ }
+ }
else
- caster->ModifyPower(powertype,-manaPerSecond);
+ {
+ if (caster->GetPower(powertype) >= manaPerSecond)
+ caster->ModifyPower(powertype, -manaPerSecond);
+ else
+ {
+ m_target->RemoveAura(this);
+ return;
+ }
+ }
}
}
}
}
- // Channeled aura required check distance from caster except in possessed cases
- if(IsChanneledSpell(m_spellProto) && m_caster_guid != m_target->GetGUID() && !m_target->isPossessed())
- {
- Unit* caster = GetCaster();
- if(!caster)
- {
- m_target->RemoveAura(GetId(),GetEffIndex());
- return;
- }
-
- // Get spell range
- float radius;
- SpellModOp mod;
- if (m_spellProto->EffectRadiusIndex[GetEffIndex()])
- {
- radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellProto->EffectRadiusIndex[GetEffIndex()]));
- mod = SPELLMOD_RADIUS;
- }
- else
- {
- radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellProto->rangeIndex));
- mod = SPELLMOD_RANGE;
- }
-
- if(Player* modOwner = caster->GetSpellModOwner())
- modOwner->ApplySpellMod(GetId(), mod, radius,NULL);
-
- if(!caster->IsWithinDistInMap(m_target,radius))
- {
- m_target->RemoveAura(GetId(),GetEffIndex());
- return;
- }
- }
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ if (m_partAuras[i])
+ m_partAuras[i]->Update(diff);
+}
- if(m_isPeriodic && (m_duration >= 0 || m_isPassive || m_permanent))
+void AuraEffect::Update(uint32 diff)
+{
+ if (m_isPeriodic && (GetParentAura()->GetAuraDuration() >=0 || GetParentAura()->IsPassive() || GetParentAura()->IsPermanent()))
{
m_periodicTimer -= diff;
- if(m_periodicTimer <= 0) // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
+ if(m_periodicTimer <= 0) // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
{
++m_tickNumber;
- if( m_modifier.m_auraname == SPELL_AURA_MOD_REGEN ||
- m_modifier.m_auraname == SPELL_AURA_MOD_POWER_REGEN ||
- // Cannibalize, eating items and other spells
- m_modifier.m_auraname == SPELL_AURA_OBS_MOD_HEALTH ||
- // Eating items and other spells
- m_modifier.m_auraname == SPELL_AURA_OBS_MOD_MANA )
- {
- ApplyModifier(true);
- return;
- }
// update before applying (aura can be removed in TriggerSpell or PeriodicTick calls)
- m_periodicTimer += m_modifier.periodictime;
+ m_periodicTimer += m_amplitude;
if(!m_target->hasUnitState(UNIT_STAT_ISOLATED))
- {
- if(m_isTrigger)
- TriggerSpell();
- else
- PeriodicTick();
- }
+ PeriodicTick();
}
}
}
-void AreaAura::Update(uint32 diff)
+void AreaAuraEffect::Update(uint32 diff)
{
// update for the caster of the aura
- if(m_caster_guid == m_target->GetGUID())
+ if(m_formalCasterGUID == m_target->GetGUID())
{
Unit* caster = m_target;
@@ -621,17 +694,20 @@ void AreaAura::Update(uint32 diff)
case AREA_AURA_PARTY:
caster->GetPartyMember(targets, m_radius);
break;
+ case AREA_AURA_RAID:
+ caster->GetRaidMember(targets, m_radius);
+ break;
case AREA_AURA_FRIEND:
{
Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(caster, caster, m_radius);
- Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(targets, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(caster, targets, u_check);
caster->VisitNearbyObject(m_radius, searcher);
break;
}
case AREA_AURA_ENEMY:
{
Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(caster, caster, m_radius); // No GetCharmer in searcher
- Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(targets, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(caster, targets, u_check);
caster->VisitNearbyObject(m_radius, searcher);
break;
}
@@ -646,7 +722,25 @@ void AreaAura::Update(uint32 diff)
for(std::list<Unit *>::iterator tIter = targets.begin(); tIter != targets.end(); tIter++)
{
- if((*tIter)->HasAura(GetId(), m_effIndex))
+ bool skip=false;
+ for(Unit::AuraMap::iterator iter = (*tIter)->GetAuras().begin(); iter != (*tIter)->GetAuras().end();++iter)
+ {
+ bool samecaster = iter->second->GetCasterGUID() == GetCasterGUID();
+ if (samecaster && iter->first == GetId())
+ {
+ if (AuraEffect * aurEff = iter->second->GetPartAura(m_effIndex))
+ {
+ skip=true;
+ }
+ break;
+ }
+ if (spellmgr.IsNoStackSpellDueToSpell(GetId(), iter->first,samecaster))
+ {
+ skip=true;
+ break;
+ }
+ }
+ if(skip)
continue;
if(SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel()))
@@ -655,136 +749,167 @@ void AreaAura::Update(uint32 diff)
// recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?)
//if(actualSpellInfo != GetSpellProto())
// actualBasePoints = actualSpellInfo->EffectBasePoints[m_effIndex];
- AreaAura *aur;
- if(actualSpellInfo == GetSpellProto())
- aur = new AreaAura(actualSpellInfo, m_effIndex, &m_modifier.m_amount, (*tIter), caster, NULL);
- else
- aur = new AreaAura(actualSpellInfo, m_effIndex, NULL, (*tIter), caster, NULL);
- (*tIter)->AddAura(aur);
+ Aura * aur = (*tIter)->AddAuraEffect(actualSpellInfo->Id, GetEffIndex(), caster);
if(m_areaAuraType == AREA_AURA_ENEMY)
caster->CombatStart(*tIter);
}
}
}
- Aura::Update(diff);
+ AuraEffect::Update(diff);
}
else // aura at non-caster
{
- Unit * tmp_target = m_target;
- Unit* caster = GetCaster();
- uint32 tmp_spellId = GetId(), tmp_effIndex = m_effIndex;
-
// WARNING: the aura may get deleted during the update
// DO NOT access its members after update!
- Aura::Update(diff);
+ AuraEffect::Update(diff);
+
+ // Speedup - no need to do more checks
+ if (GetParentAura()->IsRemoved())
+ return;
+
+ // Caster may be deleted due to update
+ Unit* caster = GetFormalCaster();
// remove aura if out-of-range from caster (after teleport for example)
// or caster is isolated or caster no longer has the aura
// or caster is (no longer) friendly
bool needFriendly = (m_areaAuraType == AREA_AURA_ENEMY ? false : true);
if( !caster || caster->hasUnitState(UNIT_STAT_ISOLATED) ||
- !caster->IsWithinDistInMap(tmp_target, m_radius) ||
- !caster->HasAura(tmp_spellId, tmp_effIndex) ||
- caster->IsFriendlyTo(tmp_target) != needFriendly
+ !caster->HasAuraEffect(GetId(), m_effIndex) ||
+ caster->IsFriendlyTo(m_target) != needFriendly
)
{
- tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
+ m_target->RemoveAura(GetParentAura());
}
- else if( m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group
+ else if (!caster->IsWithinDistInMap(m_target, m_radius))
{
- if(!tmp_target->IsInPartyWith(caster))
- tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
+ if (needFriendly)
+ {
+ m_removeTime -= diff;
+ if (m_removeTime < 0)
+ m_target->RemoveAura(GetParentAura());
+ }
+ else
+ m_target->RemoveAura(GetParentAura());
}
- else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )
+ else
{
- if( tmp_target->GetGUID() != caster->GetCharmerOrOwnerGUID() )
- tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
+ // Reset aura remove timer
+ m_removeTime = FRIENDLY_AA_REMOVE_TIME;
+ if( m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group
+ {
+ if(!m_target->IsInPartyWith(caster))
+ m_target->RemoveAura(GetParentAura());
+ }
+ else if( m_areaAuraType == AREA_AURA_RAID)
+ {
+ if(!m_target->IsInRaidWith(caster))
+ m_target->RemoveAura(GetParentAura());
+ }
+ else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )
+ {
+ if( m_target->GetGUID() != caster->GetCharmerOrOwnerGUID() )
+ m_target->RemoveAura(GetParentAura());
+ }
}
}
}
-void PersistentAreaAura::Update(uint32 diff)
+void PersistentAreaAuraEffect::Update(uint32 diff)
{
- bool remove = false;
-
- // remove the aura if its caster or the dynamic object causing it was removed
- // or if the target moves too far from the dynamic object
- Unit *caster = GetCaster();
- if (caster)
+ if(Unit *caster = GetParentAura()->GetCaster())
{
- DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex());
- if (dynObj)
+ if(DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex()))
{
- if (!m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius()))
- remove = true;
+ if(m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius()))
+ {
+ AuraEffect::Update(diff);
+ return;
+ }
}
- else
- remove = true;
}
- else
- remove = true;
-
- Unit *tmp_target = m_target;
- uint32 tmp_id = GetId(), tmp_index = GetEffIndex();
- // WARNING: the aura may get deleted during the update
- // DO NOT access its members after update!
- Aura::Update(diff);
-
- if(remove)
- tmp_target->RemoveAura(tmp_id, tmp_index);
+ // remove the aura if its caster or the dynamic object causing it was removed
+ // or if the target moves too far from the dynamic object
+ m_target->RemoveAura(GetParentAura());
}
-void Aura::ApplyModifier(bool apply, bool Real)
+void AuraEffect::ApplyModifier(bool apply, bool Real)
{
- AuraType aura = m_modifier.m_auraname;
+ if (GetParentAura()->IsRemoved())
+ return;
- m_in_use = true;
- if(aura<TOTAL_AURAS)
- (*this.*AuraHandler [aura])(apply,Real);
- m_in_use = false;
+ if(m_auraName<TOTAL_AURAS)
+ (*this.*AuraHandler [m_auraName])(apply,Real);
}
-void Aura::UpdateAuraDuration()
+void AuraEffect::CleanupTriggeredSpells()
{
- if(m_auraSlot >= MAX_AURAS || m_isPassive)
+ uint32 tSpellId = m_spellProto->EffectTriggerSpell[GetEffIndex()];
+ if(!tSpellId)
return;
- if( m_target->GetTypeId() == TYPEID_PLAYER)
- {
- WorldPacket data(SMSG_UPDATE_AURA_DURATION, 5);
- data << (uint8)m_auraSlot << (uint32)m_duration;
- ((Player*)m_target)->SendDirectMessage(&data);
+ SpellEntry const* tProto = sSpellStore.LookupEntry(tSpellId);
+ if(!tProto)
+ return;
- data.Initialize(SMSG_SET_EXTRA_AURA_INFO, (8+1+4+4+4));
- data.append(m_target->GetPackGUID());
- data << uint8(m_auraSlot);
- data << uint32(GetId());
- data << uint32(GetAuraMaxDuration());
- data << uint32(GetAuraDuration());
- ((Player*)m_target)->SendDirectMessage(&data);
- }
+ if(GetSpellDuration(tProto) != -1)
+ return;
- // not send in case player loading (will not work anyway until player not added to map), sent in visibility change code
- if(m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading())
+ // needed for spell 43680, maybe others
+ // TODO: is there a spell flag, which can solve this in a more sophisticated way?
+ if(m_spellProto->EffectApplyAuraName[GetEffIndex()] == SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
+ GetSpellDuration(m_spellProto) == m_spellProto->EffectAmplitude[GetEffIndex()])
return;
- Unit* caster = GetCaster();
+ m_target->RemoveAurasDueToSpell(tSpellId, GetCasterGUID());
+}
- if(caster && caster->GetTypeId() == TYPEID_PLAYER && caster != m_target)
- SendAuraDurationForCaster((Player*)caster);
+void Aura::ApplyAllModifiers(bool apply, bool Real)
+{
+ for (uint8 i = 0; i<MAX_SPELL_EFFECTS;++i)
+ if (m_partAuras[i])
+ m_partAuras[i]->ApplyModifier(apply, Real);
}
-void Aura::SendAuraDurationForCaster(Player* caster)
+void Aura::SendAuraUpdate()
{
- WorldPacket data(SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE, (8+1+4+4+4));
+ if (m_auraSlot>=MAX_AURAS)
+ return;
+ WorldPacket data(SMSG_AURA_UPDATE);
+
data.append(m_target->GetPackGUID());
data << uint8(m_auraSlot);
+
+ if(!m_target->GetVisibleAura(m_auraSlot))
+ {
+ data << uint32(0);
+ sLog.outDebug("Aura %u removed slot %u",GetId(), m_auraSlot);
+ m_target->SendMessageToSet(&data, true);
+ return;
+ }
+
data << uint32(GetId());
- data << uint32(GetAuraMaxDuration()); // full
- data << uint32(GetAuraDuration()); // remain
- caster->GetSession()->SendPacket(&data);
+ data << uint8(m_auraFlags);
+ data << uint8(m_auraLevel);
+ data << uint8(m_stackAmount>1 ? m_stackAmount : m_procCharges);
+
+ if(!(m_auraFlags & AFLAG_CASTER))
+ {
+ if (Unit * caster = GetCaster())
+ data.append(caster->GetPackGUID());
+ else
+ data << uint8(0);
+ }
+
+ if(m_auraFlags & AFLAG_DURATION)
+ {
+ data << uint32(m_maxduration);
+ data << uint32(m_duration);
+ }
+
+ m_target->SendMessageToSet(&data, true);
}
void Aura::_AddAura()
@@ -794,139 +919,158 @@ void Aura::_AddAura()
if(!m_target)
return;
- // we can found aura in NULL_AURA_SLOT and then need store state instead check slot != NULL_AURA_SLOT
- bool secondaura = false;
- uint8 slot = NULL_AURA_SLOT;
+ Unit* caster = GetCaster();
- for(uint8 i = 0; i < 3; i++)
+ // set infinity cooldown state for spells
+ if(caster && caster->GetTypeId() == TYPEID_PLAYER)
{
- Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i);
- for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
+ if (m_spellProto->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE)
+ {
+ Item* castItem = m_castItemGuid ? ((Player*)caster)->GetItemByGuid(m_castItemGuid) : NULL;
+ ((Player*)caster)->AddSpellAndCategoryCooldowns(m_spellProto,castItem ? castItem->GetEntry() : 0, NULL,true);
+ }
+ }
+
+ // passive auras (except totem auras) do not get placed in the slots
+ // area auras with SPELL_AURA_NONE are not shown on target
+ if((m_spellProto->Attributes & 0x80 && GetTalentSpellPos(GetId()))
+ || !m_isPassive
+ || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())
+ || (IsAuraType(SPELL_AURA_ABILITY_IGNORE_AURASTATE))
+ && (!IsAreaAura()
+ || m_target!=caster ||
+ (m_spellProto->Effect[0]!=SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
+ && m_spellProto->Effect[1]!=SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
+ && m_spellProto->Effect[2]!=SPELL_EFFECT_APPLY_AREA_AURA_ENEMY)))
+ {
+ // Try find slot for aura
+ uint8 slot = MAX_AURAS;
+ // Lookup for auras already applied from spell
+ if (Aura * foundAura = m_target->GetAura(GetId(), GetCasterGUID()))
{
// allow use single slot only by auras from same caster
- if(itr->second->GetCasterGUID()==GetCasterGUID())
+ slot = foundAura->GetAuraSlot();
+ }
+ else
+ {
+ Unit::VisibleAuraMap const * visibleAuras= m_target->GetVisibleAuras();
+ // lookup for free slots in units visibleAuras
+ Unit::VisibleAuraMap::const_iterator itr = visibleAuras->find(0);
+ for(uint32 freeSlot = 0; freeSlot < MAX_AURAS; ++itr , ++freeSlot)
{
- secondaura = true;
- slot = itr->second->GetAuraSlot();
- break;
+ if(itr == visibleAuras->end() || itr->first != freeSlot)
+ {
+ slot = freeSlot;
+ break;
+ }
}
}
- if(secondaura)
- break;
+ // Register Visible Aura
+ if(slot < MAX_AURAS)
+ {
+ m_auraFlags |= (IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE) |
+ (GetCasterGUID() == m_target->GetGUID() ? AFLAG_CASTER : AFLAG_NONE) |
+ (GetAuraMaxDuration() > 0 ? AFLAG_DURATION : AFLAG_NONE);
+ m_auraLevel = (caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
+ SetAuraSlot( slot );
+ m_target->SetVisibleAura(slot, this);
+ m_target->UpdateAuraForGroup(slot);
+ SendAuraUpdate();
+ sLog.outDebug("Aura: %u Effect: %d put to unit visible auras slot: %u",GetId(), GetEffectMask(), slot);
+ }
+ else
+ sLog.outDebug("Aura: %u Effect: %d could not find empty unit visible slot",GetId(), GetEffectMask());
}
- Unit* caster = GetCaster();
+ // Sitdown on apply aura req seated
+ if (m_spellProto->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED && !m_target->IsSitState())
+ m_target->SetStandState(UNIT_STAND_STATE_SIT);
- // not call total regen auras at adding
- switch (m_modifier.m_auraname)
- {
- /*case SPELL_AURA_PERIODIC_DAMAGE:
- case SPELL_AURA_PERIODIC_LEECH:
- if(caster)
- m_modifier.m_amount = caster->SpellDamageBonus(m_target, m_spellProto, m_modifier.m_amount, DOT);
- break;
- case SPELL_AURA_PERIODIC_HEAL:
- if(caster)
- m_modifier.m_amount = caster->SpellHealingBonus(m_spellProto, m_modifier.m_amount, DOT, m_target);
- break;*/
- case SPELL_AURA_OBS_MOD_HEALTH:
- case SPELL_AURA_OBS_MOD_MANA:
- m_periodicTimer = m_modifier.periodictime;
- break;
- case SPELL_AURA_MOD_REGEN:
- case SPELL_AURA_MOD_POWER_REGEN:
- case SPELL_AURA_MOD_MANA_REGEN_FROM_STAT:
- m_periodicTimer = 5000;
- break;
- }
-
- // register aura
+ // register aura diminishing on apply
if (getDiminishGroup() != DIMINISHING_NONE )
m_target->ApplyDiminishingAura(getDiminishGroup(),true);
- // passive auras (except totem auras) do not get placed in the slots
- // area auras with SPELL_AURA_NONE are not shown on target
- if((!m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) &&
- (m_spellProto->Effect[GetEffIndex()] != SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || m_target != caster))
+ // Apply linked auras (On first aura apply)
+ uint32 id = GetId();
+ if(spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_AURA)
{
- if(!secondaura) // new slot need
- {
- if (IsPositive()) // empty positive slot
+ if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(id + SPELL_LINK_AURA))
+ for(std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
{
- for (uint8 i = 0; i < MAX_POSITIVE_AURAS; i++)
- {
- if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
- {
- slot = i;
- break;
- }
- }
- }
- else // empty negative slot
- {
- for (uint8 i = MAX_POSITIVE_AURAS; i < MAX_AURAS; i++)
- {
- if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
- {
- slot = i;
- break;
- }
- }
+ if(*itr < 0)
+ m_target->ApplySpellImmune(id, IMMUNITY_ID, -(*itr), m_target);
+ else if(Unit* caster = GetCaster())
+ caster->AddAura(*itr, m_target);
}
+ }
- SetAuraSlot( slot );
+ //*****************************************************
+ // Update target aura state flag
+ //*****************************************************
- // Not update fields for not first spell's aura, all data already in fields
- if(slot < MAX_AURAS) // slot found
- {
- SetAura(slot, false);
- SetAuraFlag(slot, true);
- SetAuraLevel(slot,caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
- UpdateAuraCharges();
+ // Update Seals information
+ if (IsSealSpell(m_spellProto))
+ SetAuraState(AURA_STATE_JUDGEMENT);
- // update for out of range group members
- m_target->UpdateAuraForGroup(slot);
- }
- }
- else // use found slot
- {
- SetAuraSlot( slot );
- }
+ // Conflagrate aura state on Immolate or Shadowflame
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && (m_spellProto->SpellFamilyFlags[0] & 4
+ || m_spellProto->SpellFamilyFlags[2] & 2))
+ SetAuraState(AURA_STATE_IMMOLATE);
+
+ // Faerie Fire (druid versions)
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags[0] & 0x400)
+ SetAuraState(AURA_STATE_FAERIE_FIRE);
- UpdateSlotCounterAndDuration();
+ // Victorious
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags[1] & 0x00040000)
+ SetAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH);
- // Update Seals information
- if( IsSealSpell(GetSpellProto()) )
- m_target->ModifyAuraState(AURA_STATE_JUDGEMENT, true);
+ // Swiftmend state on Regrowth & Rejuvenation
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags[0] & 0x50 )
+ SetAuraState(AURA_STATE_SWIFTMEND);
- // Conflagrate aura state
- if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
- m_target->ModifyAuraState(AURA_STATE_IMMOLATE, true);
+ // Deadly poison aura state
+ if(m_spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellProto->SpellFamilyFlags[0] & 0x10000)
+ SetAuraState(AURA_STATE_DEADLY_POISON);
- if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
- && (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10))
+ // Enrage aura state
+ if(m_spellProto->Dispel == DISPEL_ENRAGE)
+ SetAuraState(AURA_STATE_ENRAGE);
+
+ if(GetSpellSchoolMask(m_spellProto) & SPELL_SCHOOL_MASK_FROST)
+ {
+ for (uint8 i = 0;i<MAX_SPELL_EFFECTS;++i)
{
- m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, true);
+ if (m_spellProto->EffectApplyAuraName[i]==SPELL_AURA_MOD_STUN
+ || m_spellProto->EffectApplyAuraName[i]==SPELL_AURA_MOD_ROOT)
+ {
+ SetAuraState(AURA_STATE_FROZEN);
+ break;
+ }
}
}
+
+ m_target->ApplyModFlag(UNIT_FIELD_AURASTATE, GetAuraStateMask(), true);
+}
+
+bool Aura::SetPartAura(AuraEffect* aurEff, uint8 effIndex)
+{
+ if (IsRemoved())
+ return false;
+ if (m_auraFlags & (1<<effIndex))
+ return false;
+ m_auraFlags |= 1<<effIndex;
+ m_partAuras[effIndex]=aurEff;
+ m_target->HandleAuraEffect(aurEff, true);
+ SendAuraUpdate();
+ return true;
}
void Aura::_RemoveAura()
{
Unit* caster = GetCaster();
- if(caster && IsPersistent())
- {
- DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex());
- if (dynObj)
- dynObj->RemoveAffected(m_target);
- }
-
- // unregister aura
- if (getDiminishGroup() != DIMINISHING_NONE )
- m_target->ApplyDiminishingAura(getDiminishGroup(),false);
-
//passive auras do not get put in slots
// Note: but totem can be not accessible for aura target in time remove (to far for find in grid)
//if(m_isPassive && !(caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem()))
@@ -934,185 +1078,415 @@ void Aura::_RemoveAura()
uint8 slot = GetAuraSlot();
- if(slot >= MAX_AURAS) // slot not set
- return;
+ if (Aura * foundAura = m_target->GetAura(GetId(), GetCasterGUID()))
+ {
+ // allow use single slot only by auras from same caster
+ slot = foundAura->GetAuraSlot();
+ if(slot < MAX_AURAS) // slot not set
+ if (Aura *entry = m_target->GetVisibleAura(slot))
+ {
+ // set not valid slot for aura - prevent removing other visible aura
+ slot = MAX_AURAS;
+ }
+ }
- if(m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + slot)) == 0)
- return;
+ // update for out of range group members
+ if (slot < MAX_AURAS)
+ {
+ m_target->RemoveVisibleAura(slot);
+ m_target->UpdateAuraForGroup(slot);
+ SendAuraUpdate();
+ }
- bool samespell = false;
+ // unregister aura diminishing (and store last time)
+ if (getDiminishGroup() != DIMINISHING_NONE )
+ m_target->ApplyDiminishingAura(getDiminishGroup(),false);
- // find other aura in same slot (current already removed from list)
- for(uint8 i = 0; i < 3; i++)
+ // Check needed only if aura applies aurastate
+ if(GetAuraStateMask())
{
- Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i);
- for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
+ uint32 foundMask = 0;
+ Unit::AuraMap& Auras = m_target->GetAuras();
+ // Get mask of all aurastates from remaining auras
+ for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
{
- if(itr->second->GetAuraSlot()==slot)
+ foundMask|=(*i).second->GetAuraStateMask();
+ }
+ // Remove only aurastates which were not found
+ foundMask = GetAuraStateMask() &~foundMask;
+ if (foundMask)
+ m_target->ApplyModFlag(UNIT_FIELD_AURASTATE, foundMask, false);
+ }
+
+ // since now aura cannot apply/remove it's modifiers
+ m_isRemoved = true;
+ // disable client server communication for removed aura
+ SetAuraSlot(MAX_AURAS);
+
+ // reset cooldown state for spells
+ if(caster && caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE )
+ // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)
+ ((Player*)caster)->SendCooldownEvent(GetSpellProto());
+ }
+ uint32 id = GetId();
+ // Remove Linked Auras
+ if(spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_REMOVE)
+ {
+ if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(-(int32)id))
+ for(std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
{
- samespell = true;
+ if(*itr < 0)
+ m_target->RemoveAurasDueToSpell(-(*itr));
+ else if(Unit* caster = GetCaster())
+ if (m_removeMode!=AURA_REMOVE_BY_DEFAULT && m_removeMode!=AURA_REMOVE_BY_DEATH)
+ m_target->CastSpell(m_target, *itr, true, 0, 0, caster->GetGUID());
+ }
+ }
+ if(spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_AURA)
+ {
+ if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(id + SPELL_LINK_AURA))
+ for(std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
+ {
+ if(*itr < 0)
+ m_target->ApplySpellImmune(id, IMMUNITY_ID, -(*itr), false);
+ else
+ m_target->RemoveAurasDueToSpell(*itr);
+ }
+ }
- break;
+ // Proc on aura remove (only spell flags for now)
+ if (caster)
+ {
+ uint32 procEx=0;
+ if (m_removeMode == AURA_REMOVE_BY_ENEMY_SPELL)
+ procEx = PROC_EX_AURA_REMOVE_DESTROY;
+ else if (m_removeMode == AURA_REMOVE_BY_EXPIRE || m_removeMode == AURA_REMOVE_BY_CANCEL)
+ procEx = PROC_EX_AURA_REMOVE_EXPIRE;
+ if (procEx)
+ {
+ uint32 ProcCaster, ProcVictim;
+ if (IsPositiveSpell(GetId()))
+ {
+ ProcCaster = PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL;
+ ProcVictim = PROC_FLAG_TAKEN_POSITIVE_SPELL;
+ }
+ else
+ {
+ ProcCaster = PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT;
+ ProcVictim = PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT;
}
+ caster->ProcDamageAndSpell(m_target,ProcCaster, ProcVictim, procEx, m_procDamage, BASE_ATTACK, m_spellProto);
}
- if(samespell)
- break;
}
+}
- // only remove icon when the last aura of the spell is removed (current aura already removed from list)
- if (!samespell)
+void Aura::SetStackAmount(uint8 stackAmount)
+{
+ if (stackAmount != m_stackAmount)
{
- SetAura(slot, true);
- SetAuraFlag(slot, false);
- SetAuraLevel(slot,caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
-
- SetAuraApplication(slot, 0);
- // update for out of range group members
- m_target->UpdateAuraForGroup(slot);
-
- if( IsSealSpell(GetSpellProto()) )
- m_target->ModifyAuraState(AURA_STATE_JUDGEMENT,false);
-
- // Conflagrate aura state
- if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
- m_target->ModifyAuraState(AURA_STATE_IMMOLATE, false);
-
- // Swiftmend aura state
- if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
- && (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10))
+ Unit *target = GetTarget();
+ Unit *caster = GetCaster();
+ if (target && caster)
{
- bool found = false;
- Unit::AuraList const& RejorRegr = m_target->GetAurasByType(SPELL_AURA_PERIODIC_HEAL);
- for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
+ m_stackAmount = stackAmount;
+ for (uint8 i=0;i<MAX_SPELL_EFFECTS;++i)
{
- if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
- && ((*i)->GetSpellProto()->SpellFamilyFlags == 0x40 || (*i)->GetSpellProto()->SpellFamilyFlags == 0x10) )
+ if (AuraEffect * part = GetPartAura(i))
{
- found = true;
- break;
+ int32 amount = m_stackAmount * caster->CalculateSpellDamage(m_spellProto, part->GetEffIndex(), part->GetBasePoints(), target);
+ // Reapply if amount change
+ if (amount!=part->GetAmount())
+ {
+ // Auras which are applying spellmod should have removed spellmods for real
+ part->ApplyModifier(false,true);
+ part->SetAmount(amount);
+ part->ApplyModifier(true,true);
+ }
}
}
- if(!found)
- m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, false);
}
+ }
+ RefreshAura();
+}
- // reset cooldown state for spells
- if(caster && caster->GetTypeId() == TYPEID_PLAYER)
- {
- if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE )
- ((Player*)caster)->SendCooldownEvent(GetSpellProto());
- }
+bool Aura::modStackAmount(int32 num)
+{
+ // Can`t mod
+ if (!m_spellProto->StackAmount)
+ return true;
+
+ // Modify stack but limit it
+ int32 stackAmount = m_stackAmount + num;
+ if (stackAmount > m_spellProto->StackAmount)
+ stackAmount = m_spellProto->StackAmount;
+ else if (stackAmount <=0) // Last aura from stack removed
+ {
+ m_stackAmount = 0;
+ return true; // need remove aura
}
+
+ // Update stack amount
+ SetStackAmount(stackAmount);
+ return false;
+}
+
+void Aura::SetAuraDuration(int32 duration)
+{
+ m_duration = duration;
+ //if (duration<0)
+ //m_permanent=true;
+ //else
+ //m_permanent=false;
+ SendAuraUpdate();
+}
+
+void Aura::SetAuraCharges(uint8 charges)
+{
+ if (m_procCharges == charges)
+ return;
+ m_procCharges = charges;
+ SendAuraUpdate();
}
-void Aura::SetAuraFlag(uint32 slot, bool add)
+void Aura::DropAuraCharge()
{
- uint32 index = slot / 4;
- uint32 byte = (slot % 4) * 8;
- uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURAFLAGS + index);
- val &= ~((uint32)AFLAG_MASK << byte);
- if(add)
+ if(m_procCharges) //auras without charges always have charge = 0
{
- if (IsPositive())
- val |= ((uint32)AFLAG_POSITIVE << byte);
- else
- val |= ((uint32)AFLAG_NEGATIVE << byte);
+ if(--m_procCharges) // Send charge change
+ SendAuraUpdate();
+ else // Last charge dropped
+ m_target->RemoveAura(this);
}
- m_target->SetUInt32Value(UNIT_FIELD_AURAFLAGS + index, val);
}
-void Aura::SetAuraLevel(uint32 slot,uint32 level)
+bool Aura::IsPersistent() const
{
- uint32 index = slot / 4;
- uint32 byte = (slot % 4) * 8;
- uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURALEVELS + index);
- val &= ~(0xFF << byte);
- val |= (level << byte);
- m_target->SetUInt32Value(UNIT_FIELD_AURALEVELS + index, val);
+ for(uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ if(m_partAuras[i] && m_partAuras[i]->IsPersistent())
+ return true;
+ }
+ return false;
}
-void Aura::SetAuraApplication(uint32 slot, int8 count)
+bool Aura::IsAreaAura() const
{
- uint32 index = slot / 4;
- uint32 byte = (slot % 4) * 8;
- uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS + index);
- val &= ~(0xFF << byte);
- val |= ((uint8(count)) << byte);
- m_target->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS + index, val);
+ for(uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ if(m_partAuras[i] && m_partAuras[i]->IsAreaAura())
+ return true;
+ }
+ return false;
}
-void Aura::UpdateSlotCounterAndDuration()
+bool Aura::IsAuraType(AuraType type) const
{
- uint8 slot = GetAuraSlot();
- if(slot >= MAX_AURAS)
- return;
+ for(uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ if(m_partAuras[i] && m_partAuras[i]->GetAuraName() == type)
+ return true;
+ }
+ return false;
+}
- // Three possibilities:
- // Charge = 0; Stack >= 0
- // Charge = 1; Stack >= 0
- // Charge > 1; Stack = 0
- if(m_procCharges < 2)
- SetAuraApplication(slot, m_stackAmount-1);
+void Aura::SetLoadedState(uint64 caster_guid,int32 maxduration,int32 duration,int32 charges, uint8 stackamount, int32 * amount)
+{
+ m_caster_guid = caster_guid;
+ m_maxduration = maxduration;
+ m_duration = duration;
+ m_procCharges = charges;
+ m_stackAmount = stackamount;
+ for (uint8 i=0; i<MAX_SPELL_EFFECTS;++i)
+ if (m_partAuras[i])
+ m_partAuras[i]->SetAmount(amount[i]);
+}
- UpdateAuraDuration();
+void AuraEffect::HandleShapeshiftBoosts(bool apply)
+{
+ uint32 spellId = 0;
+ uint32 spellId2 = 0;
+ uint32 HotWSpellId = 0;
+
+ switch(GetMiscValue())
+ {
+ case FORM_CAT:
+ spellId = 3025;
+ HotWSpellId = 24900;
+ break;
+ case FORM_TREE:
+ spellId = 5420;
+ spellId2 = 34123;
+ break;
+ case FORM_TRAVEL:
+ spellId = 5419;
+ break;
+ case FORM_AQUA:
+ spellId = 5421;
+ break;
+ case FORM_BEAR:
+ spellId = 1178;
+ spellId2 = 21178;
+ HotWSpellId = 24899;
+ break;
+ case FORM_DIREBEAR:
+ spellId = 9635;
+ spellId2 = 21178;
+ HotWSpellId = 24899;
+ break;
+ case FORM_BATTLESTANCE:
+ spellId = 21156;
+ break;
+ case FORM_DEFENSIVESTANCE:
+ spellId = 7376;
+ break;
+ case FORM_BERSERKERSTANCE:
+ spellId = 7381;
+ break;
+ case FORM_MOONKIN:
+ spellId = 24905;
+ // aura from effect trigger spell
+ spellId2 = 24907;
+ break;
+ case FORM_FLIGHT:
+ spellId = 33948;
+ spellId2 = 34764;
+ break;
+ case FORM_FLIGHT_EPIC:
+ spellId = 40122;
+ spellId2 = 40121;
+ break;
+ case FORM_METAMORPHOSIS:
+ spellId = 54817;
+ spellId2 = 54879;
+ break;
+ case FORM_SPIRITOFREDEMPTION:
+ spellId = 27792;
+ spellId2 = 27795; // must be second, this important at aura remove to prevent to early iterator invalidation.
+ break;
+ case FORM_GHOSTWOLF:
+ case FORM_AMBIENT:
+ case FORM_GHOUL:
+ case FORM_SHADOW:
+ case FORM_STEALTH:
+ case FORM_CREATURECAT:
+ case FORM_CREATUREBEAR:
+ spellId = 0;
+ break;
+ }
+
+ uint32 form = GetMiscValue()-1;
+
+ if(apply)
+ {
+ if (spellId) m_target->CastSpell(m_target, spellId, true, NULL, this );
+ if (spellId2) m_target->CastSpell(m_target, spellId2, true, NULL, this);
+
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ {
+ const PlayerSpellMap& sp_list = ((Player *)m_target)->GetSpellMap();
+ for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
+ {
+ if(itr->second->state == PLAYERSPELL_REMOVED) continue;
+ if(itr->first==spellId || itr->first==spellId2) continue;
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
+ if (!spellInfo || !(spellInfo->Attributes & (SPELL_ATTR_PASSIVE | (1<<7)))) continue;
+ if (spellInfo->Stances & (1<<form))
+ m_target->CastSpell(m_target, itr->first, true, NULL, this);
+ }
+ //LotP
+ if (((Player*)m_target)->HasSpell(17007))
+ {
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(24932);
+ if (spellInfo && spellInfo->Stances & (1<<form))
+ m_target->CastSpell(m_target, 24932, true, NULL, this);
+ }
+ // HotW
+ if (HotWSpellId)
+ {
+ Unit::AuraEffectList const& mModTotalStatPct = m_target->GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
+ for(Unit::AuraEffectList::const_iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i)
+ {
+ if ((*i)->GetSpellProto()->SpellIconID == 240 && (*i)->GetMiscValue() == 3)
+ {
+ int32 HotWMod = (*i)->GetAmount();
+ if(GetMiscValue() == FORM_CAT)
+ HotWMod /= 2;
+
+ m_target->CastCustomSpell(m_target, HotWSpellId, &HotWMod, NULL, NULL, true, NULL, this);
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ m_target->RemoveAurasDueToSpell(spellId);
+ m_target->RemoveAurasDueToSpell(spellId2);
+
+ Unit::AuraMap& tAuras = m_target->GetAuras();
+ for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
+ {
+ if (itr->second->IsRemovedOnShapeLost())
+ {
+ m_target->RemoveAura(itr);
+ }
+ else
+ {
+ ++itr;
+ }
+ }
+ }
+}
+
+bool AuraEffect::isAffectedOnSpell(SpellEntry const *spell) const
+{
+ if (!spell)
+ return false;
+ // Check family name
+ if (spell->SpellFamilyName != m_spellProto->SpellFamilyName)
+ return false;
+ // Check EffectClassMask
+ if (m_spellProto->EffectSpellClassMask[m_effIndex] & spell->SpellFamilyFlags)
+ return true;
+ return false;
}
/*********************************************************/
/*** BASIC AURA FUNCTION ***/
/*********************************************************/
-void Aura::HandleAddModifier(bool apply, bool Real)
+void AuraEffect::HandleAddModifier(bool apply, bool Real)
{
if(m_target->GetTypeId() != TYPEID_PLAYER || !Real)
return;
- SpellEntry const *spellInfo = GetSpellProto();
- if(!spellInfo)
- return;
-
- if(m_modifier.m_miscvalue >= MAX_SPELLMOD)
+ if(GetMiscValue() >= MAX_SPELLMOD)
return;
if (apply)
{
- // Add custom charges for some mod aura
- switch (m_spellProto->Id)
- {
- case 17941: // Shadow Trance
- case 22008: // Netherwind Focus
- case 34936: // Backlash
- m_procCharges = 1;
- break;
- }
SpellModifier *mod = new SpellModifier;
- mod->op = SpellModOp(m_modifier.m_miscvalue);
- mod->value = GetModifierValue();
- mod->type = SpellModType(m_modifier.m_auraname); // SpellModType value == spell aura types
+ mod->op = SpellModOp(GetMiscValue());
+ mod->value = m_amount;
+ mod->type = SpellModType(m_auraName); // SpellModType value == spell aura types
mod->spellId = GetId();
- mod->effectId = m_effIndex;
- mod->lastAffected = NULL;
-
- uint64 spellAffectMask = spellmgr.GetSpellAffectMask(GetId(), m_effIndex);
- if (spellAffectMask)
- mod->mask = spellAffectMask;
- else
- mod->mask = spellInfo->EffectItemType[m_effIndex];
-
- if (m_procCharges > 0)
- mod->charges = m_procCharges;
- else
- mod->charges = 0;
+ flag96 const *spellAffect = spellmgr.GetSpellAffect(GetId(), m_effIndex);
+ if (!spellAffect)
+ spellAffect = &m_spellProto->EffectSpellClassMask[m_effIndex];
+ mod->mask = *spellAffect;
+ mod->charges = GetParentAura()->GetAuraCharges();
m_spellmod = mod;
}
- uint64 spellFamilyMask = m_spellmod->mask;
-
((Player*)m_target)->AddSpellMod(m_spellmod, apply);
// reapply some passive spells after add/remove related spellmods
- if(spellInfo->SpellFamilyName==SPELLFAMILY_WARRIOR && (spellFamilyMask & 0x0000100000000000LL))
+ if(m_spellProto->SpellFamilyName==SPELLFAMILY_WARRIOR && (m_spellmod->mask[1] & 0x00001000))
{
m_target->RemoveAurasDueToSpell(45471);
@@ -1120,8 +1494,31 @@ void Aura::HandleAddModifier(bool apply, bool Real)
m_target->CastSpell(m_target,45471,true);
}
}
+void AuraEffect::HandleAddTargetTrigger(bool apply, bool Real)
+{
+ // Use SpellModifier structure for check
+ // used only fields:
+ // spellId, mask, mask2
+ if (apply)
+ {
+ SpellModifier *mod = new SpellModifier;
+ mod->spellId = GetId();
+
+ flag96 const *spellAffect = spellmgr.GetSpellAffect(GetId(), m_effIndex);
+ if (!spellAffect)
+ spellAffect = &m_spellProto->EffectSpellClassMask[m_effIndex];
+
+ mod->mask = *spellAffect;
+ m_spellmod = mod;
+ }
+ else
+ {
+ delete m_spellmod;
+ m_spellmod = NULL;
+ }
+}
-void Aura::TriggerSpell()
+void AuraEffect::TriggerSpell()
{
Unit* caster = GetCaster();
Unit* target = GetTriggerTarget();
@@ -1132,8 +1529,6 @@ void Aura::TriggerSpell()
// generic casting code with custom spells and target/caster customs
uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex];
- uint64 originalCasterGUID = GetCasterGUID();
-
SpellEntry const *triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id);
SpellEntry const *auraSpellInfo = GetSpellProto();
uint32 auraId = auraSpellInfo->Id;
@@ -1172,7 +1567,7 @@ void Aura::TriggerSpell()
}
// remove old enchanting before applying new
((Player*)caster)->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,false);
- item->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, m_modifier.periodictime+1000, 0);
+ item->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, m_amplitude+1000, 0);
// add new enchanting
((Player*)caster)->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,true);
return;
@@ -1218,8 +1613,7 @@ void Aura::TriggerSpell()
case 23493:
{
int32 heal = caster->GetMaxHealth() / 10;
- caster->ModifyHealth( heal );
- caster->SendHealSpellLog(caster, 23493, heal);
+ caster->DealHeal(caster, heal, auraSpellInfo);
int32 mana = caster->GetMaxPower(POWER_MANA);
if (mana)
@@ -1228,7 +1622,7 @@ void Aura::TriggerSpell()
caster->ModifyPower( POWER_MANA, mana );
caster->SendEnergizeSpellLog(caster, 23493, mana, POWER_MANA);
}
- break;
+ return;
}
// // Stoneclaw Totem Passive TEST
// case 23792: break;
@@ -1285,8 +1679,13 @@ void Aura::TriggerSpell()
} break;
// // Steam Tank Passive
// case 27747: break;
-// // Frost Blast
-// case 27808: break;
+ // Frost Blast
+ case 27808:
+ {
+ int32 bpDamage = target->GetMaxHealth()*26/100;
+ caster->CastCustomSpell(target,29879,&bpDamage,NULL,NULL,true,NULL,this);
+ return;
+ }
// // Detonate Mana
// case 27819: break;
// // Controller Timer
@@ -1307,8 +1706,11 @@ void Aura::TriggerSpell()
// case 28522: break;
// // Silithyst
// case 29519: break;
-// // Inoculate Nestlewood Owlkin
- case 29528: trigger_spell_id = 28713; break;
+ // Inoculate Nestlewood Owlkin
+ case 29528:
+ if(target->GetTypeId()!=TYPEID_UNIT)// prevent error reports in case ignored player target
+ return;
+ break;
// // Overload
// case 29768: break;
// // Return Fire
@@ -1341,32 +1743,15 @@ void Aura::TriggerSpell()
Creature* creature = (Creature*)target;
// missing lootid has been reported on startup - just return
if (!creature->GetCreatureInfo()->SkinLootId)
- {
return;
- }
- Loot *loot = &creature->loot;
- loot->clear();
- loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, NULL);
- for(uint8 i=0;i<loot->items.size();i++)
- {
- LootItem *item = loot->LootItemInSlot(i,player);
- ItemPosCountVec dest;
- uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, item->itemid, item->count );
- if ( msg == EQUIP_ERR_OK )
- {
- Item * newitem = player->StoreNewItem( dest, item->itemid, true, item->randomPropertyId);
-
- player->SendNewItem(newitem, uint32(item->count), false, false, true);
- }
- else
- player->SendEquipError( msg, NULL, NULL );
- }
+
+ player->AutoStoreLoot(creature->GetCreatureInfo()->SkinLootId,LootTemplates_Skinning,true);
+
creature->setDeathState(JUST_DIED);
creature->RemoveCorpse();
creature->SetHealth(0); // just for nice GM-mode view
}
return;
- break;
}
// Quake
case 30576: trigger_spell_id = 30571; break;
@@ -1569,13 +1954,13 @@ void Aura::TriggerSpell()
// Aura of Desire
case 41350:
{
- Unit::AuraList const& mMod = m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT);
- for(Unit::AuraList::const_iterator i = mMod.begin(); i != mMod.end(); ++i)
+ Unit::AuraEffectList const& mMod = m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT);
+ for(Unit::AuraEffectList::const_iterator i = mMod.begin(); i != mMod.end(); ++i)
{
if ((*i)->GetId() == 41350)
{
(*i)->ApplyModifier(false);
- (*i)->GetModifier()->m_amount -= 5;
+ (*i)->SetAmount((*i)->GetAmount()-5);
(*i)->ApplyModifier(true);
break;
}
@@ -1616,11 +2001,8 @@ void Aura::TriggerSpell()
{
// Invisibility
case 66:
- {
- if(!m_duration)
- m_target->CastSpell(m_target, 32612, true, NULL, this);
+ // Here need periodic triger reducing threat spell (or do it manually)
return;
- }
default:
break;
}
@@ -1666,7 +2048,7 @@ void Aura::TriggerSpell()
case 22896:
case 26999:
{
- int32 LifePerRage = GetModifier()->m_amount;
+ int32 LifePerRage = GetAmount();
int32 lRage = m_target->GetPower(POWER_RAGE);
if(lRage > 100) // rage stored as rage*10
@@ -1730,7 +2112,7 @@ void Aura::TriggerSpell()
{
SpellEntry const* spell = itr->second->GetSpellProto();
if( spell->SpellFamilyName == SPELLFAMILY_SHAMAN &&
- spell->SpellFamilyFlags & 0x0000000000000400L)
+ spell->SpellFamilyFlags[0] & 0x400)
return;
}
target->RemoveAurasDueToSpell(28820);
@@ -1740,9 +2122,9 @@ void Aura::TriggerSpell()
case 38443:
{
bool all = true;
- for(int i = 0; i < MAX_TOTEM; ++i)
+ for(int i = SUMMON_SLOT_TOTEM; i < MAX_TOTEM_SLOT; ++i)
{
- if(!caster->m_TotemSlot[i])
+ if(!caster->m_SummonSlot[i])
{
all = false;
break;
@@ -1763,13 +2145,9 @@ void Aura::TriggerSpell()
default:
break;
}
+
// Reget trigger spell proto
triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id);
- if(triggeredSpellInfo == NULL)
- {
- sLog.outError("Aura::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",GetId(),GetEffIndex());
- return;
- }
}
else
{
@@ -1786,22 +2164,22 @@ void Aura::TriggerSpell()
// 2) maybe aura must be replace by new with accumulative stat mods instead stacking
// prevent cast by triggered auras
- if(m_caster_guid == m_target->GetGUID())
+ if(GetCasterGUID() == m_target->GetGUID())
return;
// stop triggering after each affected stats lost > 90
int32 intellectLoss = 0;
int32 spiritLoss = 0;
- Unit::AuraList const& mModStat = m_target->GetAurasByType(SPELL_AURA_MOD_STAT);
- for(Unit::AuraList::const_iterator i = mModStat.begin(); i != mModStat.end(); ++i)
+ Unit::AuraEffectList const& mModStat = m_target->GetAurasByType(SPELL_AURA_MOD_STAT);
+ for(Unit::AuraEffectList::const_iterator i = mModStat.begin(); i != mModStat.end(); ++i)
{
if ((*i)->GetId() == 1010)
{
- switch((*i)->GetModifier()->m_miscvalue)
+ switch((*i)->GetMiscValue())
{
- case STAT_INTELLECT: intellectLoss += (*i)->GetModifierValue(); break;
- case STAT_SPIRIT: spiritLoss += (*i)->GetModifierValue(); break;
+ case STAT_INTELLECT: intellectLoss += (*i)->GetAmount(); break;
+ case STAT_SPIRIT: spiritLoss += (*i)->GetAmount(); break;
default: break;
}
}
@@ -1811,42 +2189,62 @@ void Aura::TriggerSpell()
return;
caster = target;
- originalCasterGUID = 0;
break;
}
// Mana Tide
case 16191:
{
- caster->CastCustomSpell(target, trigger_spell_id, &m_modifier.m_amount, NULL, NULL, true, NULL, this, originalCasterGUID);
+ caster->CastCustomSpell(target, trigger_spell_id, &m_amount, NULL, NULL, true, NULL, this);
return;
}
// Negative Energy Periodic
case 46284:
- {
- caster->CastCustomSpell(trigger_spell_id, SPELLVALUE_MAX_TARGETS, m_tickNumber / 10 + 1, NULL, true, NULL, this, originalCasterGUID);
+ caster->CastCustomSpell(trigger_spell_id, SPELLVALUE_MAX_TARGETS, m_tickNumber / 10 + 1, NULL, true, NULL, this);
return;
- }
+ // Poison (Grobbulus)
+ case 28158:
+ case 54362:
+ m_target->CastCustomSpell(trigger_spell_id, SPELLVALUE_RADIUS_MOD, (int32)((((float)m_tickNumber / 60) * 0.9f + 0.1f) * 10000), NULL, true, NULL, this);
+ return;
}
}
- if(!GetSpellMaxRange(sSpellRangeStore.LookupEntry(triggeredSpellInfo->rangeIndex)))
- target = m_target; //for druid dispel poison
- m_target->CastSpell(target, triggeredSpellInfo, true, 0, this, originalCasterGUID);
+
+ if(triggeredSpellInfo)
+ {
+ if(!caster->GetSpellMaxRangeForTarget(m_target,sSpellRangeStore.LookupEntry(triggeredSpellInfo->rangeIndex)))
+ target = m_target; //for druid dispel poison
+ m_target->CastSpell(target, triggeredSpellInfo, true, 0, this, GetCasterGUID());
+ }
+ else if(target->GetTypeId()!=TYPEID_UNIT || !Script->EffectDummyCreature(caster, GetId(), GetEffIndex(), (Creature*)target))
+ sLog.outError("AuraEffect::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",GetId(),GetEffIndex());
}
-Unit* Aura::GetTriggerTarget() const
+Unit* AuraEffect::GetTriggerTarget() const
{
- Unit* target = ObjectAccessor::GetUnit(*m_target,
- /*m_target->GetTypeId()==TYPEID_PLAYER ?
- ((Player*)m_target)->GetSelection() :*/
- m_target->GetUInt64Value(UNIT_FIELD_TARGET));
+ Unit* target = ObjectAccessor::GetUnit(*m_target, m_target->GetUInt64Value(UNIT_FIELD_TARGET));
return target ? target : m_target;
}
+void AuraEffect::TriggerSpellWithValue()
+{
+ Unit* caster = GetCaster();
+ Unit* target = GetTriggerTarget();
+
+ if(!caster || !target)
+ return;
+
+ // generic casting code with custom spells and target/caster customs
+ uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex];
+ int32 basepoints0 = this->GetAmount();
+
+ caster->CastCustomSpell(target, trigger_spell_id, &basepoints0, 0, 0, true, 0, this);
+}
+
/*********************************************************/
/*** AURA EFFECTS ***/
/*********************************************************/
-void Aura::HandleAuraDummy(bool apply, bool Real)
+void AuraEffect::HandleAuraDummy(bool apply, bool Real)
{
// spells required only Real aura add/remove
if(!Real)
@@ -1859,6 +2257,12 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
{
switch(GetId())
{
+ // Haunting Spirits - perdiodic trigger demon
+ case 7057:
+ m_isPeriodic = true;
+ m_amplitude = irand (0, 60) + 30;
+ m_amplitude *= IN_MILISECONDS;
+ return;
case 1515: // Tame beast
// FIX_ME: this is 2.0.12 threat effect replaced in 2.1.x by dummy aura, must be checked for correctness
if( caster && m_target->CanHaveThreatList())
@@ -1869,13 +2273,50 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
if(caster)
caster->CastSpell(caster,13138,true,NULL,this);
return;
+ case 34026: // kill command
+ {
+ Unit * pet = m_target->GetGuardianPet();
+ if (!pet)
+ return;
+
+ m_target->CastSpell(m_target,34027,true,NULL,this);
+
+ // set 3 stacks and 3 charges (to make all auras not disappear at once)
+ Aura* owner_aura = m_target->GetAura(34027,GetCasterGUID());
+ Aura* pet_aura = pet->GetAura(58914, GetCasterGUID());
+ if( owner_aura )
+ {
+ owner_aura->SetStackAmount(owner_aura->GetSpellProto()->StackAmount);
+ }
+ if( pet_aura )
+ {
+ pet_aura->SetAuraCharges(0);
+ pet_aura->SetStackAmount(owner_aura->GetSpellProto()->StackAmount);
+ }
+ return;
+ }
+ case 55198: // Tidal Force
+ {
+ m_target->CastSpell(m_target,55166,true,NULL,this);
+ // set 3 stacks and 3 charges (to make all auras not disappear at once)
+ Aura* owner_aura = m_target->GetAura(55166,GetCasterGUID());
+ if( owner_aura )
+ {
+ // This aura lasts 2 sec, need this hack to properly proc spells
+ // TODO: drop aura charges for ApplySpellMod in ProcDamageAndSpell
+ GetParentAura()->SetAuraDuration(owner_aura->GetAuraDuration());
+ // Make aura be not charged-this prevents removing charge on not crit spells
+ owner_aura->SetAuraCharges(0);
+ owner_aura->SetStackAmount(owner_aura->GetSpellProto()->StackAmount);
+ }
+ return;
+ }
case 39850: // Rocket Blast
if(roll_chance_i(20)) // backfire stun
m_target->CastSpell(m_target, 51581, true, NULL, this);
return;
case 43873: // Headless Horseman Laugh
- if(caster->GetTypeId() == TYPEID_PLAYER)
- ((Player*)caster)->SendPlaySound(11965, false);
+ m_target->PlayDistanceSound(11965);
return;
case 46354: // Blood Elf Illusion
if(caster)
@@ -1900,24 +2341,26 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
}
// Earth Shield
- if ( caster && GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (GetSpellProto()->SpellFamilyFlags & 0x40000000000LL))
+ if ( caster && GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (GetSpellProto()->SpellFamilyFlags[1] & 0x400))
{
// prevent double apply bonuses
if(m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading())
- m_modifier.m_amount = caster->SpellHealingBonus(GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE, m_target);
+ m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_amount, SPELL_DIRECT_DAMAGE);
return;
}
+ //Druid, Survival Instincts
+ if(GetSpellProto()->SpellFamilyName==SPELLFAMILY_DRUID && GetSpellProto()->SpellFamilyFlags[2]& 0x40 )
+ {
+ if(!m_target)
+ return;
+
+ int32 bp0 = int32(m_target->GetMaxHealth() * m_amount / 100);
+ m_target->CastCustomSpell(m_target, 50322, &bp0, NULL, NULL, true);
+ }
}
// AT REMOVE
else
{
- if( m_target->GetTypeId() == TYPEID_PLAYER && GetSpellProto()->Effect[0]==72 )
- {
- // spells with SpellEffect=72 and aura=4: 6196, 6197, 21171, 21425
- ((Player*)m_target)->ClearFarsight();
- return;
- }
-
if( (IsQuestTameSpell(GetId())) && caster && caster->isAlive() && m_target->isAlive())
{
uint32 finalSpelId = 0;
@@ -1971,6 +2414,29 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
m_target->SetReducedThreatPercent(0, 0);
return;
}
+
+ switch(m_spellProto->SpellFamilyName)
+ {
+ case SPELLFAMILY_WARLOCK:
+ // Haunt
+ if(m_spellProto->SpellFamilyFlags[1] & 0x40000)
+ {
+ int32 bp0 = GetParentAura()->GetProcDamage() * m_amount / 100;
+ if(caster)
+ caster->CastCustomSpell(caster, 48210, &bp0, 0, 0, true, NULL, this);
+ return;
+ }
+ break;
+ case SPELLFAMILY_MAGE:
+ // Living Bomb
+ if(m_spellProto->SpellFamilyFlags[1] & 0x20000)
+ {
+ if(caster && (GetParentAura()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL || GetParentAura()->GetRemoveMode() == AURA_REMOVE_BY_DEATH || GetParentAura()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE))
+ caster->CastSpell(m_target, GetAmount(), true);
+ return;
+ }
+ break;
+ }
}
// AT APPLY & REMOVE
@@ -1979,105 +2445,203 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
{
case SPELLFAMILY_GENERIC:
{
- // Unstable Power
- if( GetId()==24658 )
+ switch(GetId())
{
- uint32 spellId = 24659;
- if (apply)
+ // Unstable Power
+ case 24658:
{
- const SpellEntry *spell = sSpellStore.LookupEntry(spellId);
- if (!spell)
+ uint32 spellId = 24659;
+ if (apply && caster)
+ {
+ const SpellEntry *spell = sSpellStore.LookupEntry(spellId);
+ if (!spell)
+ return;
+
+ for (int i=0; i < spell->StackAmount; ++i)
+ caster->CastSpell(m_target, spell->Id, true, NULL, NULL, GetCasterGUID());
return;
- for (int i=0; i < spell->StackAmount; ++i)
- caster->CastSpell(m_target, spell->Id, true, NULL, NULL, GetCasterGUID());
+ }
+ m_target->RemoveAurasDueToSpell(spellId);
return;
}
- m_target->RemoveAurasDueToSpell(spellId);
- return;
- }
- // Restless Strength
- if( GetId()==24661 )
- {
- uint32 spellId = 24662;
- if (apply)
+ // Restless Strength
+ case 24661:
{
- const SpellEntry *spell = sSpellStore.LookupEntry(spellId);
- if (!spell)
+ uint32 spellId = 24662;
+ if (apply && caster)
+ {
+ const SpellEntry *spell = sSpellStore.LookupEntry(spellId);
+ if (!spell)
+ return;
+ for (int i=0; i < spell->StackAmount; ++i)
+ caster->CastSpell(m_target, spell->Id, true, NULL, NULL, GetCasterGUID());
return;
- for (int i=0; i < spell->StackAmount; ++i)
- caster->CastSpell(m_target, spell->Id, true, NULL, NULL, GetCasterGUID());
+ }
+ m_target->RemoveAurasDueToSpell(spellId);
return;
}
- m_target->RemoveAurasDueToSpell(spellId);
- return;
- }
- // Victorious
- if(GetId()==32216 && m_target->getClass()==CLASS_WARRIOR)
- {
- m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, apply);
- return;
- }
- //Summon Fire Elemental
- if (GetId() == 40133 && caster)
- {
- Unit *owner = caster->GetOwner();
- if (owner && owner->GetTypeId() == TYPEID_PLAYER)
+ //Summon Fire Elemental
+ case 40133:
{
- if(apply)
- owner->CastSpell(owner,8985,true);
- else
- ((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
- }
- return;
- }
+ if (!caster)
+ return;
- //Summon Earth Elemental
- if (GetId() == 40132 && caster)
- {
- Unit *owner = caster->GetOwner();
- if (owner && owner->GetTypeId() == TYPEID_PLAYER)
+ Unit *owner = caster->GetOwner();
+ if (owner && owner->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(apply)
+ owner->CastSpell(owner,8985,true);
+ else
+ ((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
+ }
+ return;
+ }
+ //Summon Earth Elemental
+ case 40132 :
{
- if(apply)
- owner->CastSpell(owner,19704,true);
- else
- ((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
+ if (!caster)
+ return;
+
+ Unit *owner = caster->GetOwner();
+ if (owner && owner->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(apply)
+ owner->CastSpell(owner,19704,true);
+ else
+ ((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
+ }
+ return;
}
- return;
+ // LK Intro VO (1)
+ case 58204:
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ {
+ // Play part 1
+ if(apply)
+ m_target->PlayDirectSound(14970, (Player *)m_target);
+ // continue in 58205
+ else
+ m_target->CastSpell(m_target, 58205, true);
+ }
+ return;
+ // LK Intro VO (2)
+ case 58205:
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ {
+ // Play part 2
+ if(apply)
+ m_target->PlayDirectSound(14971, (Player *)m_target);
+ // Play part 3
+ else
+ m_target->PlayDirectSound(14972, (Player *)m_target);
+ }
+ return;
}
break;
}
case SPELLFAMILY_MAGE:
{
- // Hypothermia
- if( GetId()==41425 )
+ break;
+ }
+ case SPELLFAMILY_PRIEST:
+ {
+ // Pain and Suffering
+ if( m_spellProto->SpellIconID == 2874 && m_target->GetTypeId()==TYPEID_PLAYER )
{
- m_target->ModifyAuraState(AURA_STATE_HYPOTHERMIA,apply);
+ if(apply)
+ {
+ // Reduce backfire damage (dot damage) from Shadow Word: Death
+ SpellModifier *mod = new SpellModifier;
+ mod->op = SPELLMOD_DOT;
+ mod->value = m_amount;
+ mod->type = SPELLMOD_PCT;
+ mod->spellId = GetId();
+ mod->mask[1] = 0x00002000;
+ m_spellmod = mod;
+ }
+ ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
return;
}
break;
}
case SPELLFAMILY_DRUID:
{
+ switch(GetId())
+ {
+ case 34246: // Idol of the Emerald Queen
+ {
+ if (m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if(apply)
+ {
+ SpellModifier *mod = new SpellModifier;
+ mod->op = SPELLMOD_DOT;
+ mod->value = m_amount/7;
+ mod->type = SPELLMOD_FLAT;
+ mod->spellId = GetId();
+ mod->mask[1] = 0x0010;
+
+ m_spellmod = mod;
+ }
+
+ ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
+ return;
+ }
+ case 61336: // Survival Instincts
+ {
+ if(apply)
+ {
+ if (!m_target->IsInFeralForm())
+ return;
+
+ int32 bp0 = int32(m_target->GetMaxHealth() * m_amount / 100);
+ m_target->CastCustomSpell(m_target, 50322, &bp0, NULL, NULL, true);
+ }
+ else
+ m_target-> RemoveAurasDueToSpell(50322);
+ return;
+ }
+ }
+
// Lifebloom
- if ( GetSpellProto()->SpellFamilyFlags & 0x1000000000LL )
+ if ( GetSpellProto()->SpellFamilyFlags[1] & 0x10 )
{
if ( apply )
{
if ( caster )
// prevent double apply bonuses
if(m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading())
- m_modifier.m_amount = caster->SpellHealingBonus(GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE, m_target);
+ m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_amount, SPELL_DIRECT_DAMAGE);
}
- // Do final heal for real !apply
- else if (Real)
+ else
{
- if (GetAuraDuration() <= 0 || m_removeMode==AURA_REMOVE_BY_DISPEL)
+ // Final heal only on dispelled or duration end
+ if (GetParentAura()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetParentAura()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL)
+ return;
+
+ // Not needed in 3.1
+ if (GetParentAura() && GetParentAura()->GetStackAmount()!=0)
+ m_amount /= GetParentAura()->GetStackAmount();
+
+ // final heal
+ if(m_target->IsInWorld())
+ m_target->CastCustomSpell(m_target,33778,&m_amount,NULL,NULL,true,NULL,this,GetCasterGUID());
+
+ /*// have a look if there is still some other Lifebloom dummy aura
+ Unit::AuraList auras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraList::iterator itr = auras.begin(); itr!=auras.end(); ++itr)
+ if((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID &&
+ (*itr)->GetSpellProto()->SpellFamilyFlags & 0x1000000000LL)
+ return;
+
+ // final heal
+ if(m_target->IsInWorld() && m_stackAmount > 0)
{
- // final heal
- if(m_target->IsInWorld())
- m_target->CastCustomSpell(m_target,33778,&m_modifier.m_amount,NULL,NULL,true,NULL,this,GetCasterGUID());
- }
+ int32 amount = m_amount / m_stackAmount;
+ m_target->CastCustomSpell(m_target,33778,&amount,NULL,NULL,true,NULL,this,GetCasterGUID());
+ }*/
}
return;
}
@@ -2088,20 +2652,22 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
((Player*)m_target)->UpdateAttackPowerAndDamage();
return;
}
- // Idol of the Emerald Queen
- if ( GetId() == 34246 && m_target->GetTypeId()==TYPEID_PLAYER )
+ break;
+ }
+ case SPELLFAMILY_HUNTER:
+ {
+ // Improved Aspect of the Viper
+ if( GetId()==38390 && m_target->GetTypeId()==TYPEID_PLAYER )
{
if(apply)
{
+ // + effect value for Aspect of the Viper
SpellModifier *mod = new SpellModifier;
- mod->op = SPELLMOD_DOT;
- mod->value = m_modifier.m_amount/7;
+ mod->op = SPELLMOD_EFFECT1;
+ mod->value = m_amount;
mod->type = SPELLMOD_FLAT;
mod->spellId = GetId();
- mod->effectId = m_effIndex;
- mod->lastAffected = NULL;
- mod->mask = 0x001000000000LL;
- mod->charges = 0;
+ mod->mask[1] = 0x40000;
m_spellmod = mod;
}
@@ -2109,29 +2675,22 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
((Player*)m_target)->AddSpellMod(m_spellmod, apply);
return;
}
- break;
- }
- case SPELLFAMILY_HUNTER:
- {
- // Improved Aspect of the Viper
- if( GetId()==38390 && m_target->GetTypeId()==TYPEID_PLAYER )
+ // Glyph of Aspect of the Monkey
+ if(m_spellProto->Id==56833)
{
if(apply)
{
- // + effect value for Aspect of the Viper
+ // Reduce backfire damage (dot damage) from Shadow Word: Death
SpellModifier *mod = new SpellModifier;
- mod->op = SPELLMOD_EFFECT1;
- mod->value = m_modifier.m_amount;
+ mod->op = SPELLMOD_CHANCE_OF_SUCCESS;
+ mod->value = 100;
mod->type = SPELLMOD_FLAT;
mod->spellId = GetId();
- mod->effectId = m_effIndex;
- mod->lastAffected = NULL;
- mod->mask = 0x4000000000000LL;
- mod->charges = 0;
-
+ mod->mask[2] = 8192;
+ mod->mask[1] = 0x00000000;
+ mod->mask[0] = 524288;
m_spellmod = mod;
}
-
((Player*)m_target)->AddSpellMod(m_spellmod, apply);
return;
}
@@ -2146,21 +2705,18 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
{
SpellModifier *mod = new SpellModifier;
mod->op = SPELLMOD_EFFECT1;
- mod->value = m_modifier.m_amount;
+ mod->value = m_amount;
mod->type = SPELLMOD_PCT;
mod->spellId = GetId();
- mod->effectId = m_effIndex;
- mod->lastAffected = NULL;
switch (m_effIndex)
{
case 0:
- mod->mask = 0x00200000000LL; // Windfury Totem
+ mod->mask[1] = 0x002; // Windfury Totem
break;
case 1:
- mod->mask = 0x00400000000LL; // Flametongue Totem
+ mod->mask[1] = 0x004; // Flametongue Totem
break;
}
- mod->charges = 0;
m_spellmod = mod;
}
@@ -2174,10 +2730,10 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
{
if (apply)
{
- uint64 guid = caster->m_TotemSlot[3];
+ uint64 guid = caster->m_SummonSlot[3];
if (guid)
{
- Creature *totem = ObjectAccessor::GetCreature(*caster, guid);
+ Creature *totem = caster->GetMap()->GetCreature(guid);
if (totem && totem->isTotem())
((Player*)caster)->CastSpell(totem, 6277, true);
}
@@ -2199,45 +2755,32 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
m_target->RemovePetAura(petSpell);
return;
}
-}
-
-void Aura::HandleAuraPeriodicDummy(bool apply, bool Real)
-{
- // spells required only Real aura add/remove
- if(!Real)
- return;
- SpellEntry const*spell = GetSpellProto();
- switch( spell->SpellFamilyName)
+ if(GetEffIndex()==0 && m_target->GetTypeId()==TYPEID_PLAYER)
{
- case SPELLFAMILY_ROGUE:
+ SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAuraMapBounds(GetId());
+ if(saBounds.first != saBounds.second)
{
- // Master of Subtlety
- if (spell->Id==31666 && !apply && Real)
- {
- m_target->RemoveAurasDueToSpell(31665);
- break;
- }
- break;
- }
- case SPELLFAMILY_HUNTER:
- {
- // Aspect of the Viper
- if (spell->SpellFamilyFlags&0x0004000000000000LL)
+ uint32 zone, area;
+ m_target->GetZoneAndAreaId(zone,area);
+
+ for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
{
- // Update regen on remove
- if (!apply && m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->UpdateManaRegen();
- break;
+ // some auras remove at aura remove
+ if(!itr->second->IsFitToRequirements((Player*)m_target,zone,area))
+ m_target->RemoveAurasDueToSpell(itr->second->spellId);
+ // some auras applied at aura apply
+ else if(itr->second->autocast)
+ {
+ if( !m_target->HasAuraEffect(itr->second->spellId,0) )
+ m_target->CastSpell(m_target,itr->second->spellId,true);
+ }
}
- break;
}
}
-
- m_isPeriodic = apply;
}
-void Aura::HandleAuraMounted(bool apply, bool Real)
+void AuraEffect::HandleAuraMounted(bool apply, bool Real)
{
// only at real add/remove aura
if(!Real)
@@ -2245,10 +2788,10 @@ void Aura::HandleAuraMounted(bool apply, bool Real)
if(apply)
{
- CreatureInfo const* ci = objmgr.GetCreatureTemplate(m_modifier.m_miscvalue);
+ CreatureInfo const* ci = objmgr.GetCreatureTemplate(GetMiscValue());
if(!ci)
{
- sLog.outErrorDb("AuraMounted: `creature_template`='%u' not found in database (only need it modelid)", m_modifier.m_miscvalue);
+ sLog.outErrorDb("AuraMounted: `creature_template`='%u' not found in database (only need it modelid)",GetMiscValue());
return;
}
@@ -2261,6 +2804,11 @@ void Aura::HandleAuraMounted(bool apply, bool Real)
if (minfo)
display_id = minfo->modelid;
+ //some spell has one aura of mount and one of vehicle
+ for(uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ if(GetSpellProto()->Effect[i] == SPELL_EFFECT_SUMMON
+ && GetSpellProto()->EffectMiscValue[i] == GetMiscValue())
+ display_id = 0;
m_target->Mount(display_id);
}
else
@@ -2269,7 +2817,7 @@ void Aura::HandleAuraMounted(bool apply, bool Real)
}
}
-void Aura::HandleAuraWaterWalk(bool apply, bool Real)
+void AuraEffect::HandleAuraWaterWalk(bool apply, bool Real)
{
// only at real add/remove aura
if(!Real)
@@ -2285,7 +2833,7 @@ void Aura::HandleAuraWaterWalk(bool apply, bool Real)
m_target->SendMessageToSet(&data,true);
}
-void Aura::HandleAuraFeatherFall(bool apply, bool Real)
+void AuraEffect::HandleAuraFeatherFall(bool apply, bool Real)
{
// only at real add/remove aura
if(!Real)
@@ -2301,7 +2849,7 @@ void Aura::HandleAuraFeatherFall(bool apply, bool Real)
m_target->SendMessageToSet(&data,true);
}
-void Aura::HandleAuraHover(bool apply, bool Real)
+void AuraEffect::HandleAuraHover(bool apply, bool Real)
{
// only at real add/remove aura
if(!Real)
@@ -2317,31 +2865,21 @@ void Aura::HandleAuraHover(bool apply, bool Real)
m_target->SendMessageToSet(&data,true);
}
-void Aura::HandleWaterBreathing(bool apply, bool Real)
+void AuraEffect::HandleWaterBreathing(bool apply, bool Real)
{
- if(apply)
- m_target->waterbreath = true;
- else if(m_target->GetAurasByType(SPELL_AURA_WATER_BREATHING).empty())
- {
- m_target->waterbreath = false;
-
- // update for enable timer in case not moving target
- if(m_target->GetTypeId()==TYPEID_PLAYER && m_target->IsInWorld())
- {
- ((Player*)m_target)->UpdateUnderwaterState(m_target->GetMap(),m_target->GetPositionX(),m_target->GetPositionY(),m_target->GetPositionZ());
- ((Player*)m_target)->HandleDrowning();
- }
- }
+ // update timers in client
+ if(m_target->GetTypeId()==TYPEID_PLAYER)
+ ((Player*)m_target)->UpdateMirrorTimers();
}
-void Aura::HandleAuraModShapeshift(bool apply, bool Real)
+void AuraEffect::HandleAuraModShapeshift(bool apply, bool Real)
{
if(!Real)
return;
uint32 modelid = 0;
Powers PowerType = POWER_MANA;
- ShapeshiftForm form = ShapeshiftForm(m_modifier.m_miscvalue);
+ ShapeshiftForm form = ShapeshiftForm(GetMiscValue());
switch(form)
{
case FORM_CAT:
@@ -2402,6 +2940,9 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
else
modelid = 21244;
break;
+ case FORM_METAMORPHOSIS:
+ modelid = 25277;
+ break;
case FORM_AMBIENT:
case FORM_SHADOW:
case FORM_STEALTH:
@@ -2418,7 +2959,7 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
modelid = 16031;
break;
default:
- sLog.outError("Auras: Unknown Shapeshift Type: %u", m_modifier.m_miscvalue);
+ sLog.outError("Auras: Unknown Shapeshift Type: %u", GetMiscValue());
}
// remove polymorph before changing display id to keep new display id
@@ -2434,8 +2975,8 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
case FORM_FLIGHT:
case FORM_MOONKIN:
// remove movement affects
- m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT);
- m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_DECREASE_SPEED);
+ m_target->RemoveAurasByType(SPELL_AURA_MOD_ROOT);
+ m_target->RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
// and polymorphic affects
if(m_target->IsPolymorphed())
@@ -2449,7 +2990,7 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
{
// remove other shapeshift before applying a new one
if(m_target->m_ShapeShiftFormSpellId)
- m_target->RemoveAurasDueToSpell(m_target->m_ShapeShiftFormSpellId,this);
+ m_target->RemoveAurasDueToSpell(m_target->m_ShapeShiftFormSpellId);
m_target->SetByteValue(UNIT_FIELD_BYTES_2, 3, form);
@@ -2469,22 +3010,22 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
case FORM_DIREBEAR:
{
// get furor proc chance
- uint32 FurorChance = 0;
- Unit::AuraList const& mDummy = m_target->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator i = mDummy.begin(); i != mDummy.end(); ++i)
+ int32 FurorChance = 0;
+ Unit::AuraEffectList const& mDummy = m_target->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraEffectList::const_iterator i = mDummy.begin(); i != mDummy.end(); ++i)
{
if ((*i)->GetSpellProto()->SpellIconID == 238)
{
- FurorChance = (*i)->GetModifier()->m_amount;
+ FurorChance = (*i)->GetAmount();
break;
}
}
- if (m_modifier.m_miscvalue == FORM_CAT)
+ if (GetMiscValue() == FORM_CAT)
{
m_target->SetPower(POWER_ENERGY,0);
if(urand(1,100) <= FurorChance)
- m_target->CastSpell(m_target,17099,true,NULL,this);
+ m_target->CastCustomSpell(m_target,17099,&FurorChance, NULL, NULL,true,NULL,this);
}
else
{
@@ -2540,18 +3081,16 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
case FORM_BEAR:
case FORM_DIREBEAR:
case FORM_CAT:
- {
- if(Aura* dummy = m_target->GetDummyAura(37315) )
+ if(AuraEffect* dummy = m_target->GetDummyAura(37315) )
m_target->CastSpell(m_target,37316,true,NULL,dummy);
break;
- }
// Nordrassil Regalia - bonus
case FORM_MOONKIN:
- {
- if(Aura* dummy = m_target->GetDummyAura(37324) )
+ if(AuraEffect* dummy = m_target->GetDummyAura(37324) )
m_target->CastSpell(m_target,37325,true,NULL,dummy);
break;
- }
+ default:
+ break;
}
}
@@ -2561,20 +3100,34 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
if(m_target->GetTypeId()==TYPEID_PLAYER)
((Player*)m_target)->InitDataForForm();
+
+ if(m_target->getClass() == CLASS_DRUID)
+ {
+ if(form == FORM_CAT && apply) // add dash if in cat-from
+ {
+ if(AuraEffect * aurEff =m_target->GetAura(SPELL_AURA_MOD_INCREASE_SPEED, SPELLFAMILY_DRUID, 0, 0, 0x8))
+ m_target->HandleAuraEffect(aurEff, true);
+ }
+ else // remove dash effect(not buff) if out of cat-from
+ {
+ if(AuraEffect * aurEff =m_target->GetAura(SPELL_AURA_MOD_INCREASE_SPEED, SPELLFAMILY_DRUID, 0, 0, 0x8))
+ m_target->HandleAuraEffect(aurEff, false);
+ }
+ }
}
-void Aura::HandleAuraTransform(bool apply, bool Real)
+void AuraEffect::HandleAuraTransform(bool apply, bool Real)
{
if (apply)
{
// special case (spell specific functionality)
- if(m_modifier.m_miscvalue==0)
+ if(GetMiscValue()==0)
{
// player applied only
- if(m_target->GetTypeId()!=TYPEID_PLAYER)
+ if (m_target->GetTypeId()!=TYPEID_PLAYER)
return;
- switch(GetId())
+ switch (GetId())
{
// Orb of Deception
case 16739:
@@ -2633,12 +3186,12 @@ void Aura::HandleAuraTransform(bool apply, bool Real)
}
else
{
- CreatureInfo const * ci = objmgr.GetCreatureTemplate(m_modifier.m_miscvalue);
+ CreatureInfo const * ci = objmgr.GetCreatureTemplate(GetMiscValue());
if(!ci)
{
//pig pink ^_^
m_target->SetDisplayId(16358);
- sLog.outError("Auras: unknown creature id = %d (only need its modelid) Form Spell Aura Transform in Spell ID = %d", m_modifier.m_miscvalue, GetId());
+ sLog.outError("Auras: unknown creature id = %d (only need its modelid) Form Spell Aura Transform in Spell ID = %d", GetMiscValue(), GetId());
}
else
{
@@ -2650,38 +3203,41 @@ void Aura::HandleAuraTransform(bool apply, bool Real)
if(GetId()==42016 && m_target->GetMountID() && !m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED).empty())
m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314);
}
- m_target->setTransForm(GetId());
}
+ // update active transform spell only not set or not overwriting negative by positive case
+ if (!m_target->getTransForm() || !IsPositiveSpell(GetId()) || IsPositiveSpell(m_target->getTransForm()))
+ m_target->setTransForm(GetId());
+
// polymorph case
- if( Real && m_target->GetTypeId() == TYPEID_PLAYER && m_target->IsPolymorphed())
+ if (Real && m_target->GetTypeId() == TYPEID_PLAYER && m_target->IsPolymorphed())
{
// for players, start regeneration after 1s (in polymorph fast regeneration case)
// only if caster is Player (after patch 2.4.2)
- if(IS_PLAYER_GUID(GetCasterGUID()) )
- ((Player*)m_target)->setRegenTimer(1000);
+ if (IS_PLAYER_GUID(GetCasterGUID()) )
+ ((Player*)m_target)->setRegenTimer(1*IN_MILISECONDS);
//dismount polymorphed target (after patch 2.4.2)
if (m_target->IsMounted())
- m_target->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+ m_target->RemoveAurasByType(SPELL_AURA_MOUNTED);
}
}
else
{
- Unit::AuraList const& otherTransforms = m_target->GetAurasByType(SPELL_AURA_TRANSFORM);
- if(otherTransforms.empty())
- {
- m_target->SetDisplayId(m_target->GetNativeDisplayId());
- m_target->setTransForm(0);
- }
- else
+ // ApplyModifier(true) will reapply it if need
+ m_target->setTransForm(0);
+ m_target->SetDisplayId(m_target->GetNativeDisplayId());
+
+ // re-aplly some from still active with preference negative cases
+ Unit::AuraEffectList const& otherTransforms = m_target->GetAurasByType(SPELL_AURA_TRANSFORM);
+ if (!otherTransforms.empty())
{
// look for other transform auras
- Aura* handledAura = *otherTransforms.begin();
- for(Unit::AuraList::const_iterator i = otherTransforms.begin();i != otherTransforms.end(); ++i)
+ AuraEffect* handledAura = *otherTransforms.begin();
+ for(Unit::AuraEffectList::const_iterator i = otherTransforms.begin();i != otherTransforms.end(); ++i)
{
// negative auras are preferred
- if(!IsPositiveSpell((*i)->GetSpellProto()->Id))
+ if (!IsPositiveSpell((*i)->GetSpellProto()->Id))
{
handledAura = *i;
break;
@@ -2691,11 +3247,11 @@ void Aura::HandleAuraTransform(bool apply, bool Real)
}
// Dragonmaw Illusion (restore mount model)
- if(GetId()==42016 && m_target->GetMountID()==16314)
+ if (GetId()==42016 && m_target->GetMountID()==16314)
{
- if(!m_target->GetAurasByType(SPELL_AURA_MOUNTED).empty())
+ if (!m_target->GetAurasByType(SPELL_AURA_MOUNTED).empty())
{
- uint32 cr_id = m_target->GetAurasByType(SPELL_AURA_MOUNTED).front()->GetModifier()->m_miscvalue;
+ uint32 cr_id = m_target->GetAurasByType(SPELL_AURA_MOUNTED).front()->GetMiscValue();
if(CreatureInfo const* ci = objmgr.GetCreatureTemplate(cr_id))
{
uint32 team = 0;
@@ -2714,7 +3270,7 @@ void Aura::HandleAuraTransform(bool apply, bool Real)
}
}
-void Aura::HandleForceReaction(bool apply, bool Real)
+void AuraEffect::HandleForceReaction(bool apply, bool Real)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -2724,44 +3280,32 @@ void Aura::HandleForceReaction(bool apply, bool Real)
Player* player = (Player*)m_target;
- uint32 faction_id = m_modifier.m_miscvalue;
- uint32 faction_rank = m_modifier.m_amount;
+ uint32 faction_id = GetMiscValue();
+ uint32 faction_rank = m_amount;
- if(apply)
- player->m_forcedReactions[faction_id] = ReputationRank(faction_rank);
- else
- player->m_forcedReactions.erase(faction_id);
-
- WorldPacket data;
- data.Initialize(SMSG_SET_FORCED_REACTIONS, 4+player->m_forcedReactions.size()*(4+4));
- data << uint32(player->m_forcedReactions.size());
- for(ForcedReactions::const_iterator itr = player->m_forcedReactions.begin(); itr != player->m_forcedReactions.end(); ++itr)
- {
- data << uint32(itr->first); // faction_id (Faction.dbc)
- data << uint32(itr->second); // reputation rank
- }
- player->SendDirectMessage(&data);
+ player->GetReputationMgr().ApplyForceReaction(faction_id,ReputationRank(faction_rank),apply);
+ player->GetReputationMgr().SendForceReactions();
}
-void Aura::HandleAuraModSkill(bool apply, bool Real)
+void AuraEffect::HandleAuraModSkill(bool apply, bool Real)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
uint32 prot=GetSpellProto()->EffectMiscValue[m_effIndex];
- int32 points = GetModifierValue();
+ int32 points = m_amount;
- ((Player*)m_target)->ModifySkillBonus(prot,(apply ? points: -points),m_modifier.m_auraname==SPELL_AURA_MOD_SKILL_TALENT);
+ ((Player*)m_target)->ModifySkillBonus(prot,(apply ? points: -points),m_auraName==SPELL_AURA_MOD_SKILL_TALENT);
if(prot == SKILL_DEFENSE)
((Player*)m_target)->UpdateDefenseBonusesMod();
}
-void Aura::HandleChannelDeathItem(bool apply, bool Real)
+void AuraEffect::HandleChannelDeathItem(bool apply, bool Real)
{
if(Real && !apply)
{
Unit* caster = GetCaster();
- Unit* victim = GetTarget();
+ Unit* victim = m_target;
if(!caster || caster->GetTypeId() != TYPEID_PLAYER || !victim)// || m_removeMode!=AURA_REMOVE_BY_DEATH)
return;
@@ -2769,6 +3313,9 @@ void Aura::HandleChannelDeathItem(bool apply, bool Real)
//talent will remove the caster's aura->interrupt channel->remove victim aura
if(victim->GetHealth() > 0)
return;
+ // Item amount
+ if (m_amount <= 0)
+ return;
SpellEntry const *spellInfo = GetSpellProto();
if(spellInfo->EffectItemType[m_effIndex] == 0)
@@ -2779,100 +3326,156 @@ void Aura::HandleChannelDeathItem(bool apply, bool Real)
(victim->getLevel() <= Trinity::XP::GetGrayLevel(caster->getLevel()) ||
victim->GetTypeId()==TYPEID_UNIT && !((Player*)caster)->isAllowedToLoot((Creature*)victim)) )
return;
+ //Adding items
+ uint32 noSpaceForCount = 0;
+ uint32 count = m_amount;
+
ItemPosCountVec dest;
- uint8 msg = ((Player*)caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], 1 );
+ uint8 msg = ((Player*)caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], count, &noSpaceForCount);
if( msg != EQUIP_ERR_OK )
{
+ count-=noSpaceForCount;
((Player*)caster)->SendEquipError( msg, NULL, NULL );
- return;
+ if (count==0)
+ return;
}
Item* newitem = ((Player*)caster)->StoreNewItem(dest, spellInfo->EffectItemType[m_effIndex], true);
- ((Player*)caster)->SendNewItem(newitem, 1, true, false);
+ ((Player*)caster)->SendNewItem(newitem, count, true, false);
}
}
-void Aura::HandleBindSight(bool apply, bool Real)
+void AuraEffect::HandleBindSight(bool apply, bool Real)
{
Unit* caster = GetCaster();
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
return;
- if (apply)
- m_target->AddPlayerToVision((Player*)caster);
- else
- m_target->RemovePlayerFromVision((Player*)caster);
+ ((Player*)caster)->SetViewpoint(m_target, apply);
}
-void Aura::HandleFarSight(bool apply, bool Real)
+void AuraEffect::HandleFarSight(bool apply, bool Real)
{
- Unit* caster = GetCaster();
- if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
- return;
-
- ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL);
+ //Handled by client
}
-void Aura::HandleAuraTrackCreatures(bool apply, bool Real)
+void AuraEffect::HandleAuraTrackCreatures(bool apply, bool Real)
{
if(m_target->GetTypeId()!=TYPEID_PLAYER)
return;
- if(apply)
- m_target->RemoveNoStackAurasDueToAura(this);
- m_target->SetUInt32Value(PLAYER_TRACK_CREATURES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1) : 0 );
+ m_target->SetUInt32Value(PLAYER_TRACK_CREATURES, apply ? ((uint32)1)<<(GetMiscValue()-1) : 0 );
}
-void Aura::HandleAuraTrackResources(bool apply, bool Real)
+void AuraEffect::HandleAuraTrackResources(bool apply, bool Real)
{
if(m_target->GetTypeId()!=TYPEID_PLAYER)
return;
- if(apply)
- m_target->RemoveNoStackAurasDueToAura(this);
- m_target->SetUInt32Value(PLAYER_TRACK_RESOURCES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1): 0 );
+ m_target->SetUInt32Value(PLAYER_TRACK_RESOURCES, apply ? ((uint32)1)<<(GetMiscValue()-1): 0 );
}
-void Aura::HandleAuraTrackStealthed(bool apply, bool Real)
+void AuraEffect::HandleAuraTrackStealthed(bool apply, bool Real)
{
if(m_target->GetTypeId()!=TYPEID_PLAYER)
return;
- if(apply)
- m_target->RemoveNoStackAurasDueToAura(this);
-
m_target->ApplyModFlag(PLAYER_FIELD_BYTES,PLAYER_FIELD_BYTE_TRACK_STEALTHED,apply);
}
-void Aura::HandleAuraModScale(bool apply, bool Real)
+void AuraEffect::HandleAuraModScale(bool apply, bool Real)
{
- m_target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X,GetModifierValue(),apply);
+ m_target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X,m_amount,apply);
}
-void Aura::HandleModPossess(bool apply, bool Real)
+/*void AuraEffect::HandleModPossess(bool apply, bool Real)
{
if(!Real)
return;
+ if(m_target->getLevel() > m_amount)
+ return;
+
+ // not possess yourself
+ if(GetCasterGUID() == m_target->GetGUID())
+ return;
+
Unit* caster = GetCaster();
- if(caster && caster->GetTypeId() == TYPEID_UNIT)
- {
- HandleModCharm(apply, Real);
+ if(!caster)
return;
- }
- if(apply)
+ if( apply )
{
- if(m_target->getLevel() > m_modifier.m_amount)
- return;
+ m_target->SetCharmerGUID(GetCasterGUID());
+ m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
- m_target->SetCharmedOrPossessedBy(caster, true);
+ caster->SetCharm(m_target);
+
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)caster)->SetFarSightGUID(m_target->GetGUID());
+ ((Player*)caster)->SetClientControl(m_target, 1);
+ }
+
+ m_target->CombatStop();
+ m_target->DeleteThreatList();
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ m_target->StopMoving();
+ m_target->GetMotionMaster()->Clear();
+ m_target->GetMotionMaster()->MoveIdle();
+ }
+ else if(m_target->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)m_target)->SetClientControl(m_target, 0);
+ }
+
+ if(CharmInfo *charmInfo = m_target->InitCharmInfo(m_target))
+ charmInfo->InitPossessCreateSpells();
+
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)caster)->PossessSpellInitialize();
}
else
- m_target->RemoveCharmedOrPossessedBy(caster);
+ {
+ m_target->SetCharmerGUID(0);
+ caster->InterruptSpell(CURRENT_CHANNELED_SPELL); // the spell is not automatically canceled when interrupted, do it now
+
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)m_target)->setFactionForRace(m_target->getRace());
+ ((Player*)m_target)->SetClientControl(m_target, 1);
+ }
+ else if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
+ m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A);
+ }
+
+ caster->SetCharm(NULL);
+
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)caster)->SetFarSightGUID(0);
+ ((Player*)caster)->SetClientControl(m_target,0);
+
+ WorldPacket data(SMSG_PET_SPELLS, 8+4);
+ data << uint64(0);
+ data << uint32(0);
+ ((Player*)caster)->GetSession()->SendPacket(&data);
+ }
+
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ ((Creature*)m_target)->AIM_Initialize();
+
+ if (((Creature*)m_target)->AI())
+ ((Creature*)m_target)->AI()->AttackedBy(caster);
+ }
+ }
}
-void Aura::HandleModPossessPet(bool apply, bool Real)
+void AuraEffect::HandleModPossessPet(bool apply, bool Real)
{
if(!Real)
return;
@@ -2881,46 +3484,155 @@ void Aura::HandleModPossessPet(bool apply, bool Real)
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
return;
+ Pet *pet = caster->GetGuardianPet();
+ if(!pet || pet != m_target)
+ return;
+
if(apply)
- {
- if(caster->GetPet() != m_target)
- return;
+ pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
+ else
+ pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
- m_target->SetCharmedOrPossessedBy(caster, true);
+ ((Player*)caster)->SetFarSightGUID(apply ? pet->GetGUID() : 0);
+ ((Player*)caster)->SetCharm(apply ? pet : NULL);
+ ((Player*)caster)->SetClientControl(pet, apply ? 1 : 0);
+
+ if(apply)
+ {
+ pet->StopMoving();
+ pet->GetMotionMaster()->Clear();
+ pet->GetMotionMaster()->MoveIdle();
}
else
{
- m_target->RemoveCharmedOrPossessedBy(caster);
-
- // Reinitialize the pet bar and make the pet come back to the owner
- ((Player*)caster)->PetSpellInitialize();
- if(!m_target->getVictim())
- {
- m_target->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
- m_target->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
- }
+ pet->AttackStop();
+ pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ pet->SetUnitMovementFlags(MOVEMENTFLAG_NONE);
}
+}*/
+
+void AuraEffect::HandleAuraModPetTalentsPoints(bool Apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ if(m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ // Recalculate pet tlaent points
+ if (Pet *pet = ((Player*)m_target)->GetPet())
+ pet->InitTalentForLevel();
}
-void Aura::HandleModCharm(bool apply, bool Real)
+/*void AuraEffect::HandleModCharm(bool apply, bool Real)
{
if(!Real)
return;
+ // not charm yourself
+ if(GetCasterGUID() == m_target->GetGUID())
+ return;
+
Unit* caster = GetCaster();
+ if(!caster)
+ return;
- if(apply)
+ if(int32(m_target->getLevel()) <= m_amount)
{
- if(int32(m_target->getLevel()) > m_modifier.m_amount)
- return;
+ if( apply )
+ {
+ m_target->SetCharmerGUID(GetCasterGUID());
+ m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
+ m_target->CastStop(m_target==caster ? GetId() : 0);
+ caster->SetCharm(m_target);
- m_target->SetCharmedOrPossessedBy(caster, false);
+ m_target->CombatStop();
+ m_target->DeleteThreatList();
+
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ ((Creature*)m_target)->AIM_Initialize();
+ CharmInfo *charmInfo = m_target->InitCharmInfo(m_target);
+ charmInfo->InitCharmCreateSpells();
+ charmInfo->SetReactState( REACT_DEFENSIVE );
+
+ if(caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK)
+ {
+ CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
+ if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
+ {
+ //to prevent client crash
+ m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048);
+ //just to enable stat window
+ charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true);
+ //if charmed two demons the same session, the 2nd gets the 1st one's name
+ m_target->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
+ }
+ }
+ }
+
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)caster)->CharmSpellInitialize();
+ }
+ }
+ else
+ {
+ m_target->SetCharmerGUID(0);
+
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)m_target)->setFactionForRace(m_target->getRace());
+ else
+ {
+ CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
+
+ // restore faction
+ if(((Creature*)m_target)->isPet())
+ {
+ if(Unit* owner = m_target->GetOwner())
+ m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,owner->getFaction());
+ else if(cinfo)
+ m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A);
+ }
+ else if(cinfo) // normal creature
+ m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A);
+
+ // restore UNIT_FIELD_BYTES_0
+ if(cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON)
+ {
+ CreatureDataAddon const *cainfo = ((Creature*)m_target)->GetCreatureAddon();
+ if(cainfo && cainfo->bytes0 != 0)
+ m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0);
+ else
+ m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048);
+
+ if(m_target->GetCharmInfo())
+ m_target->GetCharmInfo()->SetPetNumber(0, true);
+ else
+ sLog.outError("AuraEffect::HandleModCharm: target="I64FMTD" with typeid=%d has a charm aura but no charm info!", m_target->GetGUID(), m_target->GetTypeId());
+ }
+ }
+
+ caster->SetCharm(NULL);
+
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ WorldPacket data(SMSG_PET_SPELLS, 8+4);
+ data << uint64(0);
+ data << uint32(0);
+ ((Player*)caster)->GetSession()->SendPacket(&data);
+ }
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ ((Creature*)m_target)->AIM_Initialize();
+ if (((Creature*)m_target)->AI())
+ ((Creature*)m_target)->AI()->AttackedBy(caster);
+ }
+ }
}
- else
- m_target->RemoveCharmedOrPossessedBy(caster);
-}
+}*/
-void Aura::HandleModConfuse(bool apply, bool Real)
+void AuraEffect::HandleModConfuse(bool apply, bool Real)
{
if(!Real)
return;
@@ -2929,7 +3641,7 @@ void Aura::HandleModConfuse(bool apply, bool Real)
m_target->SetControlled(apply, UNIT_STAT_CONFUSED);
}
-void Aura::HandleModFear(bool apply, bool Real)
+void AuraEffect::HandleModFear(bool apply, bool Real)
{
if (!Real)
return;
@@ -2938,7 +3650,7 @@ void Aura::HandleModFear(bool apply, bool Real)
m_target->SetControlled(apply, UNIT_STAT_FLEEING);
}
-void Aura::HandleFeignDeath(bool apply, bool Real)
+void AuraEffect::HandleFeignDeath(bool apply, bool Real)
{
if(!Real)
return;
@@ -2957,7 +3669,7 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
std::list<Unit*> targets;
Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_target, m_target, World::GetMaxVisibleDistance());
- Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(targets, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(m_target, targets, u_check);
m_target->VisitNearbyObject(World::GetMaxVisibleDistance(), searcher);
for(std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter)
{
@@ -2974,7 +3686,7 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
}
}
// blizz like 2.0.x
- m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN6);
+ m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
// blizz like 2.0.x
m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
// blizz like 2.0.x
@@ -2982,10 +3694,10 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
m_target->addUnitState(UNIT_STAT_DIED);
m_target->CombatStop();
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
+ m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
// prevent interrupt message
- if(m_caster_guid==m_target->GetGUID() && m_target->m_currentSpells[CURRENT_GENERIC_SPELL])
+ if(GetCasterGUID()==m_target->GetGUID() && m_target->m_currentSpells[CURRENT_GENERIC_SPELL])
m_target->m_currentSpells[CURRENT_GENERIC_SPELL]->finish();
m_target->InterruptNonMeleeSpells(true);
m_target->getHostilRefManager().deleteReferences();
@@ -2999,7 +3711,7 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
m_target->SendMessageToSet(&data,true);
*/
// blizz like 2.0.x
- m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN6);
+ m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
// blizz like 2.0.x
m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
// blizz like 2.0.x
@@ -3009,221 +3721,142 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
}
}
-void Aura::HandleAuraModDisarm(bool apply, bool Real)
+void AuraEffect::HandleAuraModDisarm(bool apply, bool Real)
{
- if(!Real)
+ if (!Real)
return;
+ AuraType type = AuraType(GetAuraName());
- if(!apply && m_target->HasAuraType(SPELL_AURA_MOD_DISARM))
+ //Prevent handling aura twice
+ if(apply && m_target->GetAurasByType(type).size()>1)
return;
-
- // not sure for it's correctness
+ if(!apply && m_target->HasAuraType(type))
+ return;
+ uint32 field, flag, slot;
+ WeaponAttackType attType;
+ switch (type)
+ {
+ case SPELL_AURA_MOD_DISARM:
+ field=UNIT_FIELD_FLAGS;
+ flag=UNIT_FLAG_DISARMED;
+ slot=EQUIPMENT_SLOT_MAINHAND;
+ attType=BASE_ATTACK;
+ break;
+ case SPELL_AURA_MOD_DISARM_OFFHAND:
+ field=UNIT_FIELD_FLAGS_2;
+ flag=UNIT_FLAG2_DISARM_OFFHAND;
+ slot=EQUIPMENT_SLOT_OFFHAND;
+ attType=OFF_ATTACK;
+ break;
+ case SPELL_AURA_MOD_DISARM_RANGED:
+ field=UNIT_FIELD_FLAGS_2;
+ flag=UNIT_FLAG2_DISARM_RANGED;
+ slot=EQUIPMENT_SLOT_RANGED;
+ attType=RANGED_ATTACK;
+ break;
+ }
if(apply)
- m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
+ m_target->SetFlag(field, flag);
else
- m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
+ m_target->RemoveFlag(field, flag);
if (m_target->GetTypeId() == TYPEID_PLAYER)
{
- // main-hand attack speed already set to special value for feral form already and don't must change and reset at remove.
- if (((Player *)m_target)->IsInFeralForm())
+ Item *pItem = ((Player*)m_target)->GetItemByPos( INVENTORY_SLOT_BAG_0, slot );
+ if(!pItem )
return;
-
- if (apply)
- m_target->SetAttackTime(BASE_ATTACK,BASE_ATTACK_TIME);
- else
- ((Player *)m_target)->SetRegularAttackTime();
+ ((Player*)m_target)->_ApplyItemMods(pItem, slot, !apply);
}
- else
- {
- // creature does not have equipment
- if(apply && !((Creature*)m_target)->GetCurrentEquipmentId())
- return;
- }
-
- m_target->UpdateDamagePhysical(BASE_ATTACK);
+ else if (((Creature*)m_target)->GetCurrentEquipmentId())
+ m_target->UpdateDamagePhysical(attType);
}
-void Aura::HandleAuraModStun(bool apply, bool Real)
+void AuraEffect::HandleModStealth(bool apply, bool Real)
{
if(!Real)
return;
- m_target->SetControlled(apply, UNIT_STAT_STUNNED);
-}
-
-void Aura::HandleModStealth(bool apply, bool Real)
-{
if(apply)
{
- if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
- {
- // drop flag at stealth in bg
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
-
- // remove player from the objective's active player count at stealth
- if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP())
- pvp->HandlePlayerActivityChanged((Player*)m_target);
- }
-
- // only at real aura add
- if(Real)
- {
- m_target->SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x02);
- if(m_target->GetTypeId()==TYPEID_PLAYER)
- m_target->SetFlag(PLAYER_FIELD_BYTES2, 0x2000);
+ // drop flag at stealth in bg
+ m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
- // apply only if not in GM invisibility (and overwrite invisibility state)
- if(m_target->GetVisibility()!=VISIBILITY_OFF)
- {
- //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
- //m_target->SetVisibility(VISIBILITY_OFF);
- m_target->SetVisibility(VISIBILITY_GROUP_STEALTH);
- }
+ m_target->SetStandFlags(UNIT_STAND_FLAGS_CREEP);
+ if(m_target->GetTypeId()==TYPEID_PLAYER)
+ m_target->SetFlag(PLAYER_FIELD_BYTES2, 0x2000);
- // for RACE_NIGHTELF stealth
- if(m_target->GetTypeId()==TYPEID_PLAYER && GetId()==20580)
- m_target->CastSpell(m_target, 21009, true, NULL, this);
- }
+ // apply only if not in GM invisibility (and overwrite invisibility state)
+ if(m_target->GetVisibility() != VISIBILITY_OFF)
+ m_target->SetVisibility(VISIBILITY_GROUP_STEALTH);
}
- else
+ else if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH)) // if last SPELL_AURA_MOD_STEALTH
{
- // only at real aura remove
- if(Real)
- {
- // for RACE_NIGHTELF stealth
- if(m_target->GetTypeId()==TYPEID_PLAYER && GetId()==20580)
- m_target->RemoveAurasDueToSpell(21009);
-
- // if last SPELL_AURA_MOD_STEALTH and no GM invisibility
- if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH) && m_target->GetVisibility()!=VISIBILITY_OFF)
- {
- m_target->SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x00);
- if(m_target->GetTypeId()==TYPEID_PLAYER)
- m_target->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000);
-
- // restore invisibility if any
- if(m_target->HasAuraType(SPELL_AURA_MOD_INVISIBILITY))
- {
- //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
- //m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
- m_target->SetVisibility(VISIBILITY_ON);
- }
- else
- {
- m_target->SetVisibility(VISIBILITY_ON);
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP())
- pvp->HandlePlayerActivityChanged((Player*)m_target);
- }
- }
- }
- }
+ m_target->RemoveStandFlags(UNIT_STAND_FLAGS_CREEP);
+ if(m_target->GetTypeId()==TYPEID_PLAYER)
+ m_target->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000);
- // Master of Subtlety
- Unit::AuraList const& mDummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
- {
- if ((*i)->GetSpellProto()->SpellIconID == 2114 && Real)
- {
- if (apply)
- {
- int32 bp = (*i)->GetModifier()->m_amount;
- m_target->CastCustomSpell(m_target,31665,&bp,NULL,NULL,true);
- }
- else
- m_target->CastSpell(m_target,31666,true);
- break;
- }
+ if(m_target->GetVisibility() != VISIBILITY_OFF)
+ m_target->SetVisibility(VISIBILITY_ON);
}
}
-void Aura::HandleInvisibility(bool apply, bool Real)
+void AuraEffect::HandleInvisibility(bool apply, bool Real)
{
if(apply)
{
- m_target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue);
-
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
+ m_target->m_invisibilityMask |= (1 << GetMiscValue());
- if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
+ if(Real)
{
+ m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
+
// apply glow vision
- m_target->SetFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
- // remove player from the objective's active player count at invisibility
- if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP())
- pvp->HandlePlayerActivityChanged((Player*)m_target);
- }
+ if(m_target->GetTypeId()==TYPEID_PLAYER)
+ m_target->SetFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
- // apply only if not in GM invisibility and not stealth
- if(m_target->GetVisibility()==VISIBILITY_ON)
- {
- // Aura not added yet but visibility code expect temporary add aura
- //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
- //m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
- m_target->SetVisibility(VISIBILITY_ON);
+ m_target->SetToNotify();
}
}
else
{
// recalculate value at modifier remove (current aura already removed)
m_target->m_invisibilityMask = 0;
- Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY);
- for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
- m_target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue);
+ Unit::AuraEffectList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY);
+ for(Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+ m_target->m_invisibilityMask |= (1 << GetMiscValue());
// only at real aura remove and if not have different invisibility auras.
- if(Real && m_target->m_invisibilityMask==0)
+ if(Real)
{
// remove glow vision
- if(m_target->GetTypeId() == TYPEID_PLAYER)
+ if(!m_target->m_invisibilityMask && m_target->GetTypeId() == TYPEID_PLAYER)
m_target->RemoveFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
- // apply only if not in GM invisibility & not stealthed while invisible
- if(m_target->GetVisibility()!=VISIBILITY_OFF)
- {
- // if have stealth aura then already have stealth visibility
- if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH))
- {
- m_target->SetVisibility(VISIBILITY_ON);
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP())
- pvp->HandlePlayerActivityChanged((Player*)m_target);
- }
- }
+ m_target->SetToNotify();
}
}
}
-void Aura::HandleInvisibilityDetect(bool apply, bool Real)
+void AuraEffect::HandleInvisibilityDetect(bool apply, bool Real)
{
if(apply)
{
- m_target->m_detectInvisibilityMask |= (1 << m_modifier.m_miscvalue);
+ m_target->m_detectInvisibilityMask |= (1 << GetMiscValue());
}
else
{
// recalculate value at modifier remove (current aura already removed)
m_target->m_detectInvisibilityMask = 0;
- Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION);
- for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
- m_target->m_detectInvisibilityMask |= (1 << m_modifier.m_miscvalue);
+ Unit::AuraEffectList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION);
+ for(Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+ m_target->m_detectInvisibilityMask |= (1 << GetMiscValue());
}
if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
//ObjectAccessor::UpdateVisibilityForPlayer((Player*)m_target);
m_target->SetToNotify();
}
-void Aura::HandleAuraModRoot(bool apply, bool Real)
-{
- // only at real add/remove aura
- if(!Real)
- return;
-
- m_target->SetControlled(apply, UNIT_STAT_ROOT);
-}
-
-void Aura::HandleAuraModSilence(bool apply, bool Real)
+void AuraEffect::HandleAuraModSilence(bool apply, bool Real)
{
// only at real add/remove aura
if(!Real)
@@ -3234,18 +3867,8 @@ void Aura::HandleAuraModSilence(bool apply, bool Real)
m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED);
// Stop cast only spells vs PreventionType == SPELL_PREVENTION_TYPE_SILENCE
for (uint32 i = CURRENT_MELEE_SPELL; i < CURRENT_MAX_SPELL;i++)
- {
- Spell* currentSpell = m_target->m_currentSpells[i];
- if (currentSpell && currentSpell->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
- {
- uint32 state = currentSpell->getState();
- // Stop spells on prepare or casting state
- if ( state == SPELL_STATE_PREPARING || state == SPELL_STATE_CASTING )
- {
- currentSpell->cancel();
- }
- }
- }
+ if (m_target->m_currentSpells[i] && m_target->m_currentSpells[i]->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
+ m_target->InterruptSpell(i,false); // Stop spells on prepare or casting state
switch (GetId())
{
@@ -3257,10 +3880,10 @@ void Aura::HandleAuraModSilence(bool apply, bool Real)
return;
// Search Mana Tap auras on caster
- Aura * dummy = m_target->GetDummyAura(28734);
+ AuraEffect * dummy = caster->GetDummyAura(28734);
if (dummy)
{
- int32 bp = dummy->GetStackAmount() * 10;
+ int32 bp = dummy->GetParentAura()->GetStackAmount() * 10;
caster->CastCustomSpell(caster, 25048, &bp, NULL, NULL, true);
m_target->RemoveAurasDueToSpell(28734);
}
@@ -3277,7 +3900,7 @@ void Aura::HandleAuraModSilence(bool apply, bool Real)
}
}
-void Aura::HandleModThreat(bool apply, bool Real)
+void AuraEffect::HandleModThreat(bool apply, bool Real)
{
// only at real add/remove aura
if(!Real)
@@ -3307,19 +3930,19 @@ void Aura::HandleModThreat(bool apply, bool Real)
break;
}
if (level_diff > 0)
- m_modifier.m_amount += multiplier * level_diff;
+ m_amount += multiplier * level_diff;
for(int8 x=0;x < MAX_SPELL_SCHOOL;x++)
{
- if(m_modifier.m_miscvalue & int32(1<<x))
+ if(GetMiscValue() & int32(1<<x))
{
if(m_target->GetTypeId() == TYPEID_PLAYER)
- ApplyPercentModFloatVar(m_target->m_threatModifier[x], m_positive ? GetModifierValue() : -GetModifierValue(), apply);
+ ApplyPercentModFloatVar(m_target->m_threatModifier[x], m_amount, apply);
}
}
}
-void Aura::HandleAuraModTotalThreat(bool apply, bool Real)
+void AuraEffect::HandleAuraModTotalThreat(bool apply, bool Real)
{
// only at real add/remove aura
if(!Real)
@@ -3335,14 +3958,14 @@ void Aura::HandleAuraModTotalThreat(bool apply, bool Real)
float threatMod = 0.0f;
if(apply)
- threatMod = float(GetModifierValue());
+ threatMod = float(m_amount);
else
- threatMod = float(-GetModifierValue());
+ threatMod = float(-m_amount);
m_target->getHostilRefManager().threatAssist(caster, threatMod);
}
-void Aura::HandleModTaunt(bool apply, bool Real)
+void AuraEffect::HandleModTaunt(bool apply, bool Real)
{
// only at real add/remove aura
if(!Real)
@@ -3368,16 +3991,20 @@ void Aura::HandleModTaunt(bool apply, bool Real)
/*********************************************************/
/*** MODIFY SPEED ***/
/*********************************************************/
-void Aura::HandleAuraModIncreaseSpeed(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModIncreaseSpeed(bool apply, bool Real)
{
// all applied/removed only at real aura add/remove
if(!Real)
return;
+ if(apply) // Dash wont work if you are not in cat form
+ if(m_spellProto->SpellFamilyName==SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags[2] & 0x8 && m_target->m_form != FORM_CAT )
+ return;
+
m_target->UpdateSpeed(MOVE_RUN, true);
}
-void Aura::HandleAuraModIncreaseMountedSpeed(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModIncreaseMountedSpeed(bool /*apply*/, bool Real)
{
// all applied/removed only at real aura add/remove
if(!Real)
@@ -3386,14 +4013,14 @@ void Aura::HandleAuraModIncreaseMountedSpeed(bool /*apply*/, bool Real)
m_target->UpdateSpeed(MOVE_RUN, true);
}
-void Aura::HandleAuraModIncreaseFlightSpeed(bool apply, bool Real)
+void AuraEffect::HandleAuraModIncreaseFlightSpeed(bool apply, bool Real)
{
// all applied/removed only at real aura add/remove
if(!Real)
return;
// Enable Fly mode for flying mounts
- if (m_modifier.m_auraname == SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED)
+ if (m_auraName == SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED)
{
WorldPacket data;
if(apply)
@@ -3409,14 +4036,14 @@ void Aura::HandleAuraModIncreaseFlightSpeed(bool apply, bool Real)
m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_POLYMORPH,apply);
// Dragonmaw Illusion (overwrite mount model, mounted aura already applied)
- if( apply && m_target->HasAura(42016,0) && m_target->GetMountID())
+ if( apply && m_target->HasAuraEffect(42016,0) && m_target->GetMountID())
m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314);
}
m_target->UpdateSpeed(MOVE_FLIGHT, true);
}
-void Aura::HandleAuraModIncreaseSwimSpeed(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModIncreaseSwimSpeed(bool /*apply*/, bool Real)
{
// all applied/removed only at real aura add/remove
if(!Real)
@@ -3425,19 +4052,18 @@ void Aura::HandleAuraModIncreaseSwimSpeed(bool /*apply*/, bool Real)
m_target->UpdateSpeed(MOVE_SWIM, true);
}
-void Aura::HandleAuraModDecreaseSpeed(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModDecreaseSpeed(bool /*apply*/, bool Real)
{
// all applied/removed only at real aura add/remove
if(!Real)
return;
- //m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
m_target->UpdateSpeed(MOVE_RUN, true);
m_target->UpdateSpeed(MOVE_SWIM, true);
m_target->UpdateSpeed(MOVE_FLIGHT, true);
}
-void Aura::HandleAuraModUseNormalSpeed(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModUseNormalSpeed(bool /*apply*/, bool Real)
{
// all applied/removed only at real aura add/remove
if(!Real)
@@ -3452,51 +4078,80 @@ void Aura::HandleAuraModUseNormalSpeed(bool /*apply*/, bool Real)
/*** IMMUNITY ***/
/*********************************************************/
-void Aura::HandleModMechanicImmunity(bool apply, bool Real)
+void AuraEffect::HandleModStateImmunityMask(bool apply, bool Real)
+{
+ std::list <AuraType> immunity_list;
+ if (GetMiscValue() & (1<<10))
+ immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ if (GetMiscValue() & (1<<7))
+ immunity_list.push_back(SPELL_AURA_MOD_DISARM);
+ if (GetMiscValue() & (1<<1))
+ immunity_list.push_back(SPELL_AURA_MOD_TAUNT);
+
+ // These flag can be recognized wrong:
+ if (GetMiscValue() & (1<<6))
+ immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
+ if (GetMiscValue() & (1<<0))
+ immunity_list.push_back(SPELL_AURA_MOD_ROOT);
+ if (GetMiscValue() & (1<<2))
+ immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
+ if (GetMiscValue() & (1<<9))
+ immunity_list.push_back(SPELL_AURA_MOD_FEAR);
+
+ // Patch 3.0.3 Bladestorm now breaks all snares and roots on the warrior when activated.
+ // however not all mechanic specified in immunity
+ if (apply && GetId()==46924)
+ {
+ m_target->RemoveAurasByType(SPELL_AURA_MOD_ROOT);
+ m_target->RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
+ }
+
+ if(apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
+ {
+ for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end();++iter)
+ {
+ m_target->RemoveAurasByType(*iter);
+ }
+ }
+ for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end();++iter)
+ {
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,*iter,apply);
+ }
+}
+
+void AuraEffect::HandleModMechanicImmunity(bool apply, bool Real)
{
- uint32 mechanic = 1 << m_modifier.m_miscvalue;
+ uint32 mechanic;
+ mechanic = 1 << GetMiscValue();
//immune movement impairment and loss of control
- if(GetId()==42292)
+ if(GetId()==42292 || GetId()==59752)
mechanic=IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK;
+ if (!mechanic)
+ return;
if(apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
{
Unit::AuraMap& Auras = m_target->GetAuras();
- for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
+ for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end();)
{
- next = iter;
- ++next;
SpellEntry const *spell = iter->second->GetSpellProto();
- if (!( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) // spells unaffected by invulnerability
- && !iter->second->IsPositive() // only remove negative spells
- && spell->Id != GetId())
+ if (spell->Id != GetId())
{
//check for mechanic mask
- if(GetSpellMechanicMask(spell, iter->second->GetEffIndex()) & mechanic)
+ if(GetAllSpellMechanicMask(spell) & mechanic)
{
- m_target->RemoveAurasDueToSpell(spell->Id);
- if(Auras.empty())
- break;
- else
- next = Auras.begin();
+ m_target->RemoveAura(iter);
}
+ else
+ ++iter;
}
+ else
+ ++iter;
}
}
- m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,m_modifier.m_miscvalue,apply);
-
- // special cases
- switch(m_modifier.m_miscvalue)
- {
- case MECHANIC_INVULNERABILITY:
- m_target->ModifyAuraState(AURA_STATE_FORBEARANCE,apply);
- break;
- case MECHANIC_SHIELD:
- m_target->ModifyAuraState(AURA_STATE_WEAKENED_SOUL,apply);
- break;
- }
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,GetMiscValue(),apply);
// Bestial Wrath
if ( GetSpellProto()->SpellFamilyName == SPELLFAMILY_HUNTER && GetSpellProto()->Id == 19574)
@@ -3505,8 +4160,8 @@ void Aura::HandleModMechanicImmunity(bool apply, bool Real)
if ( Unit* owner = m_target->GetOwner() )
{
// Search talent
- Unit::AuraList const& m_dummyAuras = owner->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator i = m_dummyAuras.begin(); i != m_dummyAuras.end(); ++i)
+ Unit::AuraEffectList const& m_dummyAuras = owner->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraEffectList::const_iterator i = m_dummyAuras.begin(); i != m_dummyAuras.end(); ++i)
{
if ( (*i)->GetSpellProto()->SpellIconID == 2229 )
{
@@ -3538,103 +4193,82 @@ void Aura::HandleModMechanicImmunity(bool apply, bool Real)
m_target->RemoveAurasDueToSpell(26592);
}
}
+
+ // Heroic Fury (remove Intercept cooldown)
+ if( apply && GetId() == 60970 && m_target->GetTypeId() == TYPEID_PLAYER )
+ {
+ ((Player*)m_target)->RemoveSpellCooldown(20252);
+
+ WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8));
+ data << uint32(20252);
+ data << uint64(m_target->GetGUID());
+ ((Player*)m_target)->GetSession()->SendPacket(&data);
+ }
}
-void Aura::HandleAuraModEffectImmunity(bool apply, bool Real)
+//this method is called whenever we add / remove aura which gives m_target some imunity to some spell effect
+void AuraEffect::HandleAuraModEffectImmunity(bool apply, bool Real)
{
- if(!apply)
+ // when removing flag aura, handle flag drop
+ if( !apply && m_target->GetTypeId() == TYPEID_PLAYER
+ && (GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION) )
{
if(m_target->GetTypeId() == TYPEID_PLAYER)
{
if(((Player*)m_target)->InBattleGround())
{
- BattleGround *bg = ((Player*)m_target)->GetBattleGround();
- if(bg)
- {
- switch(bg->GetTypeID())
- {
- case BATTLEGROUND_AV:
- {
- break;
- }
- case BATTLEGROUND_WS:
- {
- // Warsong Flag, horde // Silverwing Flag, alliance
- if(GetId() == 23333 || GetId() == 23335)
- bg->EventPlayerDroppedFlag(((Player*)m_target));
- break;
- }
- case BATTLEGROUND_AB:
- {
- break;
- }
- case BATTLEGROUND_EY:
- {
- if(GetId() == 34976)
- bg->EventPlayerDroppedFlag(((Player*)m_target));
- break;
- }
- }
- }
+ if( BattleGround *bg = ((Player*)m_target)->GetBattleGround() )
+ bg->EventPlayerDroppedFlag(((Player*)m_target));
}
else
sOutdoorPvPMgr.HandleDropFlag((Player*)m_target,GetSpellProto()->Id);
}
}
- m_target->ApplySpellImmune(GetId(),IMMUNITY_EFFECT,m_modifier.m_miscvalue,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_EFFECT,GetMiscValue(),apply);
}
-void Aura::HandleAuraModStateImmunity(bool apply, bool Real)
+void AuraEffect::HandleAuraModStateImmunity(bool apply, bool Real)
{
if(apply && Real && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
{
- Unit::AuraList const& auraList = m_target->GetAurasByType(AuraType(m_modifier.m_miscvalue));
- for(Unit::AuraList::const_iterator itr = auraList.begin(); itr != auraList.end();)
- {
- if (auraList.front() != this) // skip itself aura (it already added)
- {
- m_target->RemoveAurasDueToSpell(auraList.front()->GetId());
- itr = auraList.begin();
- }
- else
- ++itr;
- }
+ m_target->RemoveAurasByType(AuraType(GetMiscValue()), NULL , GetParentAura());
}
- m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,m_modifier.m_miscvalue,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,GetMiscValue(),apply);
}
-void Aura::HandleAuraModSchoolImmunity(bool apply, bool Real)
+void AuraEffect::HandleAuraModSchoolImmunity(bool apply, bool Real)
{
- if(apply && m_modifier.m_miscvalue == SPELL_SCHOOL_MASK_NORMAL)
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
+ if(apply && GetMiscValue() == SPELL_SCHOOL_MASK_NORMAL)
+ m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
- m_target->ApplySpellImmune(GetId(),IMMUNITY_SCHOOL,m_modifier.m_miscvalue,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_SCHOOL,GetMiscValue(),apply);
- if(Real && apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
+ // remove all flag auras (they are positive, but they must be removed when you are immune)
+ if( this->GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY
+ && this->GetSpellProto()->AttributesEx2 & SPELL_ATTR_EX2_DAMAGE_REDUCED_SHIELD )
+ m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
+
+ // TODO: optimalize this cycle - use RemoveAurasWithInterruptFlags call or something else
+ if( Real && apply
+ && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY
+ && IsPositiveSpell(GetId()) ) //Only positive immunity removes auras
{
- if(IsPositiveSpell(GetId())) //Only positive immunity removes auras
+ uint32 school_mask = GetMiscValue();
+ Unit::AuraMap& Auras = m_target->GetAuras();
+ for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end();)
{
- uint32 school_mask = m_modifier.m_miscvalue;
- Unit::AuraMap& Auras = m_target->GetAuras();
- for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
+ SpellEntry const *spell = iter->second->GetSpellProto();
+ if((GetSpellSchoolMask(spell) & school_mask)//Check for school mask
+ && IsDispelableBySpell(GetSpellProto(),spell->Id, true)
+ && !iter->second->IsPositive() //Don't remove positive spells
+ && spell->Id != GetId() ) //Don't remove self
{
- next = iter;
- ++next;
- SpellEntry const *spell = iter->second->GetSpellProto();
- if((GetSpellSchoolMask(spell) & school_mask)//Check for school mask
- && !( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) //Spells unaffected by invulnerability
- && !iter->second->IsPositive() //Don't remove positive spells
- && spell->Id != GetId() ) //Don't remove self
- {
- m_target->RemoveAurasDueToSpell(spell->Id);
- if(Auras.empty())
- break;
- else
- next = Auras.begin();
- }
+ m_target->RemoveAura(iter);
}
+ else
+ ++iter;
}
}
if( Real && GetSpellProto()->Mechanic == MECHANIC_BANISH )
@@ -3646,40 +4280,27 @@ void Aura::HandleAuraModSchoolImmunity(bool apply, bool Real)
}
}
-void Aura::HandleAuraModDmgImmunity(bool apply, bool Real)
+void AuraEffect::HandleAuraModDmgImmunity(bool apply, bool Real)
{
- m_target->ApplySpellImmune(GetId(),IMMUNITY_DAMAGE,m_modifier.m_miscvalue,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_DAMAGE,GetMiscValue(),apply);
}
-void Aura::HandleAuraModDispelImmunity(bool apply, bool Real)
+void AuraEffect::HandleAuraModDispelImmunity(bool apply, bool Real)
{
// all applied/removed only at real aura add/remove
if(!Real)
return;
- m_target->ApplySpellDispelImmunity(m_spellProto, DispelType(m_modifier.m_miscvalue), apply);
+ m_target->ApplySpellDispelImmunity(m_spellProto, DispelType(GetMiscValue()), apply);
}
-void Aura::HandleAuraProcTriggerSpell(bool apply, bool Real)
+void AuraEffect::HandleAuraProcTriggerSpell(bool apply, bool Real)
{
if(!Real)
return;
-
- if(apply)
- {
- // some spell have charges by functionality not have its in spell data
- switch (GetId())
- {
- case 28200: // Ascendance (Talisman of Ascendance trinket)
- m_procCharges = 6;
- UpdateAuraCharges();
- break;
- default: break;
- }
- }
}
-void Aura::HandleAuraModStalked(bool apply, bool Real)
+void AuraEffect::HandleAuraModStalked(bool apply, bool Real)
{
// used by spells: Hunter's Mark, Mind Vision, Syndicate Tracker (MURP) DND
if(apply)
@@ -3692,20 +4313,19 @@ void Aura::HandleAuraModStalked(bool apply, bool Real)
/*** PERIODIC ***/
/*********************************************************/
-void Aura::HandlePeriodicTriggerSpell(bool apply, bool Real)
+void AuraEffect::HandlePeriodicTriggerSpell(bool apply, bool Real)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
m_isPeriodic = apply;
- m_isTrigger = apply;
-
- // Curse of the Plaguebringer
- if (!apply && m_spellProto->Id == 29213 && m_removeMode!=AURA_REMOVE_BY_DISPEL)
+ if (m_spellProto->Id == 66 && !apply)
{
- // Cast Wrath of the Plaguebringer if not dispelled
- m_target->CastSpell(m_target, 29214, true, 0, this);
+ if (GetParentAura()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
+ m_target->CastSpell(m_target, 32612, true, NULL, this);
}
+}
+
+void AuraEffect::HandlePeriodicTriggerSpellWithValue(bool apply, bool Real)
+{
+ m_isPeriodic = apply;
// Wrath of the Astromancer
if(!apply && m_spellProto->Id == 42783)
@@ -3714,89 +4334,83 @@ void Aura::HandlePeriodicTriggerSpell(bool apply, bool Real)
}
}
-void Aura::HandlePeriodicEnergize(bool apply, bool Real)
+void AuraEffect::HandlePeriodicEnergize(bool apply, bool Real)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
+ if (!Real)
+ return;
m_isPeriodic = apply;
+
+ // Replenishment (0.25% from max)
+ // Infinite Replenishment
+ if (m_spellProto->SpellIconID == 3184 && m_spellProto->SpellVisual[0] == 12495)
+ m_amount = m_target->GetMaxPower(POWER_MANA) * 25 / 10000;
}
-void Aura::HandlePeriodicHeal(bool apply, bool Real)
+void AuraEffect::HandleAuraPowerBurn(bool apply, bool Real)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
m_isPeriodic = apply;
+}
- // only at real apply
- if (Real && apply && GetSpellProto()->Mechanic == MECHANIC_BANDAGE)
- {
- // provided m_target as original caster to prevent apply aura caster selection for this negative buff
- m_target->CastSpell(m_target,11196,true,NULL,this,m_target->GetGUID());
- }
+void AuraEffect::HandleAuraPeriodicDummy(bool apply, bool Real)
+{
+ // spells required only Real aura add/remove
+ if(!Real)
+ return;
// For prevent double apply bonuses
bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading());
- if(!loading && apply)
+ Unit* caster = GetCaster();
+
+ SpellEntry const*spell = GetSpellProto();
+ switch( spell->SpellFamilyName)
{
- switch (m_spellProto->SpellFamilyName)
+ case SPELLFAMILY_HUNTER:
{
- case SPELLFAMILY_DRUID:
- {
- // Rejuvenation
- if(m_spellProto->SpellFamilyFlags & 0x0000000000000010LL)
- {
- if(Unit* caster = GetCaster())
- {
- Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k)
- {
- int32 tickcount = GetSpellDuration(m_spellProto) / m_spellProto->EffectAmplitude[m_effIndex];
- switch((*k)->GetModifier()->m_miscvalue)
- {
- case 4953: // Increased Rejuvenation Healing - Harold's Rejuvenating Broach Aura
- case 4415: // Increased Rejuvenation Healing - Idol of Rejuvenation Aura
- {
- m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount;
- break;
- }
- }
- }
- }
- }
- }
+ // Explosive Shot
+ if (apply && !loading && caster)
+ m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 16 / 100);
+ break;
}
}
+
+ m_isPeriodic = apply;
}
-void Aura::HandlePeriodicDamage(bool apply, bool Real)
+void AuraEffect::HandlePeriodicHeal(bool apply, bool Real)
+{
+ m_isPeriodic = apply;
+}
+
+void AuraEffect::HandlePeriodicDamage(bool apply, bool Real)
{
// spells required only Real aura add/remove
if(!Real)
return;
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
m_isPeriodic = apply;
// For prevent double apply bonuses
bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading());
+ // Custom damage calculation after
+ if (!apply || loading)
+ return;
+
Unit *caster = GetCaster();
+ if (!caster)
+ return;
switch (m_spellProto->SpellFamilyName)
{
case SPELLFAMILY_GENERIC:
{
// Pounce Bleed
- if ( m_spellProto->SpellIconID == 147 && m_spellProto->SpellVisual == 0 )
+ if ( m_spellProto->SpellIconID == 147 && m_spellProto->SpellVisual[0] == 0 )
{
// $AP*0.18/6 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100);
+ m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100);
return;
}
break;
@@ -3804,18 +4418,14 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
case SPELLFAMILY_WARRIOR:
{
// Rend
- if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
+ if (m_spellProto->SpellFamilyFlags[0] & 0x20)
{
- // 0.00743*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick
- if (apply && !loading && caster)
- {
- float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
- int32 mws = caster->GetAttackTime(BASE_ATTACK);
- float mwb_min = caster->GetWeaponDamageRange(BASE_ATTACK,MINDAMAGE);
- float mwb_max = caster->GetWeaponDamageRange(BASE_ATTACK,MAXDAMAGE);
- // WARNING! in 3.0 multiplier 0.00743f change to 0.6
- m_modifier.m_amount+=int32(((mwb_min+mwb_max)/2+ap*mws/14000)*0.00743f);
- }
+ // $0.2*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick
+ float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
+ int32 mws = caster->GetAttackTime(BASE_ATTACK);
+ float mwb_min = caster->GetWeaponDamageRange(BASE_ATTACK,MINDAMAGE);
+ float mwb_max = caster->GetWeaponDamageRange(BASE_ATTACK,MAXDAMAGE);
+ m_amount+=int32(((mwb_min+mwb_max)/2+ap*mws/14000)*0.2f);
return;
}
break;
@@ -3823,92 +4433,80 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
case SPELLFAMILY_DRUID:
{
// Rake
- if (m_spellProto->SpellFamilyFlags & 0x0000000000001000LL)
+ if (m_spellProto->SpellFamilyFlags[0] & 0x1000)
{
- // $AP*0.06/3 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 2 / 100);
+ // $AP*0.06 bonus per tick
+ m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 6 / 100);
return;
}
// Lacerate
- if (m_spellProto->SpellFamilyFlags & 0x000000010000000000LL)
+ if (m_spellProto->SpellFamilyFlags[1] & 0x0000000100)
{
// $AP*0.05/5 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
+ m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
return;
}
// Rip
- if (m_spellProto->SpellFamilyFlags & 0x000000000000800000LL)
+ if (m_spellProto->SpellFamilyFlags[1] & 0x800000)
{
- // $AP * min(0.06*$cp, 0.24)/6 [Yes, there is no difference, whether 4 or 5 CPs are being used]
- if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER)
- {
- uint8 cp = ((Player*)caster)->GetComboPoints();
+ // 0.01*$AP*cp
+ if (caster->GetTypeId() != TYPEID_PLAYER)
+ return;
- // Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs
- Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
+ uint8 cp = ((Player*)caster)->GetComboPoints();
+
+ // Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs
+ Unit::AuraEffectList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraEffectList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
+ {
+ if((*itr)->GetId()==34241)
{
- if((*itr)->GetId()==34241)
- {
- m_modifier.m_amount += cp * (*itr)->GetModifier()->m_amount;
- break;
- }
+ m_amount += cp * (*itr)->GetAmount();
+ break;
}
-
- if (cp > 4) cp = 4;
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
}
+ m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
+ return;
+ }
+ // Lock Jaw
+ if (m_spellProto->SpellFamilyFlags[1] & 0x10000000)
+ {
+ // 0.15*$AP
+ m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 15 / 100);
return;
}
break;
}
case SPELLFAMILY_ROGUE:
{
- // Deadly poison aura state
- if((m_spellProto->SpellFamilyFlags & 0x10000) && m_spellProto->SpellVisual==5100)
+ // Rupture
+ if (m_spellProto->SpellFamilyFlags[0] & 0x100000)
{
- if(apply)
- m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,true);
- else
- {
- // current aura already removed, search present of another
- bool found = false;
- Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
- for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
- {
- SpellEntry const* itr_spell = (*itr)->GetSpellProto();
- if(itr_spell && itr_spell->SpellFamilyName==SPELLFAMILY_ROGUE && (itr_spell->SpellFamilyFlags & 0x10000) && itr_spell->SpellVisual==5100)
- {
- found = true;
- break;
- }
- }
- // this has been last deadly poison aura
- if(!found)
- m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,false);
- }
+ if (caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+ //1 point : ${($m1+$b1*1+0.015*$AP)*4} damage over 8 secs
+ //2 points: ${($m1+$b1*2+0.024*$AP)*5} damage over 10 secs
+ //3 points: ${($m1+$b1*3+0.03*$AP)*6} damage over 12 secs
+ //4 points: ${($m1+$b1*4+0.03428571*$AP)*7} damage over 14 secs
+ //5 points: ${($m1+$b1*5+0.0375*$AP)*8} damage over 16 secs
+ float AP_per_combo[] = {0, 0.015f, 0.024, 0.03, 0.03428571, 0.0375};
+ uint8 cp = ((Player*)caster)->GetComboPoints();
+ if (cp > 5) cp = 5;
+ m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * AP_per_combo[cp]);
return;
}
- // Rupture
- if (m_spellProto->SpellFamilyFlags & 0x000000000000100000LL)
+ // Garrote
+ if (m_spellProto->SpellFamilyFlags[0] & 0x100)
{
- // Dmg/tick = $AP*min(0.01*$cp, 0.03) [Like Rip: only the first three CP increase the contribution from AP]
- if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER)
- {
- uint8 cp = ((Player*)caster)->GetComboPoints();
- if (cp > 3) cp = 3;
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
- }
+ // $AP*0.07 bonus per tick
+ m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 7 / 100);
return;
}
- // Garrote
- if (m_spellProto->SpellFamilyFlags & 0x000000000000000100LL)
+ // Deadly Poison
+ if (m_spellProto->SpellFamilyFlags[0] & 0x10000)
{
- // $AP*0.18/6 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100);
+ // 0.08*$AP / 4 * amount of stack
+ m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 2 * GetParentAura()->GetStackAmount() / 100);
return;
}
break;
@@ -3916,47 +4514,17 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
case SPELLFAMILY_HUNTER:
{
// Serpent Sting
- if (m_spellProto->SpellFamilyFlags & 0x0000000000004000LL)
+ if (m_spellProto->SpellFamilyFlags[0] & 0x4000)
{
// $RAP*0.1/5 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
+ m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
return;
}
// Immolation Trap
- if (m_spellProto->SpellFamilyFlags & 0x0000000000000004LL && m_spellProto->SpellIconID == 678)
+ if (m_spellProto->SpellFamilyFlags[0] & 0x4 && m_spellProto->SpellIconID == 678)
{
// $RAP*0.1/5 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
- return;
- }
- break;
- }
- case SPELLFAMILY_PALADIN:
- {
- // Consecration
- if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
- {
- if (apply && !loading)
- {
- if(Unit* caster = GetCaster())
- {
- Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k)
- {
- int32 tickcount = GetSpellDuration(m_spellProto) / m_spellProto->EffectAmplitude[m_effIndex];
- switch((*k)->GetModifier()->m_miscvalue)
- {
- case 5147: // Improved Consecration - Libram of the Eternal Rest
- {
- m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount;
- break;
- }
- }
- }
- }
- }
+ m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
return;
}
break;
@@ -3966,27 +4534,23 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
}
}
-void Aura::HandlePeriodicDamagePCT(bool apply, bool Real)
+void AuraEffect::HandlePeriodicDamagePCT(bool apply, bool Real)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
m_isPeriodic = apply;
}
-void Aura::HandlePeriodicLeech(bool apply, bool Real)
+void AuraEffect::HandlePeriodicLeech(bool apply, bool Real)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
m_isPeriodic = apply;
}
-void Aura::HandlePeriodicManaLeech(bool apply, bool Real)
+void AuraEffect::HandlePeriodicManaLeech(bool apply, bool Real)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
+ m_isPeriodic = apply;
+}
+void AuraEffect::HandlePeriodicHealthFunnel(bool apply, bool Real)
+{
m_isPeriodic = apply;
}
@@ -3998,90 +4562,82 @@ void Aura::HandlePeriodicManaLeech(bool apply, bool Real)
/*** RESISTANCE ***/
/********************************/
-void Aura::HandleAuraModResistanceExclusive(bool apply, bool Real)
+void AuraEffect::HandleAuraModResistanceExclusive(bool apply, bool Real)
{
for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
{
- if(m_modifier.m_miscvalue & int32(1<<x))
+ if(GetMiscValue() & int32(1<<x))
{
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_VALUE, float(m_amount), apply);
if(m_target->GetTypeId() == TYPEID_PLAYER)
- m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_positive,GetModifierValue(), apply);
+ m_target->ApplyResistanceBuffModsMod(SpellSchools(x),GetParentAura()->IsPositive(),m_amount, apply);
}
}
}
-void Aura::HandleAuraModResistance(bool apply, bool Real)
+void AuraEffect::HandleAuraModResistance(bool apply, bool Real)
{
for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
{
- if(m_modifier.m_miscvalue & int32(1<<x))
+ if(GetMiscValue() & int32(1<<x))
{
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), TOTAL_VALUE, float(m_amount), apply);
if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
- m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_positive,GetModifierValue(), apply);
+ m_target->ApplyResistanceBuffModsMod(SpellSchools(x),GetParentAura()->IsPositive(),m_amount, apply);
}
}
- // Faerie Fire (druid versions)
- if( (m_spellProto->SpellIconID == 109 &&
- m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID &&
- m_spellProto->SpellFamilyFlags & 0x0000000000000400LL)
- || m_spellProto->Id == 35325)
- {
- m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE,apply);
- }
}
-void Aura::HandleAuraModBaseResistancePCT(bool apply, bool Real)
+void AuraEffect::HandleAuraModBaseResistancePCT(bool apply, bool Real)
{
// only players have base stats
if(m_target->GetTypeId() != TYPEID_PLAYER)
{
//pets only have base armor
- if(((Creature*)m_target)->isPet() && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL))
- m_target->HandleStatModifier(UNIT_MOD_ARMOR, BASE_PCT, float(GetModifierValue()), apply);
+ if(((Creature*)m_target)->isPet() && (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
+ m_target->HandleStatModifier(UNIT_MOD_ARMOR, BASE_PCT, float(m_amount), apply);
}
else
{
for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
{
- if(m_modifier.m_miscvalue & int32(1<<x))
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, float(GetModifierValue()), apply);
+ if(GetMiscValue() & int32(1<<x))
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, float(m_amount), apply);
}
}
}
-void Aura::HandleModResistancePercent(bool apply, bool Real)
+void AuraEffect::HandleModResistancePercent(bool apply, bool Real)
{
for(int8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
{
- if(m_modifier.m_miscvalue & int32(1<<i))
+ if(GetMiscValue() & int32(1<<i))
{
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, float(m_amount), apply);
if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
{
- m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true,GetModifierValue(), apply);
- m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false,GetModifierValue(), apply);
+ m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true,m_amount, apply);
+ m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false,m_amount, apply);
}
}
}
}
-void Aura::HandleModBaseResistance(bool apply, bool Real)
+void AuraEffect::HandleModBaseResistance(bool apply, bool Real)
{
// only players have base stats
if(m_target->GetTypeId() != TYPEID_PLAYER)
{
//only pets have base stats
- if(((Creature*)m_target)->isPet() && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL))
- m_target->HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(GetModifierValue()), apply);
+ if(((Creature*)m_target)->isPet() && (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
+ m_target->HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(m_amount), apply);
}
else
{
for(int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
- if(m_modifier.m_miscvalue & (1<<i))
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_VALUE, float(GetModifierValue()), apply);
+ if(GetMiscValue() & (1<<i))
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_VALUE, float(m_amount), apply);
}
}
@@ -4089,30 +4645,30 @@ void Aura::HandleModBaseResistance(bool apply, bool Real)
/*** STAT ***/
/********************************/
-void Aura::HandleAuraModStat(bool apply, bool Real)
+void AuraEffect::HandleAuraModStat(bool apply, bool Real)
{
- if (m_modifier.m_miscvalue < -2 || m_modifier.m_miscvalue > 4)
+ if (GetMiscValue() < -2 || GetMiscValue() > 4)
{
- sLog.outError("WARNING: Spell %u effect %u have unsupported misc value (%i) for SPELL_AURA_MOD_STAT ",GetId(),GetEffIndex(),m_modifier.m_miscvalue);
+ sLog.outError("WARNING: Spell %u effect %u have unsupported misc value (%i) for SPELL_AURA_MOD_STAT ",GetId(),GetEffIndex(),GetMiscValue());
return;
}
for(int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
{
// -1 or -2 is all stats ( misc < -2 checked in function beginning )
- if (m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue == i)
+ if (GetMiscValue() < 0 || GetMiscValue() == i)
{
- //m_target->ApplyStatMod(Stats(i), m_modifier.m_amount,apply);
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(GetModifierValue()), apply);
+ //m_target->ApplyStatMod(Stats(i), m_amount,apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(m_amount), apply);
if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
- m_target->ApplyStatBuffMod(Stats(i),GetModifierValue(),apply);
+ m_target->ApplyStatBuffMod(Stats(i),m_amount,apply);
}
}
}
-void Aura::HandleModPercentStat(bool apply, bool Real)
+void AuraEffect::HandleModPercentStat(bool apply, bool Real)
{
- if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
+ if (GetMiscValue() < -1 || GetMiscValue() > 4)
{
sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
return;
@@ -4124,12 +4680,12 @@ void Aura::HandleModPercentStat(bool apply, bool Real)
for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
{
- if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(GetModifierValue()), apply);
+ if(GetMiscValue() == i || GetMiscValue() == -1)
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(m_amount), apply);
}
}
-void Aura::HandleModSpellDamagePercentFromStat(bool /*apply*/, bool Real)
+void AuraEffect::HandleModSpellDamagePercentFromStat(bool /*apply*/, bool Real)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -4140,7 +4696,7 @@ void Aura::HandleModSpellDamagePercentFromStat(bool /*apply*/, bool Real)
((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
}
-void Aura::HandleModSpellHealingPercentFromStat(bool /*apply*/, bool Real)
+void AuraEffect::HandleModSpellHealingPercentFromStat(bool /*apply*/, bool Real)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -4149,7 +4705,7 @@ void Aura::HandleModSpellHealingPercentFromStat(bool /*apply*/, bool Real)
((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
}
-void Aura::HandleAuraModDispelResist(bool apply, bool Real)
+void AuraEffect::HandleAuraModDispelResist(bool apply, bool Real)
{
if(!Real || !apply)
return;
@@ -4158,7 +4714,7 @@ void Aura::HandleAuraModDispelResist(bool apply, bool Real)
m_target->CastSpell(m_target,44416,true,NULL,this,GetCasterGUID());
}
-void Aura::HandleModSpellDamagePercentFromAttackPower(bool /*apply*/, bool Real)
+void AuraEffect::HandleModSpellDamagePercentFromAttackPower(bool /*apply*/, bool Real)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -4169,7 +4725,7 @@ void Aura::HandleModSpellDamagePercentFromAttackPower(bool /*apply*/, bool Real)
((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
}
-void Aura::HandleModSpellHealingPercentFromAttackPower(bool /*apply*/, bool Real)
+void AuraEffect::HandleModSpellHealingPercentFromAttackPower(bool /*apply*/, bool Real)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -4178,7 +4734,7 @@ void Aura::HandleModSpellHealingPercentFromAttackPower(bool /*apply*/, bool Real
((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
}
-void Aura::HandleModHealingDone(bool /*apply*/, bool Real)
+void AuraEffect::HandleModHealingDone(bool /*apply*/, bool Real)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -4187,9 +4743,9 @@ void Aura::HandleModHealingDone(bool /*apply*/, bool Real)
((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
}
-void Aura::HandleModTotalPercentStat(bool apply, bool Real)
+void AuraEffect::HandleModTotalPercentStat(bool apply, bool Real)
{
- if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
+ if (GetMiscValue() < -1 || GetMiscValue() > 4)
{
sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
return;
@@ -4201,16 +4757,16 @@ void Aura::HandleModTotalPercentStat(bool apply, bool Real)
for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
{
- if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
+ if(GetMiscValue() == i || GetMiscValue() == -1)
{
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(m_amount), apply);
if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
- m_target->ApplyStatPercentBuffMod(Stats(i), GetModifierValue(), apply );
+ m_target->ApplyStatPercentBuffMod(Stats(i), m_amount, apply );
}
}
//recalculate current HP/MP after applying aura modifications (only for spells with 0x10 flag)
- if ((m_modifier.m_miscvalue == STAT_STAMINA) && (maxHPValue > 0) && (m_spellProto->Attributes & 0x10))
+ if ((GetMiscValue() == STAT_STAMINA) && (maxHPValue > 0) && (m_spellProto->Attributes & 0x10))
{
// newHP = (curHP / maxHP) * newMaxHP = (newMaxHP * curHP) / maxHP -> which is better because no int -> double -> int conversion is needed
uint32 newHPValue = (m_target->GetMaxHealth() * curHPValue) / maxHPValue;
@@ -4218,12 +4774,12 @@ void Aura::HandleModTotalPercentStat(bool apply, bool Real)
}
}
-void Aura::HandleAuraModResistenceOfStatPercent(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModResistenceOfStatPercent(bool /*apply*/, bool Real)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
- if(m_modifier.m_miscvalue != SPELL_SCHOOL_MASK_NORMAL)
+ if(GetMiscValue() != SPELL_SCHOOL_MASK_NORMAL)
{
// support required adding replace UpdateArmor by loop by UpdateResistence at intellect update
// and include in UpdateResistence same code as in UpdateArmor for aura mod apply.
@@ -4238,128 +4794,53 @@ void Aura::HandleAuraModResistenceOfStatPercent(bool /*apply*/, bool Real)
/********************************/
/*** HEAL & ENERGIZE ***/
/********************************/
-void Aura::HandleAuraModTotalHealthPercentRegen(bool apply, bool Real)
+void AuraEffect::HandleAuraModTotalHealthPercentRegen(bool apply, bool Real)
{
- /*
- Need additional checking for auras who reduce or increase healing, magic effect like Dumpen Magic,
- so this aura not fully working.
- */
- if(apply)
- {
- if(!m_target->isAlive())
- return;
-
- if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !m_target->IsSitState())
- m_target->SetStandState(PLAYER_STATE_SIT);
-
- if(m_periodicTimer <= 0)
- {
- m_periodicTimer += m_modifier.periodictime;
-
- if(m_target->GetHealth() < m_target->GetMaxHealth())
- {
- // PeriodicTick can cast triggered spells with stats changes
- PeriodicTick();
- }
- }
- }
-
m_isPeriodic = apply;
}
-void Aura::HandleAuraModTotalManaPercentRegen(bool apply, bool Real)
+void AuraEffect::HandleAuraModTotalEnergyPercentRegen(bool apply, bool Real)
{
- if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply && !m_target->IsSitState())
- m_target->SetStandState(PLAYER_STATE_SIT);
- if(apply)
- {
- if(m_modifier.periodictime == 0)
- m_modifier.periodictime = 1000;
- if(m_periodicTimer <= 0 && m_target->getPowerType() == POWER_MANA)
- {
- m_periodicTimer += m_modifier.periodictime;
-
- if(m_target->GetPower(POWER_MANA) < m_target->GetMaxPower(POWER_MANA))
- {
- // PeriodicTick can cast triggered spells with stats changes
- PeriodicTick();
- }
- }
- }
+ if(m_amplitude == 0)
+ m_amplitude = 1000;
+ m_periodicTimer = m_amplitude;
m_isPeriodic = apply;
}
-void Aura::HandleModRegen(bool apply, bool Real) // eating
+void AuraEffect::HandleModRegen(bool apply, bool Real) // eating
{
- if(apply)
- {
- if(!m_target->isAlive())
- return;
-
- if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !m_target->IsSitState())
- m_target->SetStandState(PLAYER_STATE_SIT);
-
- if(m_periodicTimer <= 0)
- {
- m_periodicTimer += 5000;
- int32 gain = m_target->ModifyHealth(GetModifierValue());
- Unit *caster = GetCaster();
- if (caster)
- {
- SpellEntry const *spellProto = GetSpellProto();
- if (spellProto)
- m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, spellProto);
- }
- }
- }
+ if(m_amplitude == 0)
+ m_amplitude = 5000;
+ m_periodicTimer = 5000;
m_isPeriodic = apply;
}
-void Aura::HandleModPowerRegen(bool apply, bool Real) // drinking
+void AuraEffect::HandleModPowerRegen(bool apply, bool Real) // drinking
{
- if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply && !m_target->IsSitState())
- m_target->SetStandState(PLAYER_STATE_SIT);
+ if (!Real)
+ return;
- if(apply && m_periodicTimer <= 0)
+ Powers pt = m_target->getPowerType();
+ if(m_amplitude == 0)
{
-
- Powers pt = m_target->getPowerType();
+ // Anger Management (only spell use this aura for rage)
if (pt == POWER_RAGE)
- m_periodicTimer = 3000;
- else
- m_periodicTimer = 2000;
+ m_amplitude = 3000;
+ else
+ m_amplitude = 2000;
+ }
- if(int32(pt) != m_modifier.m_miscvalue)
- return;
+ m_periodicTimer = 5000;
- if ( GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED )
- {
- // eating anim
- m_target->HandleEmoteCommand(EMOTE_ONESHOT_EAT);
- }
- else if( GetId() == 20577 )
- {
- // cannibalize anim
- m_target->HandleEmoteCommand(398);
- }
+ if (m_target->GetTypeId() == TYPEID_PLAYER && GetMiscValue() == POWER_MANA)
+ ((Player*)m_target)->UpdateManaRegen();
- // Warrior talent, gain 1 rage every 3 seconds while in combat
- // Anger Menagement
- // amount = 1+ 16 = 17 = 3,4*5 = 10,2*5/3
- // so 17 is rounded amount for 5 sec tick grow ~ 1 range grow in 3 sec
- if(pt == POWER_RAGE)
- {
- m_target->ModifyPower(pt, m_modifier.m_amount*3/5);
- }
- }
m_isPeriodic = apply;
- if (Real && m_target->GetTypeId() == TYPEID_PLAYER && m_modifier.m_miscvalue == POWER_MANA)
- ((Player*)m_target)->UpdateManaRegen();
}
-void Aura::HandleModPowerRegenPCT(bool /*apply*/, bool Real)
+void AuraEffect::HandleModPowerRegenPCT(bool /*apply*/, bool Real)
{
// spells required only Real aura add/remove
if(!Real)
@@ -4369,11 +4850,11 @@ void Aura::HandleModPowerRegenPCT(bool /*apply*/, bool Real)
return;
// Update manaregen value
- if (m_modifier.m_miscvalue == POWER_MANA)
+ if (GetMiscValue() == POWER_MANA)
((Player*)m_target)->UpdateManaRegen();
}
-void Aura::HandleModManaRegen(bool /*apply*/, bool Real)
+void AuraEffect::HandleModManaRegen(bool /*apply*/, bool Real)
{
// spells required only Real aura add/remove
if(!Real)
@@ -4386,7 +4867,7 @@ void Aura::HandleModManaRegen(bool /*apply*/, bool Real)
((Player*)m_target)->UpdateManaRegen();
}
-void Aura::HandleComprehendLanguage(bool apply, bool Real)
+void AuraEffect::HandleComprehendLanguage(bool apply, bool Real)
{
if(apply)
m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_COMPREHEND_LANG);
@@ -4394,32 +4875,32 @@ void Aura::HandleComprehendLanguage(bool apply, bool Real)
m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_COMPREHEND_LANG);
}
-void Aura::HandleAuraModIncreaseHealth(bool apply, bool Real)
+void AuraEffect::HandleAuraModIncreaseHealth(bool apply, bool Real)
{
if(Real)
{
if(apply)
{
- m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetModifierValue()), apply);
- m_target->ModifyHealth(m_modifier.m_amount);
+ m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_amount), apply);
+ m_target->ModifyHealth(m_amount);
}
else
{
- if (int32(m_target->GetHealth()) > m_modifier.m_amount)
- m_target->ModifyHealth(-m_modifier.m_amount);
+ if (int32(m_target->GetHealth()) > m_amount)
+ m_target->ModifyHealth(-m_amount);
else
m_target->SetHealth(1);
- m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_amount), apply);
}
}
}
-void Aura::HandleAuraModIncreaseMaxHealth(bool apply, bool Real)
+void AuraEffect::HandleAuraModIncreaseMaxHealth(bool apply, bool Real)
{
uint32 oldhealth = m_target->GetHealth();
double healthPercentage = (double)oldhealth / (double)m_target->GetMaxHealth();
- m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply);
+ m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_amount), apply);
// refresh percentage
if(oldhealth > 0)
@@ -4432,38 +4913,43 @@ void Aura::HandleAuraModIncreaseMaxHealth(bool apply, bool Real)
}
}
-void Aura::HandleAuraModIncreaseEnergy(bool apply, bool Real)
+void AuraEffect::HandleAuraModIncreaseEnergy(bool apply, bool Real)
{
Powers powerType = m_target->getPowerType();
- if(int32(powerType) != m_modifier.m_miscvalue)
+ if(int32(powerType) != GetMiscValue())
return;
UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType);
- m_target->HandleStatModifier(unitMod, TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(unitMod, TOTAL_VALUE, float(m_amount), apply);
}
-void Aura::HandleAuraModIncreaseEnergyPercent(bool apply, bool /*Real*/)
+void AuraEffect::HandleAuraModIncreaseEnergyPercent(bool apply, bool /*Real*/)
{
Powers powerType = m_target->getPowerType();
- if(int32(powerType) != m_modifier.m_miscvalue)
+ if(int32(powerType) != GetMiscValue())
return;
UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType);
- m_target->HandleStatModifier(unitMod, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(unitMod, TOTAL_PCT, float(m_amount), apply);
+}
+
+void AuraEffect::HandleAuraModIncreaseHealthPercent(bool apply, bool /*Real*/)
+{
+ m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(m_amount), apply);
}
-void Aura::HandleAuraModIncreaseHealthPercent(bool apply, bool /*Real*/)
+void AuraEffect::HandleAuraIncreaseBaseHealthPercent(bool apply, bool /*Real*/)
{
- m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_HEALTH, BASE_PCT, float(m_amount), apply);
}
/********************************/
/*** FIGHT ***/
/********************************/
-void Aura::HandleAuraModParryPercent(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModParryPercent(bool /*apply*/, bool Real)
{
if(m_target->GetTypeId()!=TYPEID_PLAYER)
return;
@@ -4471,25 +4957,25 @@ void Aura::HandleAuraModParryPercent(bool /*apply*/, bool Real)
((Player*)m_target)->UpdateParryPercentage();
}
-void Aura::HandleAuraModDodgePercent(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModDodgePercent(bool /*apply*/, bool Real)
{
if(m_target->GetTypeId()!=TYPEID_PLAYER)
return;
((Player*)m_target)->UpdateDodgePercentage();
- //sLog.outError("BONUS DODGE CHANCE: + %f", float(m_modifier.m_amount));
+ //sLog.outError("BONUS DODGE CHANCE: + %f", float(m_amount));
}
-void Aura::HandleAuraModBlockPercent(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModBlockPercent(bool /*apply*/, bool Real)
{
if(m_target->GetTypeId()!=TYPEID_PLAYER)
return;
((Player*)m_target)->UpdateBlockPercentage();
- //sLog.outError("BONUS BLOCK CHANCE: + %f", float(m_modifier.m_amount));
+ //sLog.outError("BONUS BLOCK CHANCE: + %f", float(m_amount));
}
-void Aura::HandleAuraModRegenInterrupt(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModRegenInterrupt(bool /*apply*/, bool Real)
{
// spells required only Real aura add/remove
if(!Real)
@@ -4501,7 +4987,7 @@ void Aura::HandleAuraModRegenInterrupt(bool /*apply*/, bool Real)
((Player*)m_target)->UpdateManaRegen();
}
-void Aura::HandleAuraModCritPercent(bool apply, bool Real)
+void AuraEffect::HandleAuraModCritPercent(bool apply, bool Real)
{
if(m_target->GetTypeId()!=TYPEID_PLAYER)
return;
@@ -4516,13 +5002,13 @@ void Aura::HandleAuraModCritPercent(bool apply, bool Real)
// mods must be applied base at equipped weapon class and subclass comparison
// with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
- // m_modifier.m_miscvalue comparison with item generated damage types
+ // GetMiscValue() comparison with item generated damage types
if (GetSpellProto()->EquippedItemClass == -1)
{
- ((Player*)m_target)->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float (GetModifierValue()), apply);
- ((Player*)m_target)->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (GetModifierValue()), apply);
- ((Player*)m_target)->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float (GetModifierValue()), apply);
+ ((Player*)m_target)->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float (m_amount), apply);
+ ((Player*)m_target)->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (m_amount), apply);
+ ((Player*)m_target)->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float (m_amount), apply);
}
else
{
@@ -4530,18 +5016,33 @@ void Aura::HandleAuraModCritPercent(bool apply, bool Real)
}
}
-void Aura::HandleModHitChance(bool apply, bool Real)
+void AuraEffect::HandleModHitChance(bool apply, bool Real)
{
- m_target->m_modMeleeHitChance += apply ? GetModifierValue() : -GetModifierValue();
- m_target->m_modRangedHitChance += apply ? GetModifierValue() : -GetModifierValue();
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)m_target)->UpdateMeleeHitChances();
+ ((Player*)m_target)->UpdateRangedHitChances();
+ }
+ else
+ {
+ m_target->m_modMeleeHitChance += apply ? m_amount : (-m_amount);
+ m_target->m_modRangedHitChance += apply ? m_amount : (-m_amount);
+ }
}
-void Aura::HandleModSpellHitChance(bool apply, bool Real)
+void AuraEffect::HandleModSpellHitChance(bool apply, bool Real)
{
- m_target->m_modSpellHitChance += apply ? GetModifierValue(): -GetModifierValue();
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)m_target)->UpdateSpellHitChances();
+ }
+ else
+ {
+ m_target->m_modSpellHitChance += apply ? m_amount: (-m_amount);
+ }
}
-void Aura::HandleModSpellCritChance(bool apply, bool Real)
+void AuraEffect::HandleModSpellCritChance(bool apply, bool Real)
{
// spells required only Real aura add/remove
if(!Real)
@@ -4553,11 +5054,11 @@ void Aura::HandleModSpellCritChance(bool apply, bool Real)
}
else
{
- m_target->m_baseSpellCritChance += apply ? GetModifierValue():-GetModifierValue();
+ m_target->m_baseSpellCritChance += apply ? m_amount:-m_amount;
}
}
-void Aura::HandleModSpellCritChanceShool(bool /*apply*/, bool Real)
+void AuraEffect::HandleModSpellCritChanceShool(bool /*apply*/, bool Real)
{
// spells required only Real aura add/remove
if(!Real)
@@ -4567,7 +5068,7 @@ void Aura::HandleModSpellCritChanceShool(bool /*apply*/, bool Real)
return;
for(int school = SPELL_SCHOOL_NORMAL; school < MAX_SPELL_SCHOOL; ++school)
- if (m_modifier.m_miscvalue & (1<<school))
+ if (GetMiscValue() & (1<<school))
((Player*)m_target)->UpdateSpellCritChance(school);
}
@@ -4575,131 +5076,111 @@ void Aura::HandleModSpellCritChanceShool(bool /*apply*/, bool Real)
/*** ATTACK SPEED ***/
/********************************/
-void Aura::HandleModCastingSpeed(bool apply, bool Real)
+void AuraEffect::HandleModCastingSpeed(bool apply, bool Real)
{
- m_target->ApplyCastTimePercentMod(GetModifierValue(),apply);
+ m_target->ApplyCastTimePercentMod(m_amount,apply);
}
-void Aura::HandleModMeleeRangedSpeedPct(bool apply, bool Real)
+void AuraEffect::HandleModMeleeRangedSpeedPct(bool apply, bool Real)
{
- m_target->ApplyAttackTimePercentMod(BASE_ATTACK,GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(OFF_ATTACK,GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, GetModifierValue(), apply);
+ m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_amount,apply);
+ m_target->ApplyAttackTimePercentMod(OFF_ATTACK,m_amount,apply);
+ m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_amount, apply);
}
-void Aura::HandleModCombatSpeedPct(bool apply, bool Real)
+void AuraEffect::HandleModCombatSpeedPct(bool apply, bool Real)
{
- m_target->ApplyCastTimePercentMod(GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(BASE_ATTACK,GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(OFF_ATTACK,GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, GetModifierValue(), apply);
+ m_target->ApplyCastTimePercentMod(m_amount,apply);
+ m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_amount,apply);
+ m_target->ApplyAttackTimePercentMod(OFF_ATTACK,m_amount,apply);
+ m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_amount, apply);
}
-void Aura::HandleModAttackSpeed(bool apply, bool Real)
+void AuraEffect::HandleModAttackSpeed(bool apply, bool Real)
{
if(!m_target->isAlive() )
return;
- m_target->ApplyAttackTimePercentMod(BASE_ATTACK,GetModifierValue(),apply);
+ m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_amount,apply);
}
-void Aura::HandleHaste(bool apply, bool Real)
+void AuraEffect::HandleHaste(bool apply, bool Real)
{
- m_target->ApplyAttackTimePercentMod(BASE_ATTACK, GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(OFF_ATTACK, GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,GetModifierValue(),apply);
+ m_target->ApplyAttackTimePercentMod(BASE_ATTACK, m_amount,apply);
+ m_target->ApplyAttackTimePercentMod(OFF_ATTACK, m_amount,apply);
+ m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_amount,apply);
}
-void Aura::HandleAuraModRangedHaste(bool apply, bool Real)
+void AuraEffect::HandleAuraModRangedHaste(bool apply, bool Real)
{
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, GetModifierValue(), apply);
+ m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_amount, apply);
}
-void Aura::HandleRangedAmmoHaste(bool apply, bool Real)
+void AuraEffect::HandleRangedAmmoHaste(bool apply, bool Real)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,GetModifierValue(), apply);
+ m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_amount, apply);
}
/********************************/
/*** ATTACK POWER ***/
/********************************/
-void Aura::HandleAuraModAttackPower(bool apply, bool Real)
-{
- m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(GetModifierValue()), apply);
- if(apply)
- switch(m_spellProto->Id){
- // Warrior & Druid Demoshout should remove stealth
- case 1160:
- case 6190:
- case 11554:
- case 11555:
- case 11556:
- case 25202:
- case 25203:
- case 47437: //WotLK spell
- case 99:
- case 1735:
- case 9490:
- case 9747:
- case 9898:
- case 26998:
- case 48559: //WotLK spell
- case 48560: //WotLK spell
- m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
- break;
- }
+void AuraEffect::HandleAuraModAttackPower(bool apply, bool Real)
+{
+ m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(m_amount), apply);
}
-void Aura::HandleAuraModRangedAttackPower(bool apply, bool Real)
+void AuraEffect::HandleAuraModRangedAttackPower(bool apply, bool Real)
{
if((m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
return;
- m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(m_amount), apply);
}
-void Aura::HandleAuraModAttackPowerPercent(bool apply, bool Real)
+void AuraEffect::HandleAuraModAttackPowerPercent(bool apply, bool Real)
{
//UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1
- m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(m_amount), apply);
}
-void Aura::HandleAuraModRangedAttackPowerPercent(bool apply, bool Real)
+void AuraEffect::HandleAuraModRangedAttackPowerPercent(bool apply, bool Real)
{
if((m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
return;
//UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = multiplier - 1
- m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(m_amount), apply);
}
-void Aura::HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real)
+void AuraEffect::HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real)
{
// spells required only Real aura add/remove
if(!Real)
return;
- if(m_target->GetTypeId() == TYPEID_PLAYER && (m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
- return;
+ // Recalculate bonus
+ if(m_target->GetTypeId() == TYPEID_PLAYER && !(m_target->getClassMask() & CLASSMASK_WAND_USERS))
+ ((Player*)m_target)->UpdateAttackPowerAndDamage(true);
+}
- if(m_modifier.m_miscvalue != STAT_INTELLECT)
- {
- // support required adding UpdateAttackPowerAndDamage calls at stat update
- sLog.outError("Aura SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT (212) need support non-intellect stats!");
+void AuraEffect::HandleAuraModAttackPowerOfStatPercent(bool apply, bool Real)
+{
+ // spells required only Real aura add/remove
+ if(!Real)
return;
- }
// Recalculate bonus
- ((Player*)m_target)->UpdateAttackPowerAndDamage(true);
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)m_target)->UpdateAttackPowerAndDamage(false);
}
/********************************/
/*** DAMAGE BONUS ***/
/********************************/
-void Aura::HandleModDamageDone(bool apply, bool Real)
+void AuraEffect::HandleModDamageDone(bool apply, bool Real)
{
// apply item specific bonuses for already equipped weapon
if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
@@ -4709,23 +5190,23 @@ void Aura::HandleModDamageDone(bool apply, bool Real)
((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem,WeaponAttackType(i),this,apply);
}
- // m_modifier.m_miscvalue is bitmask of spell schools
+ // GetMiscValue() is bitmask of spell schools
// 1 ( 0-bit ) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
// 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wands
// 127 - full bitmask any damages
//
// mods must be applied base at equipped weapon class and subclass comparison
// with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
- // m_modifier.m_miscvalue comparison with item generated damage types
+ // GetMiscValue() comparison with item generated damage types
- if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) != 0)
+ if((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) != 0)
{
// apply generic physical damage bonuses including wand case
if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER)
{
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(GetModifierValue()), apply);
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(GetModifierValue()), apply);
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(m_amount), apply);
+ m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(m_amount), apply);
+ m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(m_amount), apply);
}
else
{
@@ -4734,15 +5215,15 @@ void Aura::HandleModDamageDone(bool apply, bool Real)
if(m_target->GetTypeId() == TYPEID_PLAYER)
{
- if(m_positive)
- m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,GetModifierValue(),apply);
+ if(GetParentAura()->IsPositive())
+ m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,m_amount,apply);
else
- m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG,GetModifierValue(),apply);
+ m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG,m_amount,apply);
}
}
// Skip non magic case for speedup
- if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_MAGIC) == 0)
+ if((GetMiscValue() & SPELL_SCHOOL_MASK_MAGIC) == 0)
return;
if( GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0 )
@@ -4758,31 +5239,31 @@ void Aura::HandleModDamageDone(bool apply, bool Real)
// This information for client side use only
if(m_target->GetTypeId() == TYPEID_PLAYER)
{
- if(m_positive)
+ if(GetParentAura()->IsPositive())
{
for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
{
- if((m_modifier.m_miscvalue & (1<<i)) != 0)
- m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i,GetModifierValue(),apply);
+ if((GetMiscValue() & (1<<i)) != 0)
+ m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i,m_amount,apply);
}
}
else
{
for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
{
- if((m_modifier.m_miscvalue & (1<<i)) != 0)
- m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG+i,GetModifierValue(),apply);
+ if((GetMiscValue() & (1<<i)) != 0)
+ m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG+i,m_amount,apply);
}
}
- Pet* pet = m_target->GetPet();
+ Pet* pet = ((Player*)m_target)->GetPet();
if(pet)
pet->UpdateAttackPowerAndDamage();
}
}
-void Aura::HandleModDamagePercentDone(bool apply, bool Real)
+void AuraEffect::HandleModDamagePercentDone(bool apply, bool Real)
{
- sLog.outDebug("AURA MOD DAMAGE type:%u negative:%u", m_modifier.m_miscvalue, m_positive ? 0 : 1);
+ sLog.outDebug("AURA MOD DAMAGE type:%u negative:%u", GetMiscValue(), GetParentAura()->IsPositive() ? 0 : 1);
// apply item specific bonuses for already equipped weapon
if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
@@ -4792,23 +5273,23 @@ void Aura::HandleModDamagePercentDone(bool apply, bool Real)
((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem,WeaponAttackType(i),this,apply);
}
- // m_modifier.m_miscvalue is bitmask of spell schools
+ // GetMiscValue() is bitmask of spell schools
// 1 ( 0-bit ) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
// 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wand
// 127 - full bitmask any damages
//
// mods must be applied base at equipped weapon class and subclass comparison
// with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
- // m_modifier.m_miscvalue comparison with item generated damage types
+ // GetMiscValue() comparison with item generated damage types
- if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) != 0)
+ if((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) != 0)
{
// apply generic physical damage bonuses including wand case
if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER)
{
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(GetModifierValue()), apply);
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(GetModifierValue()), apply);
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(m_amount), apply);
+ m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(m_amount), apply);
+ m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(m_amount), apply);
}
else
{
@@ -4816,11 +5297,11 @@ void Aura::HandleModDamagePercentDone(bool apply, bool Real)
}
// For show in client
if(m_target->GetTypeId() == TYPEID_PLAYER)
- m_target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT,m_modifier.m_amount/100.0f,apply);
+ m_target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT,m_amount/100.0f,apply);
}
// Skip non magic case for speedup
- if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_MAGIC) == 0)
+ if((GetMiscValue() & SPELL_SCHOOL_MASK_MAGIC) == 0)
return;
if( GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0 )
@@ -4836,10 +5317,10 @@ void Aura::HandleModDamagePercentDone(bool apply, bool Real)
// Send info to client
if(m_target->GetTypeId() == TYPEID_PLAYER)
for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
- m_target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT+i,m_modifier.m_amount/100.0f,apply);
+ m_target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT+i,m_amount/100.0f,apply);
}
-void Aura::HandleModOffhandDamagePercent(bool apply, bool Real)
+void AuraEffect::HandleModOffhandDamagePercent(bool apply, bool Real)
{
// spells required only Real aura add/remove
if(!Real)
@@ -4847,177 +5328,75 @@ void Aura::HandleModOffhandDamagePercent(bool apply, bool Real)
sLog.outDebug("AURA MOD OFFHAND DAMAGE");
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(m_amount), apply);
}
/********************************/
/*** POWER COST ***/
/********************************/
-void Aura::HandleModPowerCostPCT(bool apply, bool Real)
+void AuraEffect::HandleModPowerCostPCT(bool apply, bool Real)
{
// spells required only Real aura add/remove
if(!Real)
return;
- float amount = GetModifierValue() /100.0f;
+ float amount = m_amount /100.0f;
for(int i = 0; i < MAX_SPELL_SCHOOL; ++i)
- if(m_modifier.m_miscvalue & (1<<i))
+ if(GetMiscValue() & (1<<i))
m_target->ApplyModSignedFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,amount,apply);
}
-void Aura::HandleModPowerCost(bool apply, bool Real)
+void AuraEffect::HandleModPowerCost(bool apply, bool Real)
{
// spells required only Real aura add/remove
if(!Real)
return;
for(int i = 0; i < MAX_SPELL_SCHOOL; ++i)
- if(m_modifier.m_miscvalue & (1<<i))
- m_target->ApplyModInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+i,GetModifierValue(),apply);
+ if(GetMiscValue() & (1<<i))
+ m_target->ApplyModInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+i,m_amount,apply);
+}
+
+void AuraEffect::HandleNoReagentUseAura(bool Apply, bool Real)
+{
+ // spells required only Real aura add/remove
+ if(!Real)
+ return;
+ if(m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+ flag96 mask;
+ Unit::AuraEffectList const& noReagent = m_target->GetAurasByType(SPELL_AURA_NO_REAGENT_USE);
+ for(Unit::AuraEffectList::const_iterator i = noReagent.begin(); i != noReagent.end(); ++i)
+ mask |= (*i)->m_spellProto->EffectSpellClassMask[(*i)->m_effIndex];
+
+ m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1 , mask[0]);
+ m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+1, mask[1]);
+ m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+2, mask[2]);
}
/*********************************************************/
/*** OTHERS ***/
/*********************************************************/
-void Aura::HandleShapeshiftBoosts(bool apply)
+void AuraEffect::HandleAuraAllowOnlyAbility(bool apply, bool Real)
{
- uint32 spellId = 0;
- uint32 spellId2 = 0;
- uint32 HotWSpellId = 0;
-
- switch(GetModifier()->m_miscvalue)
- {
- case FORM_CAT:
- spellId = 3025;
- HotWSpellId = 24900;
- break;
- case FORM_TREE:
- spellId = 5420;
- break;
- case FORM_TRAVEL:
- spellId = 5419;
- break;
- case FORM_AQUA:
- spellId = 5421;
- break;
- case FORM_BEAR:
- spellId = 1178;
- spellId2 = 21178;
- HotWSpellId = 24899;
- break;
- case FORM_DIREBEAR:
- spellId = 9635;
- spellId2 = 21178;
- HotWSpellId = 24899;
- break;
- case FORM_BATTLESTANCE:
- spellId = 21156;
- break;
- case FORM_DEFENSIVESTANCE:
- spellId = 7376;
- break;
- case FORM_BERSERKERSTANCE:
- spellId = 7381;
- break;
- case FORM_MOONKIN:
- spellId = 24905;
- // aura from effect trigger spell
- spellId2 = 24907;
- break;
- case FORM_FLIGHT:
- spellId = 33948;
- break;
- case FORM_FLIGHT_EPIC:
- spellId = 40122;
- spellId2 = 40121;
- break;
- case FORM_SPIRITOFREDEMPTION:
- spellId = 27792;
- spellId2 = 27795; // must be second, this important at aura remove to prevent to early iterator invalidation.
- break;
- case FORM_GHOSTWOLF:
- case FORM_AMBIENT:
- case FORM_GHOUL:
- case FORM_SHADOW:
- case FORM_STEALTH:
- case FORM_CREATURECAT:
- case FORM_CREATUREBEAR:
- spellId = 0;
- break;
- }
-
- uint32 form = GetModifier()->m_miscvalue-1;
-
- if(apply)
- {
- if (spellId) m_target->CastSpell(m_target, spellId, true, NULL, this );
- if (spellId2) m_target->CastSpell(m_target, spellId2, true, NULL, this);
+ if(!Real)
+ return;
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- {
- const PlayerSpellMap& sp_list = ((Player *)m_target)->GetSpellMap();
- for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
- {
- if(itr->second->state == PLAYERSPELL_REMOVED) continue;
- if(itr->first==spellId || itr->first==spellId2) continue;
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
- if (!spellInfo || !(spellInfo->Attributes & ((1<<6) | (1<<7)))) continue;
- if (spellInfo->Stances & (1<<form))
- m_target->CastSpell(m_target, itr->first, true, NULL, this);
- }
- //LotP
- if (((Player*)m_target)->HasSpell(17007))
- {
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(24932);
- if (spellInfo && spellInfo->Stances & (1<<form))
- m_target->CastSpell(m_target, 24932, true, NULL, this);
- }
- // HotW
- if (HotWSpellId)
- {
- Unit::AuraList const& mModTotalStatPct = m_target->GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
- for(Unit::AuraList::const_iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i)
- {
- if ((*i)->GetSpellProto()->SpellIconID == 240 && (*i)->GetModifier()->m_miscvalue == 3)
- {
- int32 HotWMod = (*i)->GetModifier()->m_amount;
- if(GetModifier()->m_miscvalue == FORM_CAT)
- HotWMod /= 2;
+ if(!apply && m_target->HasAuraType(SPELL_AURA_ALLOW_ONLY_ABILITY))
+ return;
- m_target->CastCustomSpell(m_target, HotWSpellId, &HotWMod, NULL, NULL, true, NULL, this);
- break;
- }
- }
- }
- }
- }
- else
+ if(m_target->GetTypeId()==TYPEID_PLAYER)
{
- m_target->RemoveAurasDueToSpell(spellId);
- m_target->RemoveAurasDueToSpell(spellId2);
-
- Unit::AuraMap& tAuras = m_target->GetAuras();
- for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
- {
- if (itr->second->IsRemovedOnShapeLost())
- {
- m_target->RemoveAurasDueToSpell(itr->second->GetId());
- itr = tAuras.begin();
- }
- else
- {
- ++itr;
- }
- }
+ if (apply)
+ m_target->SetFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY);
+ else
+ m_target->RemoveFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY);
}
-
- /*double healthPercentage = (double)m_target->GetHealth() / (double)m_target->GetMaxHealth();
- m_target->SetHealth(uint32(ceil((double)m_target->GetMaxHealth() * healthPercentage)));*/
}
-void Aura::HandleAuraEmpathy(bool apply, bool Real)
+void AuraEffect::HandleAuraEmpathy(bool apply, bool Real)
{
if(m_target->GetTypeId() != TYPEID_UNIT)
return;
@@ -5027,15 +5406,15 @@ void Aura::HandleAuraEmpathy(bool apply, bool Real)
m_target->ApplyModUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO, apply);
}
-void Aura::HandleAuraUntrackable(bool apply, bool Real)
+void AuraEffect::HandleAuraUntrackable(bool apply, bool Real)
{
if(apply)
- m_target->SetFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_UNTRACKABLE);
+ m_target->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_UNTRACKABLE);
else
- m_target->RemoveFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_UNTRACKABLE);
+ m_target->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_UNTRACKABLE);
}
-void Aura::HandleAuraModPacify(bool apply, bool Real)
+void AuraEffect::HandleAuraModPacify(bool apply, bool Real)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -5055,13 +5434,13 @@ void Aura::HandleAuraModPacify(bool apply, bool Real)
}
}
-void Aura::HandleAuraModPacifyAndSilence(bool apply, bool Real)
+void AuraEffect::HandleAuraModPacifyAndSilence(bool apply, bool Real)
{
HandleAuraModPacify(apply,Real);
HandleAuraModSilence(apply,Real);
}
-void Aura::HandleAuraGhost(bool apply, bool Real)
+void AuraEffect::HandleAuraGhost(bool apply, bool Real)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -5076,7 +5455,7 @@ void Aura::HandleAuraGhost(bool apply, bool Real)
}
}
-void Aura::HandleAuraAllowFlight(bool apply, bool Real)
+void AuraEffect::HandleAuraAllowFlight(bool apply, bool Real)
{
// all applied/removed only at real aura add/remove
if(!Real)
@@ -5085,15 +5464,29 @@ void Aura::HandleAuraAllowFlight(bool apply, bool Real)
// allow fly
WorldPacket data;
if(apply)
+ {
data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12);
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ m_target->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02);
+ m_target->AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
+ }
+ }
else
+ {
data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12);
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ m_target->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02);
+ m_target->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING2);
+ }
+ }
data.append(m_target->GetPackGUID());
data << uint32(0); // unk
m_target->SendMessageToSet(&data, true);
}
-void Aura::HandleModRating(bool apply, bool Real)
+void AuraEffect::HandleModRating(bool apply, bool Real)
{
// spells required only Real aura add/remove
if(!Real)
@@ -5103,11 +5496,25 @@ void Aura::HandleModRating(bool apply, bool Real)
return;
for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
- if (m_modifier.m_miscvalue & (1 << rating))
- ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), GetModifierValue(), apply);
+ if (GetMiscValue() & (1 << rating))
+ ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), m_amount, apply);
+}
+
+void AuraEffect::HandleModRatingFromStat(bool apply, bool Real)
+{
+ // spells required only Real aura add/remove
+ if(!Real)
+ return;
+
+ if(m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+ // Just recalculate ratings
+ for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
+ if (GetMiscValue() & (1 << rating))
+ ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), 0, apply);
}
-void Aura::HandleForceMoveForward(bool apply, bool Real)
+void AuraEffect::HandleForceMoveForward(bool apply, bool Real)
{
if(!Real || m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -5117,7 +5524,7 @@ void Aura::HandleForceMoveForward(bool apply, bool Real)
m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE);
}
-void Aura::HandleAuraModExpertise(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModExpertise(bool /*apply*/, bool Real)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -5126,7 +5533,7 @@ void Aura::HandleAuraModExpertise(bool /*apply*/, bool Real)
((Player*)m_target)->UpdateExpertise(OFF_ATTACK);
}
-void Aura::HandleModTargetResistance(bool apply, bool Real)
+void AuraEffect::HandleModTargetResistance(bool apply, bool Real)
{
// spells required only Real aura add/remove
if(!Real)
@@ -5134,25 +5541,25 @@ void Aura::HandleModTargetResistance(bool apply, bool Real)
// applied to damage as HandleNoImmediateEffect in Unit::CalcAbsorbResist and Unit::CalcArmorReducedDamage
// show armor penetration
- if (m_target->GetTypeId() == TYPEID_PLAYER && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL))
- m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE,GetModifierValue(), apply);
+ if (m_target->GetTypeId() == TYPEID_PLAYER && (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
+ m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE,m_amount, apply);
// show as spell penetration only full spell penetration bonuses (all resistances except armor and holy
- if (m_target->GetTypeId() == TYPEID_PLAYER && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_SPELL)==SPELL_SCHOOL_MASK_SPELL)
- m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE,GetModifierValue(), apply);
+ if (m_target->GetTypeId() == TYPEID_PLAYER && (GetMiscValue() & SPELL_SCHOOL_MASK_SPELL)==SPELL_SCHOOL_MASK_SPELL)
+ m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE,m_amount, apply);
}
-void Aura::HandleShieldBlockValue(bool apply, bool Real)
+void AuraEffect::HandleShieldBlockValue(bool apply, bool Real)
{
BaseModType modType = FLAT_MOD;
- if(m_modifier.m_auraname == SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT)
+ if(m_auraName == SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT)
modType = PCT_MOD;
if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->HandleBaseModValue(SHIELD_BLOCK_VALUE, modType, float(GetModifierValue()), apply);
+ ((Player*)m_target)->HandleBaseModValue(SHIELD_BLOCK_VALUE, modType, float(m_amount), apply);
}
-void Aura::HandleAuraRetainComboPoints(bool apply, bool Real)
+void AuraEffect::HandleAuraRetainComboPoints(bool apply, bool Real)
{
// spells required only Real aura add/remove
if(!Real)
@@ -5165,23 +5572,26 @@ void Aura::HandleAuraRetainComboPoints(bool apply, bool Real)
// combo points was added in SPELL_EFFECT_ADD_COMBO_POINTS handler
// remove only if aura expire by time (in case combo points amount change aura removed without combo points lost)
- if( !apply && m_duration==0 && target->GetComboTarget())
+ if( !apply && GetParentAura()->GetAuraDuration()==0 && target->GetComboTarget())
if(Unit* unit = ObjectAccessor::GetUnit(*m_target,target->GetComboTarget()))
- target->AddComboPoints(unit, -GetModifierValue());
+ target->AddComboPoints(unit, -m_amount);
}
-void Aura::HandleModUnattackable( bool Apply, bool Real )
+void AuraEffect::HandleModUnattackable( bool Apply, bool Real )
{
- if(Real && Apply)
+ if(!Real)
+ return;
+
+ if(Apply)
{
m_target->CombatStop();
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
+ m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
}
- m_target->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE,Apply);
+ m_target->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE, Apply);
}
-void Aura::HandleSpiritOfRedemption( bool apply, bool Real )
+void AuraEffect::HandleSpiritOfRedemption( bool apply, bool Real )
{
// spells required only Real aura add/remove
if(!Real)
@@ -5197,7 +5607,7 @@ void Aura::HandleSpiritOfRedemption( bool apply, bool Real )
// set stand state (expected in this form)
if(!m_target->IsStandState())
- m_target->SetStandState(PLAYER_STATE_NONE);
+ m_target->SetStandState(UNIT_STAND_STATE_STAND);
}
m_target->SetHealth(1);
@@ -5207,36 +5617,7 @@ void Aura::HandleSpiritOfRedemption( bool apply, bool Real )
m_target->setDeathState(JUST_DIED);
}
-void Aura::CleanupTriggeredSpells()
-{
- uint32 tSpellId = m_spellProto->EffectTriggerSpell[GetEffIndex()];
- if(!tSpellId)
- return;
-
- SpellEntry const* tProto = sSpellStore.LookupEntry(tSpellId);
- if(!tProto)
- return;
-
- if(GetSpellDuration(tProto) != -1)
- return;
-
- // needed for spell 43680, maybe others
- // TODO: is there a spell flag, which can solve this in a more sophisticated way?
- if(m_spellProto->EffectApplyAuraName[GetEffIndex()] == SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
- GetSpellDuration(m_spellProto) == m_spellProto->EffectAmplitude[GetEffIndex()])
- return;
- m_target->RemoveAurasDueToSpell(tSpellId);
-}
-
-void Aura::HandleAuraPowerBurn(bool apply, bool Real)
-{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
- m_isPeriodic = apply;
-}
-
-void Aura::HandleSchoolAbsorb(bool apply, bool Real)
+void AuraEffect::HandleSchoolAbsorb(bool apply, bool Real)
{
if(!Real)
return;
@@ -5250,29 +5631,26 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real)
switch(m_spellProto->SpellFamilyName)
{
case SPELLFAMILY_PRIEST:
- if(m_spellProto->SpellFamilyFlags == 0x1) //PW:S
+ if(m_spellProto->SpellFamilyFlags.IsEqual(0x1)) //PW:S
{
//+30% from +healing bonus
DoneActualBenefit = caster->SpellBaseHealingBonus(GetSpellSchoolMask(m_spellProto)) * 0.3f;
- break;
}
break;
case SPELLFAMILY_MAGE:
- if(m_spellProto->SpellFamilyFlags == 0x80100 || m_spellProto->SpellFamilyFlags == 0x8 || m_spellProto->SpellFamilyFlags == 0x100000000LL)
+ if(m_spellProto->SpellFamilyFlags.IsEqual(0x80100) || m_spellProto->SpellFamilyFlags.IsEqual(0x8) || m_spellProto->SpellFamilyFlags.IsEqual(0,0x1))
{
//frost ward, fire ward, ice barrier
//+10% from +spd bonus
DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.1f;
- break;
}
break;
case SPELLFAMILY_WARLOCK:
- if(m_spellProto->SpellFamilyFlags == 0x00)
+ if(m_spellProto->SpellFamilyFlags.IsEqual(0,0,0x40))
{
//shadow ward
//+10% from +spd bonus
DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.1f;
- break;
}
break;
default:
@@ -5281,17 +5659,17 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real)
DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellProto());
- m_modifier.m_amount += (int32)DoneActualBenefit;
+ m_amount += (int32)DoneActualBenefit;
}
}
}
-void Aura::PeriodicTick()
+void AuraEffect::PeriodicTick()
{
if(!m_target->isAlive())
return;
- switch(m_modifier.m_auraname)
+ switch(GetAuraName())
{
case SPELL_AURA_PERIODIC_DAMAGE:
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
@@ -5305,11 +5683,11 @@ void Aura::PeriodicTick()
return;
// Check for immune (not use charges)
- if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
+ if(m_target->IsImmunedToDamage(GetSpellProto()))
return;
// some auras remove at specific health level or more
- if(m_modifier.m_auraname==SPELL_AURA_PERIODIC_DAMAGE)
+ if(m_auraName==SPELL_AURA_PERIODIC_DAMAGE)
{
switch(GetId())
{
@@ -5336,18 +5714,18 @@ void Aura::PeriodicTick()
}
case 41337:// aura of anger
{
- Unit::AuraList const& mMod = m_target->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
- for(Unit::AuraList::const_iterator i = mMod.begin(); i != mMod.end(); ++i)
+ Unit::AuraEffectList const& mMod = m_target->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ for(Unit::AuraEffectList::const_iterator i = mMod.begin(); i != mMod.end(); ++i)
{
if ((*i)->GetId() == 41337)
{
(*i)->ApplyModifier(false);
- (*i)->GetModifier()->m_amount += 5;
+ (*i)->SetAmount((*i)->GetAmount()+5);
(*i)->ApplyModifier(true);
break;
}
}
- m_modifier.m_amount = 100 * m_tickNumber;
+ m_amount = 100 * m_tickNumber;
}break;
default:
break;
@@ -5359,30 +5737,27 @@ void Aura::PeriodicTick()
CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ //uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ uint32 pdamage = GetAmount() > 0 ? GetAmount() : 0;
- uint32 pdamage;
-
- if(m_modifier.m_auraname == SPELL_AURA_PERIODIC_DAMAGE)
+ if(GetAuraName() == SPELL_AURA_PERIODIC_DAMAGE)
{
- pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),amount,DOT);
+ pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetParentAura()->GetStackAmount());
// Calculate armor mitigation if it is a physical spell
// But not for bleed mechanic spells
if ( GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL &&
GetEffectMechanic(GetSpellProto(), m_effIndex) != MECHANIC_BLEED)
{
- uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage);
+ uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage, GetSpellProto());
cleanDamage.damage += pdamage - pdamageReductedArmor;
pdamage = pdamageReductedArmor;
}
- //pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
-
// Curse of Agony damage-per-tick calculation
- if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 0x0000000000000400LL) && GetSpellProto()->SpellIconID==544)
+ if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags[0] & 0x400) && GetSpellProto()->SpellIconID==544)
{
- uint32 totalTick = m_maxduration / m_modifier.periodictime;
+ uint32 totalTick = GetParentAura()->GetAuraMaxDuration() / m_amplitude;
// 1..4 ticks, 1/2 from normal tick damage
if(m_tickNumber <= totalTick / 3)
pdamage = pdamage/2;
@@ -5393,16 +5768,14 @@ void Aura::PeriodicTick()
}
}
else
- pdamage = uint32(m_target->GetMaxHealth()*amount/100);
+ pdamage = uint32(m_target->GetMaxHealth()*pdamage/100);
//As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit
// Reduce dot damage from resilience for players
if (m_target->GetTypeId()==TYPEID_PLAYER)
pdamage-=((Player*)m_target)->GetDotDamageReduction(pdamage);
- pdamage *= GetStackAmount();
-
- pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
+ pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist, m_spellProto);
sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
@@ -5412,8 +5785,9 @@ void Aura::PeriodicTick()
data.appendPackGUID(GetCasterGUID());
data << uint32(GetId());
data << uint32(1);
- data << uint32(m_modifier.m_auraname);
+ data << uint32(m_auraName);
data << (uint32)pdamage;
+ data << uint32(0); // overkill
data << (uint32)GetSpellSchoolMask(GetSpellProto()); // will be mask in 2.4.x
data << (uint32)absorb;
data << (uint32)resist;
@@ -5434,6 +5808,7 @@ void Aura::PeriodicTick()
break;
}
case SPELL_AURA_PERIODIC_LEECH:
+ case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
{
Unit *pCaster = GetCaster();
if(!pCaster)
@@ -5446,88 +5821,32 @@ void Aura::PeriodicTick()
pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE)
return;
- // Check for immune (not use charges)
- if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
+ // Check for immune
+ if(m_target->IsImmunedToDamage(GetSpellProto()))
return;
uint32 absorb=0;
uint32 resist=0;
CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
- uint32 pdamage = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
- pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
+ //uint32 pdamage = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ uint32 pdamage = GetAmount() > 0 ? GetAmount() : 0;
+ pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetParentAura()->GetStackAmount());
//Calculate armor mitigation if it is a physical spell
if (GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL)
{
- uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage);
+ uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage, GetSpellProto());
cleanDamage.damage += pdamage - pdamageReductedArmor;
pdamage = pdamageReductedArmor;
}
- //pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
-
- // talent Soul Siphon add bonus to Drain Life spells
- if( GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 0x8) )
- {
- // find talent max bonus percentage
- Unit::AuraList const& mClassScriptAuras = pCaster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(Unit::AuraList::const_iterator i = mClassScriptAuras.begin(); i != mClassScriptAuras.end(); ++i)
- {
- if ((*i)->GetModifier()->m_miscvalue == 4992 || (*i)->GetModifier()->m_miscvalue == 4993)
- {
- if((*i)->GetEffIndex()!=1)
- {
- sLog.outError("Expected spell %u structure change, need code update",(*i)->GetId());
- break;
- }
-
- // effect 1 m_amount
- int32 maxPercent = (*i)->GetModifier()->m_amount;
- // effect 0 m_amount
- int32 stepPercent = pCaster->CalculateSpellDamage((*i)->GetSpellProto(),0,(*i)->GetSpellProto()->EffectBasePoints[0],pCaster);
-
- // count affliction effects and calc additional damage in percentage
- int32 modPercent = 0;
- Unit::AuraMap const& victimAuras = m_target->GetAuras();
- for (Unit::AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr)
- {
- Aura* aura = itr->second;
- if (aura->IsPositive())continue;
- SpellEntry const* m_spell = aura->GetSpellProto();
- if (m_spell->SpellFamilyName != SPELLFAMILY_WARLOCK)
- continue;
-
- SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(m_spell->Id);
- SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(m_spell->Id);
-
- for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
- {
- if(_spell_idx->second->skillId == SKILL_AFFLICTION)
- {
- modPercent += stepPercent;
- if (modPercent >= maxPercent)
- {
- modPercent = maxPercent;
- break;
- }
- }
- }
- }
- pdamage += (pdamage*modPercent/100);
- break;
- }
- }
- }
-
//As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit
// Reduce dot damage from resilience for players
if (m_target->GetTypeId()==TYPEID_PLAYER)
pdamage-=((Player*)m_target)->GetDotDamageReduction(pdamage);
- pdamage *= GetStackAmount();
-
- pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
+ pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist, m_spellProto);
if(m_target->GetHealth() < pdamage)
pdamage = uint32(m_target->GetHealth());
@@ -5537,10 +5856,10 @@ void Aura::PeriodicTick()
pCaster->SendSpellNonMeleeDamageLog(m_target, GetId(), pdamage, GetSpellSchoolMask(GetSpellProto()), absorb, resist, false, 0);
-
Unit* target = m_target; // aura can be deleted in DealDamage
SpellEntry const* spellProto = GetSpellProto();
float multiplier = spellProto->EffectMultipleValue[GetEffIndex()] > 0 ? spellProto->EffectMultipleValue[GetEffIndex()] : 1;
+ int32 stackAmount = GetParentAura()->GetStackAmount();
// Set trigger flag
uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;// | PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT;
@@ -5564,12 +5883,11 @@ void Aura::PeriodicTick()
if(Player *modOwner = pCaster->GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_MULTIPLE_VALUE, multiplier);
- uint32 heal = pCaster->SpellHealingBonus(spellProto, uint32(new_damage * multiplier), DOT, pCaster);
+ // Don't apply heal mods for this aura
+ uint32 heal = uint32(new_damage * multiplier);//pCaster->SpellHealingBonus(pCaster, spellProto, uint32(new_damage * multiplier), DOT, stackAmount);
- int32 gain = pCaster->ModifyHealth(heal);
+ int32 gain = pCaster->DealHeal(pCaster, heal, spellProto);
pCaster->getHostilRefManager().threatAssist(pCaster, gain * 0.5f, spellProto);
-
- pCaster->SendHealSpellLog(pCaster, spellProto->Id, heal);
break;
}
case SPELL_AURA_PERIODIC_HEAL:
@@ -5580,53 +5898,52 @@ void Aura::PeriodicTick()
return;
// heal for caster damage (must be alive)
- if(m_target != pCaster && GetSpellProto()->SpellVisual==163 && !pCaster->isAlive())
+ if(m_target != pCaster && GetSpellProto()->SpellVisual[0]==163 && !pCaster->isAlive())
return;
- // ignore non positive values (can be result apply spellmods to aura damage
- uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ if(GetParentAura()->GetAuraDuration() ==-1 && m_target->GetHealth()==m_target->GetMaxHealth())
+ return;
- uint32 pdamage;
+ // ignore non positive values (can be result apply spellmods to aura damage
+ //uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ int32 pdamage = GetAmount() > 0 ? GetAmount() : 0;
- if(m_modifier.m_auraname==SPELL_AURA_OBS_MOD_HEALTH)
- pdamage = uint32(m_target->GetMaxHealth() * amount/100);
+ if(m_auraName==SPELL_AURA_OBS_MOD_HEALTH)
+ pdamage = uint32(m_target->GetMaxHealth() * pdamage * GetParentAura()->GetStackAmount() / 100);
else
- pdamage = pCaster->SpellHealingBonus(GetSpellProto(), amount, DOT, m_target);
-
- pdamage *= GetStackAmount();
-
- //pdamage = pCaster->SpellHealingBonus(GetSpellProto(), pdamage, DOT, m_target);
+ pdamage = pCaster->SpellHealingBonus(m_target, GetSpellProto(), pdamage, DOT, GetParentAura()->GetStackAmount());
sLog.outDetail("PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u",
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
+ int32 gain = m_target->ModifyHealth(pdamage);
+
WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
data.append(m_target->GetPackGUID());
data.appendPackGUID(GetCasterGUID());
data << uint32(GetId());
data << uint32(1);
- data << uint32(m_modifier.m_auraname);
+ data << uint32(m_auraName);
data << (uint32)pdamage;
+ data << uint32(pdamage - gain); // wotlk
m_target->SendMessageToSet(&data,true);
- int32 gain = m_target->ModifyHealth(pdamage);
-
// add HoTs to amount healed in bgs
if( pCaster->GetTypeId() == TYPEID_PLAYER )
if( BattleGround *bg = ((Player*)pCaster)->GetBattleGround() )
bg->UpdatePlayerScore(((Player*)pCaster), SCORE_HEALING_DONE, gain);
//Do check before because m_modifier.auraName can be invalidate by DealDamage.
- bool procSpell = (m_modifier.m_auraname == SPELL_AURA_PERIODIC_HEAL && m_target != pCaster);
+ bool procSpell = (m_auraName == SPELL_AURA_PERIODIC_HEAL && m_target != pCaster);
m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
Unit* target = m_target; // aura can be deleted in DealDamage
SpellEntry const* spellProto = GetSpellProto();
- bool haveCastItem = GetCastItemGUID()!=0;
+ bool haveCastItem = GetParentAura()->GetCastItemGUID()!=0;
// heal for caster damage
- if(m_target!=pCaster && spellProto->SpellVisual==163)
+ if(m_target!=pCaster && spellProto->SpellVisual[0]==163)
{
uint32 dmg = spellProto->manaPerSecond;
if(pCaster->GetHealth() <= dmg && pCaster->GetTypeId()==TYPEID_PLAYER)
@@ -5653,15 +5970,24 @@ void Aura::PeriodicTick()
}
}
- uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;// | PROC_FLAG_SUCCESSFUL_HEAL;
- uint32 procVictim = 0;//ROC_FLAG_ON_TAKE_PERIODIC | PROC_FLAG_TAKEN_HEAL;
+ /*uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;// | PROC_FLAG_SUCCESSFUL_HEAL;
+ uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC; //| PROC_FLAG_TAKEN_HEAL;
// ignore item heals
-// if(procSpell && !haveCastItem)
-// pCaster->ProcDamageAndSpell(target, procAttacker, procVictim, PROC_EX_NORMAL_HIT, pdamage, BASE_ATTACK, spellProto);
+ if(procSpell && !haveCastItem)
+ pCaster->ProcDamageAndSpell(target, procAttacker, procVictim, PROC_EX_NORMAL_HIT, pdamage, BASE_ATTACK, spellProto);*/
break;
}
case SPELL_AURA_PERIODIC_MANA_LEECH:
{
+ if(GetMiscValue() < 0 || GetMiscValue() >= MAX_POWERS)
+ return;
+
+ Powers power = Powers(GetMiscValue());
+
+ // power type might have changed between aura applying and tick (druid's shapeshift)
+ if(m_target->getPowerType() != power)
+ return;
+
Unit *pCaster = GetCaster();
if(!pCaster)
return;
@@ -5674,24 +6000,26 @@ void Aura::PeriodicTick()
return;
// Check for immune (not use charges)
- if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
+ if(m_target->IsImmunedToDamage(GetSpellProto()))
return;
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 pdamage = GetModifierValue() > 0 ? GetModifierValue() : 0;
+ uint32 pdamage = m_amount > 0 ? m_amount : 0;
+
+ // Special case: draining x% of mana (up to a maximum of 2*x% of the caster's maximum mana)
+ // It's mana percent cost spells, m_amount is percent drain from target
+ if (m_spellProto->ManaCostPercentage)
+ {
+ // max value
+ uint32 maxmana = pCaster->GetMaxPower(power) * pdamage * 2 / 100;
+ pdamage = m_target->GetMaxPower(power) * pdamage / 100;
+ if(pdamage > maxmana)
+ pdamage = maxmana;
+ }
sLog.outDetail("PeriodicTick: %u (TypeId: %u) power leech of %u (TypeId: %u) for %u dmg inflicted by %u",
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
- if(m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue > 4)
- break;
-
- Powers power = Powers(m_modifier.m_miscvalue);
-
- // power type might have changed between aura applying and tick (druid's shapeshift)
- if(m_target->getPowerType() != power)
- break;
-
int32 drain_amount = m_target->GetPower(power) > pdamage ? pdamage : m_target->GetPower(power);
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
@@ -5715,7 +6043,7 @@ void Aura::PeriodicTick()
data.appendPackGUID(GetCasterGUID());
data << uint32(GetId());
data << uint32(1);
- data << uint32(m_modifier.m_auraname);
+ data << uint32(m_auraName);
data << (uint32)power; // power type
data << (uint32)drain_amount;
data << (float)gain_multiplier;
@@ -5734,7 +6062,7 @@ void Aura::PeriodicTick()
{
m_target->CastSpell(m_target, 31463, true, 0, this);
// Remove aura
- SetAuraDuration(0);
+ GetParentAura()->SetAuraDuration(0);
}
// Mark of Kazzak
@@ -5747,67 +6075,78 @@ void Aura::PeriodicTick()
{
m_target->CastSpell(m_target, 32961, true, 0, this);
// Remove aura
- SetAuraDuration(0);
+ GetParentAura()->SetAuraDuration(0);
}
}
break;
}
- case SPELL_AURA_PERIODIC_ENERGIZE:
+ case SPELL_AURA_OBS_MOD_ENERGY:
{
- // ignore non positive values (can be result apply spellmods to aura damage
- uint32 pdamage = GetModifierValue() > 0 ? GetModifierValue() : 0;
+ if(GetMiscValue() < 0)
+ return;
- sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u dmg inflicted by %u",
- GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
+ Powers power;
+ if (GetMiscValue() == POWER_ALL)
+ power = m_target->getPowerType();
+ else
+ power = Powers(GetMiscValue());
- if(m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue > 4)
- break;
+ if(m_target->GetMaxPower(power) == 0)
+ return;
- Powers power = Powers(m_modifier.m_miscvalue);
+ if(GetParentAura()->GetAuraDuration() ==-1 && m_target->GetPower(power)==m_target->GetMaxPower(power))
+ return;
- if(m_target->GetMaxPower(power) == 0)
- break;
+ uint32 amount = m_amount * m_target->GetMaxPower(power) /100;
+ sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u dmg inflicted by %u",
+ GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), amount, GetId());
WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
data.append(m_target->GetPackGUID());
data.appendPackGUID(GetCasterGUID());
data << uint32(GetId());
data << uint32(1);
- data << uint32(m_modifier.m_auraname);
- data << (uint32)power; // power type
- data << (uint32)pdamage;
+ data << uint32(m_auraName);
+ data << uint32(power); // power type
+ data << (uint32)amount;
m_target->SendMessageToSet(&data,true);
- int32 gain = m_target->ModifyPower(power,pdamage);
+ int32 gain = m_target->ModifyPower(power,amount);
if(Unit* pCaster = GetCaster())
m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
break;
}
- case SPELL_AURA_OBS_MOD_MANA:
+ case SPELL_AURA_PERIODIC_ENERGIZE:
{
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 amount = GetModifierValue() > 0 ? GetModifierValue() : 0;
+ if(m_amount < 0 || GetMiscValue() >= MAX_POWERS)
+ return;
- uint32 pdamage = uint32(m_target->GetMaxPower(POWER_MANA) * amount/100);
+ Powers power = Powers(GetMiscValue());
- sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u mana inflicted by %u",
- GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
+ if(m_target->GetMaxPower(power) == 0)
+ return;
- if(m_target->GetMaxPower(POWER_MANA) == 0)
- break;
+ if(GetParentAura()->GetAuraDuration() ==-1 && m_target->GetPower(power)==m_target->GetMaxPower(power))
+ return;
+
+ uint32 amount = m_amount;
WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
data.append(m_target->GetPackGUID());
data.appendPackGUID(GetCasterGUID());
data << uint32(GetId());
data << uint32(1);
- data << uint32(m_modifier.m_auraname);
- data << (uint32)0; // ?
- data << (uint32)pdamage;
+ data << uint32(m_auraName);
+ data << (uint32)power; // power type
+ data << (uint32)amount;
m_target->SendMessageToSet(&data,true);
- int32 gain = m_target->ModifyPower(POWER_MANA, pdamage);
+ sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u dmg inflicted by %u",
+ GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), amount, GetId());
+
+ int32 gain = m_target->ModifyPower(power,amount);
if(Unit* pCaster = GetCaster())
m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
@@ -5820,12 +6159,12 @@ void Aura::PeriodicTick()
return;
// Check for immune (not use charges)
- if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
+ if(m_target->IsImmunedToDamage(GetSpellProto()))
return;
- int32 pdamage = GetModifierValue() > 0 ? GetModifierValue() : 0;
+ int32 pdamage = m_amount > 0 ? m_amount : 0;
- Powers powerType = Powers(m_modifier.m_miscvalue);
+ Powers powerType = Powers(GetMiscValue());
if(!m_target->isAlive() || m_target->getPowerType() != powerType)
return;
@@ -5857,127 +6196,143 @@ void Aura::PeriodicTick()
pCaster->DealSpellDamage(&damageInfo, true);
break;
}
+ case SPELL_AURA_MOD_REGEN:
+ {
+ int32 gain = m_target->ModifyHealth(m_amount);
+ if (Unit *caster = GetCaster())
+ m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, GetSpellProto());
+ break;
+ }
+ case SPELL_AURA_MOD_POWER_REGEN:
+ {
+ Powers pt = m_target->getPowerType();
+ if(int32(pt) != GetMiscValue())
+ return;
+
+ if ( GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED )
+ {
+ // eating anim
+ m_target->HandleEmoteCommand(EMOTE_ONESHOT_EAT);
+ }
+ else if( GetId() == 20577 )
+ {
+ // cannibalize anim
+ m_target->HandleEmoteCommand(EMOTE_STATE_CANNIBALIZE);
+ }
+
+ // Anger Management
+ // amount = 1+ 16 = 17 = 3,4*5 = 10,2*5/3
+ // so 17 is rounded amount for 5 sec tick grow ~ 1 range grow in 3 sec
+ if(pt == POWER_RAGE)
+ m_target->ModifyPower(pt, m_amount*3/5);
+ break;
+ }
+ case SPELL_AURA_DUMMY:
+ {
+ // Haunting Spirits
+ if (GetId() == 7057)
+ {
+ m_target->CastSpell((Unit*)NULL , m_amount , true);
+ m_amplitude = irand (0 , 60 ) + 30;
+ m_amplitude *= IN_MILISECONDS;
+ break;
+ }
+ break;
+ }
// Here tick dummy auras
case SPELL_AURA_PERIODIC_DUMMY:
{
PeriodicDummyTick();
break;
}
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
+ {
+ TriggerSpell();
+ break;
+ }
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
+ {
+ TriggerSpellWithValue();
+ break;
+ }
default:
break;
}
}
-void Aura::PeriodicDummyTick()
+void AuraEffect::PeriodicDummyTick()
{
+ Unit *caster = GetCaster();
SpellEntry const* spell = GetSpellProto();
- switch (spell->Id)
- {
- // Drink
- case 430:
- case 431:
- case 432:
- case 1133:
- case 1135:
- case 1137:
- case 10250:
- case 22734:
- case 27089:
- case 34291:
- case 43706:
- case 46755:
+ switch (spell->SpellFamilyName)
+ {
+ case SPELLFAMILY_GENERIC:
+ switch (spell->Id)
{
- if (m_target->GetTypeId() != TYPEID_PLAYER)
- return;
- // Search SPELL_AURA_MOD_POWER_REGEN aura for this spell and add bonus
- Unit::AuraList const& aura = m_target->GetAurasByType(SPELL_AURA_MOD_POWER_REGEN);
- for(Unit::AuraList::const_iterator i = aura.begin(); i != aura.end(); ++i)
+ // Drink
+ case 430:
+ case 431:
+ case 432:
+ case 1133:
+ case 1135:
+ case 1137:
+ case 10250:
+ case 22734:
+ case 27089:
+ case 34291:
+ case 43706:
+ case 46755:
+ case 49472: // Drink Coffee
+ case 61830:
{
- if ((*i)->GetId() == GetId())
+ if (m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+ // Search SPELL_AURA_MOD_POWER_REGEN aura for this spell and add bonus
+ Unit::AuraEffectList const& aura = m_target->GetAurasByType(SPELL_AURA_MOD_POWER_REGEN);
+ for(Unit::AuraEffectList::const_iterator i = aura.begin(); i != aura.end(); ++i)
{
- // Get tick number
- int32 tick = (m_maxduration - m_duration) / m_modifier.periodictime;
- // Default case (not on arenas)
- if (tick == 0)
+ if ((*i)->GetId() == GetId())
{
- (*i)->GetModifier()->m_amount = m_modifier.m_amount;
+ (*i)->SetAmount(m_amount);
((Player*)m_target)->UpdateManaRegen();
// Disable continue
m_isPeriodic = false;
- }
- return;
- //**********************************************
- // Code commended since arena patch not added
- // This feature uses only in arenas
- //**********************************************
- // Here need increase mana regen per tick (6 second rule)
- // on 0 tick - 0 (handled in 2 second)
- // on 1 tick - 166% (handled in 4 second)
- // on 2 tick - 133% (handled in 6 second)
- // Not need update after 3 tick
- /*
- if (tick > 3)
return;
- // Apply bonus for 0 - 3 tick
- switch (tick)
- {
- case 0: // 0%
- (*i)->GetModifier()->m_amount = m_modifier.m_amount = 0;
- break;
- case 1: // 166%
- (*i)->GetModifier()->m_amount = m_modifier.m_amount * 5 / 3;
- break;
- case 2: // 133%
- (*i)->GetModifier()->m_amount = m_modifier.m_amount * 4 / 3;
- break;
- default: // 100% - normal regen
- (*i)->GetModifier()->m_amount = m_modifier.m_amount;
- break;
}
- ((Player*)m_target)->UpdateManaRegen();
- return;*/
}
+ return;
+ }
+ // Forsaken Skills
+ case 7054:
+ {
+ // Possibly need cast one of them (but
+ // 7038 Forsaken Skill: Swords
+ // 7039 Forsaken Skill: Axes
+ // 7040 Forsaken Skill: Daggers
+ // 7041 Forsaken Skill: Maces
+ // 7042 Forsaken Skill: Staves
+ // 7043 Forsaken Skill: Bows
+ // 7044 Forsaken Skill: Guns
+ // 7045 Forsaken Skill: 2H Axes
+ // 7046 Forsaken Skill: 2H Maces
+ // 7047 Forsaken Skill: 2H Swords
+ // 7048 Forsaken Skill: Defense
+ // 7049 Forsaken Skill: Fire
+ // 7050 Forsaken Skill: Frost
+ // 7051 Forsaken Skill: Holy
+ // 7053 Forsaken Skill: Shadow
+ return;
}
- return;
- }
// // Panda
// case 19230: break;
-// // Master of Subtlety
-// case 31666: break;
// // Gossip NPC Periodic - Talk
// case 33208: break;
// // Gossip NPC Periodic - Despawn
// case 33209: break;
-// // Force of Nature
-// case 33831: break;
- // Aspect of the Viper
- case 34074:
- {
- if (m_target->GetTypeId() != TYPEID_PLAYER)
- return;
- // Should be manauser
- if (m_target->getPowerType()!=POWER_MANA)
- return;
- Unit *caster = GetCaster();
- if (!caster)
- return;
- // Regen amount is max (100% from spell) on 21% or less mana and min on 92.5% or greater mana (20% from spell)
- int mana = m_target->GetPower(POWER_MANA);
- int max_mana = m_target->GetMaxPower(POWER_MANA);
- int32 base_regen = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, m_target);
- float regen_pct = 1.20f - 1.1f * mana / max_mana;
- if (regen_pct > 1.0f) regen_pct = 1.0f;
- else if (regen_pct < 0.2f) regen_pct = 0.2f;
- m_modifier.m_amount = int32 (base_regen * regen_pct);
- ((Player*)m_target)->UpdateManaRegen();
- return;
- }
// // Steal Weapon
// case 36207: break;
// // Simon Game START timer, (DND)
// case 39993: break;
-// // Harpooner's Mark
-// case 40084: break;
// // Knockdown Fel Cannon: break; The Aggro Burst
// case 40119: break;
// // Old Mount Spell
@@ -5990,6 +6345,8 @@ void Aura::PeriodicDummyTick()
// case 40846: break;
// // Copy Weapon
// case 41054: break;
+// // Dementia
+// case 41404: break;
// // Ethereal Ring Visual, Lightning Aura
// case 41477: break;
// // Ethereal Ring Visual, Lightning Aura (Fork)
@@ -6038,6 +6395,8 @@ void Aura::PeriodicDummyTick()
// case 43310: break;
// // Headless Horseman - Maniacal Laugh, Maniacal, Delayed 17
// case 43884: break;
+// // Wretched!
+// case 43963: break;
// // Headless Horseman - Maniacal Laugh, Maniacal, other, Delayed 17
// case 44000: break;
// // Energy Feedback
@@ -6104,25 +6463,199 @@ void Aura::PeriodicDummyTick()
// case 47407: break;
// // Mole Machine Port Schedule
// case 47489: break;
+// case 47941: break; // Crystal Spike
+// case 48200: break; // Healer Aura
+// case 48630: break; // Summon Gauntlet Mobs Periodic
+// case 49313: break; // Proximity Mine Area Aura
// // Mole Machine Portal Schedule
// case 49466: break;
-// // Drink Coffee
-// case 49472: break;
+// case 49555: break; // Corpse Explode
+// case 49592: break; // Temporal Rift
+// case 49957: break; // Cutting Laser
+// case 50085: break; // Slow Fall
// // Listening to Music
// case 50493: break;
// // Love Rocket Barrage
// case 50530: break;
+// Exist more after, need add later
+ default:
+ break;
+ }
+ break;
+ case SPELLFAMILY_MAGE:
+ {
+ // Mirror Image
+// if (spell->Id == 55342)
+// return;
+ break;
+ }
+ case SPELLFAMILY_WARRIOR:
+ {
+ // Armored to the Teeth
+ if (spell->SpellIconID == 3516)
+ {
+ // Increases your attack power by $s1 for every $s2 armor value you have.
+ // Calculate AP bonus (from 1 efect of this spell)
+ int32 apBonus = m_amount * m_target->GetArmor() / m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target);
+ m_target->CastCustomSpell(m_target, 61217, &apBonus, &apBonus, 0, true, 0, this);
+ return;
+ }
+ break;
+ }
+ case SPELLFAMILY_DRUID:
+ {
+ switch (spell->Id)
+ {
+ // Frenzied Regeneration
+ case 22842:
+ {
+ // Converts up to 10 rage per second into health for $d. Each point of rage is converted into ${$m2/10}.1% of max health.
+ // Should be manauser
+ if (m_target->getPowerType()!=POWER_RAGE)
+ return;
+ uint32 rage = m_target->GetPower(POWER_RAGE);
+ // Nothing todo
+ if (rage == 0)
+ return;
+ int32 mod = (rage < 100) ? rage : 100;
+ int32 points = m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target);
+ int32 regen = m_target->GetMaxHealth() * (mod * points / 10) / 1000;
+ m_target->CastCustomSpell(m_target, 22845, &regen, 0, 0, true, 0, this);
+ m_target->SetPower(POWER_RAGE, rage-mod);
+ return;
+ }
+ // Force of Nature
+ case 33831:
+ return;
+ default:
+ break;
+ }
+ break;
+ }
+ case SPELLFAMILY_ROGUE:
+ {
+ switch (spell->Id)
+ {
+ // Killing Spree
+// case 51690: break;
+ // Overkill
+ case 58428:
+ if (!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH))
+ m_target->RemoveAurasDueToSpell(58427);
+ break;
+ // Master of Subtlety
+ case 31666:
+ if (!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH))
+ m_target->RemoveAurasDueToSpell(31665);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case SPELLFAMILY_HUNTER:
+ {
+ // Explosive Shot
+ if (spell->SpellFamilyFlags[1] & 0x80000000)
+ {
+ if (!caster)
+ return;
+ int32 damage = m_amount;
+ caster->CastCustomSpell(m_target, 56298, &damage, 0, 0, true, 0, this);
+ return;
+ }
+ switch (spell->Id)
+ {
+ // Harpooner's Mark
+ // case 40084:
+ // return;
+ // Feeding Frenzy Rank 1
+ case 53511:
+ if ( m_target->GetHealth() * 100 < m_target->GetMaxHealth() * 35 )
+ m_target->CastSpell(m_target, 60096, true, 0, this);
+ return;
+ // Feeding Frenzy Rank 2
+ case 53512:
+ if ( m_target->GetHealth() * 100 < m_target->GetMaxHealth() * 35 )
+ m_target->CastSpell(m_target, 60097, true, 0, this);
+ return;
+ default:
+ break;
+ }
+ break;
+ }
+ case SPELLFAMILY_SHAMAN:
+ {
+ // Astral Shift
+ if (spell->Id == 52179)
+ {
+ // Periodic need for remove visual on stun/fear/silence lost
+ if (!(m_target->GetUInt32Value(UNIT_FIELD_FLAGS)&(UNIT_FLAG_STUNNED|UNIT_FLAG_FLEEING|UNIT_FLAG_SILENCED)))
+ m_target->RemoveAurasDueToSpell(52179);
+ return;
+ }
+ break;
+ }
+ case SPELLFAMILY_DEATHKNIGHT:
+ {
+ // Death and Decay
+ if (spell->SpellFamilyFlags[0] & 0x20)
+ {
+ if (caster)
+ caster->CastCustomSpell(m_target, 52212, &m_amount, NULL, NULL, true, 0, this);
+ return;
+ }
+ // Raise Dead
+// if (spell->SpellFamilyFlags & 0x0000000000001000LL)
+// return;
+ // Chains of Ice
+ if (spell->SpellFamilyFlags[1] & 0x00004000)
+ {
+ // Get 0 effect aura
+ AuraEffect *slow = m_target->GetAuraEffect(GetId(), 0);
+ if (slow)
+ {
+ slow->ApplyModifier(false);;
+ slow->SetAmount(GetAmount()*2);
+ if (slow->GetAmount() > 0) slow->SetAmount(0);
+ slow->ApplyModifier(true);
+ }
+ return;
+ }
+ // Summon Gargoyle
+// if (spell->SpellFamilyFlags & 0x0000008000000000LL)
+// return;
+ // Death Rune Mastery
+// if (spell->SpellFamilyFlags & 0x0000000000004000LL)
+// return;
+ // Bladed Armor
+ if (spell->SpellIconID == 2653)
+ {
+ // Increases your attack power by $s1 for every $s2 armor value you have.
+ // Calculate AP bonus (from 1 efect of this spell)
+ int32 apBonus = m_amount * m_target->GetArmor() / m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target);
+ m_target->CastCustomSpell(m_target, 61217, &apBonus, &apBonus, 0, true, 0, this);
+ return;
+ }
+ // Reaping
+// if (spell->SpellIconID == 22)
+// return;
+ // Blood of the North
+// if (spell->SpellIconID == 30412)
+// return;
+ break;
+ }
default:
break;
}
}
-void Aura::HandlePreventFleeing(bool apply, bool Real)
+void AuraEffect::HandlePreventFleeing(bool apply, bool Real)
{
if(!Real)
return;
- Unit::AuraList const& fearAuras = m_target->GetAurasByType(SPELL_AURA_MOD_FEAR);
+ Unit::AuraEffectList const& fearAuras = m_target->GetAurasByType(SPELL_AURA_MOD_FEAR);
if( !fearAuras.empty() )
{
m_target->SetControlled(!apply, UNIT_STAT_FLEEING);
@@ -6133,7 +6666,7 @@ void Aura::HandlePreventFleeing(bool apply, bool Real)
}
}
-void Aura::HandleManaShield(bool apply, bool Real)
+void AuraEffect::HandleManaShield(bool apply, bool Real)
{
if(!Real)
return;
@@ -6147,7 +6680,7 @@ void Aura::HandleManaShield(bool apply, bool Real)
switch(m_spellProto->SpellFamilyName)
{
case SPELLFAMILY_MAGE:
- if(m_spellProto->SpellFamilyFlags & 0x8000)
+ if(m_spellProto->SpellFamilyFlags[0] & 0x8000)
{
// Mana Shield
// +50% from +spd bonus
@@ -6161,12 +6694,12 @@ void Aura::HandleManaShield(bool apply, bool Real)
DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellProto());
- m_modifier.m_amount += (int32)DoneActualBenefit;
+ m_amount += (int32)DoneActualBenefit;
}
}
}
-void Aura::HandleArenaPreparation(bool apply, bool Real)
+void AuraEffect::HandleArenaPreparation(bool apply, bool Real)
{
if(!Real)
return;
@@ -6177,3 +6710,220 @@ void Aura::HandleArenaPreparation(bool apply, bool Real)
m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION);
}
+void AuraEffect::HandleAuraControlVehicle(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ if(m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if(Pet *pet = ((Player*)m_target)->GetPet())
+ pet->Remove(PET_SAVE_AS_CURRENT);
+
+ //WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
+ //((Player*)m_target)->GetSession()->SendPacket(&data);
+}
+
+void AuraEffect::HandleAuraConvertRune(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ if(m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ Player *plr = (Player*)m_target;
+
+ if(plr->getClass() != CLASS_DEATH_KNIGHT)
+ return;
+
+ // how to determine what rune need to be converted?
+ for(uint32 i = 0; i < MAX_RUNES; ++i)
+ {
+ if(apply)
+ {
+ if(!plr->GetRuneCooldown(i))
+ {
+ plr->ConvertRune(i, GetSpellProto()->EffectMiscValueB[m_effIndex]);
+ break;
+ }
+ }
+ else
+ {
+ if(plr->GetCurrentRune(i) == GetSpellProto()->EffectMiscValueB[m_effIndex])
+ {
+ plr->ConvertRune(i, plr->GetBaseRune(i));
+ break;
+ }
+ }
+ }
+}
+
+// Control Auras
+
+void AuraEffect::HandleAuraModStun(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ m_target->SetControlled(apply, UNIT_STAT_STUNNED);
+}
+
+void AuraEffect::HandleAuraModRoot(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ m_target->SetControlled(apply, UNIT_STAT_ROOT);
+}
+
+// Charm Auras
+
+void AuraEffect::HandleModPossess(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ Unit* caster = GetCaster();
+ if(caster && caster->GetTypeId() == TYPEID_UNIT)
+ {
+ HandleModCharm(apply, Real);
+ return;
+ }
+
+ if(apply)
+ {
+ if(m_target->getLevel() > m_amount)
+ return;
+
+ m_target->SetCharmedOrPossessedBy(caster, true);
+ }
+ else
+ m_target->RemoveCharmedOrPossessedBy(caster);
+}
+
+void AuraEffect::HandleModPossessPet(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ Unit* caster = GetCaster();
+ if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if(apply)
+ {
+ if(caster->GetGuardianPet() != m_target)
+ return;
+
+ m_target->SetCharmedOrPossessedBy(caster, true);
+ }
+ else
+ {
+ m_target->RemoveCharmedOrPossessedBy(caster);
+
+ // Reinitialize the pet bar and make the pet come back to the owner
+ ((Player*)caster)->PetSpellInitialize();
+ if(!m_target->getVictim())
+ {
+ m_target->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ m_target->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
+ }
+ }
+}
+
+void AuraEffect::HandleModCharm(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ Unit* caster = GetCaster();
+
+ if(apply)
+ {
+ if(int32(m_target->getLevel()) > m_amount)
+ return;
+
+ m_target->SetCharmedOrPossessedBy(caster, false);
+ }
+ else
+ m_target->RemoveCharmedOrPossessedBy(caster);
+}
+
+void AuraEffect::HandlePhase(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ // always non stackable
+ if(apply)
+ {
+ m_target->RemoveAurasByType(SPELL_AURA_PHASE, NULL, GetParentAura());
+ }
+
+ // no-phase is also phase state so same code for apply and remove
+
+ // phase auras normally not expected at BG but anyway better check
+ if(m_target->GetTypeId()==TYPEID_PLAYER)
+ {
+ // drop flag at invisible in bg
+ if(((Player*)m_target)->InBattleGround())
+ if(BattleGround *bg = ((Player*)m_target)->GetBattleGround())
+ bg->EventPlayerDroppedFlag((Player*)m_target);
+
+ // GM-mode have mask 0xFFFFFFFF
+ if(!((Player*)m_target)->isGameMaster())
+ m_target->SetPhaseMask(apply ? GetMiscValue() : PHASEMASK_NORMAL,false);
+
+ ((Player*)m_target)->GetSession()->SendSetPhaseShift(apply ? GetMiscValue() : PHASEMASK_NORMAL);
+
+ if(GetEffIndex()==0)
+ {
+ SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAuraMapBounds(GetId());
+ if(saBounds.first != saBounds.second)
+ {
+ uint32 zone, area;
+ m_target->GetZoneAndAreaId(zone,area);
+
+ for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
+ {
+ // some auras remove at aura remove
+ if(!itr->second->IsFitToRequirements((Player*)m_target,zone,area))
+ m_target->RemoveAurasDueToSpell(itr->second->spellId);
+ // some auras applied at aura apply
+ else if(itr->second->autocast)
+ {
+ if( !m_target->HasAura(itr->second->spellId) )
+ m_target->CastSpell(m_target,itr->second->spellId,true);
+ }
+ }
+ }
+ }
+ }
+ else
+ m_target->SetPhaseMask(apply ? GetMiscValue() : PHASEMASK_NORMAL,false);
+
+ // need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases)
+ if(m_target->GetVisibility()!=VISIBILITY_OFF)
+ m_target->SetVisibility(m_target->GetVisibility());
+}
+
+void Aura::UnregisterSingleCastAura()
+{
+ if (IsSingleTarget())
+ {
+ Unit* caster = NULL;
+ caster = GetCaster();
+ if(caster)
+ {
+ caster->GetSingleCastAuras().remove(this);
+ }
+ else
+ {
+ sLog.outError("Couldn't find the caster of the single target aura, may crash later!");
+ assert(false);
+ }
+ m_isSingleTargetAura = false;
+ }
+}
diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h
index 40552a3cb40..89d8da7e500 100644
--- a/src/game/SpellAuras.h
+++ b/src/game/SpellAuras.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,23 +22,6 @@
#include "SpellAuraDefines.h"
-struct DamageManaShield
-{
- uint32 m_spellId;
- uint32 m_modType;
- int32 m_schoolType;
- uint32 m_totalAbsorb;
- uint32 m_currAbsorb;
-};
-
-struct Modifier
-{
- AuraType m_auraname;
- int32 m_amount;
- int32 m_miscvalue;
- uint32 periodictime;
-};
-
class Unit;
struct SpellEntry;
struct SpellModifier;
@@ -46,8 +29,9 @@ struct ProcTriggerSpell;
// forward decl
class Aura;
+class AuraEffect;
-typedef void(Aura::*pAuraHandler)(bool Apply, bool Real);
+typedef void(AuraEffect::*pAuraHandler)(bool Apply, bool Real);
// Real == true at aura add/remove
// Real == false at aura mod unapply/reapply; when adding/removing dependent aura/item/stat mods
//
@@ -63,9 +47,126 @@ typedef void(Aura::*pAuraHandler)(bool Apply, bool Real);
class TRINITY_DLL_SPEC Aura
{
- friend Aura* CreateAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem);
+ friend void Player::SendAurasForTarget(Unit *target);
+ public:
+ virtual ~Aura();
+ Aura(SpellEntry const* spellproto, uint32 effMask, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL, Unit * formalCaster=NULL);
+
+ SpellEntry const* GetSpellProto() const { return m_spellProto; }
+ uint32 GetId() const{ return m_spellProto->Id; }
+ uint64 GetCastItemGUID() const { return m_castItemGuid; }
+
+ uint64 const& GetCasterGUID() const { return m_caster_guid; }
+ Unit* GetCaster() const;
+ Unit* GetTarget() const { return m_target; }
+ time_t GetAuraApplyTime() const { return m_applyTime; }
+
+ int32 GetAuraMaxDuration() const { return m_maxduration; }
+ void SetAuraMaxDuration(int32 duration) { m_maxduration = duration; }
+ int32 GetAuraDuration() const { return m_duration; }
+ void SetAuraDuration(int32 duration);
+ void RefreshAura(){ SetAuraDuration (m_maxduration); }
+
+ void SendAuraUpdate();
+ uint8 GetAuraSlot() const { return m_auraSlot; }
+ void SetAuraSlot(uint8 slot) { m_auraSlot = slot; }
+ uint8 GetAuraCharges() const { return m_procCharges; }
+ void SetAuraCharges(uint8 charges);
+ void DropAuraCharge();
+ void SetProcDamage(uint32 val) { m_procDamage = val; }
+ uint32 GetProcDamage() const { return m_procDamage; }
+
+ int8 GetStackAmount() const {return m_stackAmount;}
+ void SetStackAmount(uint8 num);
+ bool modStackAmount(int32 num); // return true if last charge dropped
+ uint32 GetAuraStateMask(){return m_auraStateMask;}
+ void SetAuraState(uint8 num){m_auraStateMask |= 1<<(num-1);} //modifies aura's aura state (not unit!)
+
+ void SetRemoveMode(AuraRemoveMode mode) { m_removeMode = mode; }
+ uint8 GetRemoveMode() const {return m_removeMode;}
+
+ inline uint8 GetEffectMask() const {return m_auraFlags & 7;}
+ AuraEffect * GetPartAura (uint8 effIndex) const {return m_partAuras[effIndex];}
+ bool SetPartAura(AuraEffect* aurEff, uint8 effIndex);
+ bool IsPositive() const { return m_positive; }
+ void SetNegative() { m_positive = false; }
+ void SetPositive() { m_positive = true; }
+ bool IsPermanent() const { return m_permanent; }
+ void SetPermanent(bool val) { m_permanent = val; }
+
+ bool IsPassive() const { return m_isPassive; }
+ bool IsDeathPersistent() const { return m_isDeathPersist; }
+ bool IsRemovedOnShapeLost() const { return m_isRemovedOnShapeLost; }
+ bool IsUpdated() const { return m_updated; }
+ bool IsRemoved() const { return m_isRemoved; }
+ void SetUpdated(bool val) { m_updated = val; }
+
+ bool IsPersistent() const;
+ bool IsAreaAura() const;
+ bool IsAuraType(AuraType type) const;
+ void SetLoadedState(uint64 caster_guid,int32 maxduration,int32 duration,int32 charges, uint8 stackamount, int32 * amount);
+ bool HasEffect(uint8 effIndex) const {return bool (m_partAuras[effIndex]);}
+ inline void HandleEffects(bool apply)
+ {
+ for (uint8 i = 0; i<MAX_SPELL_EFFECTS;++i)
+ if (m_partAuras[i])
+ m_target->HandleAuraEffect(m_partAuras[i], apply);
+ }
+ void ApplyAllModifiers(bool apply, bool Real=false);
+
+ void Update(uint32 diff);
+
+ void _AddAura();
+ void _RemoveAura();
+
+ // Allow Apply Aura Handler to modify and access m_AuraDRGroup
+ void setDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; }
+ DiminishingGroup getDiminishGroup() const { return m_AuraDRGroup; }
+
+ // Single cast aura helpers
+ void UnregisterSingleCastAura();
+ bool IsSingleTarget() const {return m_isSingleTargetAura;}
+ void SetIsSingleTarget(bool val) { m_isSingleTargetAura = val;}
+
+ private:
+ SpellEntry const *m_spellProto;
+ Unit * const m_target;
+ uint64 m_caster_guid;
+ uint64 m_castItemGuid; // it is NOT safe to keep a pointer to the item because it may get deleted
+ time_t m_applyTime;
+
+ int32 m_maxduration; // Max aura duration
+ int32 m_duration; // Current time
+ int32 m_timeCla; // Timer for power per sec calcultion
+
+ AuraRemoveMode m_removeMode:8; // Store info for know remove aura reason
+ DiminishingGroup m_AuraDRGroup:8; // Diminishing
+
+ uint8 m_auraSlot; // Aura slot on unit (for show in client)
+ uint8 m_auraFlags; // Aura info flag (for send data to client)
+ uint8 m_auraLevel; // Aura level (store caster level for correct show level dep amount)
+ uint8 m_procCharges; // Aura charges (0 for infinite)
+ uint32 m_procDamage; // used in aura proc code
+ uint8 m_stackAmount; // Aura stack amount
+ uint32 m_auraStateMask;
+ AuraEffect * m_partAuras[3];
+
+ bool m_isDeathPersist:1;
+ bool m_isRemovedOnShapeLost:1;
+ bool m_isPassive:1;
+ bool m_positive:1;
+ bool m_permanent:1;
+ bool m_isRemoved:1;
+ bool m_updated:1; // Prevent remove aura by stack if set
+ bool m_isSingleTargetAura:1; // true if it's a single target spell and registered at caster - can change at spell steal for example
+};
+
+class TRINITY_DLL_SPEC AuraEffect
+{
public:
+ friend AuraEffect* CreateAuraEffect(Aura * parentAura, uint32 effIndex, int32 *currentBasePoints, Unit * caster, Item * castItem, Unit * formalCaster);
+ friend void Aura::SetStackAmount(uint8 stackAmount);
//aura handlers
void HandleNULL(bool, bool)
{
@@ -100,6 +201,7 @@ class TRINITY_DLL_SPEC Aura
void HandleAuraFeatherFall(bool Apply, bool Real);
void HandleAuraHover(bool Apply, bool Real);
void HandleAddModifier(bool Apply, bool Real);
+ void HandleAddTargetTrigger(bool Apply, bool Real);
void HandleAuraModStun(bool Apply, bool Real);
void HandleModDamageDone(bool Apply, bool Real);
void HandleAuraUntrackable(bool Apply, bool Real);
@@ -111,13 +213,15 @@ class TRINITY_DLL_SPEC Aura
void HandleAuraModRegenInterrupt(bool Apply, bool Real);
void HandleHaste(bool Apply, bool Real);
void HandlePeriodicTriggerSpell(bool Apply, bool Real);
+ void HandlePeriodicTriggerSpellWithValue(bool apply, bool Real);
void HandlePeriodicEnergize(bool Apply, bool Real);
void HandleAuraModResistanceExclusive(bool Apply, bool Real);
+ void HandleAuraModPetTalentsPoints(bool Apply, bool Real);
void HandleModStealth(bool Apply, bool Real);
void HandleInvisibility(bool Apply, bool Real);
void HandleInvisibilityDetect(bool Apply, bool Real);
void HandleAuraModTotalHealthPercentRegen(bool Apply, bool Real);
- void HandleAuraModTotalManaPercentRegen(bool Apply, bool Real);
+ void HandleAuraModTotalEnergyPercentRegen(bool Apply, bool Real);
void HandleAuraModResistance(bool Apply, bool Real);
void HandleAuraModRoot(bool Apply, bool Real);
void HandleAuraModSilence(bool Apply, bool Real);
@@ -147,6 +251,7 @@ class TRINITY_DLL_SPEC Aura
void HandleModSpellHitChance(bool Apply, bool Real);
void HandleAuraModScale(bool Apply, bool Real);
void HandlePeriodicManaLeech(bool Apply, bool Real);
+ void HandlePeriodicHealthFunnel(bool apply, bool Real);
void HandleModCastingSpeed(bool Apply, bool Real);
void HandleAuraMounted(bool Apply, bool Real);
void HandleWaterBreathing(bool Apply, bool Real);
@@ -165,6 +270,7 @@ class TRINITY_DLL_SPEC Aura
void HandleFarSight(bool Apply, bool Real);
void HandleModPossessPet(bool Apply, bool Real);
void HandleModMechanicImmunity(bool Apply, bool Real);
+ void HandleModStateImmunityMask(bool apply, bool Real);
void HandleAuraModSkill(bool Apply, bool Real);
void HandleModDamagePercentDone(bool Apply, bool Real);
void HandleModPercentStat(bool Apply, bool Real);
@@ -184,10 +290,12 @@ class TRINITY_DLL_SPEC Aura
void HandleAuraGhost(bool Apply, bool Real);
void HandleAuraAllowFlight(bool Apply, bool Real);
void HandleModRating(bool apply, bool Real);
+ void HandleModRatingFromStat(bool apply, bool Real);
void HandleModTargetResistance(bool apply, bool Real);
void HandleAuraModAttackPowerPercent(bool apply, bool Real);
void HandleAuraModRangedAttackPowerPercent(bool apply, bool Real);
void HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real);
+ void HandleAuraModAttackPowerOfStatPercent(bool apply, bool Real);
void HandleSpiritOfRedemption(bool apply, bool Real);
void HandleModManaRegen(bool apply, bool Real);
void HandleComprehendLanguage(bool apply, bool Real);
@@ -197,6 +305,7 @@ class TRINITY_DLL_SPEC Aura
void HandleModSpellDamagePercentFromStat(bool apply, bool Real);
void HandleModSpellHealingPercentFromStat(bool apply, bool Real);
void HandleAuraModDispelResist(bool apply, bool Real);
+ void HandleAuraControlVehicle(bool apply, bool Real);
void HandleModSpellDamagePercentFromAttackPower(bool apply, bool Real);
void HandleModSpellHealingPercentFromAttackPower(bool apply, bool Real);
void HandleAuraModPacifyAndSilence(bool Apply, bool Real);
@@ -209,171 +318,92 @@ class TRINITY_DLL_SPEC Aura
void HandlePreventFleeing(bool apply, bool Real);
void HandleManaShield(bool apply, bool Real);
void HandleArenaPreparation(bool apply, bool Real);
+ void HandleAuraConvertRune(bool apply, bool Real);
+ void HandleAuraIncreaseBaseHealthPercent(bool Apply, bool Real);
+ void HandleNoReagentUseAura(bool Apply, bool Real);
+ void HandlePhase(bool Apply, bool Real);
+ void HandleAuraAllowOnlyAbility(bool apply, bool Real);
- virtual ~Aura();
+ // add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras
+ void HandleShapeshiftBoosts(bool apply);
- void SetModifier(AuraType t, int32 a, uint32 pt, int32 miscValue);
- Modifier* GetModifier() {return &m_modifier;}
- int32 GetModifierValuePerStack() {return m_modifier.m_amount;}
- int32 GetModifierValue() {return m_modifier.m_amount * m_stackAmount;}
- int32 GetMiscValue() {return m_spellProto->EffectMiscValue[m_effIndex];}
- int32 GetMiscBValue() {return m_spellProto->EffectMiscValueB[m_effIndex];}
+ inline Unit * GetCaster() const{ return m_parentAura->GetCaster(); }
+ inline uint64 GetCasterGUID() const{ return m_parentAura->GetCasterGUID(); }
+ Aura * GetParentAura() const { return m_parentAura; }
SpellEntry const* GetSpellProto() const { return m_spellProto; }
- uint32 GetId() const{ return m_spellProto->Id; }
- uint64 GetCastItemGUID() const { return m_castItemGuid; }
- uint32 GetEffIndex() const{ return m_effIndex; }
+ uint32 GetId() const { return m_spellProto->Id; }
+ uint32 GetEffIndex() const { return m_effIndex; }
int32 GetBasePoints() const { return m_currentBasePoints; }
+ int32 GetAuraAmplitude(){return m_amplitude;}
+ virtual void Update(uint32 diff);
- int32 GetAuraMaxDuration() const { return m_maxduration; }
- void SetAuraMaxDuration(int32 duration) { m_maxduration = duration; }
- int32 GetAuraDuration() const { return m_duration; }
- void SetAuraDuration(int32 duration)
- {
- m_duration = duration;
- if (duration<0)
- m_permanent=true;
- else
- m_permanent=false;
- }
- time_t GetAuraApplyTime() { return m_applyTime; }
- void UpdateAuraDuration();
- void SendAuraDurationForCaster(Player* caster);
- void UpdateSlotCounterAndDuration();
uint32 GetTickNumber() const { return m_tickNumber; }
-
- uint64 const& GetCasterGUID() const { return m_caster_guid; }
- Unit* GetCaster() const;
- Unit* GetTarget() const { return m_target; }
- void SetTarget(Unit* target) { m_target = target; }
- void SetLoadedState(uint64 caster_guid,int32 damage,int32 maxduration,int32 duration,int32 charges)
- {
- m_caster_guid = caster_guid;
- m_modifier.m_amount = damage;
- m_maxduration = maxduration;
- m_duration = duration;
- m_procCharges = charges;
- }
-
- uint8 GetAuraSlot() const { return m_auraSlot; }
- void SetAuraSlot(uint8 slot) { m_auraSlot = slot; }
- void UpdateAuraCharges()
- {
- uint8 slot = GetAuraSlot();
-
- // only aura in slot with charges and without stack limitation
- if (slot < MAX_AURAS && m_procCharges >= 1 && GetSpellProto()->StackAmount==0)
- SetAuraApplication(slot, m_procCharges - 1);
- }
-
- bool IsPositive() { return m_positive; }
- void SetNegative() { m_positive = false; }
- void SetPositive() { m_positive = true; }
-
- bool IsPermanent() const { return m_permanent; }
bool IsAreaAura() const { return m_isAreaAura; }
bool IsPeriodic() const { return m_isPeriodic; }
- bool IsTrigger() const { return m_isTrigger; }
- bool IsPassive() const { return m_isPassive; }
bool IsPersistent() const { return m_isPersistent; }
- bool IsDeathPersistent() const { return m_isDeathPersist; }
- bool IsRemovedOnShapeLost() const { return m_isRemovedOnShapeLost; }
- bool IsInUse() const { return m_in_use;}
- void CleanupTriggeredSpells();
+ bool isAffectedOnSpell(SpellEntry const *spell) const;
- virtual void Update(uint32 diff);
void ApplyModifier(bool apply, bool Real = false);
-
- void _AddAura();
- void _RemoveAura();
-
- void TriggerSpell();
-
- bool IsUpdated() { return m_updated; }
- void SetUpdated(bool val) { m_updated = val; }
- void SetRemoveMode(AuraRemoveMode mode) { m_removeMode = mode; }
-
- int32 m_procCharges;
- void SetAuraProcCharges(int32 charges) { m_procCharges = charges; }
+ void HandleAuraEffect(bool apply);
+ void ApplyAllModifiers(bool apply, bool Real);
Unit* GetTriggerTarget() const;
-
- // add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras
- void HandleShapeshiftBoosts(bool apply);
-
- // Allow Apply Aura Handler to modify and access m_AuraDRGroup
- void setDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; }
- DiminishingGroup getDiminishGroup() const { return m_AuraDRGroup; }
-
+ void TriggerSpell();
+ void TriggerSpellWithValue();
void PeriodicTick();
void PeriodicDummyTick();
- int32 GetStackAmount() {return m_stackAmount;}
- void SetStackAmount(int32 amount) {m_stackAmount=amount;}
+ int32 GetMiscBValue() const {return m_spellProto->EffectMiscValueB[m_effIndex];}
+ int32 GetMiscValue() const {return m_spellProto->EffectMiscValue[m_effIndex];}
+ uint32 GetAuraName() const {return m_auraName;}
+ int32 GetAmount() const {return m_amount;}
+ void SetAmount(int32 amount) { m_amount = amount; }
+ void CleanupTriggeredSpells();
+
protected:
- Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL);
+ AuraEffect (Aura * parentAura, uint8 effIndex, int32 * currentBasePoints , Unit * caster,Item * castItem);
+ Aura * const m_parentAura;
+ Unit * const m_target;
- Modifier m_modifier;
- SpellModifier *m_spellmod;
- uint32 m_effIndex;
SpellEntry const *m_spellProto;
- int32 m_currentBasePoints; // cache SpellEntry::EffectBasePoints and use for set custom base points
- uint64 m_caster_guid;
- Unit* m_target;
- int32 m_maxduration;
- int32 m_duration;
uint32 m_tickNumber;
- int32 m_timeCla;
- uint64 m_castItemGuid; // it is NOT safe to keep a pointer to the item because it may get deleted
- time_t m_applyTime;
- AuraRemoveMode m_removeMode;
+ uint8 m_effIndex;
+ AuraType m_auraName;
+ int32 m_currentBasePoints;
+ int32 m_amount;
- uint8 m_auraSlot;
+ SpellModifier *m_spellmod;
+
+ int32 m_periodicTimer; // Timer for periodic auras
+ int32 m_amplitude;
- bool m_positive:1;
- bool m_permanent:1;
bool m_isPeriodic:1;
- bool m_isTrigger:1;
bool m_isAreaAura:1;
- bool m_isPassive:1;
bool m_isPersistent:1;
- bool m_isDeathPersist:1;
- bool m_isRemovedOnShapeLost:1;
- bool m_updated:1;
- bool m_in_use:1; // true while in Aura::ApplyModifier call
-
- int32 m_periodicTimer;
- uint32 m_PeriodicEventId;
- DiminishingGroup m_AuraDRGroup;
-
- int32 m_stackAmount;
- private:
- void SetAura(uint32 slot, bool remove) { m_target->SetUInt32Value(UNIT_FIELD_AURA + slot, remove ? 0 : GetId()); }
- void SetAuraFlag(uint32 slot, bool add);
- void SetAuraLevel(uint32 slot, uint32 level);
- void SetAuraApplication(uint32 slot, int8 count);
};
-class TRINITY_DLL_SPEC AreaAura : public Aura
+class TRINITY_DLL_SPEC AreaAuraEffect : public AuraEffect
{
public:
- AreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL);
- ~AreaAura();
+ AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * currentBasePoints, Unit * caster=NULL, Item * castItem=NULL, Unit * formalCaster=NULL);
+ ~AreaAuraEffect();
+ Unit* GetFormalCaster() const;
void Update(uint32 diff);
private:
float m_radius;
+ int32 m_removeTime;
AreaAuraType m_areaAuraType;
+ uint64 m_formalCasterGUID; // used for check range
};
-class TRINITY_DLL_SPEC PersistentAreaAura : public Aura
+class TRINITY_DLL_SPEC PersistentAreaAuraEffect : public AuraEffect
{
public:
- PersistentAreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL);
- ~PersistentAreaAura();
+ PersistentAreaAuraEffect(Aura * parentAura, uint32 eff, int32 *currentBasePoints, Unit *caster = NULL, Item* castItem = NULL);
+ ~PersistentAreaAuraEffect();
void Update(uint32 diff);
};
-
-Aura* CreateAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL);
+AuraEffect* CreateAuraEffect(Aura * parentAura, uint32 effIndex, int32 *currentBasePoints, Unit * caster, Item * castItem = NULL, Unit * formalCaster=NULL);
#endif
-
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index c38f46d867b..1cbd5f94772 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -19,10 +19,8 @@
*/
#include "Common.h"
-#include "SharedDefines.h"
#include "Database/DatabaseEnv.h"
#include "WorldPacket.h"
-#include "WorldSession.h"
#include "Opcodes.h"
#include "Log.h"
#include "UpdateMask.h"
@@ -32,7 +30,6 @@
#include "Player.h"
#include "SkillExtraItems.h"
#include "Unit.h"
-#include "CreatureAI.h"
#include "Spell.h"
#include "DynamicObject.h"
#include "SpellAuras.h"
@@ -47,6 +44,7 @@
#include "Creature.h"
#include "Totem.h"
#include "CreatureAI.h"
+#include "BattleGroundMgr.h"
#include "BattleGround.h"
#include "BattleGroundEY.h"
#include "BattleGroundWS.h"
@@ -60,6 +58,9 @@
#include "CellImpl.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
+#include "SkillDiscovery.h"
+#include "Formulas.h"
+#include "Vehicle.h"
pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
{
@@ -104,8 +105,8 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectDispel, // 38 SPELL_EFFECT_DISPEL
&Spell::EffectUnused, // 39 SPELL_EFFECT_LANGUAGE
&Spell::EffectDualWield, // 40 SPELL_EFFECT_DUAL_WIELD
- &Spell::EffectSummonWild, // 41 SPELL_EFFECT_SUMMON_WILD
- &Spell::EffectSummonGuardian, // 42 SPELL_EFFECT_SUMMON_GUARDIAN
+ &Spell::EffectJump, // 41 SPELL_EFFECT_JUMP
+ &Spell::EffectJump, // 42 SPELL_EFFECT_JUMP2
&Spell::EffectTeleUnitsFaceCaster, // 43 SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
&Spell::EffectLearnSkill, // 44 SPELL_EFFECT_SKILL_STEP
&Spell::EffectAddHonor, // 45 SPELL_EFFECT_ADD_HONOR honor/pvp related
@@ -128,16 +129,16 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectPowerBurn, // 62 SPELL_EFFECT_POWER_BURN
&Spell::EffectThreat, // 63 SPELL_EFFECT_THREAT
&Spell::EffectTriggerSpell, // 64 SPELL_EFFECT_TRIGGER_SPELL
- &Spell::EffectUnused, // 65 SPELL_EFFECT_HEALTH_FUNNEL unused
- &Spell::EffectUnused, // 66 SPELL_EFFECT_POWER_FUNNEL unused
+ &Spell::EffectApplyAreaAura, // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID
+ &Spell::EffectUnused, // 66 SPELL_EFFECT_CREATE_MANA_GEM (possibly recharge it, misc - is item ID)
&Spell::EffectHealMaxHealth, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH
&Spell::EffectInterruptCast, // 68 SPELL_EFFECT_INTERRUPT_CAST
&Spell::EffectDistract, // 69 SPELL_EFFECT_DISTRACT
&Spell::EffectPull, // 70 SPELL_EFFECT_PULL one spell: Distract Move
&Spell::EffectPickPocket, // 71 SPELL_EFFECT_PICKPOCKET
&Spell::EffectAddFarsight, // 72 SPELL_EFFECT_ADD_FARSIGHT
- &Spell::EffectSummonPossessed, // 73 SPELL_EFFECT_SUMMON_POSSESSED
- &Spell::EffectSummonTotem, // 74 SPELL_EFFECT_SUMMON_TOTEM
+ &Spell::EffectUnused, // 73 SPELL_EFFECT_UNTRAIN_TALENTS
+ &Spell::EffectApplyGlyph, // 74 SPELL_EFFECT_APPLY_GLYPH
&Spell::EffectHealMechanical, // 75 SPELL_EFFECT_HEAL_MECHANICAL one spell: Mechanical Patch Kit
&Spell::EffectSummonObjectWild, // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD
&Spell::EffectScriptEffect, // 77 SPELL_EFFECT_SCRIPT_EFFECT
@@ -150,17 +151,17 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectStuck, // 84 SPELL_EFFECT_STUCK
&Spell::EffectSummonPlayer, // 85 SPELL_EFFECT_SUMMON_PLAYER
&Spell::EffectActivateObject, // 86 SPELL_EFFECT_ACTIVATE_OBJECT
- &Spell::EffectSummonTotem, // 87 SPELL_EFFECT_SUMMON_TOTEM_SLOT1
- &Spell::EffectSummonTotem, // 88 SPELL_EFFECT_SUMMON_TOTEM_SLOT2
- &Spell::EffectSummonTotem, // 89 SPELL_EFFECT_SUMMON_TOTEM_SLOT3
- &Spell::EffectSummonTotem, // 90 SPELL_EFFECT_SUMMON_TOTEM_SLOT4
+ &Spell::EffectUnused, // 87 SPELL_EFFECT_WMO_DAMAGE
+ &Spell::EffectUnused, // 88 SPELL_EFFECT_WMO_REPAIR
+ &Spell::EffectUnused, // 89 SPELL_EFFECT_WMO_CHANGE
+ &Spell::EffectUnused, // 90 SPELL_EFFECT_KILL_CREDIT
&Spell::EffectUnused, // 91 SPELL_EFFECT_THREAT_ALL one spell: zzOLDBrainwash
&Spell::EffectEnchantHeldItem, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM
&Spell::EffectUnused, // 93 SPELL_EFFECT_SUMMON_PHANTASM
&Spell::EffectSelfResurrect, // 94 SPELL_EFFECT_SELF_RESURRECT
&Spell::EffectSkinning, // 95 SPELL_EFFECT_SKINNING
&Spell::EffectUnused, // 96 SPELL_EFFECT_CHARGE
- &Spell::EffectSummonCritter, // 97 SPELL_EFFECT_SUMMON_CRITTER
+ &Spell::EffectUnused, // 97 SPELL_EFFECT_97
&Spell::EffectKnockBack, // 98 SPELL_EFFECT_KNOCK_BACK
&Spell::EffectDisEnchant, // 99 SPELL_EFFECT_DISENCHANT
&Spell::EffectInebriate, //100 SPELL_EFFECT_INEBRIATE
@@ -175,7 +176,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectSummonDeadPet, //109 SPELL_EFFECT_SUMMON_DEAD_PET
&Spell::EffectDestroyAllTotems, //110 SPELL_EFFECT_DESTROY_ALL_TOTEMS
&Spell::EffectDurabilityDamage, //111 SPELL_EFFECT_DURABILITY_DAMAGE
- &Spell::EffectSummonDemon, //112 SPELL_EFFECT_SUMMON_DEMON
+ &Spell::EffectUnused, //112 SPELL_EFFECT_112
&Spell::EffectResurrectNew, //113 SPELL_EFFECT_RESURRECT_NEW
&Spell::EffectTaunt, //114 SPELL_EFFECT_ATTACK_ME
&Spell::EffectDurabilityDamagePCT, //115 SPELL_EFFECT_DURABILITY_DAMAGE_PCT
@@ -195,21 +196,21 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectApplyAreaAura, //129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
&Spell::EffectRedirectThreat, //130 SPELL_EFFECT_REDIRECT_THREAT
&Spell::EffectUnused, //131 SPELL_EFFECT_131 used in some test spells
- &Spell::EffectNULL, //132 SPELL_EFFECT_PLAY_MUSIC sound id in misc value
+ &Spell::EffectNULL, //132 SPELL_EFFECT_PLAY_MUSIC sound id in misc value (SoundEntries.dbc)
&Spell::EffectUnlearnSpecialization, //133 SPELL_EFFECT_UNLEARN_SPECIALIZATION unlearn profession specialization
&Spell::EffectKillCredit, //134 SPELL_EFFECT_KILL_CREDIT misc value is creature entry
&Spell::EffectNULL, //135 SPELL_EFFECT_CALL_PET
&Spell::EffectHealPct, //136 SPELL_EFFECT_HEAL_PCT
&Spell::EffectEnergisePct, //137 SPELL_EFFECT_ENERGIZE_PCT
- &Spell::EffectNULL, //138 SPELL_EFFECT_138 Leap
- &Spell::EffectUnused, //139 SPELL_EFFECT_139 unused
+ &Spell::EffectJump2, //138 SPELL_EFFECT_138 Leap
+ &Spell::EffectUnused, //139 SPELL_EFFECT_CLEAR_QUEST (misc - is quest ID)
&Spell::EffectForceCast, //140 SPELL_EFFECT_FORCE_CAST
&Spell::EffectNULL, //141 SPELL_EFFECT_141 damage and reduce speed?
&Spell::EffectTriggerSpellWithValue, //142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
&Spell::EffectApplyAreaAura, //143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER
&Spell::EffectKnockBack, //144 SPELL_EFFECT_KNOCK_BACK_2 Spectral Blast
&Spell::EffectPlayerPull, //145 SPELL_EFFECT_145 Black Hole Effect
- &Spell::EffectUnused, //146 SPELL_EFFECT_146 unused
+ &Spell::EffectActivateRune, //146 SPELL_EFFECT_ACTIVATE_RUNE
&Spell::EffectQuestFail, //147 SPELL_EFFECT_QUEST_FAIL quest fail
&Spell::EffectUnused, //148 SPELL_EFFECT_148 unused
&Spell::EffectNULL, //149 SPELL_EFFECT_149 swoop
@@ -217,6 +218,12 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectTriggerRitualOfSummoning, //151 SPELL_EFFECT_TRIGGER_SPELL_2
&Spell::EffectNULL, //152 SPELL_EFFECT_152 summon Refer-a-Friend
&Spell::EffectNULL, //153 SPELL_EFFECT_CREATE_PET misc value is creature entry
+ &Spell::EffectNULL, //154 unused
+ &Spell::EffectTitanGrip, //155 SPELL_EFFECT_TITAN_GRIP Allows you to equip two-handed axes, maces and swords in one hand, but you attack $49152s1% slower than normal.
+ &Spell::EffectEnchantItemPrismatic, //156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
+ &Spell::EffectCreateItem2, //157 SPELL_EFFECT_CREATE_ITEM_2 create/learn item/spell for profession
+ &Spell::EffectMilling, //158 SPELL_EFFECT_MILLING milling
+ &Spell::EffectRenamePet //159 SPELL_EFFECT_ALLOW_RENAME_PET allow rename pet once again
};
void Spell::EffectNULL(uint32 /*i*/)
@@ -291,13 +298,13 @@ void Spell::EffectEnvirinmentalDMG(uint32 i)
// Note: this hack with damage replace required until GO casting not implemented
// environment damage spells already have around enemies targeting but this not help in case not existed GO casting support
// currently each enemy selected explicitly and self cast damage, we prevent apply self casted spell bonuses/etc
- damage = m_spellInfo->EffectBasePoints[i]+m_spellInfo->EffectBaseDice[i];
+ damage = m_spellInfo->CalculateSimpleValue(i);
- m_caster->CalcAbsorbResist(m_caster,GetSpellSchoolMask(m_spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
+ m_caster->CalcAbsorbResist(m_caster,GetSpellSchoolMask(m_spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist, m_spellInfo);
m_caster->SendSpellNonMeleeDamageLog(m_caster, m_spellInfo->Id, damage, GetSpellSchoolMask(m_spellInfo), absorb, resist, false, 0, false);
if(m_caster->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_caster)->EnvironmentalDamage(m_caster->GetGUID(),DAMAGE_FIRE,damage);
+ ((Player*)m_caster)->EnvironmentalDamage(DAMAGE_FIRE,damage);
}
void Spell::EffectSchoolDMG(uint32 effect_idx)
@@ -331,14 +338,6 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
switch(m_spellInfo->Id) // better way to check unknown
{
- case 35354: //Hand of Death
- {
- if(unitTarget && unitTarget->HasAura(38528,0)) //Protection of Elune
- {
- damage = 0;
- }
- break;
- }
// percent from health with min
case 25599: // Thundercrash
{
@@ -347,6 +346,13 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
damage = 200;
break;
}
+ // Intercept (warrior spell trigger)
+ case 20253:
+ case 61491:
+ {
+ damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.12f);
+ break;
+ }
// arcane charge. must only affect demons (also undead?)
case 45072:
{
@@ -362,7 +368,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
if(unitTarget->GetGUID() == m_caster->GetGUID() || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[0]));
+ float radius = GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[0]));
if(!radius) return;
float distance = m_caster->GetDistance2d(unitTarget);
damage = (distance > radius ) ? 0 : (int32)(m_spellInfo->EffectBasePoints[0]*((radius - distance)/radius));
@@ -374,7 +380,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
case SPELLFAMILY_MAGE:
{
// Arcane Blast
- if(m_spellInfo->SpellFamilyFlags & 0x20000000LL)
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x20000000)
{
m_caster->CastSpell(m_caster,36032,true);
}
@@ -383,109 +389,108 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
case SPELLFAMILY_WARRIOR:
{
// Bloodthirst
- if(m_spellInfo->SpellFamilyFlags & 0x40000000000LL)
+ if(m_spellInfo->SpellFamilyFlags[1] & 0x400)
{
damage = uint32(damage * (m_caster->GetTotalAttackPowerValue(BASE_ATTACK)) / 100);
}
// Shield Slam
- else if(m_spellInfo->SpellFamilyFlags & 0x100000000LL)
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->Category==1209)
damage += int32(m_caster->GetShieldBlockValue());
// Victory Rush
- else if(m_spellInfo->SpellFamilyFlags & 0x10000000000LL)
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x100)
{
damage = uint32(damage * m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
m_caster->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, false);
}
+ // Revenge ${$m1+$AP*0.207} to ${$M1+$AP*0.207}
+ else if(m_spellInfo->SpellFamilyFlags[0] & 0x400)
+ damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.207f);
+ // Heroic Throw ${$m1+$AP*.50}
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x00000001)
+ damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.5f);
+ // Shockwave ${$m3/100*$AP}
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x00008000)
+ {
+ int32 pct = m_caster->CalculateSpellDamage(m_spellInfo, 2, m_spellInfo->EffectBasePoints[2], unitTarget);
+ if (pct > 0)
+ damage+= int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * pct / 100);
+ break;
+ }
+ // Thunder Clap
+ else if(m_spellInfo->SpellFamilyFlags[0] & 0x80)
+ {
+ damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 12 / 100);
+ break;
+ }
break;
}
case SPELLFAMILY_WARLOCK:
{
// Incinerate Rank 1 & 2
- if((m_spellInfo->SpellFamilyFlags & 0x00004000000000LL) && m_spellInfo->SpellIconID==2128)
+ if((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID==2128)
{
// Incinerate does more dmg (dmg*0.25) if the target is Immolated.
- if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE))
- damage += int32(damage*0.25);
+ if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE, m_spellInfo, m_caster))
+ damage += int32(damage*0.25f);
}
-
// Conflagrate - consumes immolate
if (m_spellInfo->TargetAuraState == AURA_STATE_IMMOLATE)
{
+ // Glyph of Conflagrate
+ if (m_caster->HasAura(56235))
+ break;
// for caster applied auras only
- Unit::AuraList const &mPeriodic = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
- for(Unit::AuraList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
+ Unit::AuraEffectList const &mPeriodic = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
+ for(Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
{
- if( (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && ((*i)->GetSpellProto()->SpellFamilyFlags & 4) &&
+ if( (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && ((*i)->GetSpellProto()->SpellFamilyFlags[0] & 4 || (*i)->GetSpellProto()->SpellFamilyFlags[2] & 2) &&
(*i)->GetCasterGUID()==m_caster->GetGUID() )
{
- unitTarget->RemoveAurasByCasterSpell((*i)->GetId(), m_caster->GetGUID());
+ unitTarget->RemoveAurasDueToSpell((*i)->GetId(), m_caster->GetGUID());
break;
}
}
}
break;
}
+ case SPELLFAMILY_PRIEST:
+ {
+ // Shadow Word: Death - deals damage equal to damage done to caster
+ if (m_spellInfo->SpellFamilyFlags[1] & 0x2)
+ m_caster->CastCustomSpell(m_caster, 32409, &damage, 0, 0, true);
+ break;
+ }
case SPELLFAMILY_DRUID:
{
// Ferocious Bite
- if((m_spellInfo->SpellFamilyFlags & 0x000800000) && m_spellInfo->SpellVisual==6587)
+ if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0]==6587)
{
- // converts each extra point of energy into ($f1+$AP/630) additional damage
- float multiple = m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 630 + m_spellInfo->DmgMultiplier[effect_idx];
+ // converts each extra point of energy into ($f1+$AP/410) additional damage
+ float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
+ float multiple = ap / 410 + m_spellInfo->DmgMultiplier[effect_idx];
damage += int32(m_caster->GetPower(POWER_ENERGY) * multiple);
+ damage += int32(((Player*)m_caster)->GetComboPoints() * ap * 7 / 100);
m_caster->SetPower(POWER_ENERGY,0);
}
// Rake
- else if(m_spellInfo->SpellFamilyFlags & 0x0000000000001000LL)
+ else if(m_spellInfo->SpellFamilyFlags[0] & 0x1000)
{
damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
}
// Swipe
- else if(m_spellInfo->SpellFamilyFlags & 0x0010000000000000LL)
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x00100000)
{
damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.08f);
}
- // Starfire
- else if ( m_spellInfo->SpellFamilyFlags & 0x0004LL )
- {
- Unit::AuraList const& m_OverrideClassScript = m_caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(Unit::AuraList::const_iterator i = m_OverrideClassScript.begin(); i != m_OverrideClassScript.end(); ++i)
- {
- // Starfire Bonus (caster)
- switch((*i)->GetModifier()->m_miscvalue)
- {
- case 5481: // Nordrassil Regalia - bonus
- {
- Unit::AuraList const& m_periodicDamageAuras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
- for(Unit::AuraList::const_iterator itr = m_periodicDamageAuras.begin(); itr != m_periodicDamageAuras.end(); ++itr)
- {
- // Moonfire or Insect Swarm (target debuff from any casters)
- if ( (*itr)->GetSpellProto()->SpellFamilyFlags & 0x00200002LL )
- {
- int32 mod = (*i)->GetModifier()->m_amount;
- damage += damage*mod/100;
- break;
- }
- }
- break;
- }
- case 5148: //Improved Starfire - Ivory Idol of the Moongoddes Aura
- {
- damage += (*i)->GetModifier()->m_amount;
- break;
- }
- }
- }
- }
//Mangle Bonus for the initial damage of Lacerate and Rake
- if((m_spellInfo->SpellFamilyFlags==0x0000000000001000LL && m_spellInfo->SpellIconID==494) ||
- (m_spellInfo->SpellFamilyFlags==0x0000010000000000LL && m_spellInfo->SpellIconID==2246))
+ if((m_spellInfo->SpellFamilyFlags.IsEqual(0x1000,0,0) && m_spellInfo->SpellIconID==494) ||
+ (m_spellInfo->SpellFamilyFlags.IsEqual(0,0x100,0) && m_spellInfo->SpellIconID==2246))
{
- Unit::AuraList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
- if((*i)->GetSpellProto()->SpellFamilyFlags & 0x0000044000000000LL && (*i)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_DRUID)
+ Unit::AuraEffectList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraEffectList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
+ if((*i)->GetSpellProto()->SpellFamilyFlags[1] & 0x00000440 && (*i)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_DRUID)
{
- damage = int32(damage*(100.0f+(*i)->GetModifier()->m_amount)/100.0f);
+ damage = int32(damage*(100.0f+(*i)->GetAmount())/100.0f);
break;
}
}
@@ -494,78 +499,97 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
case SPELLFAMILY_ROGUE:
{
// Envenom
- if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & 0x800000000LL))
+ if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags[1] & 0x8))
{
// consume from stack dozes not more that have combo-points
if(uint32 combo = ((Player*)m_caster)->GetComboPoints())
{
- // count consumed deadly poison doses at target
- uint32 doses = 0;
-
- // remove consumed poison doses
- Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
- for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end() && combo;)
- {
- // Deadly poison (only attacker applied)
- if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && ((*itr)->GetSpellProto()->SpellFamilyFlags & 0x10000) &&
- (*itr)->GetSpellProto()->SpellVisual==5100 && (*itr)->GetCasterGUID()==m_caster->GetGUID() )
+ Aura *poison = 0;
+ // Lookup for Deadly poison (only attacker applied)
+ Unit::AuraEffectList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
+ for(Unit::AuraEffectList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
+ if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE &&
+ (*itr)->GetSpellProto()->SpellFamilyFlags[0] & 0x10000 &&
+ (*itr)->GetCasterGUID()==m_caster->GetGUID() )
{
- --combo;
- ++doses;
-
- unitTarget->RemoveSingleAuraFromStack((*itr)->GetId(), (*itr)->GetEffIndex());
-
- itr = auras.begin();
+ poison = (*itr)->GetParentAura();
+ break;
}
- else
- ++itr;
+ // count consumed deadly poison doses at target
+ if (poison)
+ {
+ uint32 spellId = poison->GetId();
+ uint32 doses = poison->GetStackAmount();
+ if (doses > combo)
+ doses = combo;
+ for (int i=0; i< doses; i++)
+ unitTarget->RemoveAuraFromStack(spellId);
+ damage *= doses;
+ damage += int32(((Player*)m_caster)->GetTotalAttackPowerValue(BASE_ATTACK) * 0.03f * doses);
}
-
- damage *= doses;
- damage += int32(((Player*)m_caster)->GetTotalAttackPowerValue(BASE_ATTACK) * 0.03f * doses);
-
// Eviscerate and Envenom Bonus Damage (item set effect)
if(m_caster->GetDummyAura(37169))
damage += ((Player*)m_caster)->GetComboPoints()*40;
}
}
// Eviscerate
- else if((m_spellInfo->SpellFamilyFlags & 0x00020000LL) && m_caster->GetTypeId()==TYPEID_PLAYER)
+ else if((m_spellInfo->SpellFamilyFlags[0] & 0x00020000) && m_caster->GetTypeId()==TYPEID_PLAYER)
{
if(uint32 combo = ((Player*)m_caster)->GetComboPoints())
{
- damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * combo * 0.03f);
+ float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
+ damage += irand(int32(ap * combo * 0.03f), int32(ap * combo * 0.07f));
// Eviscerate and Envenom Bonus Damage (item set effect)
if(m_caster->GetDummyAura(37169))
damage += combo*40;
}
}
+ // Gouge
+ else if(m_spellInfo->SpellFamilyFlags[0] & 0x8)
+ {
+ damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.02f);
+ }
+ // Instant Poison
+ else if(m_spellInfo->SpellFamilyFlags[0] & 0x2000)
+ {
+ damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.10f);
+ }
+ // Wound Poison
+ else if(m_spellInfo->SpellFamilyFlags[0] & 0x10000000)
+ {
+ damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.04f);
+ }
break;
}
case SPELLFAMILY_HUNTER:
{
// Mongoose Bite
- if((m_spellInfo->SpellFamilyFlags & 0x000000002) && m_spellInfo->SpellVisual==342)
+ if((m_spellInfo->SpellFamilyFlags[0] & 0x2) && m_spellInfo->SpellVisual[0]==342)
{
- damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2);
+ damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f);
+ }
+ // Counterattack
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x00080000)
+ {
+ damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f);
}
// Arcane Shot
- else if((m_spellInfo->SpellFamilyFlags & 0x00000800) && m_spellInfo->maxLevel > 0)
+ else if((m_spellInfo->SpellFamilyFlags[0] & 0x00000800) && m_spellInfo->maxLevel > 0)
{
- damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.15);
+ damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.15f);
}
// Steady Shot
- else if(m_spellInfo->SpellFamilyFlags & 0x100000000LL)
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x1)
{
int32 base = irand((int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE),(int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE));
- damage += int32(float(base)/m_caster->GetAttackTime(RANGED_ATTACK)*2800 + m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.2f);
+ damage += int32(float(base)/m_caster->GetAttackTime(RANGED_ATTACK)*2800 + m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.1f);
bool found = false;
// check dazed affect
- Unit::AuraList const& decSpeedList = unitTarget->GetAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
- for(Unit::AuraList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
+ Unit::AuraEffectList const& decSpeedList = unitTarget->GetAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
+ for(Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
{
if((*iter)->GetSpellProto()->SpellIconID==15 && (*iter)->GetSpellProto()->Dispel==0)
{
@@ -578,28 +602,59 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
if(found)
damage += m_spellInfo->EffectBasePoints[1];
}
- //Explosive Trap Effect
- else if(m_spellInfo->SpellFamilyFlags & 0x00000004)
+ // Explosive Trap Effect
+ else if(m_spellInfo->SpellFamilyFlags[0] & 0x00000004)
{
- damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.1);
+ damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.1f);
}
break;
}
case SPELLFAMILY_PALADIN:
{
- //Judgement of Vengeance
- if((m_spellInfo->SpellFamilyFlags & 0x800000000LL) && m_spellInfo->SpellIconID==2292)
+ // Judgement of Vengeance/Corruption ${1+0.22*$SPH+0.14*$AP} + 10% for each application of Holy Vengeance/Blood Corruption on the target
+ if((m_spellInfo->SpellFamilyFlags[1] & 0x400000) && m_spellInfo->SpellIconID==2292)
{
+ float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
+ int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) +
+ m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
+ damage+=int32(ap * 0.14f) + int32(holy * 22 / 100);
+ // Get stack of Holy Vengeance/Blood Corruption on the target added by caster
uint32 stacks = 0;
- Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
- for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
- if((*itr)->GetId() == 31803 && (*itr)->GetCasterGUID()==m_caster->GetGUID())
- ++stacks;
- if(!stacks)
- //No damage if the target isn't affected by this
- damage = -1;
- else
- damage *= stacks;
+ Unit::AuraEffectList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
+ for(Unit::AuraEffectList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
+ if(((*itr)->GetId() == 31803 || (*itr)->GetId() == 53742) && (*itr)->GetCasterGUID()==m_caster->GetGUID())
+ {
+ stacks = (*itr)->GetParentAura()->GetStackAmount();
+ break;
+ }
+ // + 10% for each application of Holy Vengeance/Blood Corruption on the target
+ if(stacks)
+ damage += damage * stacks * 10 /100;
+ }
+ // Avenger's Shield ($m1+0.07*$SPH+0.07*$AP)
+ else if(m_spellInfo->SpellFamilyFlags[0] & 0x4000)
+ {
+ float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
+ damage += int32(ap * 0.07f);
+ }
+ // Hammer of Wrath ($m1+0.15*$SPH+0.15*$AP)
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x00000080)
+ {
+ float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
+ damage += int32(ap * 0.15f);
+ }
+ // Hammer of the Righteous
+ else if(m_spellInfo->SpellFamilyFlags[1]&0x00040000)
+ {
+ // Add main hand dps * effect[2] amount
+ float averange = (m_caster->GetFloatValue(UNIT_FIELD_MINDAMAGE) + m_caster->GetFloatValue(UNIT_FIELD_MAXDAMAGE)) / 2;
+ int32 count = m_caster->CalculateSpellDamage(m_spellInfo, 2, m_spellInfo->EffectBasePoints[2], unitTarget);
+ damage += count * int32(averange * IN_MILISECONDS) / m_caster->GetAttackTime(BASE_ATTACK);
+ }
+ // Shield of Righteousness
+ else if(m_spellInfo->SpellFamilyFlags[1]&0x00100000)
+ {
+ damage+=int32(m_caster->GetShieldBlockValue());
}
break;
}
@@ -659,9 +714,9 @@ void Spell::EffectDummy(uint32 i)
if (!creatureTarget || !pGameObj) return;
- if (!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), 181574, creatureTarget->GetMap(),
+ if (!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), 181574, creatureTarget->GetMap(), creatureTarget->GetPhaseMask(),
creatureTarget->GetPositionX(), creatureTarget->GetPositionY(), creatureTarget->GetPositionZ(),
- creatureTarget->GetOrientation(), 0, 0, 0, 0, 100, 1))
+ creatureTarget->GetOrientation(), 0, 0, 0, 0, 100, GO_STATE_READY))
{
delete pGameObj;
return;
@@ -767,12 +822,6 @@ void Spell::EffectDummy(uint32 i)
m_caster->CastCustomSpell(unitTarget, 12721, &deepWoundsDotBasePoints0, NULL, NULL, true, NULL);
return;
}
- case 12975: //Last Stand
- {
- int32 healthModSpellBasePoints0 = int32(m_caster->GetMaxHealth()*0.3);
- m_caster->CastCustomSpell(m_caster, 12976, &healthModSpellBasePoints0, NULL, NULL, true, NULL);
- return;
- }
case 13120: // net-o-matic
{
if(!unitTarget)
@@ -809,30 +858,6 @@ void Spell::EffectDummy(uint32 i)
}
return;
}
- case 14185: // Preparation Rogue
- {
- if(m_caster->GetTypeId()!=TYPEID_PLAYER)
- return;
-
- //immediately finishes the cooldown on certain Rogue abilities
- const PlayerSpellMap& sp_list = ((Player *)m_caster)->GetSpellMap();
- for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
- {
- uint32 classspell = itr->first;
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell);
-
- if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags & 0x26000000860LL))
- {
- ((Player*)m_caster)->RemoveSpellCooldown(classspell);
-
- WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8));
- data << uint32(classspell);
- data << uint64(m_caster->GetGUID());
- ((Player*)m_caster)->GetSession()->SendPacket(&data);
- }
- }
- return;
- }
case 15998: // Capture Worg Pup
case 29435: // Capture Female Kaliri Hatchling
{
@@ -897,19 +922,20 @@ void Spell::EffectDummy(uint32 i)
if(creatureTarget->isPet())
return;
+ GameObject* Crystal_Prison = m_caster->SummonGameObject(179644, creatureTarget->GetPositionX(), creatureTarget->GetPositionY(), creatureTarget->GetPositionZ(), creatureTarget->GetOrientation(), 0, 0, 0, 0, creatureTarget->GetRespawnTime()-time(NULL));
+ sLog.outDebug("SummonGameObject at SpellEfects.cpp EffectDummy for Spell 23019");
+
creatureTarget->setDeathState(JUST_DIED);
creatureTarget->RemoveCorpse();
creatureTarget->SetHealth(0); // just for nice GM-mode view
- GameObject* Crystal_Prison = m_caster->SummonGameObject(179644, creatureTarget->GetPositionX(), creatureTarget->GetPositionY(), creatureTarget->GetPositionZ(), creatureTarget->GetOrientation(), 0, 0, 0, 0, creatureTarget->GetRespawnTime()-time(NULL));
- sLog.outDebug("SummonGameObject at SpellEfects.cpp EffectDummy for Spell 23019\n");
WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8);
data << uint64(Crystal_Prison->GetGUID());
m_caster->SendMessageToSet(&data,true);
return;
}
- case 23074: // Arc. Dragonling
+ case 23074: // Arcanite Dragonling
if (!m_CastItem) return;
m_caster->CastSpell(m_caster,19804,true,m_CastItem);
return;
@@ -957,7 +983,7 @@ void Spell::EffectDummy(uint32 i)
float flyspeed = m_caster->GetSpeedRate(MOVE_FLIGHT);
float speed = m_caster->GetSpeedRate(MOVE_RUN);
- m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+ m_caster->RemoveAurasByType(SPELL_AURA_MOUNTED);
//5 different spells used depending on mounted speed and if mount can fly or not
if (flyspeed >= 4.1f)
@@ -977,13 +1003,13 @@ void Spell::EffectDummy(uint32 i)
// return; -- implemented at client side
case 28006: // Arcane Cloaking
{
- if( unitTarget->GetTypeId() == TYPEID_PLAYER )
+ if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER )
m_caster->CastSpell(unitTarget,29294,true);
return;
}
case 28730: // Arcane Torrent (Mana)
{
- Aura * dummy = m_caster->GetDummyAura(28734);
+ Aura * dummy = m_caster->GetAura(28734, m_caster->GetGUID());
if (dummy)
{
int32 bp = damage * dummy->GetStackAmount();
@@ -1021,6 +1047,13 @@ void Spell::EffectDummy(uint32 i)
else // backfire 20%
m_caster->CastSpell(unitTarget, 30504, true, m_CastItem);
return;
+ case 55004: //Nitro Boosts
+ if(!m_CastItem) return;
+ if(roll_chance_i(95)) //success
+ m_caster->CastSpell(m_caster, 54861, true, m_CastItem);
+ else //backfire 5%
+ m_caster->CastSpell(m_caster, 46014, true, m_CastItem);
+ return;
case 33060: // Make a Wish
{
if(m_caster->GetTypeId()!=TYPEID_PLAYER)
@@ -1121,36 +1154,6 @@ void Spell::EffectDummy(uint32 i)
m_caster->CastSpell(m_caster,42337,true,NULL);
return;
}
- case 37573: //Temporal Phase Modulator
- {
- if(!unitTarget)
- return;
-
- TemporarySummon* tempSummon = dynamic_cast<TemporarySummon*>(unitTarget);
- if(!tempSummon)
- return;
-
- uint32 health = tempSummon->GetHealth();
- const uint32 entry_list[6] = {21821, 21820, 21817};
-
- float x = tempSummon->GetPositionX();
- float y = tempSummon->GetPositionY();
- float z = tempSummon->GetPositionZ();
- float o = tempSummon->GetOrientation();
-
- tempSummon->UnSummon();
-
- Creature* pCreature = m_caster->SummonCreature(entry_list[urand(0, 2)], x, y, z, o,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,180000);
- if (!pCreature)
- return;
-
- pCreature->SetHealth(health);
-
- if(pCreature->IsAIEnabled)
- pCreature->AI()->AttackStart(m_caster);
-
- return;
- }
case 34665: //Administer Antidote
{
if(!unitTarget || m_caster->GetTypeId() != TYPEID_PLAYER )
@@ -1159,7 +1162,7 @@ void Spell::EffectDummy(uint32 i)
if(!unitTarget)
return;
- TemporarySummon* tempSummon = dynamic_cast<TemporarySummon*>(unitTarget);
+ TempSummon* tempSummon = dynamic_cast<TempSummon*>(unitTarget);
if(!tempSummon)
return;
@@ -1176,7 +1179,7 @@ void Spell::EffectDummy(uint32 i)
return;
pCreature->SetHealth(health);
- ((Player*)m_caster)->KilledMonster(16992,pCreature->GetGUID());
+ ((Player*)m_caster)->RewardPlayerAndGroupAtEvent(16992,pCreature);
if (pCreature->IsAIEnabled)
pCreature->AI()->AttackStart(m_caster);
@@ -1226,7 +1229,34 @@ void Spell::EffectDummy(uint32 i)
m_caster->CastSpell(m_caster, 30452, true, NULL);
return;
- }
+ }
+ case 52308:
+ {
+ switch(i)
+ {
+ case 0:
+ {
+ uint32 spellID = m_spellInfo->CalculateSimpleValue(0);
+ uint32 reqAuraID = m_spellInfo->CalculateSimpleValue(1);
+
+ if (m_caster->HasAuraEffect(reqAuraID,0))
+ m_caster->CastSpell(m_caster,spellID,true,NULL);
+ return;
+ }
+ case 1:
+ return; // additional data for dummy[0]
+ }
+ return;
+ }
+ case 53341:
+ case 53343:
+ {
+ m_caster->CastSpell(m_caster,54586,true);
+ return;
+ }
+ case 58418: // Portal to Orgrimmar
+ case 58420: // Portal to Stormwind
+ return; // implemented in EffectScript[0]
}
//All IconID Check in there
@@ -1300,65 +1330,135 @@ void Spell::EffectDummy(uint32 i)
break;
case SPELLFAMILY_WARRIOR:
// Charge
- if(m_spellInfo->SpellFamilyFlags & 0x1 && m_spellInfo->SpellVisual == 867)
+ if(m_spellInfo->SpellFamilyFlags & 0x1 && m_spellInfo->SpellVisual[0] == 867)
{
int32 chargeBasePoints0 = damage;
m_caster->CastCustomSpell(m_caster,34846,&chargeBasePoints0,NULL,NULL,true);
return;
}
+ //Slam
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x200000 && m_spellInfo->SpellIconID == 559)
+ {
+ int32 bp0 = damage;
+ m_caster->CastCustomSpell(unitTarget, 50783, &bp0, NULL, NULL, true, 0);
+ return;
+ }
// Execute
- if(m_spellInfo->SpellFamilyFlags & 0x20000000)
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x20000000)
{
if(!unitTarget)
return;
+ uint32 rage = m_caster->GetPower(POWER_RAGE);
+ // Glyph of Execution bonus
+ if (AuraEffect *aura = m_caster->GetDummyAura(58367))
+ rage+=aura->GetAmount();
+
spell_id = 20647;
- bp = damage+int32(m_caster->GetPower(POWER_RAGE) * m_spellInfo->DmgMultiplier[i]);
- m_caster->SetPower(POWER_RAGE,0);
+ bp = damage+int32(rage * m_spellInfo->DmgMultiplier[i] +
+ m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f);
+ // Sudden death cost modifier
+ if (Aura * aur = m_caster->GetAura(52437))
+ {
+ m_caster->ModifyPower(POWER_RAGE,- m_powerCost);
+ if (m_caster->GetPower(POWER_RAGE)<100)
+ m_caster->SetPower(POWER_RAGE,100);
+ m_caster->RemoveAura(aur);
+ }
+ else
+ m_caster->SetPower(POWER_RAGE,0);
break;
}
- if(m_spellInfo->Id==21977) //Warrior's Wrath
+ // Slam
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x200000)
{
if(!unitTarget)
return;
-
- m_caster->CastSpell(unitTarget,21887,true); // spell mod
+ m_damage+=m_caster->CalculateDamage(m_attackType, false);
+ m_damage+=damage;
+ return;
+ }
+ // Concussion Blow
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x4000000)
+ {
+ m_damage+= uint32(damage * m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
return;
}
+ switch(m_spellInfo->Id)
+ {
+ // Warrior's Wrath
+ case 21977:
+ {
+ if(!unitTarget)
+ return;
+ m_caster->CastSpell(unitTarget,21887,true); // spell mod
+ return;
+ }
+ // Last Stand
+ case 12975:
+ {
+ int32 healthModSpellBasePoints0 = int32(m_caster->GetMaxHealth()*0.3);
+ m_caster->CastCustomSpell(m_caster, 12976, &healthModSpellBasePoints0, NULL, NULL, true, NULL);
+ return;
+ }
+ // Bloodthirst
+ case 23881:
+ {
+ m_caster->CastCustomSpell(unitTarget, 23885, &damage, NULL, NULL, true, NULL);
+ return;
+ }
+ }
break;
case SPELLFAMILY_WARLOCK:
- //Life Tap (only it have this with dummy effect)
- if (m_spellInfo->SpellFamilyFlags == 0x40000)
+ // Life Tap
+ if (m_spellInfo->SpellFamilyFlags[0] & 0x40000)
{
- float cost = damage;
-
- if(Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, cost,this);
-
- int32 dmg = m_caster->SpellDamageBonus(m_caster, m_spellInfo,uint32(cost > 0 ? cost : 0), SPELL_DIRECT_DAMAGE);
-
- if(int32(m_caster->GetHealth()) > dmg)
+ // In 303 exist spirit depend
+ uint32 spirit = uint32(m_caster->GetStat(STAT_SPIRIT));
+ switch (m_spellInfo->Id)
+ {
+ case 1454: damage+=spirit; break;
+ case 1455: damage+=spirit*15/10; break;
+ case 1456: damage+=spirit*2; break;
+ case 11687: damage+=spirit*25/10; break;
+ case 11688:
+ case 11689:
+ case 27222:
+ case 57946: damage+=spirit*3; break;
+ default:
+ sLog.outError("Spell::EffectDummy: %u Life Tap need set spirit multipler", m_spellInfo->Id);
+ return;
+ }
+// Think its not need (also need remove Life Tap from SpellDamageBonus or add new value)
+// damage = m_caster->SpellDamageBonus(m_caster, m_spellInfo,uint32(damage > 0 ? damage : 0), SPELL_DIRECT_DAMAGE);
+ if(unitTarget && (int32(unitTarget->GetHealth()) > damage))
{
// Shouldn't Appear in Combat Log
- m_caster->ModifyHealth(-dmg);
-
- int32 mana = dmg;
+ unitTarget->ModifyHealth(-damage);
- Unit::AuraList const& auraDummy = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr != auraDummy.end(); ++itr)
+ int32 mana = damage;
+ // Improved Life Tap mod
+ Unit::AuraEffectList const& auraDummy = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraEffectList::const_iterator itr = auraDummy.begin(); itr != auraDummy.end(); ++itr)
{
- // only Imp. Life Tap have this in combination with dummy aura
if((*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (*itr)->GetSpellProto()->SpellIconID == 208)
- mana = ((*itr)->GetModifier()->m_amount + 100)* mana / 100;
+ mana = ((*itr)->GetAmount() + 100)* mana / 100;
}
-
- m_caster->CastCustomSpell(m_caster,31818,&mana,NULL,NULL,true,NULL);
+ m_caster->CastCustomSpell(unitTarget, 31818, &mana, NULL, NULL, true);
// Mana Feed
- int32 manaFeedVal = m_caster->CalculateSpellDamage(m_spellInfo,1, m_spellInfo->EffectBasePoints[1],m_caster);
- manaFeedVal = manaFeedVal * mana / 100;
+ int32 manaFeedVal = 0;
+ Unit::AuraEffectList const& mod = m_caster->GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER);
+ for(Unit::AuraEffectList::const_iterator itr = mod.begin(); itr != mod.end(); ++itr)
+ {
+ if((*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (*itr)->GetSpellProto()->SpellIconID == 1982)
+ manaFeedVal+= (*itr)->GetAmount();
+ }
if(manaFeedVal > 0)
- m_caster->CastCustomSpell(m_caster,32553,&manaFeedVal,NULL,NULL,true,NULL);
+ {
+ manaFeedVal = manaFeedVal * mana / 100;
+ m_caster->CastCustomSpell(m_caster, 32553, &manaFeedVal, NULL, NULL, true, NULL);
+ }
}
else
SendCastResult(SPELL_FAILED_FIZZLE);
@@ -1366,52 +1466,54 @@ void Spell::EffectDummy(uint32 i)
}
break;
case SPELLFAMILY_PRIEST:
- switch(m_spellInfo->Id )
+ // Penance
+ if (m_spellInfo->SpellFamilyFlags[1] & 0x00800000)
{
- case 28598: // Touch of Weakness triggered spell
+ if (!unitTarget)
+ return;
+
+ int hurt = 0;
+ int heal = 0;
+ switch(m_spellInfo->Id)
{
- if(!unitTarget || !m_triggeredByAuraSpell)
+ case 47540: hurt = 47758; heal = 47757; break;
+ case 53005: hurt = 53001; heal = 52986; break;
+ case 53006: hurt = 53002; heal = 52987; break;
+ case 53007: hurt = 53003; heal = 52988; break;
+ default:
+ sLog.outError("Spell::EffectDummy: Spell %u Penance need set correct heal/damage spell", m_spellInfo->Id);
return;
-
- uint32 spellid = 0;
- switch(m_triggeredByAuraSpell->Id)
- {
- case 2652: spellid = 2943; break; // Rank 1
- case 19261: spellid = 19249; break; // Rank 2
- case 19262: spellid = 19251; break; // Rank 3
- case 19264: spellid = 19252; break; // Rank 4
- case 19265: spellid = 19253; break; // Rank 5
- case 19266: spellid = 19254; break; // Rank 6
- case 25461: spellid = 25460; break; // Rank 7
- default:
- sLog.outError("Spell::EffectDummy: Spell 28598 triggered by unhandled spell %u",m_triggeredByAuraSpell->Id);
- return;
- }
- m_caster->CastSpell(unitTarget, spellid, true, NULL);
- return;
}
+ if (m_caster->IsFriendlyTo(unitTarget))
+ m_caster->CastSpell(unitTarget, heal, true, 0);
+ else
+ m_caster->CastSpell(unitTarget, hurt, true, 0);
+ return;
}
break;
case SPELLFAMILY_DRUID:
- switch(m_spellInfo->Id )
+ // Starfall
+ if (m_spellInfo->SpellFamilyFlags[2] & 0x100)
{
- case 5420: // Tree of Life passive
+ //Shapeshifting into an animal form or mounting cancels the effect.
+ if(m_caster->GetCreatureType() == CREATURE_TYPE_BEAST || m_caster->IsMounted())
{
- // Tree of Life area effect
- int32 health_mod = int32(m_caster->GetStat(STAT_SPIRIT)/4);
- m_caster->CastCustomSpell(m_caster,34123,&health_mod,NULL,NULL,true,NULL);
+ if(m_triggeredByAuraSpell)
+ m_caster->RemoveAurasDueToSpell(m_triggeredByAuraSpell->Id);
return;
}
+
+ //Any effect which causes you to lose control of your character will supress the starfall effect.
+ if(m_caster->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_ROOT | UNIT_STAT_CONFUSED))
+ return;
+
+ m_caster->CastSpell(unitTarget, damage, true);
+ return;
}
break;
case SPELLFAMILY_ROGUE:
switch(m_spellInfo->Id )
{
- case 31231: // Cheat Death
- {
- m_caster->CastSpell(m_caster,45182,true);
- return;
- }
case 5938: // Shiv
{
if(m_caster->GetTypeId() != TYPEID_PLAYER)
@@ -1447,36 +1549,38 @@ void Spell::EffectDummy(uint32 i)
m_caster->CastSpell(unitTarget, 5940, true);
return;
}
- }
- break;
- case SPELLFAMILY_HUNTER:
- // Kill command
- if(m_spellInfo->SpellFamilyFlags & 0x00080000000000LL)
- {
- if(m_caster->getClass()!=CLASS_HUNTER)
- return;
+ case 14185: // Preparation Rogue
+ {
+ if(m_caster->GetTypeId()!=TYPEID_PLAYER)
+ return;
- // clear hunter crit aura state
- m_caster->ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE,false);
+ //immediately finishes the cooldown on certain Rogue abilities
+ const PlayerSpellMap& sp_list = ((Player *)m_caster)->GetSpellMap();
+ for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
+ {
+ uint32 classspell = itr->first;
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell);
- // additional damage from pet to pet target
- Pet* pet = m_caster->GetPet();
- if(!pet || !pet->getVictim())
- return;
+ if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags[1] & 0x00000240 || spellInfo->SpellFamilyFlags[0] & 0x00000860))
+ {
+ ((Player*)m_caster)->RemoveSpellCooldown(classspell);
- uint32 spell_id = 0;
- switch (m_spellInfo->Id)
+ WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8));
+ data << uint32(classspell);
+ data << uint64(m_caster->GetGUID());
+ ((Player*)m_caster)->GetSession()->SendPacket(&data);
+ }
+ }
+ return;
+ }
+ case 31231: // Cheat Death
{
- case 34026: spell_id = 34027; break; // rank 1
- default:
- sLog.outError("Spell::EffectDummy: Spell %u not handled in KC",m_spellInfo->Id);
+ m_caster->CastSpell(m_caster,45182,true);
return;
}
-
- pet->CastSpell(pet->getVictim(), spell_id, true);
- return;
}
-
+ break;
+ case SPELLFAMILY_HUNTER:
switch(m_spellInfo->Id)
{
case 23989: //Readiness talent
@@ -1519,6 +1623,13 @@ void Spell::EffectDummy(uint32 i)
case SPELLFAMILY_PALADIN:
switch(m_spellInfo->SpellIconID)
{
+ // Divine Storm
+ if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
+ {
+ int32 damage=m_currentBasePoints[0] * damage /100;
+ m_caster->CastCustomSpell(unitTarget, 54172, &damage , 0, 0, true);
+ return;
+ }
case 156: // Holy Shock
{
if(!unitTarget)
@@ -1534,6 +1645,8 @@ void Spell::EffectDummy(uint32 i)
case 20930: hurt = 25902; heal = 25903; break;
case 27174: hurt = 27176; heal = 27175; break;
case 33072: hurt = 33073; heal = 33074; break;
+ case 48824: hurt = 48822; heal = 48820; break;
+ case 48825: hurt = 48823; heal = 48821; break;
default:
sLog.outError("Spell::EffectDummy: Spell %u not handled in HS",m_spellInfo->Id);
return;
@@ -1546,32 +1659,31 @@ void Spell::EffectDummy(uint32 i)
return;
}
- case 561: // Judgement of command
+ }
+
+ switch(m_spellInfo->Id)
+ {
+ case 20425: // Judgement of command
{
if(!unitTarget)
return;
- uint32 spell_id = m_spellInfo->EffectBasePoints[i]+1;//m_currentBasePoints[i]+1;
- SpellEntry const* spell_proto = sSpellStore.LookupEntry(spell_id);
+ SpellEntry const* spell_proto = sSpellStore.LookupEntry(damage);
if(!spell_proto)
return;
- if( !unitTarget->hasUnitState(UNIT_STAT_STUNNED) && m_caster->GetTypeId()==TYPEID_PLAYER)
+ if(unitTarget->hasUnitState(UNIT_STAT_STUNNED) && m_caster->GetTypeId()==TYPEID_PLAYER)
{
- // decreased damage (/2) for non-stunned target.
+ // always critical for stunned target
SpellModifier *mod = new SpellModifier;
- mod->op = SPELLMOD_DAMAGE;
- mod->value = -50;
- mod->type = SPELLMOD_PCT;
+ mod->op = SPELLMOD_CRITICAL_CHANCE;
+ mod->value = 100;
+ mod->type = SPELLMOD_FLAT;
mod->spellId = m_spellInfo->Id;
- mod->effectId = i;
- mod->lastAffected = NULL;
- mod->mask = 0x0000020000000000LL;
- mod->charges = 0;
+ mod->mask[1] = 0x00000200;
((Player*)m_caster)->AddSpellMod(mod, true);
m_caster->CastSpell(unitTarget,spell_proto,true,NULL);
- // mod deleted
((Player*)m_caster)->AddSpellMod(mod, false);
}
else
@@ -1579,10 +1691,6 @@ void Spell::EffectDummy(uint32 i)
return;
}
- }
-
- switch(m_spellInfo->Id)
- {
case 31789: // Righteous Defense (step 1)
{
// 31989 -> dummy effect (step 1) + dummy effect (step 2) -> 31709 (taunt like spell for each target)
@@ -1649,8 +1757,10 @@ void Spell::EffectDummy(uint32 i)
break;
case SPELLFAMILY_SHAMAN:
//Shaman Rockbiter Weapon
- if (m_spellInfo->SpellFamilyFlags == 0x400000)
+ if (m_spellInfo->SpellFamilyFlags.IsEqual(0x400000))
{
+ // TODO: use expect spell for enchant (if exist talent)
+ // In 3.0.3 no mods present for rockbiter
uint32 spell_id = 0;
switch(m_spellInfo->Id)
{
@@ -1658,11 +1768,6 @@ void Spell::EffectDummy(uint32 i)
case 8018: spell_id = 36750; break; // Rank 2
case 8019: spell_id = 36755; break; // Rank 3
case 10399: spell_id = 36759; break; // Rank 4
- case 16314: spell_id = 36763; break; // Rank 5
- case 16315: spell_id = 36766; break; // Rank 6
- case 16316: spell_id = 36771; break; // Rank 7
- case 25479: spell_id = 36775; break; // Rank 8
- case 25485: spell_id = 36499; break; // Rank 9
default:
sLog.outError("Spell::EffectDummy: Spell %u not handled in RW",m_spellInfo->Id);
return;
@@ -1672,16 +1777,16 @@ void Spell::EffectDummy(uint32 i)
if(!spellInfo)
{
- sLog.outError("WORLD: unknown spell id %i\n", spell_id);
+ sLog.outError("WORLD: unknown spell id %i", spell_id);
return;
}
if(m_caster->GetTypeId() != TYPEID_PLAYER)
return;
- for(int i = BASE_ATTACK; i <= OFF_ATTACK; ++i)
+ for(int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
{
- if(Item* item = ((Player*)m_caster)->GetWeaponForAttack(WeaponAttackType(i)))
+ if(Item* item = ((Player*)m_caster)->GetWeaponForAttack(WeaponAttackType(j)))
{
if(item->IsFitToSpellRequirements(m_spellInfo))
{
@@ -1700,18 +1805,83 @@ void Spell::EffectDummy(uint32 i)
}
return;
}
-
- if(m_spellInfo->Id == 39610) // Mana-Tide Totem effect
+ // Healing Stream Totem
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x2000)
+ {
+ m_caster->CastCustomSpell(unitTarget, 52042, &damage, 0, 0, true, 0, 0, m_originalCasterGUID);
+ return;
+ }
+ // Mana Spring Totem
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x4000)
+ {
+ if(unitTarget->getPowerType()!=POWER_MANA)
+ return;
+ m_caster->CastCustomSpell(unitTarget, 52032, &damage, 0, 0, true, 0, 0, m_originalCasterGUID);
+ return;
+ }
+ if(m_spellInfo->Id == 39610) // Mana Tide Totem effect
{
if(!unitTarget || unitTarget->getPowerType() != POWER_MANA)
return;
-
+ // Glyph of Mana Tide
+ Unit *owner = m_caster->GetOwner();
+ if (owner)
+ if (AuraEffect *dummy = owner->GetDummyAura(55441))
+ damage+=dummy->GetAmount();
// Regenerate 6% of Total Mana Every 3 secs
int32 EffectBasePoints0 = unitTarget->GetMaxPower(POWER_MANA) * damage / 100;
m_caster->CastCustomSpell(unitTarget,39609,&EffectBasePoints0,NULL,NULL,true,NULL,NULL,m_originalCasterGUID);
return;
}
+ // Lava Lash
+ if (m_spellInfo->SpellFamilyFlags[2] & 0x00000004)
+ {
+ if (m_caster->GetTypeId()!=TYPEID_PLAYER)
+ return;
+ Item *item = ((Player*)m_caster)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ if (item)
+ {
+ if (m_caster->GetAura(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 0x200000))
+ {
+ m_damage += m_damage * damage / 100;
+ }
+ }
+ return;
+ }
+ break;
+ case SPELLFAMILY_DEATHKNIGHT:
+ // Death strike dummy aura apply
+ // Used to proc healing later
+ if (m_spellInfo->SpellFamilyFlags[0] & 0x00000010)
+ {
+ spell_id=45469;
+ m_caster->CastSpell(m_caster,spell_id,true);
+ return;
+ }
+ // Death Coil
+ else if(m_spellInfo->SpellFamilyFlags[0] & 0x002000)
+ {
+ if(m_caster->IsFriendlyTo(unitTarget))
+ {
+ if(unitTarget->GetCreatureType() != CREATURE_TYPE_UNDEAD)
+ return;
+ int32 bp = damage * 1.5f;
+ m_caster->CastCustomSpell(unitTarget,47633,&bp,NULL,NULL,true);
+ }
+ else
+ {
+ int32 bp = damage;
+ m_caster->CastCustomSpell(unitTarget,47632,&bp,NULL,NULL,true);
+ }
+ return;
+ }
+ // Death Grip
+ else if(m_spellInfo->Id == 49560)
+ {
+ unitTarget->CastSpell(m_caster, damage, true);
+ return;
+ }
break;
}
@@ -1739,6 +1909,15 @@ void Spell::EffectDummy(uint32 i)
m_caster->AddPetAura(petSpell);
return;
}
+
+ // Script based implementation. Must be used only for not good for implementation in core spell effects
+ // So called only for not proccessed cases
+ if(gameObjTarget)
+ Script->EffectDummyGameObj(m_caster, m_spellInfo->Id, i, gameObjTarget);
+ else if(unitTarget && unitTarget->GetTypeId()==TYPEID_UNIT)
+ Script->EffectDummyCreature(m_caster, m_spellInfo->Id, i, (Creature*)unitTarget);
+ else if(itemTarget)
+ Script->EffectDummyItem(m_caster, m_spellInfo->Id, i, itemTarget);
}
void Spell::EffectTriggerSpellWithValue(uint32 i)
@@ -1750,7 +1929,7 @@ void Spell::EffectTriggerSpellWithValue(uint32 i)
if(!spellInfo)
{
- sLog.outError("EffectTriggerSpellWithValue of spell %u: triggering unknown spell id %i\n", m_spellInfo->Id,triggered_spell_id);
+ sLog.outError("EffectTriggerSpellWithValue of spell %u: triggering unknown spell id %i", m_spellInfo->Id,triggered_spell_id);
return;
}
@@ -1776,8 +1955,8 @@ void Spell::EffectTriggerRitualOfSummoning(uint32 i)
targets.setUnitTarget( unitTarget);
spell->prepare(&targets);
- m_caster->SetCurrentCastedSpell(spell);
- spell->m_selfContainer = &(m_caster->m_currentSpells[spell->GetCurrentContainer()]);
+ //m_caster->SetCurrentCastedSpell(spell);
+ //spell->m_selfContainer = &(m_caster->m_currentSpells[spell->GetCurrentContainer()]);
}
@@ -1810,9 +1989,9 @@ void Spell::EffectTriggerSpell(uint32 i)
// Vanish
case 18461:
{
- m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT);
- m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOD_DECREASE_SPEED);
- m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOD_STALKED);
+ m_caster->RemoveAurasByType(SPELL_AURA_MOD_ROOT);
+ m_caster->RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
+ m_caster->RemoveAurasByType(SPELL_AURA_MOD_STALKED);
// if this spell is given to NPC it must handle rest by it's own AI
if ( m_caster->GetTypeId() != TYPEID_PLAYER )
@@ -1820,6 +1999,7 @@ void Spell::EffectTriggerSpell(uint32 i)
// get highest rank of the Stealth spell
uint32 spellId = 0;
+ SpellEntry const *spellInfo;
const PlayerSpellMap& sp_list = ((Player*)m_caster)->GetSpellMap();
for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
{
@@ -1827,11 +2007,11 @@ void Spell::EffectTriggerSpell(uint32 i)
if(!itr->second->active || itr->second->disabled || itr->second->state == PLAYERSPELL_REMOVED)
continue;
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
+ spellInfo = sSpellStore.LookupEntry(itr->first);
if (!spellInfo)
continue;
- if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE_STEALTH)
+ if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_ROGUE_STEALTH)
{
spellId = spellInfo->Id;
break;
@@ -1846,7 +2026,8 @@ void Spell::EffectTriggerSpell(uint32 i)
if(((Player*)m_caster)->HasSpellCooldown(spellId))
((Player*)m_caster)->RemoveSpellCooldown(spellId);
- m_caster->CastSpell(m_caster, spellId, true);
+ // Push stealth to list because it must be handled after combat remove
+ m_TriggerSpells.push_back(spellInfo);
return;
}
// just skip
@@ -1860,7 +2041,7 @@ void Spell::EffectTriggerSpell(uint32 i)
if (!spell)
return;
- for (int i=0; i < spell->StackAmount; ++i)
+ for (int j=0; j < spell->StackAmount; ++j)
m_caster->CastSpell(unitTarget,spell->Id, true, m_CastItem, NULL, m_originalCasterGUID);
return;
}
@@ -1871,7 +2052,7 @@ void Spell::EffectTriggerSpell(uint32 i)
if (!spell)
return;
- for (int i=0; i < spell->StackAmount; ++i)
+ for (int j=0; j < spell->StackAmount; ++j)
m_caster->CastSpell(unitTarget,spell->Id, true, m_CastItem, NULL, m_originalCasterGUID);
return;
}
@@ -1886,7 +2067,7 @@ void Spell::EffectTriggerSpell(uint32 i)
{
uint32 dispelMask = GetDispellMask(DISPEL_ALL);
Unit::AuraMap& Auras = m_caster->GetAuras();
- for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end(); ++iter)
+ for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end();)
{
// remove all harmful spells on you...
SpellEntry const* spell = iter->second->GetSpellProto();
@@ -1895,16 +2076,17 @@ void Spell::EffectTriggerSpell(uint32 i)
// ignore positive and passive auras
&& !iter->second->IsPositive() && !iter->second->IsPassive())
{
- m_caster->RemoveAurasDueToSpell(spell->Id);
- iter = Auras.begin();
+ m_caster->RemoveAura(iter);
}
+ else
+ iter++;
}
return;
}
// Priest Shadowfiend (34433) need apply mana gain trigger aura on pet
case 41967:
{
- if (Unit *pet = m_caster->GetPet())
+ if (Unit *pet = m_caster->GetGuardianPet())
pet->CastSpell(pet, 28305, true);
return;
}
@@ -1919,38 +2101,6 @@ void Spell::EffectTriggerSpell(uint32 i)
return;
}
- // some triggered spells require specific equipment
- if(spellInfo->EquippedItemClass >=0 && m_caster->GetTypeId()==TYPEID_PLAYER)
- {
- // main hand weapon required
- if(spellInfo->AttributesEx3 & SPELL_ATTR_EX3_MAIN_HAND)
- {
- Item* item = ((Player*)m_caster)->GetWeaponForAttack(BASE_ATTACK);
-
- // skip spell if no weapon in slot or broken
- if(!item || item->IsBroken() )
- return;
-
- // skip spell if weapon not fit to triggered spell
- if(!item->IsFitToSpellRequirements(spellInfo))
- return;
- }
-
- // offhand hand weapon required
- if(spellInfo->AttributesEx3 & SPELL_ATTR_EX3_REQ_OFFHAND)
- {
- Item* item = ((Player*)m_caster)->GetWeaponForAttack(OFF_ATTACK);
-
- // skip spell if no weapon in slot or broken
- if(!item || item->IsBroken() )
- return;
-
- // skip spell if weapon not fit to triggered spell
- if(!item->IsFitToSpellRequirements(spellInfo))
- return;
- }
- }
-
// some triggered spells must be casted instantly (for example, if next effect case instant kill caster)
bool instant = false;
for(uint32 j = i+1; j < 3; ++j)
@@ -1988,12 +2138,65 @@ void Spell::EffectTriggerMissileSpell(uint32 effect_idx)
if (m_CastItem)
DEBUG_LOG("WORLD: cast Item spellId - %i", spellInfo->Id);
- Spell *spell = new Spell(m_caster, spellInfo, true, m_originalCasterGUID );
+ m_caster->CastSpell(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, spellInfo->Id, true, m_CastItem, 0, m_originalCasterGUID);
+}
- SpellCastTargets targets;
- targets.setDestination(m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ);
- spell->m_CastItem = m_CastItem;
- spell->prepare(&targets, NULL);
+void Spell::EffectJump(uint32 i)
+{
+ if(m_caster->isInFlight())
+ return;
+
+ // Init dest coordinates
+ float x,y,z,o;
+ if(m_targets.HasDest())
+ {
+ x = m_targets.m_destX;
+ y = m_targets.m_destY;
+ z = m_targets.m_destZ;
+
+ if(m_spellInfo->EffectImplicitTargetA[i] == TARGET_DEST_TARGET_BACK)
+ {
+ // explicit cast data from client or server-side cast
+ // some spell at client send caster
+ Unit* pTarget = NULL;
+ if(m_targets.getUnitTarget() && m_targets.getUnitTarget()!=m_caster)
+ pTarget = m_targets.getUnitTarget();
+ else if(unitTarget->getVictim())
+ pTarget = m_caster->getVictim();
+ else if(m_caster->GetTypeId() == TYPEID_PLAYER)
+ pTarget = ObjectAccessor::GetUnit(*m_caster, ((Player*)m_caster)->GetSelection());
+
+ o = pTarget ? pTarget->GetOrientation() : m_caster->GetOrientation();
+ }
+ else
+ o = m_caster->GetOrientation();
+ }
+ else if(unitTarget)
+ {
+ unitTarget->GetContactPoint(m_caster,x,y,z,CONTACT_DISTANCE);
+ o = m_caster->GetOrientation();
+ }
+ else if(gameObjTarget)
+ {
+ gameObjTarget->GetContactPoint(m_caster,x,y,z,CONTACT_DISTANCE);
+ o = m_caster->GetOrientation();
+ }
+ else
+ {
+ sLog.outError( "Spell::EffectJump - unsupported target mode for spell ID %u", m_spellInfo->Id );
+ return;
+ }
+
+ //m_caster->NearTeleportTo(x,y,z,o,true);
+ float speedZ;
+ if(m_spellInfo->EffectMiscValue[i])
+ speedZ = float(m_spellInfo->EffectMiscValue[i])/10;
+ else if(m_spellInfo->EffectMiscValueB[i])
+ speedZ = float(m_spellInfo->EffectMiscValueB[i])/10;
+ else
+ speedZ = 10.0f;
+ float speedXY = m_caster->GetExactDistance2d(x, y) * 10.0f / speedZ;
+ m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
}
void Spell::EffectTeleportUnits(uint32 i)
@@ -2007,6 +2210,7 @@ void Spell::EffectTeleportUnits(uint32 i)
sLog.outError( "Spell::EffectTeleportUnits - does not have destination for spell ID %u\n", m_spellInfo->Id );
return;
}
+
// Init dest coordinates
int32 mapid = m_targets.m_mapId;
if(mapid < 0) mapid = (int32)unitTarget->GetMapId();
@@ -2015,16 +2219,11 @@ void Spell::EffectTeleportUnits(uint32 i)
float z = m_targets.m_destZ;
float orientation = m_targets.getUnitTarget() ? m_targets.getUnitTarget()->GetOrientation() : unitTarget->GetOrientation();
sLog.outDebug("Spell::EffectTeleportUnits - teleport unit to %u %f %f %f\n", mapid, x, y, z);
- // Teleport
- if(unitTarget->GetTypeId() == TYPEID_PLAYER)
- ((Player*)unitTarget)->TeleportTo(mapid, x, y, z, orientation, TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget==m_caster ? TELE_TO_SPELL : 0));
- else
- {
- MapManager::Instance().GetMap(mapid, m_caster)->CreatureRelocation((Creature*)unitTarget, x, y, z, orientation);
- WorldPacket data;
- unitTarget->BuildTeleportAckMsg(&data, x, y, z, orientation);
- unitTarget->SendMessageToSet(&data, false);
- }
+
+ if(mapid == unitTarget->GetMapId())
+ unitTarget->NearTeleportTo(x, y, z, orientation, unitTarget == m_caster);
+ else if(unitTarget->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)unitTarget)->TeleportTo(mapid, x, y, z, orientation, unitTarget==m_caster ? TELE_TO_SPELL : 0);
// post effects for TARGET_TABLE_X_Y_Z_COORDINATES
switch ( m_spellInfo->Id )
@@ -2125,84 +2324,7 @@ void Spell::EffectTeleportUnits(uint32 i)
void Spell::EffectApplyAura(uint32 i)
{
- if(!unitTarget)
- return;
-
- SpellImmuneList const& list = unitTarget->m_spellImmune[IMMUNITY_STATE];
- for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr)
- if(itr->type == m_spellInfo->EffectApplyAuraName[i])
- return;
-
- // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load)
- if( !unitTarget->isAlive() && m_spellInfo->Id != 20584 && m_spellInfo->Id != 8326 &&
- (unitTarget->GetTypeId()!=TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) )
- return;
-
- Unit* caster = m_originalCasterGUID ? m_originalCaster : m_caster;
- if(!caster)
- return;
-
- sLog.outDebug("Spell: Aura is: %u", m_spellInfo->EffectApplyAuraName[i]);
-
- Aura* Aur = CreateAura(m_spellInfo, i, &damage, unitTarget, caster, m_CastItem);
-
- // Now Reduce spell duration using data received at spell hit
- int32 duration = Aur->GetAuraMaxDuration();
- unitTarget->ApplyDiminishingToDuration(m_diminishGroup,duration,caster,m_diminishLevel);
- Aur->setDiminishGroup(m_diminishGroup);
-
- // if Aura removed and deleted, do not continue.
- if(duration== 0 && !(Aur->IsPermanent()))
- {
- delete Aur;
- return;
- }
-
- if(duration != Aur->GetAuraMaxDuration())
- {
- Aur->SetAuraMaxDuration(duration);
- Aur->SetAuraDuration(duration);
- }
-
- bool added = unitTarget->AddAura(Aur);
-
- // Aura not added and deleted in AddAura call;
- if (!added)
- return;
-
- // found crash at character loading, broken pointer to Aur...
- // Aur was deleted in AddAura()...
- if(!Aur)
- return;
-
- // TODO Make a way so it works for every related spell!
- if(unitTarget->GetTypeId()==TYPEID_PLAYER ||( unitTarget->GetTypeId()==TYPEID_UNIT && ((Creature*)unitTarget)->isPet() ) ) // Negative buff should only be applied on players
- {
- uint32 spellId = 0;
- if(m_spellInfo->CasterAuraStateNot==AURA_STATE_WEAKENED_SOUL || m_spellInfo->TargetAuraStateNot==AURA_STATE_WEAKENED_SOUL)
- spellId = 6788; // Weakened Soul
- else if(m_spellInfo->CasterAuraStateNot==AURA_STATE_FORBEARANCE || m_spellInfo->TargetAuraStateNot==AURA_STATE_FORBEARANCE)
- spellId = 25771; // Forbearance
- else if(m_spellInfo->CasterAuraStateNot==AURA_STATE_HYPOTHERMIA)
- spellId = 41425; // Hypothermia
- else if (m_spellInfo->Mechanic == MECHANIC_BANDAGE) // Bandages
- spellId = 11196; // Recently Bandaged
- else if( (m_spellInfo->AttributesEx & 0x20) && (m_spellInfo->AttributesEx2 & 0x20000) )
- spellId = 23230; // Blood Fury - Healing Reduction
-
- SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(spellId);
- if (AdditionalSpellInfo)
- {
- // applied at target by target
- Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, 0, NULL, unitTarget,unitTarget, 0);
- unitTarget->AddAura(AdditionalAura);
- sLog.outDebug("Spell: Additional Aura is: %u", AdditionalSpellInfo->EffectApplyAuraName[0]);
- }
- }
-
- // Prayer of Mending (jump animation), we need formal caster instead original for correct animation
- if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags & 0x00002000000000LL))
- m_caster->CastSpell(unitTarget, 41637, true, NULL, Aur, m_originalCasterGUID);
+ return; //handled elsewhere
}
void Spell::EffectUnlearnSpecialization( uint32 i )
@@ -2252,7 +2374,8 @@ void Spell::EffectPowerDrain(uint32 i)
unitTarget->ModifyPower(drain_power,-new_damage);
- if(drain_power == POWER_MANA)
+ // Don`t restore from self drain
+ if(drain_power == POWER_MANA && m_caster != unitTarget)
{
float manaMultiplier = m_spellInfo->EffectMultipleValue[i];
if(manaMultiplier==0)
@@ -2271,60 +2394,9 @@ void Spell::EffectPowerDrain(uint32 i)
void Spell::EffectSendEvent(uint32 EffectIndex)
{
- if (m_caster->GetTypeId() == TYPEID_PLAYER && ((Player*)m_caster)->InBattleGround())
- {
- BattleGround* bg = ((Player *)m_caster)->GetBattleGround();
- if(bg && bg->GetStatus() == STATUS_IN_PROGRESS)
- {
- switch(m_spellInfo->Id)
- {
- case 23333: // Pickup Horde Flag
- /*do not uncomment .
- if(bg->GetTypeID()==BATTLEGROUND_WS)
- bg->EventPlayerClickedOnFlag((Player*)m_caster, gameObjTarget);
- sLog.outDebug("Send Event Horde Flag Picked Up");
- break;
- /* not used :
- case 23334: // Drop Horde Flag
- if(bg->GetTypeID()==BATTLEGROUND_WS)
- bg->EventPlayerDroppedFlag((Player*)m_caster);
- sLog.outDebug("Drop Horde Flag");
- break;
- */
- case 23335: // Pickup Alliance Flag
- /*do not uncomment ... (it will cause crash, because of null targetobject!) anyway this is a bad way to call that event, because it would cause recursion
- if(bg->GetTypeID()==BATTLEGROUND_WS)
- bg->EventPlayerClickedOnFlag((Player*)m_caster, gameObjTarget);
- sLog.outDebug("Send Event Alliance Flag Picked Up");
- break;
- /* not used :
- case 23336: // Drop Alliance Flag
- if(bg->GetTypeID()==BATTLEGROUND_WS)
- bg->EventPlayerDroppedFlag((Player*)m_caster);
- sLog.outDebug("Drop Alliance Flag");
- break;
- case 23385: // Alliance Flag Returns
- if(bg->GetTypeID()==BATTLEGROUND_WS)
- bg->EventPlayerClickedOnFlag((Player*)m_caster, gameObjTarget);
- sLog.outDebug("Alliance Flag Returned");
- break;
- case 23386: // Horde Flag Returns
- if(bg->GetTypeID()==BATTLEGROUND_WS)
- bg->EventPlayerClickedOnFlag((Player*)m_caster, gameObjTarget);
- sLog.outDebug("Horde Flag Returned");
- break;*/
- case 34976:
- /*
- if(bg->GetTypeID()==BATTLEGROUND_EY)
- bg->EventPlayerClickedOnFlag((Player*)m_caster, gameObjTarget);
- */
- break;
- default:
- sLog.outDebug("Unknown spellid %u in BG event", m_spellInfo->Id);
- break;
- }
- }
- }
+ /*
+ we do not handle a flag dropping or clicking on flag in battleground by sendevent system
+ */
sLog.outDebug("Spell ScriptStart %u for spellid %u in EffectSendEvent ", m_spellInfo->EffectMiscValue[EffectIndex], m_spellInfo->Id);
sWorld.ScriptsStart(sEventScripts, m_spellInfo->EffectMiscValue[EffectIndex], m_caster, focusObject);
}
@@ -2345,10 +2417,20 @@ void Spell::EffectPowerBurn(uint32 i)
if(damage < 0)
return;
+ Unit* caster = m_originalCaster ? m_originalCaster : m_caster;
+
+ // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
+ if(m_spellInfo->ManaCostPercentage)
+ {
+ uint32 maxdamage = m_caster->GetMaxPower(powertype) * damage * 2 / 100;
+ damage = unitTarget->GetMaxPower(powertype) * damage / 100;
+ if(damage > maxdamage) damage = maxdamage;
+ }
+
int32 curPower = int32(unitTarget->GetPower(powertype));
- // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
uint32 power = damage;
+ // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
if ( powertype == POWER_MANA && unitTarget->GetTypeId() == TYPEID_PLAYER )
power -= ((Player*)unitTarget)->GetSpellCritDamageReduction(power);
@@ -2390,27 +2472,27 @@ void Spell::SpellDamageHeal(uint32 /*i*/)
{
// Amount of heal - depends from stacked Holy Energy
int damageAmount = 0;
- Unit::AuraList const& mDummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
+ Unit::AuraEffectList const& mDummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraEffectList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
if((*i)->GetId() == 45062)
- damageAmount+=(*i)->GetModifierValue();
+ damageAmount+=(*i)->GetAmount();
if (damageAmount)
m_caster->RemoveAurasDueToSpell(45062);
addhealth += damageAmount;
}
// Swiftmend - consumes Regrowth or Rejuvenation
- else if (m_spellInfo->TargetAuraState == AURA_STATE_SWIFTMEND && unitTarget->HasAuraState(AURA_STATE_SWIFTMEND))
+ else if (m_spellInfo->TargetAuraState == AURA_STATE_SWIFTMEND && unitTarget->HasAuraState(AURA_STATE_SWIFTMEND, m_spellInfo, m_caster))
{
- Unit::AuraList const& RejorRegr = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_HEAL);
+ Unit::AuraEffectList const& RejorRegr = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_HEAL);
// find most short by duration
- Aura *targetAura = NULL;
- for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
+ AuraEffect *targetAura = NULL;
+ for(Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
{
if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
- && ((*i)->GetSpellProto()->SpellFamilyFlags == 0x40 || (*i)->GetSpellProto()->SpellFamilyFlags == 0x10) )
+ && ((*i)->GetSpellProto()->SpellFamilyFlags.IsEqual(0x40) || (*i)->GetSpellProto()->SpellFamilyFlags.IsEqual(0x10)) )
{
- if(!targetAura || (*i)->GetAuraDuration() < targetAura->GetAuraDuration())
+ if(!targetAura || (*i)->GetParentAura()->GetAuraDuration() < targetAura->GetParentAura()->GetAuraDuration())
targetAura = *i;
}
}
@@ -2421,29 +2503,43 @@ void Spell::SpellDamageHeal(uint32 /*i*/)
return;
}
- int32 tickheal = targetAura->GetModifierValuePerStack();
+ int32 tickheal = targetAura->GetAmount();
if(Unit* auraCaster = targetAura->GetCaster())
- tickheal = auraCaster->SpellHealingBonus(targetAura->GetSpellProto(), tickheal, DOT, unitTarget);
+ tickheal = auraCaster->SpellHealingBonus(unitTarget, targetAura->GetSpellProto(), tickheal, DOT);
//int32 tickheal = targetAura->GetSpellProto()->EffectBasePoints[idx] + 1;
//It is said that talent bonus should not be included
- //int32 tickheal = targetAura->GetModifierValue();
+
int32 tickcount = 0;
if(targetAura->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID)
{
- switch(targetAura->GetSpellProto()->SpellFamilyFlags)//TODO: proper spellfamily for 3.0.x
+ switch(targetAura->GetSpellProto()->SpellFamilyFlags[0])
{
case 0x10: tickcount = 4; break; // Rejuvenation
case 0x40: tickcount = 6; break; // Regrowth
}
}
addhealth += tickheal * tickcount;
- unitTarget->RemoveAurasByCasterSpell(targetAura->GetId(), targetAura->GetCasterGUID());
+
+ // Glyph of Swiftmend
+ if(!caster->GetDummyAura(54824))
+ unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID());
//addhealth += tickheal * tickcount;
//addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget);
}
+ // Riptide - increase healing done by Chain Heal
+ else if (m_spellInfo->SpellFamilyName==SPELLFAMILY_SHAMAN && m_spellInfo->SpellFamilyFlags[0] & 0x100)
+ {
+ addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL);
+ if (AuraEffect * aurEff = unitTarget->GetAura(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_SHAMAN, 0, 0, 0x10, m_originalCasterGUID))
+ {
+ addhealth *= 1.25f;
+ // consume aura
+ unitTarget->RemoveAura(aurEff->GetParentAura());
+ }
+ }
else
- addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget);
+ addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL);
m_damage -= addhealth;
}
@@ -2461,14 +2557,11 @@ void Spell::EffectHealPct( uint32 /*i*/ )
return;
uint32 addhealth = unitTarget->GetMaxHealth() * damage / 100;
- caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, false);
+ if(Player* modOwner = m_caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DAMAGE, addhealth, this);
- int32 gain = unitTarget->ModifyHealth( int32(addhealth) );
+ int32 gain = caster->DealHeal(unitTarget, addhealth, m_spellInfo);
unitTarget->getHostilRefManager().threatAssist(m_caster, float(gain) * 0.5f, m_spellInfo);
-
- if(caster->GetTypeId()==TYPEID_PLAYER)
- if(BattleGround *bg = ((Player*)caster)->GetBattleGround())
- bg->UpdatePlayerScore(((Player*)caster), SCORE_HEALING_DONE, gain);
}
}
@@ -2484,9 +2577,8 @@ void Spell::EffectHealMechanical( uint32 /*i*/ )
if (!caster)
return;
- uint32 addhealth = caster->SpellHealingBonus(m_spellInfo, uint32(damage), HEAL, unitTarget);
- caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, false);
- unitTarget->ModifyHealth( int32(damage) );
+ uint32 addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, uint32(damage), HEAL);
+ caster->DealHeal(unitTarget, addhealth, m_spellInfo);
}
}
@@ -2515,12 +2607,8 @@ void Spell::EffectHealthLeech(uint32 i)
if(m_caster->isAlive())
{
- new_damage = m_caster->SpellHealingBonus(m_spellInfo, new_damage, HEAL, m_caster);
-
- m_caster->ModifyHealth(new_damage);
-
- if(m_caster->GetTypeId() == TYPEID_PLAYER)
- m_caster->SendHealSpellLog(m_caster, m_spellInfo->Id, uint32(new_damage));
+ new_damage = m_caster->SpellHealingBonus(m_caster, m_spellInfo, new_damage, HEAL);
+ m_caster->DealHeal(m_caster, uint32(new_damage), m_spellInfo);
}
// m_healthLeech+=tmpvalue;
// m_damage+=new_damage;
@@ -2568,8 +2656,8 @@ void Spell::DoCreateItem(uint32 i, uint32 itemtype)
if (num_to_add < 1)
num_to_add = 1;
- if (num_to_add > pProto->Stackable)
- num_to_add = pProto->Stackable;
+ if (num_to_add > pProto->GetMaxStackSize())
+ num_to_add = pProto->GetMaxStackSize();
// init items_count to 1, since 1 item will be created regardless of specialization
int items_count=1;
@@ -2627,7 +2715,7 @@ void Spell::DoCreateItem(uint32 i, uint32 itemtype)
// we succeeded in creating at least one item, so a levelup is possible
player->UpdateCraftSkill(m_spellInfo->Id);
- }
+ }
}
void Spell::EffectCreateItem(uint32 i)
@@ -2635,9 +2723,24 @@ void Spell::EffectCreateItem(uint32 i)
DoCreateItem(i,m_spellInfo->EffectItemType[i]);
}
+void Spell::EffectCreateItem2(uint32 i)
+{
+ // special case: generate using spell_loot_template
+ if(!m_spellInfo->EffectItemType[i])
+ {
+ if(m_caster->GetTypeId()!=TYPEID_PLAYER)
+ return;
+
+ // create some random items
+ ((Player*)m_caster)->AutoStoreLoot(m_spellInfo->Id,LootTemplates_Spell);
+ return;
+ }
+ DoCreateItem(i,m_spellInfo->EffectItemType[i]);
+}
+
void Spell::EffectPersistentAA(uint32 i)
{
- float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ float radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
if(Player* modOwner = m_originalCaster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius);
@@ -2666,6 +2769,8 @@ void Spell::EffectEnergize(uint32 i)
if(m_spellInfo->EffectMiscValue[i] < 0 || m_spellInfo->EffectMiscValue[i] >= MAX_POWERS)
return;
+ Powers power = Powers(m_spellInfo->EffectMiscValue[i]);
+
// Some level depends spells
int multiplier = 0;
int level_diff = 0;
@@ -2693,11 +2798,18 @@ void Spell::EffectEnergize(uint32 i)
if (level_diff > 0)
damage -= multiplier * level_diff;
+ //Judgement of wisdom energize effect
+ if(m_spellInfo->Id == 20268)
+ {
+ if(unitTarget->GetTypeId() == TYPEID_PLAYER)
+ {
+ damage = unitTarget->GetCreateMana() * damage / 100;
+ }
+ }
+
if(damage < 0)
return;
- Powers power = Powers(m_spellInfo->EffectMiscValue[i]);
-
if(unitTarget->GetMaxPower(power) == 0)
return;
@@ -2765,7 +2877,7 @@ void Spell::EffectEnergisePct(uint32 i)
uint32 gain = damage * maxPower / 100;
unitTarget->ModifyPower(power, gain);
- m_caster->SendEnergizeSpellLog(unitTarget, m_spellInfo->Id, damage, power);
+ m_caster->SendEnergizeSpellLog(unitTarget, m_spellInfo->Id, gain, power);
}
void Spell::SendLoot(uint64 guid, LootType loottype)
@@ -2853,7 +2965,7 @@ void Spell::SendLoot(uint64 guid, LootType loottype)
player->SendLoot(guid, loottype);
}
-void Spell::EffectOpenLock(uint32 /*i*/)
+void Spell::EffectOpenLock(uint32 effIndex)
{
if(!m_caster || m_caster->GetTypeId() != TYPEID_PLAYER)
{
@@ -2863,7 +2975,6 @@ void Spell::EffectOpenLock(uint32 /*i*/)
Player* player = (Player*)m_caster;
- LootType loottype = LOOT_CORPSE;
uint32 lockId = 0;
uint64 guid = 0;
@@ -2875,7 +2986,7 @@ void Spell::EffectOpenLock(uint32 /*i*/)
if( goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune ||
goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK )
{
- //isAllowUseBattleGroundObject() already called in CanCast()
+ //CanUseBattleGroundObject() already called in CheckCast()
// in battleground check
if(BattleGround *bg = player->GetBattleGround())
{
@@ -2887,7 +2998,7 @@ void Spell::EffectOpenLock(uint32 /*i*/)
}
else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
{
- //isAllowUseBattleGroundObject() already called in CanCast()
+ //CanUseBattleGroundObject() already called in CheckCast()
// in battleground check
if(BattleGround *bg = player->GetBattleGround())
{
@@ -2914,93 +3025,39 @@ void Spell::EffectOpenLock(uint32 /*i*/)
return;
}
- if(!lockId) // possible case for GO and maybe for items.
- {
- SendLoot(guid, loottype);
- return;
- }
-
- // Get LockInfo
- LockEntry const *lockInfo = sLockStore.LookupEntry(lockId);
+ SkillType skillId = SKILL_NONE;
+ int32 reqSkillValue = 0;
+ int32 skillValue;
- if (!lockInfo)
+ SpellCastResult res = CanOpenLock(effIndex,lockId,skillId,reqSkillValue,skillValue);
+ if(res != SPELL_CAST_OK)
{
- sLog.outError( "Spell::EffectOpenLock: %s [guid = %u] has an unknown lockId: %u!",
- (gameObjTarget ? "gameobject" : "item"), GUID_LOPART(guid), lockId);
- SendCastResult(SPELL_FAILED_BAD_TARGETS);
+ SendCastResult(res);
return;
}
- // check key
- for(int i = 0; i < 5; ++i)
- {
- // type==1 This means lockInfo->key[i] is an item
- if(lockInfo->keytype[i]==LOCK_KEY_ITEM && lockInfo->key[i] && m_CastItem && m_CastItem->GetEntry()==lockInfo->key[i])
- {
- SendLoot(guid, loottype);
- return;
- }
- }
-
- uint32 SkillId = 0;
- // Check and skill-up skill
- if( m_spellInfo->Effect[1] == SPELL_EFFECT_SKILL )
- SkillId = m_spellInfo->EffectMiscValue[1];
- // pickpocketing spells
- else if( m_spellInfo->EffectMiscValue[0] == LOCKTYPE_PICKLOCK )
- SkillId = SKILL_LOCKPICKING;
-
- // skill bonus provided by casting spell (mostly item spells)
- uint32 spellSkillBonus = uint32(damage/*m_currentBasePoints[0]+1*/);
-
- uint32 reqSkillValue = lockInfo->requiredminingskill;
-
- if(lockInfo->requiredlockskill) // required pick lock skill applying
- {
- if(SkillId != SKILL_LOCKPICKING) // wrong skill (cheating?)
- {
- SendCastResult(SPELL_FAILED_FIZZLE);
- return;
- }
-
- reqSkillValue = lockInfo->requiredlockskill;
- }
- else if(SkillId == SKILL_LOCKPICKING) // apply picklock skill to wrong target
- {
- SendCastResult(SPELL_FAILED_BAD_TARGETS);
- return;
- }
+ SendLoot(guid, LOOT_SKINNING);
- if ( SkillId )
+ // not allow use skill grow at item base open
+ if(!m_CastItem && skillId != SKILL_NONE)
{
- loottype = LOOT_SKINNING;
- if ( player->GetSkillValue(SkillId) + spellSkillBonus < reqSkillValue )
- {
- SendCastResult(SPELL_FAILED_LOW_CASTLEVEL);
- return;
- }
-
// update skill if really known
- uint32 SkillValue = player->GetPureSkillValue(SkillId);
- if(SkillValue) // non only item base skill
+ if(uint32 pureSkillValue = player->GetPureSkillValue(skillId))
{
if(gameObjTarget)
{
// Allow one skill-up until respawned
if ( !gameObjTarget->IsInSkillupList( player->GetGUIDLow() ) &&
- player->UpdateGatherSkill(SkillId, SkillValue, reqSkillValue) )
+ player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue) )
gameObjTarget->AddToSkillupList( player->GetGUIDLow() );
}
else if(itemTarget)
{
// Do one skill-up
- uint32 SkillValue = player->GetPureSkillValue(SkillId);
- player->UpdateGatherSkill(SkillId, SkillValue, reqSkillValue);
+ player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
}
}
}
-
- SendLoot(guid, loottype);
}
void Spell::EffectSummonChangeItem(uint32 i)
@@ -3028,10 +3085,10 @@ void Spell::EffectSummonChangeItem(uint32 i)
if( !pNewItem )
return;
- for(uint8 i= PERM_ENCHANTMENT_SLOT; i<=TEMP_ENCHANTMENT_SLOT; ++i)
+ for(uint8 j= PERM_ENCHANTMENT_SLOT; j<=TEMP_ENCHANTMENT_SLOT; ++j)
{
- if(m_CastItem->GetEnchantmentId(EnchantmentSlot(i)))
- pNewItem->SetEnchantment(EnchantmentSlot(i), m_CastItem->GetEnchantmentId(EnchantmentSlot(i)), m_CastItem->GetEnchantmentDuration(EnchantmentSlot(i)), m_CastItem->GetEnchantmentCharges(EnchantmentSlot(i)));
+ if(m_CastItem->GetEnchantmentId(EnchantmentSlot(j)))
+ pNewItem->SetEnchantment(EnchantmentSlot(j), m_CastItem->GetEnchantmentId(EnchantmentSlot(j)), m_CastItem->GetEnchantmentDuration(EnchantmentSlot(j)), m_CastItem->GetEnchantmentCharges(EnchantmentSlot(j)));
}
if(m_CastItem->GetUInt32Value(ITEM_FIELD_DURABILITY) < m_CastItem->GetUInt32Value(ITEM_FIELD_MAXDURABILITY))
@@ -3126,100 +3183,198 @@ void Spell::EffectProficiency(uint32 /*i*/)
void Spell::EffectApplyAreaAura(uint32 i)
{
- if(!unitTarget)
+ return;
+/* if(!unitTarget)
return;
if(!unitTarget->isAlive())
return;
AreaAura* Aur = new AreaAura(m_spellInfo, i, &damage, unitTarget, m_caster, m_CastItem);
- unitTarget->AddAura(Aur);
+ unitTarget->AddAura(Aur);*/
}
void Spell::EffectSummonType(uint32 i)
{
- switch(m_spellInfo->EffectMiscValueB[i])
- {
- case SUMMON_TYPE_GUARDIAN:
- EffectSummonGuardian(i);
- break;
- case SUMMON_TYPE_POSESSED:
- case SUMMON_TYPE_POSESSED2:
- case SUMMON_TYPE_POSESSED3:
- EffectSummonPossessed(i);
- break;
- case SUMMON_TYPE_WILD:
- EffectSummonWild(i);
- break;
- case SUMMON_TYPE_DEMON:
- EffectSummonDemon(i);
- break;
- case SUMMON_TYPE_SUMMON:
- EffectSummon(i);
- break;
- case SUMMON_TYPE_CRITTER:
- case SUMMON_TYPE_CRITTER2:
- case SUMMON_TYPE_CRITTER3:
- EffectSummonCritter(i);
- break;
- case SUMMON_TYPE_TOTEM_SLOT1:
- case SUMMON_TYPE_TOTEM_SLOT2:
- case SUMMON_TYPE_TOTEM_SLOT3:
- case SUMMON_TYPE_TOTEM_SLOT4:
- case SUMMON_TYPE_TOTEM:
- EffectSummonTotem(i);
- break;
- case SUMMON_TYPE_UNKNOWN1:
- case SUMMON_TYPE_UNKNOWN3:
- case SUMMON_TYPE_UNKNOWN4:
- case SUMMON_TYPE_UNKNOWN5:
- break;
- default:
- sLog.outError("EffectSummonType: Unhandled summon type %u", m_spellInfo->EffectMiscValueB[i]);
- break;
- }
-}
-
-void Spell::EffectSummon(uint32 i)
-{
- uint32 pet_entry = m_spellInfo->EffectMiscValue[i];
- if(!pet_entry)
+ uint32 entry = m_spellInfo->EffectMiscValue[i];
+ if(!entry)
return;
- if(!m_originalCaster || m_originalCaster->GetTypeId() != TYPEID_PLAYER)
+ SummonPropertiesEntry const *properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i]);
+ if(!properties)
{
- EffectSummonWild(i);
+ sLog.outError("EffectSummonType: Unhandled summon type %u", m_spellInfo->EffectMiscValueB[i]);
return;
}
- Player *owner = (Player*)m_originalCaster;
-
- if(owner->GetPetGUID())
+ if(!m_originalCaster)
return;
- // Summon in dest location
- float x,y,z;
- if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)
+ int32 duration = GetSpellDuration(m_spellInfo);
+ if(Player* modOwner = m_originalCaster->GetSpellModOwner())
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
+
+ float x, y, z;
+ GetSummonPosition(x, y, z);
+
+ /*//totem must be at same Z in case swimming caster and etc.
+ if( fabs( z - m_caster->GetPositionZ() ) > 5 )
+ z = m_caster->GetPositionZ();
+
+ uint32 level = m_caster->getLevel();
+
+ // level of creature summoned using engineering item based at engineering skill level
+ if(m_caster->GetTypeId()==TYPEID_PLAYER && m_CastItem)
{
- x = m_targets.m_destX;
- y = m_targets.m_destY;
- z = m_targets.m_destZ;
- }
- else
- m_caster->GetClosePoint(x,y,z,owner->GetObjectSize());
+ ItemPrototype const *proto = m_CastItem->GetProto();
+ if(proto && proto->RequiredSkill == SKILL_ENGINERING)
+ {
+ uint16 skill202 = ((Player*)m_caster)->GetSkillValue(SKILL_ENGINERING);
+ if(skill202)
+ {
+ level = skill202/5;
+ }
+ }
+ }*/
- Pet *spawnCreature = owner->SummonPet(pet_entry, x, y, z, m_caster->GetOrientation(), SUMMON_PET, GetSpellDuration(m_spellInfo));
- if(!spawnCreature)
- return;
+ TempSummon *summon = NULL;
- spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS, 0);
- spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0);
- spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
+ switch(properties->Category)
+ {
+ default:
+ switch(properties->Type)
+ {
+ case SUMMON_TYPE_PET:
+ case SUMMON_TYPE_GUARDIAN:
+ case SUMMON_TYPE_MINION:
+ SummonGuardian(entry, properties);
+ break;
+ case SUMMON_TYPE_VEHICLE:
+ case SUMMON_TYPE_VEHICLE2:
+ {
+ Vehicle *vehicle = m_caster->SummonVehicle(entry, x, y, z, m_caster->GetOrientation());
+ if(!vehicle)
+ return;
- std::string name = owner->GetName();
- name.append(petTypeSuffix[spawnCreature->getPetType()]);
- spawnCreature->SetName( name );
+ //vehicle->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID());
+ vehicle->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
+ break;
+ }
+ case SUMMON_TYPE_TOTEM:
+ {
+ summon = m_caster->GetMap()->SummonCreature(entry, x, y, z, m_caster->GetOrientation(), properties, duration, m_originalCaster);
+ if(!summon || !summon->isTotem())
+ return;
+
+ summon->SetOwner(m_originalCaster, true);
+
+ if(damage) // if not spell info, DB values used
+ {
+ summon->SetMaxHealth(damage);
+ summon->SetHealth(damage);
+ }
+
+ if(m_originalCaster->GetTypeId() == TYPEID_PLAYER
+ && properties->Slot >= SUMMON_SLOT_TOTEM
+ && properties->Slot < MAX_TOTEM_SLOT)
+ {
+ WorldPacket data(SMSG_TOTEM_CREATED, 1+8+4+4);
+ data << uint8(properties->Slot-1);
+ data << uint64(m_originalCaster->GetGUID());
+ data << uint32(duration);
+ data << uint32(m_spellInfo->Id);
+ ((Player*)m_originalCaster)->SendDirectMessage(&data);
+ }
+ break;
+ }
+ case SUMMON_TYPE_MINIPET:
+ {
+ summon = m_caster->GetMap()->SummonCreature(entry, x, y, z, m_caster->GetOrientation(), properties, duration, m_originalCaster);
+ if(!summon)
+ return;
+
+ summon->SetOwner(m_originalCaster, true);
+ summon->SetCreatorGUID(m_originalCaster->GetGUID());
+ summon->setFaction(m_originalCaster->getFaction());
+
+ //summon->InitPetCreateSpells(); // e.g. disgusting oozeling has a create spell as summon...
+ summon->SetMaxHealth(1);
+ summon->SetHealth(1);
+ summon->SetLevel(1);
+
+ summon->SetReactState(REACT_PASSIVE);
+ summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ summon->GetMotionMaster()->MoveTargetedHome();
+
+ std::string name = m_originalCaster->GetName();
+ name.append(petTypeSuffix[3]);
+ summon->SetName( name );
+ break;
+ }
+ default:
+ {
+ float radius = GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
- spawnCreature->SetReactState( REACT_DEFENSIVE );
+ int32 amount = damage > 0 ? damage : 1;
+
+ for(int32 count = 0; count < amount; ++count)
+ {
+ float px, py, pz;
+ GetSummonPosition(px, py, pz, radius, count);
+
+ TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
+
+ m_originalCaster->SummonCreature(entry,px,py,pz,m_caster->GetOrientation(),summonType,duration);
+ }
+ break;
+ }
+ }//switch
+ break;
+ case SUMMON_CATEGORY_PET:
+ SummonGuardian(entry, properties);
+ break;
+ case SUMMON_CATEGORY_POSSESSED:
+ {
+ if(m_caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ float x, y, z;
+ m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
+
+ int32 duration = GetSpellDuration(m_spellInfo);
+
+ Pet* pet = ((Player*)m_caster)->SummonPet(entry, x, y, z, m_caster->GetOrientation(), POSSESSED_PET, duration);
+ if(!pet)
+ return;
+
+ pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
+ pet->SetCharmedOrPossessedBy(m_caster, true);
+ break;
+ }
+ case SUMMON_CATEGORY_VEHICLE:
+ {
+ float x, y, z;
+ m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
+ Vehicle *vehicle = m_caster->SummonVehicle(entry, x, y, z, m_caster->GetOrientation());
+ if(!vehicle)
+ return;
+
+ vehicle->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID());
+ vehicle->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
+
+ if(damage)
+ {
+ m_caster->CastSpell(vehicle, damage, true);
+ m_caster->EnterVehicle(vehicle);
+ }
+ break;
+ }
+ }
+
+ if(summon)
+ {
+ summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
+ }
}
void Spell::EffectLearnSpell(uint32 i)
@@ -3237,8 +3392,8 @@ void Spell::EffectLearnSpell(uint32 i)
Player *player = (Player*)unitTarget;
- uint32 spellToLearn = (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) ? damage : m_spellInfo->EffectTriggerSpell[i];
- player->learnSpell(spellToLearn);
+ uint32 spellToLearn = ((m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) || (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN_PET)) ? damage : m_spellInfo->EffectTriggerSpell[i];
+ player->learnSpell(spellToLearn,false);
sLog.outDebug( "Spell: Player %u have learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow() );
}
@@ -3248,8 +3403,7 @@ void Spell::EffectDispel(uint32 i)
if(!unitTarget)
return;
- // Fill possible dispel list
- std::vector <Aura *> dispel_list;
+ std::list < Aura * > dispel_list;
// Create dispel mask by dispel type
uint32 dispel_type = m_spellInfo->EffectMiscValue[i];
@@ -3258,7 +3412,7 @@ void Spell::EffectDispel(uint32 i)
for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
{
Aura *aur = (*itr).second;
- if (aur && (1<<aur->GetSpellProto()->Dispel) & dispelMask)
+ if (aur && ((1<<aur->GetSpellProto()->Dispel) & dispelMask))
{
if(aur->GetSpellProto()->Dispel == DISPEL_MAGIC)
{
@@ -3273,80 +3427,67 @@ void Spell::EffectDispel(uint32 i)
if(positive == unitTarget->IsFriendlyTo(m_caster))
continue;
}
- // Add every aura stack to dispel list
- for(uint32 stack_amount = 0; stack_amount < aur->GetStackAmount(); ++stack_amount)
+ for (uint8 i = aur->GetStackAmount();i!=0;--i)
dispel_list.push_back(aur);
}
}
// Ok if exist some buffs for dispel try dispel it
- if (!dispel_list.empty())
+ if (uint32 list_size = dispel_list.size())
{
- std::list < std::pair<uint32,uint64> > success_list;// (spell_id,casterGuid)
- std::list < uint32 > fail_list; // spell_id
- int32 list_size = dispel_list.size();
+ uint32 failCount = 0;
+ std::list < Aura * > success_list;
+ WorldPacket dataFail(SMSG_DISPEL_FAILED, 8+8+4+4+damage*4);
// dispel N = damage buffs (or while exist buffs for dispel)
- for (int32 count=0; count < damage && list_size > 0; ++count)
+ for (int32 count=0; count < damage && list_size > 0; ++count, list_size = dispel_list.size())
{
// Random select buff for dispel
- Aura *aur = dispel_list[urand(0, list_size-1)];
-
- SpellEntry const* spellInfo = aur->GetSpellProto();
- // Base dispel chance
- // TODO: possible chance depend from spell level??
- int32 miss_chance = 0;
- // Apply dispel mod from aura caster
- if (Unit *caster = aur->GetCaster())
+ std::list < Aura * > ::iterator itr = dispel_list.begin();
+ for (uint32 i=urand(0, list_size-1);i>0;--i)
+ itr++;
+
+ if (GetDispelChance((*itr)->GetCaster(), (*itr)->GetId()))
{
- if ( Player* modOwner = caster->GetSpellModOwner() )
- modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_RESIST_DISPEL_CHANCE, miss_chance, this);
+ success_list.push_back(*itr);
+ dispel_list.erase(itr);
}
- // Try dispel
- if (roll_chance_i(miss_chance))
- fail_list.push_back(aur->GetId());
else
- success_list.push_back(std::pair<uint32,uint64>(aur->GetId(),aur->GetCasterGUID()));
- // Remove buff from list for prevent doubles
- for (std::vector<Aura *>::iterator j = dispel_list.begin(); j != dispel_list.end(); )
{
- Aura *dispelled = *j;
- if (dispelled->GetId() == aur->GetId() && dispelled->GetCasterGUID() == aur->GetCasterGUID())
+ if (!failCount)
{
- j = dispel_list.erase(j);
- --list_size;
- break;
+ // Failed to dispell
+ dataFail << uint64(m_caster->GetGUID()); // Caster GUID
+ dataFail << uint64(unitTarget->GetGUID()); // Victim GUID
+ dataFail << uint32(m_spellInfo->Id); // dispel spell id
}
- else
- ++j;
+ failCount++;
+ dataFail << uint32((*itr)->GetId()); // Spell Id
}
}
- // Send success log and really remove auras
- if (!success_list.empty())
+ if (failCount)
+ {
+ m_caster->SendMessageToSet(&dataFail, true);
+ }
+ if (success_list.size())
{
- int32 count = success_list.size();
- WorldPacket data(SMSG_SPELLDISPELLOG, 8+8+4+1+4+count*5);
- data.append(unitTarget->GetPackGUID()); // Victim GUID
- data.append(m_caster->GetPackGUID()); // Caster GUID
- data << uint32(m_spellInfo->Id); // dispel spell id
- data << uint8(0); // not used
- data << uint32(count); // count
- for (std::list<std::pair<uint32,uint64> >::iterator j = success_list.begin(); j != success_list.end(); ++j)
+ WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8+8+4+1+4+damage*5);
+ // Send packet header
+ dataSuccess.append(unitTarget->GetPackGUID()); // Victim GUID
+ dataSuccess.append(m_caster->GetPackGUID()); // Caster GUID
+ dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
+ dataSuccess << uint8(0); // not used
+ dataSuccess << uint32(success_list.size()); // count
+ for (std::list < Aura * > ::iterator itr = success_list.begin();itr!=success_list.end();++itr)
{
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(j->first);
- data << uint32(spellInfo->Id); // Spell Id
- data << uint8(0); // 0 - dispelled !=0 cleansed
- if(spellInfo->StackAmount!= 0)
- {
- //Why are Aura's Removed by EffIndex? Auras should be removed as a whole.....
- unitTarget->RemoveSingleAuraFromStackByDispel(spellInfo->Id);
- }
- else
- unitTarget->RemoveAurasDueToSpellByDispel(spellInfo->Id, j->second, m_caster);
- }
- m_caster->SendMessageToSet(&data, true);
+ // Send dispelled spell info
+ dataSuccess << uint32((*itr)->GetId()); // Spell Id
+ dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
+ unitTarget->RemoveAurasDueToSpellByDispel((*itr)->GetId(), (*itr)->GetCasterGUID(), m_caster);
+ }
+ m_caster->SendMessageToSet(&dataSuccess, true);
// On succes dispel
// Devour Magic
- if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->Category == 12)
+ if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->Category == SPELLCATEGORY_DEVOUR_MAGIC)
{
uint32 heal_spell = 0;
switch (m_spellInfo->Id)
@@ -3357,6 +3498,7 @@ void Spell::EffectDispel(uint32 i)
case 19736: heal_spell = 19735; break;
case 27276: heal_spell = 27278; break;
case 27277: heal_spell = 27279; break;
+ case 48011: heal_spell = 48010; break;
default:
sLog.outDebug("Spell for Devour Magic %d not handled in Spell::EffectDispel", m_spellInfo->Id);
break;
@@ -3365,18 +3507,6 @@ void Spell::EffectDispel(uint32 i)
m_caster->CastSpell(m_caster, heal_spell, true);
}
}
- // Send fail log to client
- if (!fail_list.empty())
- {
- // Failed to dispell
- WorldPacket data(SMSG_DISPEL_FAILED, 8+8+4+4*fail_list.size());
- data << uint64(m_caster->GetGUID()); // Caster GUID
- data << uint64(unitTarget->GetGUID()); // Victim GUID
- data << uint32(m_spellInfo->Id); // dispel spell id
- for (std::list< uint32 >::iterator j = fail_list.begin(); j != fail_list.end(); ++j)
- data << uint32(*j); // Spell Id
- m_caster->SendMessageToSet(&data, true);
- }
}
}
@@ -3418,7 +3548,7 @@ void Spell::EffectDistract(uint32 /*i*/)
// Set creature Distracted, Stop it, And turn it
unitTarget->SetOrientation(angle);
unitTarget->StopMoving();
- unitTarget->GetMotionMaster()->MoveDistract(damage*1000);
+ unitTarget->GetMotionMaster()->MoveDistract(damage*IN_MILISECONDS);
}
}
@@ -3446,8 +3576,7 @@ void Spell::EffectPickPocket(uint32 /*i*/)
{
// Reveal action + get attack
m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK);
- if (((Creature*)unitTarget)->IsAIEnabled)
- ((Creature*)unitTarget)->AI()->AttackStart(m_caster);
+ m_caster->CombatStart(unitTarget);
}
}
}
@@ -3457,7 +3586,7 @@ void Spell::EffectAddFarsight(uint32 i)
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return;
- float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ float radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
int32 duration = GetSpellDuration(m_spellInfo);
DynamicObject* dynObj = new DynamicObject;
if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, 4, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, radius))
@@ -3473,189 +3602,8 @@ void Spell::EffectAddFarsight(uint32 i)
dynObj->GetMap()->Add(dynObj); //grid will also be loaded
// Need to update visibility of object for client to accept farsight guid
+ ((Player*)m_caster)->SetViewpoint(dynObj, true);
((Player*)m_caster)->UpdateVisibilityOf(dynObj);
- ((Player*)m_caster)->SetFarsightTarget(dynObj);
-}
-
-void Spell::EffectSummonWild(uint32 i)
-{
- uint32 creature_entry = m_spellInfo->EffectMiscValue[i];
- if(!creature_entry)
- return;
-
- uint32 level = m_caster->getLevel();
-
- // level of creature summoned using engineering item based at engineering skill level
- if(m_caster->GetTypeId()==TYPEID_PLAYER && m_CastItem)
- {
- ItemPrototype const *proto = m_CastItem->GetProto();
- if(proto && proto->RequiredSkill == SKILL_ENGINERING)
- {
- uint16 skill202 = ((Player*)m_caster)->GetSkillValue(SKILL_ENGINERING);
- if(skill202)
- {
- level = skill202/5;
- }
- }
- }
-
- // select center of summon position
- float center_x = m_targets.m_destX;
- float center_y = m_targets.m_destY;
- float center_z = m_targets.m_destZ;
-
- float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
-
- int32 amount = damage > 0 ? damage : 1;
-
- for(int32 count = 0; count < amount; ++count)
- {
- float px, py, pz;
- // If dest location if present
- if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)
- {
- // Summon 1 unit in dest location
- if (count == 0)
- {
- px = m_targets.m_destX;
- py = m_targets.m_destY;
- pz = m_targets.m_destZ;
- }
- // Summon in random point all other units if location present
- else
- m_caster->GetRandomPoint(center_x,center_y,center_z,radius,px,py,pz);
- }
- // Summon if dest location not present near caster
- else
- m_caster->GetClosePoint(px,py,pz,3.0f);
-
- int32 duration = GetSpellDuration(m_spellInfo);
-
- TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
-
- if(m_originalCaster)
- m_originalCaster->SummonCreature(creature_entry,px,py,pz,m_caster->GetOrientation(),summonType,duration);
- else
- m_caster->SummonCreature(creature_entry,px,py,pz,m_caster->GetOrientation(),summonType,duration);
- }
-}
-
-void Spell::EffectSummonGuardian(uint32 i)
-{
- uint32 pet_entry = m_spellInfo->EffectMiscValue[i];
- if(!pet_entry)
- return;
-
- // Jewelery statue case (totem like)
- if(m_spellInfo->SpellIconID==2056)
- {
- EffectSummonTotem(i);
- return;
- }
-
- Player *caster = NULL;
- if(m_originalCaster)
- {
- if(m_originalCaster->GetTypeId() == TYPEID_PLAYER)
- caster = (Player*)m_originalCaster;
- else if(((Creature*)m_originalCaster)->isTotem())
- caster = m_originalCaster->GetCharmerOrOwnerPlayerOrPlayerItself();
- }
-
- if(!caster)
- {
- EffectSummonWild(i);
- return;
- }
-
- // set timer for unsummon
- int32 duration = GetSpellDuration(m_spellInfo);
-
- // Search old Guardian only for players (if casted spell not have duration or cooldown)
- // FIXME: some guardians have control spell applied and controlled by player and anyway player can't summon in this time
- // so this code hack in fact
- if(duration <= 0 || GetSpellRecoveryTime(m_spellInfo)==0)
- if(caster->HasGuardianWithEntry(pet_entry))
- return; // find old guardian, ignore summon
-
- // in another case summon new
- uint32 level = caster->getLevel();
-
- // level of pet summoned using engineering item based at engineering skill level
- if(m_CastItem)
- {
- ItemPrototype const *proto = m_CastItem->GetProto();
- if(proto && proto->RequiredSkill == SKILL_ENGINERING)
- {
- uint16 skill202 = caster->GetSkillValue(SKILL_ENGINERING);
- if(skill202)
- {
- level = skill202/5;
- }
- }
- }
-
- // select center of summon position
- float center_x = m_targets.m_destX;
- float center_y = m_targets.m_destY;
- float center_z = m_targets.m_destZ;
-
- float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
-
- int32 amount = damage > 0 ? damage : 1;
-
- for(int32 count = 0; count < amount; ++count)
- {
- float px, py, pz;
- // If dest location if present
- if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)
- {
- // Summon 1 unit in dest location
- if (count == 0)
- {
- px = m_targets.m_destX;
- py = m_targets.m_destY;
- pz = m_targets.m_destZ;
- }
- // Summon in random point all other units if location present
- else
- m_caster->GetRandomPoint(center_x,center_y,center_z,radius,px,py,pz);
- }
- // Summon if dest location not present near caster
- else
- m_caster->GetClosePoint(px,py,pz,m_caster->GetObjectSize());
-
- Pet *spawnCreature = caster->SummonPet(m_spellInfo->EffectMiscValue[i], px, py, pz, m_caster->GetOrientation(), GUARDIAN_PET, duration);
- if(!spawnCreature)
- return;
-
- spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,0);
- spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
- }
-}
-
-void Spell::EffectSummonPossessed(uint32 i)
-{
- uint32 entry = m_spellInfo->EffectMiscValue[i];
- if(!entry)
- return;
-
- if(m_caster->GetTypeId() != TYPEID_PLAYER)
- return;
-
- uint32 level = m_caster->getLevel();
-
- float x, y, z;
- m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
-
- int32 duration = GetSpellDuration(m_spellInfo);
-
- Pet* pet = ((Player*)m_caster)->SummonPet(entry, x, y, z, m_caster->GetOrientation(), POSSESSED_PET, duration);
- if(!pet)
- return;
-
- pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
- pet->SetCharmedOrPossessedBy(m_caster, true);
}
void Spell::EffectTeleUnitsFaceCaster(uint32 i)
@@ -3666,16 +3614,12 @@ void Spell::EffectTeleUnitsFaceCaster(uint32 i)
if(unitTarget->isInFlight())
return;
- uint32 mapid = m_caster->GetMapId();
- float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ float dis = m_caster->GetSpellRadiusForTarget(unitTarget, sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
float fx,fy,fz;
m_caster->GetClosePoint(fx,fy,fz,unitTarget->GetObjectSize(),dis);
- if(unitTarget->GetTypeId() == TYPEID_PLAYER)
- ((Player*)unitTarget)->TeleportTo(mapid, fx, fy, fz, -m_caster->GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget==m_caster ? TELE_TO_SPELL : 0));
- else
- m_caster->GetMap()->CreatureRelocation((Creature*)m_caster, fx, fy, fz, -m_caster->GetOrientation());
+ unitTarget->NearTeleportTo(fx,fy,fz,-m_caster->GetOrientation(),unitTarget==m_caster);
}
void Spell::EffectLearnSkill(uint32 i)
@@ -3696,13 +3640,27 @@ void Spell::EffectAddHonor(uint32 /*i*/)
if(unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- sLog.outDebug("SpellEffect::AddHonor called for spell_id %u , that rewards %d honor points to player: %u", m_spellInfo->Id, damage, ((Player*)unitTarget)->GetGUIDLow());
-
- // TODO: find formula for honor reward based on player's level!
+ // not scale value for item based reward (/10 value expected)
+ if(m_CastItem)
+ {
+ ((Player*)unitTarget)->RewardHonor(NULL, 1, damage/10);
+ sLog.outError("SpellEffect::AddHonor (spell_id %u) rewards %d honor points (item %u) for player: %u", m_spellInfo->Id, damage/10, m_CastItem->GetEntry(),((Player*)unitTarget)->GetGUIDLow());
+ return;
+ }
- // now fixed only for level 70 players:
- if (((Player*)unitTarget)->getLevel() == 70)
+ // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
+ if( damage <= 50)
+ {
+ uint32 honor_reward = MaNGOS::Honor::hk_honor_at_level(unitTarget->getLevel(), damage);
+ ((Player*)unitTarget)->RewardHonor(NULL, 1, honor_reward);
+ sLog.outDebug("SpellEffect::AddHonor (spell_id %u) rewards %u honor points (scale) to player: %u", m_spellInfo->Id, honor_reward, ((Player*)unitTarget)->GetGUIDLow());
+ }
+ else
+ {
+ //maybe we have correct honor_gain in damage already
((Player*)unitTarget)->RewardHonor(NULL, 1, damage);
+ sLog.outError("SpellEffect::AddHonor (spell_id %u) rewards %u honor points (non scale) for player: %u", m_spellInfo->Id, damage, ((Player*)unitTarget)->GetGUIDLow());
+ }
}
void Spell::EffectTradeSkill(uint32 /*i*/)
@@ -3714,7 +3672,7 @@ void Spell::EffectTradeSkill(uint32 /*i*/)
// ((Player*)unitTarget)->SetSkill(skillid,skillval?skillval:1,skillmax+75);
}
-void Spell::EffectEnchantItemPerm(uint32 i)
+void Spell::EffectEnchantItemPerm(uint32 effect_idx)
{
if(m_caster->GetTypeId() != TYPEID_PLAYER)
return;
@@ -3723,37 +3681,95 @@ void Spell::EffectEnchantItemPerm(uint32 i)
Player* p_caster = (Player*)m_caster;
+ // not grow at item use at item case
p_caster->UpdateCraftSkill(m_spellInfo->Id);
- if (m_spellInfo->EffectMiscValue[i])
+ uint32 enchant_id = m_spellInfo->EffectMiscValue[effect_idx];
+ if (!enchant_id)
+ return;
+
+ SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
+ if(!pEnchant)
+ return;
+
+ // item can be in trade slot and have owner diff. from caster
+ Player* item_owner = itemTarget->GetOwner();
+ if(!item_owner)
+ return;
+
+ if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) )
{
- uint32 enchant_id = m_spellInfo->EffectMiscValue[i];
+ sLog.outCommand(p_caster->GetSession()->GetAccountId(),"GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)",
+ p_caster->GetName(),p_caster->GetSession()->GetAccountId(),
+ itemTarget->GetProto()->Name1,itemTarget->GetEntry(),
+ item_owner->GetName(),item_owner->GetSession()->GetAccountId());
+ }
- SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
- if(!pEnchant)
- return;
+ // remove old enchanting before applying new if equipped
+ item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,false);
- // item can be in trade slot and have owner diff. from caster
- Player* item_owner = itemTarget->GetOwner();
- if(!item_owner)
- return;
+ itemTarget->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchant_id, 0, 0);
+
+ // add new enchanting if equipped
+ item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,true);
+}
+
+void Spell::EffectEnchantItemPrismatic(uint32 effect_idx)
+{
+ if(m_caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+ if (!itemTarget)
+ return;
- if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) )
+ Player* p_caster = (Player*)m_caster;
+
+ uint32 enchant_id = m_spellInfo->EffectMiscValue[effect_idx];
+ if (!enchant_id)
+ return;
+
+ SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
+ if(!pEnchant)
+ return;
+
+ // support only enchantings with add socket in this slot
+ {
+ bool add_socket = false;
+ for(int i = 0; i < 3; ++i)
{
- sLog.outCommand(p_caster->GetSession()->GetAccountId(),"GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)",
- p_caster->GetName(),p_caster->GetSession()->GetAccountId(),
- itemTarget->GetProto()->Name1,itemTarget->GetEntry(),
- item_owner->GetName(),item_owner->GetSession()->GetAccountId());
+ if(pEnchant->type[i]==ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
+ {
+ add_socket = true;
+ break;
+ }
}
+ if(!add_socket)
+ {
+ sLog.outError("Spell::EffectEnchantItemPrismatic: attempt apply enchant spell %u with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC (%u) but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET (u), not suppoted yet.",
+ m_spellInfo->Id,SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC,ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET);
+ return;
+ }
+ }
- // remove old enchanting before applying new if equipped
- item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,false);
-
- itemTarget->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchant_id, 0, 0);
+ // item can be in trade slot and have owner diff. from caster
+ Player* item_owner = itemTarget->GetOwner();
+ if(!item_owner)
+ return;
- // add new enchanting if equipped
- item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,true);
+ if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) )
+ {
+ sLog.outCommand(p_caster->GetSession()->GetAccountId(),"GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)",
+ p_caster->GetName(),p_caster->GetSession()->GetAccountId(),
+ itemTarget->GetProto()->Name1,itemTarget->GetEntry(),
+ item_owner->GetName(),item_owner->GetSession()->GetAccountId());
}
+
+ // remove old enchanting before applying new if equipped
+ item_owner->ApplyEnchantment(itemTarget,PRISMATIC_ENCHANTMENT_SLOT,false);
+
+ itemTarget->SetEnchantment(PRISMATIC_ENCHANTMENT_SLOT, enchant_id, 0, 0);
+
+ // add new enchanting if equipped
+ item_owner->ApplyEnchantment(itemTarget,PRISMATIC_ENCHANTMENT_SLOT,true);
}
void Spell::EffectEnchantItemTmp(uint32 i)
@@ -3848,13 +3864,13 @@ void Spell::EffectEnchantItemTmp(uint32 i)
else if(m_spellInfo->SpellFamilyName==SPELLFAMILY_SHAMAN)
duration = 1800; // 30 mins
// other cases with this SpellVisual already selected
- else if(m_spellInfo->SpellVisual==215)
+ else if(m_spellInfo->SpellVisual[0]==215)
duration = 1800; // 30 mins
// some fishing pole bonuses
- else if(m_spellInfo->SpellVisual==563)
+ else if(m_spellInfo->SpellVisual[0]==563)
duration = 600; // 10 mins
// shaman rockbiter enchantments
- else if(m_spellInfo->SpellVisual==0)
+ else if(m_spellInfo->SpellVisual[0]==0)
duration = 1800; // 30 mins
else if(m_spellInfo->Id==29702)
duration = 300; // 5 mins
@@ -3917,17 +3933,19 @@ void Spell::EffectTameCreature(uint32 /*i*/)
creatureTarget->RemoveCorpse();
creatureTarget->SetHealth(0); // just for nice GM-mode view
+ uint32 level = (creatureTarget->getLevel() < (m_caster->getLevel() - 5)) ? (m_caster->getLevel() - 5) : creatureTarget->getLevel();
+
// prepare visual effect for levelup
- pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1);
+ pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
// add to world
pet->GetMap()->Add((Creature*)pet);
// visual effect for levelup
- pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel());
+ pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
// caster have pet now
- m_caster->SetPet(pet);
+ m_caster->SetGuardian(pet, true);
if(m_caster->GetTypeId() == TYPEID_PLAYER)
{
@@ -3947,14 +3965,16 @@ void Spell::EffectSummonPet(uint32 i)
owner = m_originalCaster->GetCharmerOrOwnerPlayerOrPlayerItself();
}
+ uint32 petentry = m_spellInfo->EffectMiscValue[i];
+
if(!owner)
{
- EffectSummonWild(i);
+ SummonPropertiesEntry const *properties = sSummonPropertiesStore.LookupEntry(67);
+ if(properties)
+ SummonGuardian(petentry, properties);
return;
}
- uint32 petentry = m_spellInfo->EffectMiscValue[i];
-
Pet *OldSummon = owner->GetPet();
// if pet requested type already exist
@@ -3993,7 +4013,7 @@ void Spell::EffectSummonPet(uint32 i)
Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET, 0);
if(!pet)
return;
-
+
if(m_caster->GetTypeId() == TYPEID_UNIT)
{
if ( ((Creature*)m_caster)->isTotem() )
@@ -4005,9 +4025,12 @@ void Spell::EffectSummonPet(uint32 i)
pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
// this enables popup window (pet dismiss, cancel), hunter pet additional flags set later
- pet->SetUInt32Value(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE);
+ if(m_caster->GetTypeId() == TYPEID_PLAYER)
+ pet->SetUInt32Value(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE);
+
pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
+ pet->InitTalentForLevel();
// generate new name for summon pet
std::string new_name=objmgr.GeneratePetName(petentry);
if(!new_name.empty())
@@ -4031,7 +4054,6 @@ void Spell::EffectLearnPetSpell(uint32 i)
if(!learn_spellproto)
return;
- pet->SetTP(pet->m_TrainingPoints - pet->GetTPForSpell(learn_spellproto->Id));
pet->learnSpell(learn_spellproto->Id);
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
@@ -4040,6 +4062,9 @@ void Spell::EffectLearnPetSpell(uint32 i)
void Spell::EffectTaunt(uint32 /*i*/)
{
+ if (!unitTarget)
+ return;
+
// this effect use before aura Taunt apply for prevent taunt already attacking target
// for spell as marked "non effective at already attacking target"
if(!unitTarget || !unitTarget->CanHaveThreatList()
@@ -4091,7 +4116,6 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
}
// some spell specific modifiers
- //float weaponDamagePercentMod = 1.0f; // applied to weapon damage (and to fixed effect damage bonus if customBonusDamagePercentMod not set
float totalDamagePercentMod = 1.0f; // applied to final bonus+weapon damage
int32 fixed_bonus = 0;
int32 spell_bonus = 0; // bonus specific for spell
@@ -4101,23 +4125,18 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
case SPELLFAMILY_WARRIOR:
{
// Devastate bonus and sunder armor refresh
- if(m_spellInfo->SpellVisual == 671 && m_spellInfo->SpellIconID == 1508)
+ if(m_spellInfo->SpellFamilyFlags[1] & 0x40)
{
+ if (m_caster->GetTypeId()!=TYPEID_PLAYER)
+ return;
+ SpellEntry const *spellInfo = NULL;
uint32 stack = 0;
- Unit::AuraList const& list = unitTarget->GetAurasByType(SPELL_AURA_MOD_RESISTANCE);
- for(Unit::AuraList::const_iterator itr=list.begin();itr!=list.end();++itr)
+ if (AuraEffect * aur = unitTarget->GetAura(SPELL_AURA_MOD_RESISTANCE,SPELLFAMILY_WARRIOR,SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR, 0, 0, m_caster->GetGUID()))
{
- SpellEntry const *proto = (*itr)->GetSpellProto();
- if(proto->SpellFamilyName == SPELLFAMILY_WARRIOR
- && proto->SpellFamilyFlags == SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR)
- {
- int32 duration = GetSpellDuration(proto);
- (*itr)->SetAuraDuration(duration);
- (*itr)->UpdateAuraDuration();
- stack = (*itr)->GetStackAmount();
- break;
- }
+ aur->GetParentAura()->RefreshAura();
+ spellInfo = aur->GetSpellProto();
+ stack = aur->GetParentAura()->GetStackAmount();
}
for(int j = 0; j < 3; j++)
@@ -4129,7 +4148,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
}
}
- if(stack < 5)
+ if(!spellInfo)
{
// get highest rank of the Sunder Armor spell
const PlayerSpellMap& sp_list = ((Player*)m_caster)->GetSpellMap();
@@ -4139,68 +4158,99 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
if(!itr->second->active || itr->second->disabled || itr->second->state == PLAYERSPELL_REMOVED)
continue;
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
- if (!spellInfo)
+ SpellEntry const *spellProto = sSpellStore.LookupEntry(itr->first);
+ if (!spellProto)
continue;
- if (spellInfo->SpellFamilyFlags == SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR
- && spellInfo->Id != m_spellInfo->Id
- && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR)
+ if (spellProto->SpellFamilyFlags[0] & SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR
+ && spellProto->Id != m_spellInfo->Id
+ && spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR)
{
- m_caster->CastSpell(unitTarget, spellInfo, true);
+ spellInfo = spellProto;
break;
}
}
}
+ if (!spellInfo)
+ break;
+ m_caster->CastSpell(unitTarget, spellInfo, true);
+ if (stack)
+ spell_bonus += stack * CalculateDamage(2, unitTarget);
}
break;
}
case SPELLFAMILY_ROGUE:
{
// Hemorrhage
- if(m_spellInfo->SpellFamilyFlags & 0x2000000)
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
{
if(m_caster->GetTypeId()==TYPEID_PLAYER)
((Player*)m_caster)->AddComboPoints(unitTarget, 1);
}
+ // Fan of Knives
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x40000)
+ {
+ // 50% more damage with daggers
+ if (Item* item = ((Player*)m_caster)->GetWeaponForAttack(m_attackType))
+ if (item->GetProto()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
+ totalDamagePercentMod *= 1.5f;
+ }
// Mutilate (for each hand)
- else if(m_spellInfo->SpellFamilyFlags & 0x600000000LL)
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x6)
{
- Unit::AuraMap const& auras = unitTarget->GetAuras();
- for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
+ bool found = false;
+ // fast check
+ if(unitTarget->HasAuraState(AURA_STATE_DEADLY_POISON, m_spellInfo, m_caster))
+ found = true;
+ // full aura scan
+ else
{
- if(itr->second->GetSpellProto()->Dispel == DISPEL_POISON)
+ Unit::AuraMap const& auras = unitTarget->GetAuras();
+ for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
{
- totalDamagePercentMod *= 1.5f; // 150% if poisoned
- break;
+ if(itr->second->GetSpellProto()->Dispel == DISPEL_POISON)
+ {
+ found = true;
+ break;
+ }
}
}
+
+ if(found)
+ totalDamagePercentMod *= 1.2f; // 120% if poisoned
}
break;
}
case SPELLFAMILY_PALADIN:
{
// Seal of Command - receive benefit from Spell Damage and Healing
- if(m_spellInfo->SpellFamilyFlags & 0x00000002000000LL)
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
{
- spell_bonus += int32(0.20f*m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)));
+ spell_bonus += int32(0.23f*m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)));
spell_bonus += int32(0.29f*m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget));
}
+
+ // Seal of Command Unleashed
+ else if(m_spellInfo->Id==20467)
+ {
+ spell_bonus += int32(0.16f*m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
+ spell_bonus += int32(0.25f*m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)));
+ }
break;
}
case SPELLFAMILY_SHAMAN:
{
// Skyshatter Harness item set bonus
// Stormstrike
- if(m_spellInfo->SpellFamilyFlags & 0x001000000000LL)
+ if(m_spellInfo->SpellFamilyFlags[1] & 0x0010)
{
- Unit::AuraList const& m_OverrideClassScript = m_caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(Unit::AuraList::const_iterator i = m_OverrideClassScript.begin(); i != m_OverrideClassScript.end(); ++i)
+ Unit::AuraEffectList const& m_OverrideClassScript = m_caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ for(Unit::AuraEffectList::const_iterator citr = m_OverrideClassScript.begin(); citr != m_OverrideClassScript.end(); ++citr)
{
// Stormstrike AP Buff
- if ( (*i)->GetModifier()->m_miscvalue == 5634 )
+ if ( (*citr)->GetMiscValue() == 5634 )
{
- m_caster->CastSpell(m_caster,38430,true,NULL,*i);
+ m_caster->CastSpell(m_caster,38430,true,NULL,*citr);
break;
}
}
@@ -4210,7 +4260,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
case SPELLFAMILY_DRUID:
{
// Mangle (Cat): CP
- if(m_spellInfo->SpellFamilyFlags==0x0000040000000000LL)
+ if(m_spellInfo->SpellFamilyFlags.IsEqual(0,0x00000400))
{
if(m_caster->GetTypeId()==TYPEID_PLAYER)
((Player*)m_caster)->AddComboPoints(unitTarget,1);
@@ -4235,6 +4285,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
break;
case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
weaponDamagePercentMod *= float(CalculateDamage(j,unitTarget)) / 100.0f;
+ break;
default:
break; // not weapon damage effect, just skip
}
@@ -4295,33 +4346,6 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
// Add melee damage bonuses (also check for negative)
m_caster->MeleeDamageBonus(unitTarget, &eff_damage, m_attackType, m_spellInfo);
m_damage+= eff_damage;
-
- // take ammo
- if(m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER)
- {
- Item *pItem = ((Player*)m_caster)->GetWeaponForAttack( RANGED_ATTACK );
-
- // wands don't have ammo
- if(!pItem || pItem->IsBroken() || pItem->GetProto()->SubClass==ITEM_SUBCLASS_WEAPON_WAND)
- return;
-
- if( pItem->GetProto()->InventoryType == INVTYPE_THROWN )
- {
- if(pItem->GetMaxStackCount()==1)
- {
- // decrease durability for non-stackable throw weapon
- ((Player*)m_caster)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_RANGED);
- }
- else
- {
- // decrease items amount for stackable throw weapon
- uint32 count = 1;
- ((Player*)m_caster)->DestroyItemCount( pItem, count, true);
- }
- }
- else if(uint32 ammo = ((Player*)m_caster)->GetUInt32Value(PLAYER_AMMO_ID))
- ((Player*)m_caster)->DestroyItemCount(ammo, 1, true);
- }
}
void Spell::EffectThreat(uint32 /*i*/)
@@ -4342,10 +4366,9 @@ void Spell::EffectHealMaxHealth(uint32 /*i*/)
if(!unitTarget->isAlive())
return;
- uint32 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
- unitTarget->SetHealth(unitTarget->GetMaxHealth());
+ int32 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
if(m_originalCaster)
- m_originalCaster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, false);
+ m_originalCaster->DealHeal(unitTarget, addhealth, m_spellInfo);
}
void Spell::EffectInterruptCast(uint32 i)
@@ -4366,7 +4389,7 @@ void Spell::EffectInterruptCast(uint32 i)
{
if(m_originalCaster)
{
- int32 duration = m_originalCaster->CalculateSpellDuration(m_spellInfo, i, unitTarget);
+ int32 duration = m_originalCaster->ModSpellDuration(m_spellInfo, unitTarget, m_originalCaster->CalcSpellDuration(m_spellInfo), false);
unitTarget->ProhibitSpellScholl(GetSpellSchoolMask(unitTarget->m_currentSpells[i]->m_spellInfo), duration/*GetSpellDuration(m_spellInfo)*/);
}
unitTarget->InterruptSpell(i,false);
@@ -4398,14 +4421,14 @@ void Spell::EffectSummonObjectWild(uint32 i)
Map *map = target->GetMap();
if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id, map,
- x, y, z, target->GetOrientation(), 0, 0, 0, 0, 100, 1))
+ m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY))
{
delete pGameObj;
return;
}
int32 duration = GetSpellDuration(m_spellInfo);
- pGameObj->SetRespawnTime(duration > 0 ? duration/1000 : 0);
+ pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0);
pGameObj->SetSpellId(m_spellInfo->Id);
if(pGameObj->GetGoType() != GAMEOBJECT_TYPE_FLAGDROP) // make dropped flag clickable for other players (not set owner guid (created by) for this)...
@@ -4446,9 +4469,9 @@ void Spell::EffectSummonObjectWild(uint32 i)
{
GameObject* linkedGO = new GameObject;
if(linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, map,
- x, y, z, target->GetOrientation(), 0, 0, 0, 0, 100, 1))
+ m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY))
{
- linkedGO->SetRespawnTime(duration > 0 ? duration/1000 : 0);
+ linkedGO->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0);
linkedGO->SetSpellId(m_spellInfo->Id);
m_caster->AddGameObject(linkedGO);
@@ -4467,450 +4490,677 @@ void Spell::EffectScriptEffect(uint32 effIndex)
{
// TODO: we must implement hunter pet summon at login there (spell 6962)
- // by spell id
- switch(m_spellInfo->Id)
+ switch(m_spellInfo->SpellFamilyName)
{
- // PX-238 Winter Wondervolt TRAP
- case 26275:
+ case SPELLFAMILY_GENERIC:
{
- if( unitTarget->HasAura(26272,0)
- || unitTarget->HasAura(26157,0)
- || unitTarget->HasAura(26273,0)
- || unitTarget->HasAura(26274,0))
- return;
+ switch(m_spellInfo->Id)
+ {
+ // PX-238 Winter Wondervolt TRAP
+ case 26275:
+ {
+ uint32 spells[4] = { 26272, 26157, 26273, 26274 };
- uint32 iTmpSpellId;
+ // check presence
+ for(int j = 0; j < 4; ++j)
+ if(unitTarget->HasAuraEffect(spells[j],0))
+ return;
- switch(urand(0,3))
- {
- case 0:
- iTmpSpellId = 26272;
- break;
- case 1:
- iTmpSpellId = 26157;
+ // select spell
+ uint32 iTmpSpellId = spells[urand(0,3)];
+
+ // cast
+ unitTarget->CastSpell(unitTarget, iTmpSpellId, true);
+ return;
+ }
+ // Bending Shinbone
+ case 8856:
+ {
+ if(!itemTarget && m_caster->GetTypeId()!=TYPEID_PLAYER)
+ return;
+
+ uint32 spell_id = 0;
+ switch(urand(1,5))
+ {
+ case 1: spell_id = 8854; break;
+ default: spell_id = 8855; break;
+ }
+
+ m_caster->CastSpell(m_caster,spell_id,true,NULL);
+ return;
+ }
+ // Brittle Armor - need remove one 24575 Brittle Armor aura
+ case 24590:
+ unitTarget->RemoveAuraFromStack(24575);
+ return;
+ // Mercurial Shield - need remove one 26464 Mercurial Shield aura
+ case 26465:
+ unitTarget->RemoveAuraFromStack(26464);
+ return;
+ // Orb teleport spells
+ case 25140:
+ case 25143:
+ case 25650:
+ case 25652:
+ case 29128:
+ case 29129:
+ case 35376:
+ case 35727:
+ {
+ if(!unitTarget)
+ return;
+
+ uint32 spellid;
+ switch(m_spellInfo->Id)
+ {
+ case 25140: spellid = 32571; break;
+ case 25143: spellid = 32572; break;
+ case 25650: spellid = 30140; break;
+ case 25652: spellid = 30141; break;
+ case 29128: spellid = 32568; break;
+ case 29129: spellid = 32569; break;
+ case 35376: spellid = 25649; break;
+ case 35727: spellid = 35730; break;
+ default:
+ return;
+ }
+
+ unitTarget->CastSpell(unitTarget,spellid,false);
+ return;
+ }
+ // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
+ case 22539:
+ case 22972:
+ case 22975:
+ case 22976:
+ case 22977:
+ case 22978:
+ case 22979:
+ case 22980:
+ case 22981:
+ case 22982:
+ case 22983:
+ case 22984:
+ case 22985:
+ {
+ if(!unitTarget || !unitTarget->isAlive())
+ return;
+
+ // Onyxia Scale Cloak
+ if(unitTarget->GetDummyAura(22683))
+ return;
+
+ // Shadow Flame
+ m_caster->CastSpell(unitTarget, 22682, true);
+ return;
+ }
+ // Summon Black Qiraji Battle Tank
+ case 26656:
+ {
+ if(!unitTarget)
+ return;
+
+ // Prevent stacking of mounts
+ unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED);
+
+ // Two separate mounts depending on area id (allows use both in and out of specific instance)
+ if (unitTarget->GetAreaId() == 3428)
+ unitTarget->CastSpell(unitTarget, 25863, false);
+ else
+ unitTarget->CastSpell(unitTarget, 26655, false);
+ return;
+ }
+ // Piccolo of the Flaming Fire
+ case 17512:
+ {
+ if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
+ return;
+ unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE);
+ return;
+ }
+ // Escape artist
+ case 20589:
+ {
+ if(!unitTarget)
+ return;
+ // It is said that removing effects by script should include dispel resist mods
+ unitTarget->RemoveAurasByTypeWithDispel(SPELL_AURA_MOD_ROOT, this);
+ unitTarget->RemoveAurasByTypeWithDispel(SPELL_AURA_MOD_DECREASE_SPEED, this);
+ return;
+ }
+ // Mirren's Drinking Hat
+ case 29830:
+ {
+ uint32 item = 0;
+ switch ( urand(1,6) )
+ {
+ case 1:case 2:case 3:
+ item = 23584;break; // Loch Modan Lager
+ case 4:case 5:
+ item = 23585;break; // Stouthammer Lite
+ case 6:
+ item = 23586;break; // Aerie Peak Pale Ale
+ }
+ if (item)
+ DoCreateItem(effIndex,item);
break;
- case 2:
- iTmpSpellId = 26273;
+ }
+ // Improved Sprint
+ case 30918:
+ {
+ // Removes snares and roots.
+ uint32 mechanic_mask = (1<<MECHANIC_ROOT) | (1<<MECHANIC_SNARE);
+ Unit::AuraMap& Auras = unitTarget->GetAuras();
+ for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end();)
+ {
+ Aura *aur = iter->second;
+ if (!aur->IsPositive()) //only remove negative spells
+ {
+ // check for mechanic mask
+ if(GetAllSpellMechanicMask(aur->GetSpellProto()) & mechanic_mask)
+ {
+ unitTarget->RemoveAura(iter);
+ }
+ else
+ iter++;
+ }
+ else
+ iter++;
+ }
break;
- case 3:
- iTmpSpellId = 26274;
+ }
+ /*// Flame Crash
+ case 41126:
+ {
+ if(!unitTarget)
+ return;
+
+ unitTarget->CastSpell(unitTarget, 41131, true);
break;
- }
+ }*/
+ // Draw Soul
+ case 40904:
+ {
+ if(!unitTarget)
+ return;
- unitTarget->CastSpell(unitTarget, iTmpSpellId, true);
+ unitTarget->CastSpell(m_caster, 40903, true);
+ break;
+ }
+ case 48025: // Headless Horseman's Mount
+ {
+ if(!unitTarget)
+ return;
- return;
- }
+ switch(((Player*)unitTarget)->GetBaseSkillValue(762))
+ {
+ case 75: unitTarget->CastSpell(unitTarget, 51621, true); break;;
+ case 150: unitTarget->CastSpell(unitTarget, 48024, true); break;
+ case 225: unitTarget->CastSpell(unitTarget, 51617, true); break;
+ case 300: unitTarget->CastSpell(unitTarget, 48023, true); break;
+ default: break;
+ }
+ break;
+ }
+ case 47977: // Magic Broom
+ {
+ if(!unitTarget)
+ return;
- // Bending Shinbone
- case 8856:
- {
- if(!itemTarget && m_caster->GetTypeId()!=TYPEID_PLAYER)
- return;
+ if(unitTarget)
+ {
+ switch(((Player*)unitTarget)->GetBaseSkillValue(762))
+ {
+ case 75: unitTarget->CastSpell(unitTarget, 42680, true); break;;
+ case 150: case 225: case 300: unitTarget->CastSpell(unitTarget, 42683, true); break;
+ default: break;
+ }
+ }
+ break;
+ }
+ case 41931:
+ {
+ if(m_caster->GetTypeId() != TYPEID_PLAYER)
+ return;
- uint32 spell_id = 0;
- switch(urand(1,5))
- {
- case 1: spell_id = 8854; break;
- default: spell_id = 8855; break;
- }
+ int bag=19;
+ int slot=0;
+ Item* item = NULL;
- m_caster->CastSpell(m_caster,spell_id,true,NULL);
- return;
- }
+ while (bag < 256)
+ {
+ item = ((Player*)m_caster)->GetItemByPos(bag,slot);
+ if (item && item->GetEntry() == 38587) break;
+ slot++;
+ if (slot == 39)
+ {
+ slot = 0;
+ bag++;
+ }
+ }
+ if (bag < 256)
+ {
+ if (((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount() == 1) ((Player*)m_caster)->RemoveItem(bag,slot,true);
+ else ((Player*)m_caster)->GetItemByPos(bag,slot)->SetCount(((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount()-1);
+ // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
+ m_caster->CastSpell(m_caster,42518,true);
+ return;
+ }
+ break;
+ }
+ // Force Cast - Portal Effect: Sunwell Isle
+ case 44876:
+ {
+ if(!unitTarget)
+ return;
- // Healthstone creating spells
- case 6201:
- case 6202:
- case 5699:
- case 11729:
- case 11730:
- case 27230:
+ unitTarget->CastSpell(unitTarget, 44870, true);
+ break;
+ }
+ // spell of Brutallus - Stomp
+ case 45185:
{
- uint32 itemtype;
- uint32 rank = 0;
- Unit::AuraList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
- {
- if((*i)->GetId() == 18692)
+ if(!unitTarget)
+ return;
+
+ if(unitTarget->HasAura(46394)) // spell of Brutallus - Burn
+ unitTarget->RemoveAurasDueToSpell(46394);
+
+ break;
+ }
+ // Negative Energy
+ case 46289:
{
- rank = 1;
+ if(!unitTarget)
+ return;
+
+ m_caster->CastSpell(unitTarget, 46285, true);
+ break;
+ }
+ // Goblin Weather Machine
+ case 46203:
+ {
+ if(!unitTarget)
+ return;
+
+ uint32 spellId = 0;
+ switch(rand()%4)
+ {
+ case 0: spellId = 46740; break;
+ case 1: spellId = 46739; break;
+ case 2: spellId = 46738; break;
+ case 3: spellId = 46736; break;
+ }
+ unitTarget->CastSpell(unitTarget, spellId, true);
break;
}
- else if((*i)->GetId() == 18693)
+ //5,000 Gold
+ case 46642:
{
- rank = 2;
+ if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ ((Player*)unitTarget)->ModifyMoney(50000000);
+
break;
}
- }
+ // Emblazon Runeblade
+ case 51770:
+ {
+ if(!m_originalCaster)
+ return;
- static uint32 const itypes[6][3] = {
- { 5512,19004,19005}, // Minor Healthstone
- { 5511,19006,19007}, // Lesser Healthstone
- { 5509,19008,19009}, // Healthstone
- { 5510,19010,19011}, // Greater Healthstone
- { 9421,19012,19013}, // Major Healthstone
- {22103,22104,22105} // Master Healthstone
- };
+ m_originalCaster->CastSpell(m_originalCaster, damage, false);
+ break;
+ }
+ // Death Gate
+ case 52751:
+ {
+ if(!unitTarget || unitTarget->getClass() != CLASS_DEATH_KNIGHT)
+ return;
+ // triggered spell is stored in m_spellInfo->EffectBasePoints[0]
+ unitTarget->CastSpell(unitTarget, damage, false);
+ break;
+ }
+ // Winged Steed of the Ebon Blade
+ case 54729:
+ {
+ if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
+ return;
- switch(m_spellInfo->Id)
- {
- case 6201: itemtype=itypes[0][rank];break; // Minor Healthstone
- case 6202: itemtype=itypes[1][rank];break; // Lesser Healthstone
- case 5699: itemtype=itypes[2][rank];break; // Healthstone
- case 11729: itemtype=itypes[3][rank];break; // Greater Healthstone
- case 11730: itemtype=itypes[4][rank];break; // Major Healthstone
- case 27230: itemtype=itypes[5][rank];break; // Master Healthstone
- default:
- return;
- }
- DoCreateItem( effIndex, itemtype );
- return;
- }
- // Brittle Armor - need remove one 24575 Brittle Armor aura
- case 24590:
- unitTarget->RemoveSingleAuraFromStack(24575, 0);
- unitTarget->RemoveSingleAuraFromStack(24575, 1);
- return;
- // Mercurial Shield - need remove one 26464 Mercurial Shield aura
- case 26465:
- unitTarget->RemoveSingleAuraFromStack(26464, 0);
- return;
- // Orb teleport spells
- case 25140:
- case 25143:
- case 25650:
- case 25652:
- case 29128:
- case 29129:
- case 35376:
- case 35727:
- {
- if(!unitTarget)
- return;
+ // Prevent stacking of mounts
+ unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED);
- uint32 spellid;
- switch(m_spellInfo->Id)
- {
- case 25140: spellid = 32571; break;
- case 25143: spellid = 32572; break;
- case 25650: spellid = 30140; break;
- case 25652: spellid = 30141; break;
- case 29128: spellid = 32568; break;
- case 29129: spellid = 32569; break;
- case 35376: spellid = 25649; break;
- case 35727: spellid = 35730; break;
- default:
+ // Triggered spell id dependent of riding skill
+ if(uint16 skillval = ((Player*)unitTarget)->GetSkillValue(SKILL_RIDING))
+ {
+ if (skillval >= 300)
+ unitTarget->CastSpell(unitTarget, 54727, true);
+ else
+ unitTarget->CastSpell(unitTarget, 54726, true);
+ }
return;
- }
+ }
+ case 58418: // Portal to Orgrimmar
+ case 58420: // Portal to Stormwind
+ {
+ if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || effIndex!=0)
+ return;
- unitTarget->CastSpell(unitTarget,spellid,false);
- return;
- }
+ uint32 spellID = m_spellInfo->CalculateSimpleValue(0);
+ uint32 questID = m_spellInfo->CalculateSimpleValue(1);
- // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
- case 22539:
- case 22972:
- case 22975:
- case 22976:
- case 22977:
- case 22978:
- case 22979:
- case 22980:
- case 22981:
- case 22982:
- case 22983:
- case 22984:
- case 22985:
- {
- if(!unitTarget || !unitTarget->isAlive())
- return;
+ if( ((Player*)unitTarget)->GetQuestStatus(questID) == QUEST_STATUS_COMPLETE && !((Player*)unitTarget)->GetQuestRewardStatus (questID) )
+ unitTarget->CastSpell(unitTarget, spellID, true);
- // Onyxia Scale Cloak
- if(unitTarget->GetDummyAura(22683))
- return;
+ return;
+ }
+ // random spell learn instead placeholder
+ case 60893: // Northrend Alchemy Research
+ case 61177: // Northrend Inscription Research
+ case 61288: // Minor Inscription Research
+ case 61756: // Northrend Inscription Research (FAST QA VERSION)
+ {
+ if(!IsExplicitDiscoverySpell(m_spellInfo))
+ {
+ sLog.outError("Wrong explicit discovery spell %u structure, or outdated...",m_spellInfo->Id);
+ return;
+ }
- // Shadow Flame
- m_caster->CastSpell(unitTarget, 22682, true);
- return;
- }
- break;
+ if(m_caster->GetTypeId()!=TYPEID_PLAYER)
+ return;
+ Player* player = (Player*)m_caster;
- // Summon Black Qiraji Battle Tank
- case 26656:
- {
- if(!unitTarget)
- return;
+ // need replace effect 0 item by loot
+ uint32 reagent_id = m_spellInfo->EffectItemType[0];
- // Prevent stacking of mounts
- unitTarget->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+ if(!player->HasItemCount(reagent_id,1))
+ return;
- // Two separate mounts depending on area id (allows use both in and out of specific instance)
- if (unitTarget->GetAreaId() == 3428)
- unitTarget->CastSpell(unitTarget, 25863, false);
- else
- unitTarget->CastSpell(unitTarget, 26655, false);
- break;
- }
- // Piccolo of the Flaming Fire
- case 17512:
- {
- if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
- return;
- unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE);
- break;
- }
- // Netherbloom
- case 28702:
- {
- if(!unitTarget)
- return;
- // 25% chance of casting a random buff
- if(roll_chance_i(75))
- return;
+ // remove reagent
+ uint32 count = 1;
+ player->DestroyItemCount (reagent_id,count,true);
- // triggered spells are 28703 to 28707
- // Note: some sources say, that there was the possibility of
- // receiving a debuff. However, this seems to be removed by a patch.
- const uint32 spellid = 28703;
+ // create some random items
+ player->AutoStoreLoot(m_spellInfo->Id,LootTemplates_Spell);
- // don't overwrite an existing aura
- for(uint8 i=0; i<5; i++)
- if(unitTarget->HasAura(spellid+i, 0))
+ // learn random explicit discovery recipe (if any)
+ if(uint32 discoveredSpell = GetExplicitDiscoverySpell(m_spellInfo->Id, player))
+ player->learnSpell(discoveredSpell,false);
return;
- unitTarget->CastSpell(unitTarget, spellid+urand(0, 4), true);
- break;
- }
-
- // Nightmare Vine
- case 28720:
- {
- if(!unitTarget)
- return;
- // 25% chance of casting Nightmare Pollen
- if(roll_chance_i(75))
- return;
- unitTarget->CastSpell(unitTarget, 28721, true);
- break;
- }
-
- // Mirren's Drinking Hat
- case 29830:
- {
- uint32 item = 0;
- switch ( urand(1,6) )
- {
- case 1: case 2: case 3: item = 23584; break;// Loch Modan Lager
- case 4: case 5: item = 23585; break;// Stouthammer Lite
- case 6: item = 23586; break;// Aerie Peak Pale Ale
+ }
}
- if (item)
- DoCreateItem(effIndex,item);
break;
}
- // Improved Sprint
- case 30918:
+ case SPELLFAMILY_WARLOCK:
{
- // Removes snares and roots.
- uint32 mechanic_mask = (1<<MECHANIC_ROOT) | (1<<MECHANIC_SNARE);
- Unit::AuraMap& Auras = unitTarget->GetAuras();
- for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
+ switch(m_spellInfo->Id)
{
- next = iter;
- ++next;
- Aura *aur = iter->second;
- if (!aur->IsPositive()) //only remove negative spells
+ // Healthstone creating spells
+ case 6201:
+ case 6202:
+ case 5699:
+ case 11729:
+ case 11730:
+ case 27230:
+ case 47871:
+ case 47878:
{
- // check for mechanic mask
- if(GetSpellMechanicMask(aur->GetSpellProto(), aur->GetEffIndex()) & mechanic_mask)
+ uint32 itemtype;
+ uint32 rank = 0;
+ Unit::AuraEffectList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraEffectList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
{
- unitTarget->RemoveAurasDueToSpell(aur->GetId());
- if(Auras.empty())
+ if((*i)->GetId() == 18692)
+ {
+ rank = 1;
break;
- else
- next = Auras.begin();
+ }
+ else if((*i)->GetId() == 18693)
+ {
+ rank = 2;
+ break;
+ }
}
- }
- }
- break;
- }
-
- // Goblin Weather Machine
- case 46203:
- {
- if(!unitTarget)
- return;
- uint32 spellId;
- switch(rand()%4)
- {
- case 0:
- spellId=46740;
- break;
- case 1:
- spellId=46739;
- break;
- case 2:
- spellId=46738;
- break;
- case 3:
- spellId=46736;
- break;
- }
- unitTarget->CastSpell(unitTarget, spellId, true);
- break;
- }
- case 48025: // Headless Horseman's Mount
- {
- if(!unitTarget)
- return;
+ static uint32 const itypes[8][3] = {
+ { 5512,19004,19005}, // Minor Healthstone
+ { 5511,19006,19007}, // Lesser Healthstone
+ { 5509,19008,19009}, // Healthstone
+ { 5510,19010,19011}, // Greater Healthstone
+ { 9421,19012,19013}, // Major Healthstone
+ {22103,22104,22105}, // Master Healthstone
+ {36889,36890,36891}, // Demonic Healthstone
+ {36892,36893,36894} // Fel Healthstone
+ };
- if(unitTarget)
- {
- switch(((Player*)unitTarget)->GetBaseSkillValue(762))
+ switch(m_spellInfo->Id)
{
- case 75: unitTarget->CastSpell(unitTarget, 51621, true); break;;
- case 150: unitTarget->CastSpell(unitTarget, 48024, true); break;
- case 225: unitTarget->CastSpell(unitTarget, 51617, true); break;
- case 300: unitTarget->CastSpell(unitTarget, 48023, true); break;
- default: break;
+ case 6201:
+ itemtype=itypes[0][rank];break; // Minor Healthstone
+ case 6202:
+ itemtype=itypes[1][rank];break; // Lesser Healthstone
+ case 5699:
+ itemtype=itypes[2][rank];break; // Healthstone
+ case 11729:
+ itemtype=itypes[3][rank];break; // Greater Healthstone
+ case 11730:
+ itemtype=itypes[4][rank];break; // Major Healthstone
+ case 27230:
+ itemtype=itypes[5][rank];break; // Master Healthstone
+ case 47871:
+ itemtype=itypes[6][rank];break; // Demonic Healthstone
+ case 47878:
+ itemtype=itypes[7][rank];break; // Fel Healthstone
+ default:
+ return;
}
+ DoCreateItem( effIndex, itemtype );
+ return;
}
- break;
+ // Everlasting Affliction
+ case 47422:
+ // Refresh corruption on target
+ if (AuraEffect * aur = unitTarget->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x2, 0, 0, m_caster->GetGUID()))
+ aur->GetParentAura()->RefreshAura();
+ return;
+ }
+ break;
}
- case 47977: // Magic Broom
+ case SPELLFAMILY_PRIEST:
{
- if(!unitTarget)
- return;
-
- if(unitTarget)
+ switch(m_spellInfo->Id)
{
- switch(((Player*)unitTarget)->GetBaseSkillValue(762))
+ // Pain and Suffering
+ case 47948:
{
- case 75: unitTarget->CastSpell(unitTarget, 42680, true); break;;
- case 150: case 225: case 300: unitTarget->CastSpell(unitTarget, 42683, true); break;
- default: break;
+ if (!unitTarget)
+ return;
+ // Refresh Shadow Word: Pain on target
+ if (AuraEffect * aur = unitTarget->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0, 0, m_caster->GetGUID()))
+ aur->GetParentAura()->RefreshAura();
+ return;
}
+ // Divine Hymn
+ case 47951:
+ {
+ if (!unitTarget)
+ return;
+ Unit * target=NULL;
+ unitTarget->CastSpell(target, 59600, false);
+ unitTarget->CastSpell(target, 47953, false);
+ return;
+ }
+ default:
+ break;
}
break;
}
- }
-
- if(!unitTarget || !unitTarget->isAlive()) // can we remove this check?
- {
- sLog.outError("Spell %u in EffectScriptEffect does not have unitTarget", m_spellInfo->Id);
- return;
- }
-
- switch(m_spellInfo->Id)
- {
- // Dreaming Glory
- case 28698: unitTarget->CastSpell(unitTarget, 28694, true); break;
- // Needle Spine
- //case 39835: unitTarget->CastSpell(unitTarget, 39968, true); break;
- // Draw Soul
- case 40904: unitTarget->CastSpell(m_caster, 40903, true); break;
- // Flame Crash
- //case 41126: unitTarget->CastSpell(unitTarget, 41131, true); break;
- case 41931:
+ case SPELLFAMILY_HUNTER:
{
- int bag=19;
- int slot=0;
- Item* item = NULL;
-
- while (bag < 256)
+ switch(m_spellInfo->Id)
{
- item = ((Player*)m_caster)->GetItemByPos(bag,slot);
- if (item && item->GetEntry() == 38587) break;
- slot++;
- if (slot == 39)
+ // Chimera Shot
+ case 53209:
{
- slot = 0;
- bag++;
+ uint32 spellId = 0;
+ int32 basePoint = 0;
+ Unit::AuraMap& Auras = unitTarget->GetAuras();
+ for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
+ {
+ Aura *aura = (*i).second;
+ if (aura->GetCasterGUID() != m_caster->GetGUID())
+ continue;
+ // Search only Serpent Sting, Viper Sting, Scorpid Sting auras
+ flag96 familyFlag = aura->GetSpellProto()->SpellFamilyFlags;
+ if (!(familyFlag[1] & 0x00000080 || familyFlag[0] & 0x0000C000))
+ continue;
+
+ // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting.
+ if (familyFlag[0] & 0x4000)
+ {
+ spellId = 53353; // 53353 Chimera Shot - Serpent
+ basePoint = aura->GetPartAura(0)->GetAmount() * 5 * 40 / 100;
+ }
+ // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting.
+ if (familyFlag[1] & 0x00000080)
+ {
+ int32 tickCount = aura->GetPartAura(0)->GetTickNumber();
+ spellId = 53358; // 53358 Chimera Shot - Viper
+ // Amount of one aura tick
+ basePoint = aura->GetPartAura(0)->GetAmount() * aura->GetTarget()->GetMaxPower(POWER_MANA) / 100 ;
+ int32 casterBasePoint = aura->GetPartAura(0)->GetAmount() * unitTarget->GetMaxPower(POWER_MANA) / 50 ;
+ if (basePoint > casterBasePoint)
+ basePoint = casterBasePoint;
+ basePoint = basePoint * tickCount * 60 / 100;
+ }
+ // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute.
+ if (familyFlag[0] & 0x00008000)
+ spellId = 53359; // 53359 Chimera Shot - Scorpid
+ // ?? nothing say in spell desc (possibly need addition check)
+ //if (familyFlag & 0x0000010000000000LL || // dot
+ // familyFlag & 0x0000100000000000LL) // stun
+ //{
+ // spellId = 53366; // 53366 Chimera Shot - Wyvern
+ //}
+
+ // Refresh aura duration
+ aura->RefreshAura();
+ break;
+ }
+ if (spellId)
+ m_caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, true);
+ return;
}
+ default:
+ break;
}
- if (bag < 256)
- {
- if (((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount() == 1) ((Player*)m_caster)->RemoveItem(bag,slot,true);
- else ((Player*)m_caster)->GetItemByPos(bag,slot)->SetCount(((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount()-1);
- // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
- m_caster->CastSpell(m_caster,42518,true);
- return;
- }
- }
- // Force Cast - Portal Effect: Sunwell Isle
- case 44876: unitTarget->CastSpell(unitTarget, 44870, true); break;
- // spell of Brutallus - Stomp
- case 45185:
- {
- if(unitTarget->HasAura(46394, 0)) // spell of Brutallus - Burn
- unitTarget->RemoveAurasDueToSpell(46394);
break;
}
- // Negative Energy
- case 46289: m_caster->CastSpell(unitTarget, 46285, true); break;
- //5,000 Gold
- case 46642:
- {
- if(unitTarget->GetTypeId() == TYPEID_PLAYER)
- ((Player*)unitTarget)->ModifyMoney(50000000);
- break;
- }
- }
-
- if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN )
- {
- switch(m_spellInfo->SpellFamilyFlags)
+ case SPELLFAMILY_PALADIN:
{
// Judgement
- case 0x800000:
+ if (m_spellInfo->SpellFamilyFlags[0] & 0x800000)
{
+ if(!unitTarget || !unitTarget->isAlive())
+ return;
+ uint32 spellId1 = 0;
uint32 spellId2 = 0;
- // all seals have aura dummy
- Unit::AuraList const& m_dummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator itr = m_dummyAuras.begin(); itr != m_dummyAuras.end(); ++itr)
+ // Judgement self add switch
+ switch (m_spellInfo->Id)
{
- SpellEntry const *spellInfo = (*itr)->GetSpellProto();
-
- // search seal (all seals have judgement's aura dummy spell id in 2 effect
- if ( !spellInfo || !IsSealSpell((*itr)->GetSpellProto()) || (*itr)->GetEffIndex() != 2 )
- continue;
-
- // must be calculated base at raw base points in spell proto, GetModifier()->m_value for S.Righteousness modified by SPELLMOD_DAMAGE
- spellId2 = (*itr)->GetSpellProto()->EffectBasePoints[2]+1;
-
- if(spellId2 <= 1)
- continue;
-
- // found, remove seal
- m_caster->RemoveAurasDueToSpell((*itr)->GetId());
-
- // Sanctified Judgement
- Unit::AuraList const& m_auras = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator i = m_auras.begin(); i != m_auras.end(); ++i)
+ case 41467: break; // Judgement
+ case 53407: spellId1 = 20184; break; // Judgement of Justice
+ case 20271: // Judgement of Light
+ case 57774: spellId1 = 20185; break; // Judgement of Light
+ case 53408: spellId1 = 20186; break; // Judgement of Wisdom
+ default:
+ return;
+ }
+ // all seals have aura dummy in 2 effect
+ Unit::AuraMap & sealAuras = m_caster->GetAuras();
+ for(Unit::AuraMap::iterator iter = sealAuras.begin(); iter != sealAuras.end();)
+ {
+ if (IsSealSpell(iter->second->GetSpellProto()))
{
- if ((*i)->GetSpellProto()->SpellIconID == 205 && (*i)->GetSpellProto()->Attributes == 0x01D0LL)
+ if (AuraEffect * aureff = iter->second->GetPartAura(2))
+ if (aureff->GetAuraName()==SPELL_AURA_DUMMY)
+ {
+ if (sSpellStore.LookupEntry(aureff->GetAmount()))
+ spellId2 = aureff->GetAmount();
+ break;
+ }
+ if (!spellId2)
{
- int32 chance = (*i)->GetModifier()->m_amount;
- if ( roll_chance_i(chance) )
+ switch (iter->first)
{
- int32 mana = spellInfo->manaCost;
- if ( Player* modOwner = m_caster->GetSpellModOwner() )
- modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COST, mana);
- mana = int32(mana* 0.8f);
- m_caster->CastCustomSpell(m_caster,31930,&mana,NULL,NULL,true,NULL,*i);
+ // Seal of light, wisdom, justice
+ case 20165:
+ case 20166:
+ case 20164:
+ spellId2 = 54158;
}
- break;
}
+ break;
}
+ else
+ ++iter;
+ }
+ if (spellId1)
+ m_caster->CastSpell(unitTarget, spellId1, true);
+ if (spellId2)
+ m_caster->CastSpell(unitTarget, spellId2, true);
+ return;
+ }
+ }
+ case SPELLFAMILY_POTION:
+ {
+ switch(m_spellInfo->Id)
+ {
+ // Dreaming Glory
+ case 28698:
+ {
+ if(!unitTarget)
+ return;
+ unitTarget->CastSpell(unitTarget, 28694, true);
+ break;
+ }
+ // Netherbloom
+ case 28702:
+ {
+ if(!unitTarget)
+ return;
+ // 25% chance of casting a random buff
+ if(roll_chance_i(75))
+ return;
+
+ // triggered spells are 28703 to 28707
+ // Note: some sources say, that there was the possibility of
+ // receiving a debuff. However, this seems to be removed by a patch.
+ const uint32 spellid = 28703;
+ // don't overwrite an existing aura
+ for(uint8 i=0; i<5; i++)
+ if(unitTarget->HasAuraEffect(spellid+i, 0))
+ return;
+ unitTarget->CastSpell(unitTarget, spellid+urand(0, 4), true);
break;
}
- m_caster->CastSpell(unitTarget,spellId2,true);
- return;
+ // Nightmare Vine
+ case 28720:
+ {
+ if(!unitTarget)
+ return;
+ // 25% chance of casting Nightmare Pollen
+ if(roll_chance_i(75))
+ return;
+ unitTarget->CastSpell(unitTarget, 28721, true);
+ break;
+ }
}
+ break;
}
}
@@ -4926,7 +5176,7 @@ void Spell::EffectSanctuary(uint32 /*i*/)
std::list<Unit*> targets;
Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, World::GetMaxVisibleDistance());
- Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(targets, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(unitTarget, targets, u_check);
unitTarget->VisitNearbyObject(World::GetMaxVisibleDistance(), searcher);
for(std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter)
{
@@ -4946,9 +5196,9 @@ void Spell::EffectSanctuary(uint32 /*i*/)
unitTarget->CombatStop();
unitTarget->getHostilRefManager().deleteReferences(); // stop all fighting
// Vanish allows to remove all threat and cast regular stealth so other spells can be used
- if(m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE_VANISH))
+ if(m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_ROGUE_VANISH))
{
- ((Player *)m_caster)->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT);
+ ((Player *)m_caster)->RemoveAurasByType(SPELL_AURA_MOD_ROOT);
}
}
@@ -4981,6 +5231,7 @@ void Spell::EffectDuel(uint32 i)
// Players can only fight a duel with each other outside (=not inside dungeons and not in capital cities)
// Don't have to check the target's map since you cannot challenge someone across maps
if(caster->GetMap()->Instanceable())
+ //if( mapid != 0 && mapid != 1 && mapid != 530 && mapid != 571 && mapid != 609)
{
SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
return;
@@ -5006,11 +5257,12 @@ void Spell::EffectDuel(uint32 i)
uint32 gameobject_id = m_spellInfo->EffectMiscValue[i];
Map *map = m_caster->GetMap();
- if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id, map,
+ if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id,
+ map, m_caster->GetPhaseMask(),
m_caster->GetPositionX()+(unitTarget->GetPositionX()-m_caster->GetPositionX())/2 ,
m_caster->GetPositionY()+(unitTarget->GetPositionY()-m_caster->GetPositionY())/2 ,
m_caster->GetPositionZ(),
- m_caster->GetOrientation(), 0, 0, 0, 0, 0, 1))
+ m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))
{
delete pGameObj;
return;
@@ -5019,7 +5271,7 @@ void Spell::EffectDuel(uint32 i)
pGameObj->SetUInt32Value(GAMEOBJECT_FACTION, m_caster->getFaction() );
pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()+1 );
int32 duration = GetSpellDuration(m_spellInfo);
- pGameObj->SetRespawnTime(duration > 0 ? duration/1000 : 0);
+ pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0);
pGameObj->SetSpellId(m_spellInfo->Id);
m_caster->AddGameObject(pGameObj);
@@ -5096,7 +5348,7 @@ void Spell::EffectSummonPlayer(uint32 /*i*/)
WorldPacket data(SMSG_SUMMON_REQUEST, 8+4+4);
data << uint64(m_caster->GetGUID()); // summoner guid
data << uint32(m_caster->GetZoneId()); // summoner zone
- data << uint32(MAX_PLAYER_SUMMON_DELAY*1000); // auto decline after msecs
+ data << uint32(MAX_PLAYER_SUMMON_DELAY*IN_MILISECONDS); // auto decline after msecs
((Player*)unitTarget)->GetSession()->SendPacket(&data);
}
@@ -5119,89 +5371,40 @@ void Spell::EffectActivateObject(uint32 effect_idx)
sWorld.ScriptCommandStart(activateCommand, delay_secs, m_caster, gameObjTarget);
}
-void Spell::EffectSummonTotem(uint32 i)
+void Spell::EffectApplyGlyph(uint32 i)
{
- uint8 slot = 0;
- switch(m_spellInfo->EffectMiscValueB[i])
- {
- case SUMMON_TYPE_TOTEM_SLOT1: slot = 0; break;
- case SUMMON_TYPE_TOTEM_SLOT2: slot = 1; break;
- case SUMMON_TYPE_TOTEM_SLOT3: slot = 2; break;
- case SUMMON_TYPE_TOTEM_SLOT4: slot = 3; break;
- // Battle standard case
- case SUMMON_TYPE_TOTEM: slot = 254; break;
- // jewelery statue case, like totem without slot
- case SUMMON_TYPE_GUARDIAN: slot = 255; break;
- default: return;
- }
-
- if(slot < MAX_TOTEM)
- {
- uint64 guid = m_caster->m_TotemSlot[slot];
- if(guid != 0)
- {
- Creature *OldTotem = ObjectAccessor::GetCreature(*m_caster, guid);
- if(OldTotem && OldTotem->isTotem())
- ((Totem*)OldTotem)->UnSummon();
- }
- }
-
- uint32 team = 0;
- if (m_caster->GetTypeId()==TYPEID_PLAYER)
- team = ((Player*)m_caster)->GetTeam();
-
- Totem* pTotem = new Totem;
-
- if(!pTotem->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), m_caster->GetMap(), m_spellInfo->EffectMiscValue[i], team ))
- {
- delete pTotem;
+ if(m_caster->GetTypeId() != TYPEID_PLAYER)
return;
- }
-
- float angle = slot < MAX_TOTEM ? M_PI/MAX_TOTEM - (slot*2*M_PI/MAX_TOTEM) : 0;
- float x,y,z;
- m_caster->GetClosePoint(x,y,z,pTotem->GetObjectSize(),2.0f,angle);
-
- // totem must be at same Z in case swimming caster and etc.
- if( fabs( z - m_caster->GetPositionZ() ) > 5 )
- z = m_caster->GetPositionZ();
-
- pTotem->Relocate(x, y, z, m_caster->GetOrientation());
-
- if(slot < MAX_TOTEM)
- m_caster->m_TotemSlot[slot] = pTotem->GetGUID();
-
- pTotem->SetOwner(m_caster->GetGUID());
- pTotem->SetTypeBySummonSpell(m_spellInfo); // must be after Create call where m_spells initilized
-
- int32 duration=GetSpellDuration(m_spellInfo);
- if(Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod(m_spellInfo->Id,SPELLMOD_DURATION, duration);
- pTotem->SetDuration(duration);
+ Player *player = (Player*)m_caster;
- if (damage) // if not spell info, DB values used
+ // apply new one
+ if(uint32 glyph = m_spellInfo->EffectMiscValue[i])
{
- pTotem->SetMaxHealth(damage);
- pTotem->SetHealth(damage);
- }
-
- pTotem->SetUInt32Value(UNIT_CREATED_BY_SPELL,m_spellInfo->Id);
- pTotem->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE);
-
- pTotem->ApplySpellImmune(m_spellInfo->Id,IMMUNITY_STATE,SPELL_AURA_MOD_FEAR,true);
- pTotem->ApplySpellImmune(m_spellInfo->Id,IMMUNITY_STATE,SPELL_AURA_TRANSFORM,true);
+ if(GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph))
+ {
+ if(GlyphSlotEntry const *gs = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
+ {
+ if(gp->TypeFlags != gs->TypeFlags)
+ {
+ SendCastResult(SPELL_FAILED_INVALID_GLYPH);
+ return; // glyph slot mismatch
+ }
+ }
- pTotem->Summon(m_caster);
+ // remove old glyph
+ if(uint32 oldglyph = player->GetGlyph(m_glyphIndex))
+ {
+ if(GlyphPropertiesEntry const *old_gp = sGlyphPropertiesStore.LookupEntry(oldglyph))
+ {
+ player->RemoveAurasDueToSpell(old_gp->SpellId);
+ player->SetGlyph(m_glyphIndex, 0);
+ }
+ }
- if(slot < MAX_TOTEM && m_caster->GetTypeId() == TYPEID_PLAYER)
- {
- WorldPacket data(SMSG_TOTEM_CREATED, 1+8+4+4);
- data << uint8(slot);
- data << uint64(pTotem->GetGUID());
- data << uint32(duration);
- data << uint32(m_spellInfo->Id);
- ((Player*)m_caster)->SendDirectMessage(&data);
+ player->CastSpell(m_caster, gp->SpellId, true);
+ player->SetGlyph(m_glyphIndex, glyph);
+ }
}
}
@@ -5242,7 +5445,7 @@ void Spell::EffectEnchantHeldItem(uint32 i)
return;
// Apply the temporary enchantment
- item->SetEnchantment(slot, enchant_id, duration*1000, 0);
+ item->SetEnchantment(slot, enchant_id, duration*IN_MILISECONDS, 0);
item_owner->ApplyEnchantment(item,slot,true);
}
}
@@ -5285,7 +5488,8 @@ void Spell::EffectFeedPet(uint32 i)
Player *_player = (Player*)m_caster;
- if(!itemTarget)
+ Item* foodItem = m_targets.getItemTarget();
+ if(!foodItem)
return;
Pet *pet = _player->GetPet();
@@ -5295,15 +5499,15 @@ void Spell::EffectFeedPet(uint32 i)
if(!pet->isAlive())
return;
- int32 benefit = pet->GetCurrentFoodBenefitLevel(itemTarget->GetProto()->ItemLevel);
+ int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetProto()->ItemLevel);
if(benefit <= 0)
return;
uint32 count = 1;
- _player->DestroyItemCount(itemTarget,count,true);
+ _player->DestroyItemCount(foodItem,count,true);
// TODO: fix crash when a spell has two effects, both pointed at the same item target
- m_caster->CastCustomSpell(m_caster,m_spellInfo->EffectTriggerSpell[i],&benefit,NULL,NULL,true);
+ m_caster->CastCustomSpell(pet,m_spellInfo->EffectTriggerSpell[i],&benefit,NULL,NULL,true);
}
void Spell::EffectDismissPet(uint32 /*i*/)
@@ -5311,7 +5515,7 @@ void Spell::EffectDismissPet(uint32 /*i*/)
if(m_caster->GetTypeId() != TYPEID_PLAYER)
return;
- Pet* pet = m_caster->GetPet();
+ Pet* pet = ((Player*)m_caster)->GetPet();
// not let dismiss dead pet
if(!pet||!pet->isAlive())
@@ -5339,7 +5543,7 @@ void Spell::EffectSummonObject(uint32 i)
{
GameObject* obj = NULL;
if( m_caster )
- obj = ObjectAccessor::GetGameObject(*m_caster, guid);
+ obj = m_caster->GetMap()->GetGameObject(guid);
if(obj) obj->Delete();
m_caster->m_ObjectSlot[slot] = 0;
@@ -5347,9 +5551,6 @@ void Spell::EffectSummonObject(uint32 i)
GameObject* pGameObj = new GameObject;
- float rot2 = sin(m_caster->GetOrientation()/2);
- float rot3 = cos(m_caster->GetOrientation()/2);
-
float x,y,z;
// If dest location if present
if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)
@@ -5363,7 +5564,8 @@ void Spell::EffectSummonObject(uint32 i)
m_caster->GetClosePoint(x,y,z,DEFAULT_WORLD_OBJECT_SIZE);
Map *map = m_caster->GetMap();
- if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), go_id, map, x, y, z, m_caster->GetOrientation(), 0, 0, rot2, rot3, 0, 1))
+ if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), go_id, map,
+ m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))
{
delete pGameObj;
return;
@@ -5371,7 +5573,7 @@ void Spell::EffectSummonObject(uint32 i)
//pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL,m_caster->getLevel());
int32 duration = GetSpellDuration(m_spellInfo);
- pGameObj->SetRespawnTime(duration > 0 ? duration/1000 : 0);
+ pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0);
pGameObj->SetSpellId(m_spellInfo->Id);
m_caster->AddGameObject(pGameObj);
@@ -5442,18 +5644,14 @@ void Spell::EffectAddExtraAttacks(uint32 /*i*/)
void Spell::EffectParry(uint32 /*i*/)
{
- if (unitTarget->GetTypeId() == TYPEID_PLAYER)
- {
+ if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER)
((Player*)unitTarget)->SetCanParry(true);
- }
}
void Spell::EffectBlock(uint32 /*i*/)
{
- if (unitTarget->GetTypeId() != TYPEID_PLAYER)
- return;
-
- ((Player*)unitTarget)->SetCanBlock(true);
+ if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)unitTarget)->SetCanBlock(true);
}
void Spell::EffectMomentMove(uint32 i)
@@ -5465,7 +5663,7 @@ void Spell::EffectMomentMove(uint32 i)
return;
uint32 mapid = m_caster->GetMapId();
- float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ float dis = m_caster->GetSpellRadiusForTarget(unitTarget, sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
// src point
float *fx = new float[11], *fy = new float[11], *fz = new float[11];
@@ -5503,26 +5701,9 @@ void Spell::EffectMomentMove(uint32 i)
if (hit == false)
itr_j = last_valid;
-
- if (unitTarget->GetTypeId() == TYPEID_PLAYER)
- ((Player*)unitTarget)->TeleportTo(mapid, fx[itr_j], fy[itr_j], fz[itr_j] + 0.07531, orientation, TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget == m_caster ? TELE_TO_SPELL : 0));
- else
- MapManager::Instance().GetMap(mapid, unitTarget)->CreatureRelocation((Creature*)unitTarget, fx[itr_j], fy[itr_j], fz[itr_j] + 0.07531, orientation);
+ unitTarget->NearTeleportTo(fx[itr_j], fy[itr_j], fz[itr_j] + 0.07531, orientation, unitTarget==m_caster);
delete [] fx; delete [] fy; delete [] fz;
-
-/* uint32 mapid = unitTarget->GetMapId();
- float ox,oy,oz;
- unitTarget->GetPosition(ox,oy,oz);
-
- float fx,fy,fz; // getObjectHitPos overwrite last args in any result case
- if(VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(mapid, ox,oy,oz+0.5, m_targets.m_destX,m_targets.m_destY,oz+0.5,fx,fy,fz, -0.5))
- unitTarget->UpdateGroundPositionZ(fx,fy,fz);
-
- if(unitTarget->GetTypeId() == TYPEID_PLAYER)
- ((Player*)unitTarget)->TeleportTo(mapid, fx, fy, fz, unitTarget->GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget==m_caster ? TELE_TO_SPELL : 0));
- else
- MapManager::Instance().GetMap(mapid, unitTarget)->CreatureRelocation((Creature*)unitTarget, fx, fy, fz, unitTarget->GetOrientation());*/
}
void Spell::EffectReputation(uint32 i)
@@ -5541,7 +5722,7 @@ void Spell::EffectReputation(uint32 i)
if(!factionEntry)
return;
- _player->ModifyFactionReputation(factionEntry,rep_change);
+ _player->GetReputationMgr().ModifyReputation(factionEntry,rep_change);
}
void Spell::EffectQuestComplete(uint32 i)
@@ -5635,97 +5816,11 @@ void Spell::EffectCharge(uint32 /*i*/)
m_caster->Attack(target, true);
}
-void Spell::EffectSummonCritter(uint32 i)
-{
- if(m_caster->GetTypeId() != TYPEID_PLAYER)
- return;
- Player* player = (Player*)m_caster;
-
- uint32 pet_entry = m_spellInfo->EffectMiscValue[i];
- if(!pet_entry)
- return;
-
- Pet* old_critter = player->GetMiniPet();
-
- // for same pet just despawn
- if(old_critter && old_critter->GetEntry() == pet_entry)
- {
- player->RemoveMiniPet();
- return;
- }
-
- // despawn old pet before summon new
- if(old_critter)
- player->RemoveMiniPet();
-
- // summon new pet
- Pet* critter = new Pet(MINI_PET);
-
- Map *map = m_caster->GetMap();
- uint32 pet_number = objmgr.GeneratePetNumber();
- if(!critter->Create(objmgr.GenerateLowGuid(HIGHGUID_PET),
- map, pet_entry, pet_number))
- {
- sLog.outError("Spell::EffectSummonCritter, spellid %u: no such creature entry %u", m_spellInfo->Id, pet_entry);
- delete critter;
- return;
- }
-
- float x,y,z;
- // If dest location if present
- if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)
- {
- x = m_targets.m_destX;
- y = m_targets.m_destY;
- z = m_targets.m_destZ;
- }
- // Summon if dest location not present near caster
- else
- m_caster->GetClosePoint(x,y,z,critter->GetObjectSize());
-
- critter->Relocate(x,y,z,m_caster->GetOrientation());
-
- if(!critter->IsPositionValid())
- {
- sLog.outError("ERROR: Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)",
- critter->GetGUIDLow(), critter->GetEntry(), critter->GetPositionX(), critter->GetPositionY());
- delete critter;
- return;
- }
-
- critter->SetOwnerGUID(m_caster->GetGUID());
- critter->SetCreatorGUID(m_caster->GetGUID());
- critter->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction());
- critter->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
-
- critter->AIM_Initialize();
- critter->InitPetCreateSpells(); // e.g. disgusting oozeling has a create spell as critter...
- critter->SetMaxHealth(1);
- critter->SetHealth(1);
- critter->SetLevel(1);
-
- // set timer for unsummon
- int32 duration = GetSpellDuration(m_spellInfo);
- if(duration > 0)
- critter->SetDuration(duration);
-
- std::string name = player->GetName();
- name.append(petTypeSuffix[critter->getPetType()]);
- critter->SetName( name );
- player->SetMiniPet(critter);
-
- map->Add((Creature*)critter);
-}
-
void Spell::EffectKnockBack(uint32 i)
{
if(!unitTarget)
return;
- // Effect only works on players
- if(unitTarget->GetTypeId()!=TYPEID_PLAYER)
- return;
-
float x, y;
if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)
{
@@ -5738,31 +5833,29 @@ void Spell::EffectKnockBack(uint32 i)
y = m_caster->GetPositionY();
}
- float dx = unitTarget->GetPositionX() - x;
- float dy = unitTarget->GetPositionY() - y;
- float vcos, vsin;
- if(dx < 0.001f && dy < 0.001f)
+ float speedxy = float(m_spellInfo->EffectMiscValue[i])/10;
+ float speedz = float(damage/10);
+
+ unitTarget->KnockbackFrom(x, y, speedxy, speedz);
+}
+
+void Spell::EffectJump2(uint32 i)
+{
+ if(!unitTarget)
+ return;
+
+ float speedxy = float(m_spellInfo->EffectMiscValue[i])/10;
+ float speedz = float(damage/10);
+ if(!speedxy)
{
- float angle = rand_norm()*2*M_PI;
- vcos = cos(angle);
- vsin = sin(angle);
+ if(m_targets.getUnitTarget())
+ unitTarget->JumpTo(m_targets.getUnitTarget(), speedz);
}
else
{
- float dist = sqrt((dx*dx) + (dy*dy));
- vcos = dx / dist;
- vsin = dy / dist;
+ //1891: Disengage
+ unitTarget->JumpTo(speedxy, speedz, m_spellInfo->SpellIconID != 1891);
}
-
- WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8+4+4+4+4+4));
- data.append(unitTarget->GetPackGUID());
- data << uint32(0); // Sequence
- data << float(vcos); // x direction
- data << float(vsin); // y direction
- data << float(m_spellInfo->EffectMiscValue[i])/10; // Horizontal speed
- data << float(damage/-10); // Z Movement speed (vertical)
-
- ((Player*)unitTarget)->GetSession()->SendPacket(&data);
}
void Spell::EffectSendTaxi(uint32 i)
@@ -5783,17 +5876,26 @@ void Spell::EffectSendTaxi(uint32 i)
uint32 mountid = 0;
switch(m_spellInfo->Id)
{
- case 31606: //Stormcrow Amulet
+ case 31606: //Stormcrow Amulet
mountid = 17447;
break;
- case 45071: //Quest - Sunwell Daily - Dead Scar Bombing Run
- case 45113: //Quest - Sunwell Daily - Ship Bombing Run
- case 45353: //Quest - Sunwell Daily - Ship Bombing Run Return
+ case 45071: //Quest - Sunwell Daily - Dead Scar Bombing Run
+ case 45113: //Quest - Sunwell Daily - Ship Bombing Run
+ case 45353: //Quest - Sunwell Daily - Ship Bombing Run Return
mountid = 22840;
break;
- case 34905: //Stealth Flight
+ case 34905: //Stealth Flight
mountid = 6851;
break;
+ case 45883: //Amber Ledge to Beryl Point
+ mountid = 23524;
+ break;
+ case 46064: //Amber Ledge to Coldarra
+ mountid = 6371;
+ break;
+ case 53335: //Stormwind Harbor Flight - Peaceful
+ mountid = 6852;
+ break;
case 41533: //Fly of the Netherwing
case 41540: //Fly of the Netherwing
mountid = 23468;
@@ -5835,22 +5937,21 @@ void Spell::EffectDispelMechanic(uint32 i)
uint32 mechanic = m_spellInfo->EffectMiscValue[i];
+ std::queue < std::pair < uint32, uint64 > > dispel_list;
+
Unit::AuraMap& Auras = unitTarget->GetAuras();
- for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
+ for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end(); iter++)
{
- next = iter;
- ++next;
- SpellEntry const *spell = sSpellStore.LookupEntry(iter->second->GetSpellProto()->Id);
- if(spell->Mechanic == mechanic || spell->EffectMechanic[iter->second->GetEffIndex()] == mechanic)
- {
- unitTarget->RemoveAurasDueToSpell(spell->Id);
- if(Auras.empty())
- break;
- else
- next = Auras.begin();
- }
+ if((GetAllSpellMechanicMask(iter->second->GetSpellProto()) & (1<<(mechanic))) && GetDispelChance(iter->second->GetCaster(), iter->second->GetId()))
+ {
+ dispel_list.push(std::make_pair(iter->second->GetId(), iter->second->GetCasterGUID() ) );
+ }
+ }
+
+ for(;dispel_list.size();dispel_list.pop())
+ {
+ unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, AURA_REMOVE_BY_ENEMY_SPELL);
}
- return;
}
void Spell::EffectSummonDeadPet(uint32 /*i*/)
@@ -5865,36 +5966,40 @@ void Spell::EffectSummonDeadPet(uint32 /*i*/)
return;
if(damage < 0)
return;
+
pet->SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0);
pet->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
pet->setDeathState( ALIVE );
pet->clearUnitState(UNIT_STAT_ALL_STATE);
pet->SetHealth( uint32(pet->GetMaxHealth()*(float(damage)/100)));
- pet->AIM_Initialize();
-
- _player->PetSpellInitialize();
+ //pet->AIM_Initialize();
+ //_player->PetSpellInitialize();
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
}
void Spell::EffectDestroyAllTotems(uint32 /*i*/)
{
float mana = 0;
- for(int slot = 0; slot < MAX_TOTEM; ++slot)
+ for(int slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
{
- if(!m_caster->m_TotemSlot[slot])
+ if(!m_caster->m_SummonSlot[slot])
continue;
- Creature* totem = ObjectAccessor::GetCreature(*m_caster,m_caster->m_TotemSlot[slot]);
+ Creature* totem = m_caster->GetMap()->GetCreature(m_caster->m_SummonSlot[slot]);
if(totem && totem->isTotem())
{
uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell_id);
if(spellInfo)
- mana += spellInfo->manaCost * damage / 100;
+ {
+ mana += spellInfo->manaCost;
+ mana += spellInfo->ManaCostPercentage * m_caster->GetCreateMana() / 100;
+ }
((Totem*)totem)->UnSummon();
}
}
+ mana = mana * damage / 100;
int32 gain = m_caster->ModifyPower(POWER_MANA,int32(mana));
m_caster->SendEnergizeSpellLog(m_caster, m_spellInfo->Id, gain, POWER_MANA);
@@ -5980,13 +6085,14 @@ void Spell::EffectTransmitted(uint32 effIndex)
//FIXME: this can be better check for most objects but still hack
else if(m_spellInfo->EffectRadiusIndex[effIndex] && m_spellInfo->speed==0)
{
- float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[effIndex]));
+ float dis = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[effIndex]));
m_caster->GetClosePoint(fx,fy,fz,DEFAULT_WORLD_OBJECT_SIZE, dis);
}
else
{
- float min_dis = GetSpellMinRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
- float max_dis = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
+ //GO is always friendly to it's creator, get range for friends
+ float min_dis = GetSpellMinRangeForFriend(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
+ float max_dis = GetSpellMaxRangeForFriend(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
float dis = rand_norm() * (max_dis - min_dis) + min_dis;
m_caster->GetClosePoint(fx,fy,fz,DEFAULT_WORLD_OBJECT_SIZE, dis);
@@ -6015,7 +6121,7 @@ void Spell::EffectTransmitted(uint32 effIndex)
GameObject* pGameObj = new GameObject;
if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), name_id, cMap,
- fx, fy, fz, m_caster->GetOrientation(), 0, 0, 0, 0, 100, 1))
+ m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY))
{
delete pGameObj;
return;
@@ -6028,15 +6134,11 @@ void Spell::EffectTransmitted(uint32 effIndex)
case GAMEOBJECT_TYPE_FISHINGNODE:
{
m_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT,pGameObj->GetGUID());
- // Orientation3
- pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 2, 0.88431775569915771 );
- // Orientation4
- pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 3, -0.4668855369091033 );
m_caster->AddGameObject(pGameObj); // will removed at spell cancel
// end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
// start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
- int32 lastSec;
+ int32 lastSec = 0;
switch(urand(0, 3))
{
case 0: lastSec = 3; break;
@@ -6045,7 +6147,7 @@ void Spell::EffectTransmitted(uint32 effIndex)
case 3: lastSec = 17; break;
}
- duration = duration - lastSec*1000 + FISHING_BOBBER_READY_TIME*1000;
+ duration = duration - lastSec*IN_MILISECONDS + FISHING_BOBBER_READY_TIME*IN_MILISECONDS;
break;
}
case GAMEOBJECT_TYPE_SUMMONING_RITUAL:
@@ -6065,14 +6167,14 @@ void Spell::EffectTransmitted(uint32 effIndex)
}
}
- pGameObj->SetRespawnTime(duration > 0 ? duration/1000 : 0);
+ pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0);
pGameObj->SetOwnerGUID(m_caster->GetGUID() );
//pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel() );
pGameObj->SetSpellId(m_spellInfo->Id);
- DEBUG_LOG("AddObject at SpellEfects.cpp EffectTransmitted\n");
+ DEBUG_LOG("AddObject at SpellEfects.cpp EffectTransmitted");
//m_caster->AddGameObject(pGameObj);
//m_ObjToDel.push_back(pGameObj);
@@ -6086,9 +6188,9 @@ void Spell::EffectTransmitted(uint32 effIndex)
{
GameObject* linkedGO = new GameObject;
if(linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, cMap,
- fx, fy, fz, m_caster->GetOrientation(), 0, 0, 0, 0, 100, 1))
+ m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY))
{
- linkedGO->SetRespawnTime(duration > 0 ? duration/1000 : 0);
+ linkedGO->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0);
//linkedGO->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel() );
linkedGO->SetSpellId(m_spellInfo->Id);
linkedGO->SetOwnerGUID(m_caster->GetGUID() );
@@ -6126,6 +6228,28 @@ void Spell::EffectProspecting(uint32 /*i*/)
((Player*)m_caster)->SendLoot(itemTarget->GetGUID(), LOOT_PROSPECTING);
}
+void Spell::EffectMilling(uint32 /*i*/)
+{
+ if(m_caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ Player* p_caster = (Player*)m_caster;
+ if(!itemTarget || !(itemTarget->GetProto()->BagFamily & BAG_FAMILY_MASK_HERBS))
+ return;
+
+ if(itemTarget->GetCount() < 5)
+ return;
+
+ if( sWorld.getConfig(CONFIG_SKILL_MILLING))
+ {
+ uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
+ uint32 reqSkillValue = itemTarget->GetProto()->RequiredSkillRank;
+ p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
+ }
+
+ ((Player*)m_caster)->SendLoot(itemTarget->GetGUID(), LOOT_MILLING);
+}
+
void Spell::EffectSkill(uint32 /*i*/)
{
sLog.outDebug("WORLD: SkillEFFECT");
@@ -6133,26 +6257,34 @@ void Spell::EffectSkill(uint32 /*i*/)
void Spell::EffectSummonDemon(uint32 i)
{
- float px = m_targets.m_destX;
- float py = m_targets.m_destY;
- float pz = m_targets.m_destZ;
+ float radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
- Creature* Charmed = m_caster->SummonCreature(m_spellInfo->EffectMiscValue[i], px, py, pz, m_caster->GetOrientation(),TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,3600000);
- if (!Charmed)
- return;
+ int32 amount = damage > 0 ? damage : 1;
- // might not always work correctly, maybe the creature that dies from CoD casts the effect on itself and is therefore the caster?
- Charmed->SetLevel(m_caster->getLevel());
+ for(int32 count = 0; count < amount; ++count)
+ {
+ float px, py, pz;
+ GetSummonPosition(px, py, pz, radius, count);
- // TODO: Add damage/mana/hp according to level
+ int32 duration = GetSpellDuration(m_spellInfo);
- if (m_spellInfo->EffectMiscValue[i] == 89) // Inferno summon
- {
- // Enslave demon effect, without mana cost and cooldown
- m_caster->CastSpell(Charmed, 20882, true); // FIXME: enslave does not scale with level, level 62+ minions cannot be enslaved
+ Creature* Charmed = m_caster->SummonCreature(m_spellInfo->EffectMiscValue[i], px, py, pz, m_caster->GetOrientation(),TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,duration);
+ if (!Charmed) // something fatal, not attempt more
+ return;
- // Inferno effect
- Charmed->CastSpell(Charmed, 22703, true, 0);
+ // might not always work correctly, maybe the creature that dies from CoD casts the effect on itself and is therefore the caster?
+ Charmed->SetLevel(m_caster->getLevel());
+
+ // TODO: Add damage/mana/hp according to level
+
+ if (m_spellInfo->EffectMiscValue[i] == 89) // Inferno summon
+ {
+ // Enslave demon effect, without mana cost and cooldown
+ m_caster->CastSpell(Charmed, 20882, true); // FIXME: enslave does not scale with level, level 62+ minions cannot be enslaved
+
+ // Inferno effect
+ Charmed->CastSpell(Charmed, 22703, true, 0);
+ }
}
}
@@ -6194,7 +6326,7 @@ void Spell::EffectStealBeneficialBuff(uint32 i)
if(!unitTarget || unitTarget==m_caster) // can't steal from self
return;
- std::vector <Aura *> steal_list;
+ std::list <Aura *> steal_list;
// Create dispel mask by dispel type
uint32 dispelMask = GetDispellMask( DispelType(m_spellInfo->EffectMiscValue[i]) );
Unit::AuraMap const& auras = unitTarget->GetAuras();
@@ -6204,53 +6336,38 @@ void Spell::EffectStealBeneficialBuff(uint32 i)
if (aur && (1<<aur->GetSpellProto()->Dispel) & dispelMask)
{
// Need check for passive? this
- if (aur->IsPositive() && !aur->IsPassive())
+ if (aur->IsPositive() && !aur->IsPassive() && !(aur->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_NOT_STEALABLE))
steal_list.push_back(aur);
}
}
// Ok if exist some buffs for dispel try dispel it
- if (!steal_list.empty())
+ if (uint32 list_size = steal_list.size())
{
- std::list < std::pair<uint32,uint64> > success_list;
- int32 list_size = steal_list.size();
+ std::list < Aura * > success_list;
+
// dispel N = damage buffs (or while exist buffs for dispel)
- for (int32 count=0; count < damage && list_size > 0; ++count)
+ for (int32 count=0; count < damage && list_size > 0; ++count, list_size = steal_list.size())
{
// Random select buff for dispel
- Aura *aur = steal_list[urand(0, list_size-1)];
- // Not use chance for steal
- // TODO possible need do it
- success_list.push_back( std::pair<uint32,uint64>(aur->GetId(),aur->GetCasterGUID()));
-
- // Remove buff from list for prevent doubles
- for (std::vector<Aura *>::iterator j = steal_list.begin(); j != steal_list.end(); )
- {
- Aura *stealed = *j;
- if (stealed->GetId() == aur->GetId() && stealed->GetCasterGUID() == aur->GetCasterGUID())
- {
- j = steal_list.erase(j);
- --list_size;
- }
- else
- ++j;
- }
+ std::list < Aura * > ::iterator itr = steal_list.begin();
+ for (uint32 i=urand(0, list_size-1);i>0;--i)
+ itr++;
+ success_list.push_back(*itr);
+ steal_list.erase(itr);
}
- // Really try steal and send log
- if (!success_list.empty())
+ if (success_list.size())
{
- int32 count = success_list.size();
- WorldPacket data(SMSG_SPELLSTEALLOG, 8+8+4+1+4+count*5);
+ WorldPacket data(SMSG_SPELLSTEALLOG, 8+8+4+1+4+damage*5);
data.append(unitTarget->GetPackGUID()); // Victim GUID
data.append(m_caster->GetPackGUID()); // Caster GUID
data << uint32(m_spellInfo->Id); // dispel spell id
data << uint8(0); // not used
- data << uint32(count); // count
- for (std::list<std::pair<uint32,uint64> >::iterator j = success_list.begin(); j != success_list.end(); ++j)
+ data << uint32(success_list.size()); // count
+ for (std::list < Aura * > ::iterator itr = success_list.begin();itr!=success_list.end();++itr)
{
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(j->first);
- data << uint32(spellInfo->Id); // Spell Id
+ data << uint32((*itr)->GetId()); // Spell Id
data << uint8(0); // 0 - steals !=0 transfers
- unitTarget->RemoveAurasDueToSpellBySteal(spellInfo->Id, j->second, m_caster);
+ unitTarget->RemoveAurasDueToSpellBySteal((*itr)->GetId(), (*itr)->GetCasterGUID(), m_caster);
}
m_caster->SendMessageToSet(&data, true);
}
@@ -6262,7 +6379,7 @@ void Spell::EffectKillCredit(uint32 i)
if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- ((Player*)unitTarget)->KilledMonster(m_spellInfo->EffectMiscValue[i], 0);
+ ((Player*)unitTarget)->RewardPlayerAndGroupAtEvent(m_spellInfo->EffectMiscValue[i], unitTarget);
}
void Spell::EffectQuestFail(uint32 i)
@@ -6273,9 +6390,112 @@ void Spell::EffectQuestFail(uint32 i)
((Player*)unitTarget)->FailQuest(m_spellInfo->EffectMiscValue[i]);
}
+void Spell::EffectActivateRune(uint32 eff_idx)
+{
+ if(m_caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ Player *plr = (Player*)m_caster;
+
+ if(plr->getClass() != CLASS_DEATH_KNIGHT)
+ return;
+
+ for(uint32 j = 0; j < MAX_RUNES; ++j)
+ {
+ if(plr->GetRuneCooldown(j) && plr->GetCurrentRune(j) == m_spellInfo->EffectMiscValue[eff_idx])
+ {
+ plr->SetRuneCooldown(j, 0);
+ }
+ }
+}
+
+void Spell::EffectTitanGrip(uint32 /*eff_idx*/)
+{
+ if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)unitTarget)->SetCanTitanGrip(true);
+}
+
void Spell::EffectRedirectThreat(uint32 /*i*/)
{
if(unitTarget)
m_caster->SetReducedThreatPercent((uint32)damage, unitTarget->GetGUID());
}
+void Spell::SummonGuardian(uint32 entry, SummonPropertiesEntry const *properties)
+{
+ Unit *caster = m_originalCaster;
+ if(caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())
+ caster = caster->GetOwner();
+ if(!caster)
+ return;
+
+ // in another case summon new
+ uint32 level = caster->getLevel();
+
+ // level of pet summoned using engineering item based at engineering skill level
+ if(m_CastItem && caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ ItemPrototype const *proto = m_CastItem->GetProto();
+ if(proto && proto->RequiredSkill == SKILL_ENGINERING)
+ {
+ uint16 skill202 = ((Player*)caster)->GetSkillValue(SKILL_ENGINERING);
+ if(skill202)
+ {
+ level = skill202/5;
+ }
+ }
+ }
+
+ //float radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ float radius = 5.0f;
+ int32 amount = damage > 0 ? damage : 1;
+ int32 duration = GetSpellDuration(m_spellInfo);
+ TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
+ Map *map = caster->GetMap();
+
+ for(int32 count = 0; count < amount; ++count)
+ {
+ float px, py, pz;
+ GetSummonPosition(px, py, pz, radius, count);
+
+ TempSummon *summon = map->SummonCreature(entry, px, py, pz, m_caster->GetOrientation(), properties, duration, caster);
+ if(!summon)
+ return;
+
+ if(summon->HasSummonMask(SUMMON_MASK_GUARDIAN))
+ ((Guardian*)summon)->InitStatsForLevel(level);
+
+ summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
+
+ summon->GetMotionMaster()->MoveTargetedHome();
+ }
+}
+
+void Spell::GetSummonPosition(float &x, float &y, float &z, float radius, uint32 count)
+{
+ if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)
+ {
+ // Summon 1 unit in dest location
+ if (count == 0)
+ {
+ x = m_targets.m_destX;
+ y = m_targets.m_destY;
+ z = m_targets.m_destZ;
+ }
+ // Summon in random point all other units if location present
+ else
+ m_caster->GetRandomPoint(m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ,radius,x,y,z);
+ }
+ // Summon if dest location not present near caster
+ else
+ m_caster->GetClosePoint(x,y,z,3.0f);
+}
+
+void Spell::EffectRenamePet(uint32 /*eff_idx*/)
+{
+ if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT ||
+ !((Creature*)unitTarget)->isPet() || ((Pet*)unitTarget)->getPetType() != HUNTER_PET)
+ return;
+
+ unitTarget->SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED);
+}
diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp
index efa9c6feebd..5cd5da67118 100644
--- a/src/game/SpellHandler.cpp
+++ b/src/game/SpellHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -19,36 +19,40 @@
*/
#include "Common.h"
-#include "Database/DBCStores.h"
+#include "DBCStores.h"
#include "WorldPacket.h"
#include "WorldSession.h"
-#include "World.h"
#include "ObjectMgr.h"
#include "SpellMgr.h"
#include "Log.h"
#include "Opcodes.h"
#include "Spell.h"
-#include "SpellAuras.h"
-#include "BattleGround.h"
-#include "MapManager.h"
#include "ScriptCalls.h"
#include "Totem.h"
#include "TemporarySummon.h"
+#include "SpellAuras.h"
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
{
// TODO: add targets.read() check
- CHECK_PACKET_SIZE(recvPacket,1+1+1+1+8);
+ CHECK_PACKET_SIZE(recvPacket,1+1+1+4+8+4+1);
Player* pUser = _player;
+
+ // ignore for remote control state
+ if(pUser->m_mover != pUser)
+ return;
+
uint8 bagIndex, slot;
- uint8 spell_count; // number of spells at item, not used
+ uint8 unk_flags; // flags (if 0x02 - some additional data are received)
uint8 cast_count; // next cast if exists (single or not)
uint64 item_guid;
+ uint32 glyphIndex; // something to do with glyphs?
+ uint32 spellid; // casted spell id
- recvPacket >> bagIndex >> slot >> spell_count >> cast_count >> item_guid;
+ recvPacket >> bagIndex >> slot >> cast_count >> spellid >> item_guid >> glyphIndex >> unk_flags;
- Item *pItem = pUser->GetItemByPos(bagIndex, slot);
+ Item *pItem = pUser->GetUseableItemByPos(bagIndex, slot);
if(!pItem)
{
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
@@ -61,7 +65,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
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());
+ sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, cast_count: %u, spellid: %u, Item: %u, glyphIndex: %u, unk_flags: %u, data length = %i", bagIndex, slot, cast_count, spellid, pItem->GetEntry(), glyphIndex, unk_flags, (uint32)recvPacket.size());
ItemPrototype const *proto = pItem->GetProto();
if(!proto)
@@ -95,7 +99,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
if (pUser->isInCombat())
{
- for(int i = 0; i < 5; ++i)
+ for(int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
if (SpellEntry const *spellInfo = sSpellStore.LookupEntry(proto->Spells[i].SpellId))
{
@@ -126,57 +130,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
if(!Script->ItemUse(pUser,pItem,targets))
{
// no script or script not process request by self
-
- // special learning case
- if(pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN)
- {
- uint32 learning_spell_id = pItem->GetProto()->Spells[1].SpellId;
-
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(SPELL_ID_GENERIC_LEARN);
- if(!spellInfo)
- {
- sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, SPELL_ID_GENERIC_LEARN);
- pUser->SendEquipError(EQUIP_ERR_NONE,pItem,NULL);
- return;
- }
-
- Spell *spell = new Spell(pUser, spellInfo, false);
- spell->m_CastItem = pItem;
- spell->m_cast_count = cast_count; //set count of casts
- spell->m_currentBasePoints[0] = learning_spell_id;
- spell->prepare(&targets);
- return;
- }
-
- // use triggered flag only for items with many spell casts and for not first cast
- int count = 0;
-
- for(int i = 0; i < 5; ++i)
- {
- _Spell const& spellData = pItem->GetProto()->Spells[i];
-
- // no spell
- if(!spellData.SpellId)
- continue;
-
- // wrong triggering type
- if( spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_USE && spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_NO_DELAY_USE)
- continue;
-
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellData.SpellId);
- if(!spellInfo)
- {
- sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, spellData.SpellId);
- continue;
- }
-
- Spell *spell = new Spell(pUser, spellInfo, (count > 0));
- spell->m_CastItem = pItem;
- spell->m_cast_count = cast_count; //set count of casts
- spell->prepare(&targets);
-
- ++count;
- }
+ pUser->CastItemUseSpell(pItem,targets,cast_count,glyphIndex);
}
}
@@ -190,9 +144,14 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
{
CHECK_PACKET_SIZE(recvPacket,1+1);
- sLog.outDetail("WORLD: CMSG_OPEN_ITEM packet, data length = %i",recvPacket.size());
+ sLog.outDetail("WORLD: CMSG_OPEN_ITEM packet, data length = %i",(uint32)recvPacket.size());
Player* pUser = _player;
+
+ // ignore for remote control state
+ if(pUser->m_mover != pUser)
+ return;
+
uint8 bagIndex, slot;
recvPacket >> bagIndex >> slot;
@@ -227,7 +186,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
}
// required picklocking
- if(lockInfo->requiredlockskill || lockInfo->requiredminingskill)
+ if(lockInfo->Skill[1] || lockInfo->Skill[0])
{
pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, pItem, NULL );
return;
@@ -270,7 +229,12 @@ void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data )
recv_data >> guid;
sLog.outDebug( "WORLD: Recvd CMSG_GAMEOBJ_USE Message [guid=%u]", GUID_LOPART(guid));
- GameObject *obj = ObjectAccessor::GetGameObject(*_player, guid);
+
+ // ignore for remote control state
+ if(_player->m_mover != _player)
+ return;
+
+ GameObject *obj = GetPlayer()->GetMap()->GetGameObject(guid);
if(!obj)
return;
@@ -281,17 +245,46 @@ void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data )
obj->Use(_player);
}
+void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket)
+{
+ CHECK_PACKET_SIZE(recvPacket,8);
+
+ uint64 guid;
+ recvPacket >> guid;
+
+ sLog.outDebug( "WORLD: Recvd CMSG_GAMEOBJ_REPORT_USE Message [in game guid: %u]", GUID_LOPART(guid));
+
+ // ignore for remote control state
+ if(_player->m_mover != _player)
+ return;
+
+ GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid);
+ if(!go)
+ return;
+
+ if(!go->IsWithinDistInMap(_player,INTERACTION_DISTANCE))
+ return;
+
+ _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, go->GetEntry());
+}
+
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
- CHECK_PACKET_SIZE(recvPacket,4+1+2);
+ CHECK_PACKET_SIZE(recvPacket,1+4+1);
uint32 spellId;
- uint8 cast_count;
- recvPacket >> spellId;
+ uint8 cast_count, unk_flags;
recvPacket >> cast_count;
+ recvPacket >> spellId;
+ recvPacket >> unk_flags; // flags (if 0x02 - some additional data are received)
- sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u data length = %i",
- spellId, cast_count, recvPacket.size());
+ // ignore for remote control state (for player case)
+ Unit* mover = _player->m_mover;
+ if(mover != _player && mover->GetTypeId()==TYPEID_PLAYER)
+ return;
+
+ sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u, unk_flags %u, data length = %i",
+ spellId, cast_count, unk_flags, (uint32)recvPacket.size());
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
@@ -301,11 +294,23 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
return;
}
- // not have spell or spell passive and not casted by client
- if ( !_player->HasSpell (spellId) || IsPassiveSpell(spellId) )
+ if(mover->GetTypeId()==TYPEID_PLAYER)
{
- //cheater? kick? ban?
- return;
+ // not have spell in spellbook or spell passive and not casted by client
+ if (!((Player*)mover)->HasActiveSpell (spellId) || IsPassiveSpell(spellId) )
+ {
+ //cheater? kick? ban?
+ return;
+ }
+ }
+ else
+ {
+ // not have spell in spellbook or spell passive and not casted by client
+ if (!((Creature*)mover)->HasSpell(spellId) || IsPassiveSpell(spellId) )
+ {
+ //cheater? kick? ban?
+ return;
+ }
}
// can't use our own spells when we're in possession of another unit,
@@ -314,7 +319,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
// client provided targets
SpellCastTargets targets;
- if(!targets.read(&recvPacket,_player))
+ if(!targets.read(&recvPacket,mover))
return;
// auto-selection buff level base at target level (in spellInfo)
@@ -327,16 +332,19 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
spellInfo = actualSpellInfo;
}
- Spell *spell = new Spell(_player, spellInfo, false);
+ Spell *spell = new Spell(mover, spellInfo, false);
spell->m_cast_count = cast_count; // set count of casts
spell->prepare(&targets);
}
void WorldSession::HandleCancelCastOpcode(WorldPacket& recvPacket)
{
- CHECK_PACKET_SIZE(recvPacket,4);
+ CHECK_PACKET_SIZE(recvPacket,5);
+ // increments with every CANCEL packet, don't use for now
+ uint8 counter;
uint32 spellId;
+ recvPacket >> counter;
recvPacket >> spellId;
if(_player->IsNonMeleeSpellCasted(false))
@@ -358,43 +366,17 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
if(!IsPositiveSpell(spellId) || (spellInfo->Attributes & SPELL_ATTR_CANT_CANCEL))
return;
- // lifebloom must delete final heal effect
- if (spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && (spellInfo->SpellFamilyFlags & 0x1000000000LL) )
- {
- Unit::AuraMap::iterator iter;
- while((iter = _player->m_Auras.find(Unit::spellEffectPair(spellId, 1))) != _player->m_Auras.end())
- {
- _player->m_modAuras[SPELL_AURA_DUMMY].remove(iter->second);
-
- Aura* Aur = iter->second;
- _player->m_Auras.erase(iter);
- ++_player->m_removedAuras; // internal count used by unit update
-
- delete Aur;
-
- if( _player->m_Auras.empty() )
- iter = _player->m_Auras.end();
- else
- iter = _player->m_Auras.begin();
-
- }
- }
-
// channeled spell case (it currently casted then)
- if(IsChanneledSpell(spellInfo))
+ if (IsChanneledSpell(spellInfo))
{
- if(Spell* spell = _player->m_currentSpells[CURRENT_CHANNELED_SPELL])
- {
- if(spell->m_spellInfo->Id==spellId)
- {
- spell->cancel();
- }
- }
+ if (_player->m_currentSpells[CURRENT_CHANNELED_SPELL] &&
+ _player->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id==spellId)
+ _player->InterruptSpell(CURRENT_CHANNELED_SPELL);
return;
}
// non channeled case
- _player->RemoveAurasDueToSpellByCancel(spellId);
+ _player->RemoveAurasDueToSpell(spellId, _player->GetGUID(), AURA_REMOVE_BY_CANCEL);
}
void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
@@ -414,7 +396,7 @@ void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
return;
}
- Creature* pet=ObjectAccessor::GetCreatureOrPet(*_player,guid);
+ Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid);
if(!pet)
{
@@ -422,7 +404,7 @@ void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
return;
}
- if(pet != GetPlayer()->GetPet() && pet != GetPlayer()->GetCharm())
+ if(pet != GetPlayer()->GetGuardianPet() && pet != GetPlayer()->GetCharm())
{
sLog.outError( "HandlePetCancelAura.Pet %u isn't pet of player %s", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
return;
@@ -466,17 +448,22 @@ void WorldSession::HandleTotemDestroy( WorldPacket& recvPacket)
{
CHECK_PACKET_SIZE(recvPacket, 1);
+ // ignore for remote control state
+ if(_player->m_mover != _player)
+ return;
+
uint8 slotId;
recvPacket >> slotId;
- if (slotId >= MAX_TOTEM)
+ ++slotId;
+ if (slotId >= MAX_TOTEM_SLOT)
return;
- if(!_player->m_TotemSlot[slotId])
+ if(!_player->m_SummonSlot[slotId])
return;
- Creature* totem = ObjectAccessor::GetCreature(*_player,_player->m_TotemSlot[slotId]);
+ Creature* totem = GetPlayer()->GetMap()->GetCreature(_player->m_SummonSlot[slotId]);
// Don't unsummon sentry totem
if(totem && totem->isTotem() && totem->GetEntry() != SENTRY_TOTEM_ENTRY)
((Totem*)totem)->UnSummon();
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index 95ddab074b1..6d93f292f8c 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,10 +22,11 @@
#include "ObjectMgr.h"
#include "SpellAuraDefines.h"
#include "ProgressBar.h"
-#include "Database/DBCStores.h"
+#include "DBCStores.h"
#include "World.h"
#include "Chat.h"
#include "Spell.h"
+#include "BattleGroundMgr.h"
bool IsAreaEffectTarget[TOTAL_SPELL_TARGETS];
@@ -38,25 +39,17 @@ SpellMgr::SpellMgr()
case SPELL_EFFECT_PERSISTENT_AREA_AURA: //27
case SPELL_EFFECT_SUMMON: //28
case SPELL_EFFECT_TRIGGER_MISSILE: //32
- case SPELL_EFFECT_SUMMON_WILD: //41
- case SPELL_EFFECT_SUMMON_GUARDIAN: //42
case SPELL_EFFECT_TRANS_DOOR: //50 summon object
case SPELL_EFFECT_SUMMON_PET: //56
case SPELL_EFFECT_ADD_FARSIGHT: //72
- case SPELL_EFFECT_SUMMON_POSSESSED: //73
- case SPELL_EFFECT_SUMMON_TOTEM: //74
case SPELL_EFFECT_SUMMON_OBJECT_WILD: //76
- case SPELL_EFFECT_SUMMON_TOTEM_SLOT1: //87
- case SPELL_EFFECT_SUMMON_TOTEM_SLOT2: //88
- case SPELL_EFFECT_SUMMON_TOTEM_SLOT3: //89
- case SPELL_EFFECT_SUMMON_TOTEM_SLOT4: //90
- case SPELL_EFFECT_SUMMON_CRITTER: //97
+ //case SPELL_EFFECT_SUMMON_CRITTER: //97 not 303
case SPELL_EFFECT_SUMMON_OBJECT_SLOT1: //104
case SPELL_EFFECT_SUMMON_OBJECT_SLOT2: //105
case SPELL_EFFECT_SUMMON_OBJECT_SLOT3: //106
case SPELL_EFFECT_SUMMON_OBJECT_SLOT4: //107
case SPELL_EFFECT_SUMMON_DEAD_PET: //109
- case SPELL_EFFECT_SUMMON_DEMON: //112
+ //case SPELL_EFFECT_SUMMON_DEMON: //112 not 303
case SPELL_EFFECT_TRIGGER_SPELL_2: //151 ritual of summon
EffectTargetType[i] = SPELL_REQUIRE_DEST;
break;
@@ -73,6 +66,8 @@ SpellMgr::SpellMgr()
case SPELL_EFFECT_DISENCHANT:
case SPELL_EFFECT_FEED_PET:
case SPELL_EFFECT_PROSPECTING:
+ case SPELL_EFFECT_MILLING:
+ case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC:
EffectTargetType[i] = SPELL_REQUIRE_ITEM;
break;
//caster must be pushed otherwise no sound
@@ -81,6 +76,7 @@ SpellMgr::SpellMgr()
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
case SPELL_EFFECT_APPLY_AREA_AURA_PET:
case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
+ case SPELL_EFFECT_JUMP2: //42
EffectTargetType[i] = SPELL_REQUIRE_CASTER;
break;
default:
@@ -105,7 +101,6 @@ SpellMgr::SpellMgr()
case TARGET_UNIT_TARGET_ALLY:
case TARGET_UNIT_TARGET_RAID:
case TARGET_UNIT_TARGET_ANY:
- case TARGET_UNIT_SINGLE_UNKNOWN:
case TARGET_UNIT_TARGET_ENEMY:
case TARGET_UNIT_TARGET_PARTY:
case TARGET_UNIT_PARTY_TARGET:
@@ -235,6 +230,21 @@ int32 GetSpellMaxDuration(SpellEntry const *spellInfo)
return (du->Duration[2] == -1) ? -1 : abs(du->Duration[2]);
}
+bool GetDispelChance(Unit* caster, uint32 spellId)
+{
+ // we assume that aura dispel chance is 100% on start
+ // need formula for level difference based chance
+ int32 miss_chance = 0;
+ // Apply dispel mod from aura caster
+ if (caster)
+ {
+ if ( Player* modOwner = caster->GetSpellModOwner() )
+ modOwner->ApplySpellMod(spellId, SPELLMOD_RESIST_DISPEL_CHANCE, miss_chance);
+ }
+ // Try dispel
+ return !roll_chance_i(miss_chance);
+}
+
uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell)
{
SpellCastTimesEntry const *spellCastTimeEntry = sSpellCastTimesStore.LookupEntry(spellInfo->CastingTimeIndex);
@@ -245,19 +255,8 @@ uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell)
int32 castTime = spellCastTimeEntry->CastTime;
- if (spell)
- {
- if(Player* modOwner = spell->GetCaster()->GetSpellModOwner())
- modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CASTING_TIME, castTime, spell);
-
- if( !(spellInfo->Attributes & (SPELL_ATTR_UNK4|SPELL_ATTR_UNK5)) )
- castTime = int32(castTime * spell->GetCaster()->GetFloatValue(UNIT_MOD_CAST_SPEED));
- else
- {
- if (spell->IsRangedSpell() && !spell->IsAutoRepeat())
- castTime = int32(castTime * spell->GetCaster()->m_modAttackSpeedPct[RANGED_ATTACK]);
- }
- }
+ if (spell && spell->GetCaster())
+ spell->GetCaster()->ModSpellCastTime(spellInfo, castTime, spell);
if (spellInfo->Attributes & SPELL_ATTR_RANGED && (!spell || !(spell->IsAutoRepeat())))
castTime += 500;
@@ -273,32 +272,21 @@ bool IsPassiveSpell(uint32 spellId)
return (spellInfo->Attributes & SPELL_ATTR_PASSIVE) != 0;
}
-/*bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2)
+bool IsAutocastableSpell(uint32 spellId)
{
- SpellEntry const *spellInfo_1 = sSpellStore.LookupEntry(spellId_1);
- SpellEntry const *spellInfo_2 = sSpellStore.LookupEntry(spellId_2);
- if(!spellInfo_1 || !spellInfo_2) return false;
- if(spellInfo_1->Id == spellId_2) return false;
-
- if (spellInfo_1->Effect[effIndex_1] != spellInfo_2->Effect[effIndex_2] ||
- spellInfo_1->EffectItemType[effIndex_1] != spellInfo_2->EffectItemType[effIndex_2] ||
- spellInfo_1->EffectMiscValue[effIndex_1] != spellInfo_2->EffectMiscValue[effIndex_2] ||
- spellInfo_1->EffectApplyAuraName[effIndex_1] != spellInfo_2->EffectApplyAuraName[effIndex_2])
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
+ if(!spellInfo)
+ return false;
+ if(spellInfo->Attributes & SPELL_ATTR_PASSIVE)
+ return false;
+ if(spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET)
return false;
-
return true;
-}*/
+}
-int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2)
+bool IsHigherHankOfSpell(uint32 spellId_1, uint32 spellId_2)
{
- SpellEntry const*spellInfo_1 = sSpellStore.LookupEntry(spellId_1);
- SpellEntry const*spellInfo_2 = sSpellStore.LookupEntry(spellId_2);
- if(!spellInfo_1 || !spellInfo_2) return 0;
- if (spellId_1 == spellId_2) return 0;
-
- int32 diff = spellInfo_1->EffectBasePoints[effIndex_1] - spellInfo_2->EffectBasePoints[effIndex_2];
- if (spellInfo_1->EffectBasePoints[effIndex_1]+1 < 0 && spellInfo_2->EffectBasePoints[effIndex_2]+1 < 0) return -diff;
- else return diff;
+ return spellmgr.GetSpellRank(spellId_1)<spellmgr.GetSpellRank(spellId_2);
}
SpellSpecific GetSpellSpecific(uint32 spellId)
@@ -315,31 +303,54 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
if (spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED)
{
for(int i = 0; i < 3; i++)
- if( spellInfo->EffectApplyAuraName[i]==SPELL_AURA_MOD_POWER_REGEN)
+ if( spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_POWER_REGEN
+ || spellInfo->EffectApplyAuraName[i] == SPELL_AURA_OBS_MOD_ENERGY)
return SPELL_DRINK;
- else if ( spellInfo->EffectApplyAuraName[i]==SPELL_AURA_MOD_REGEN)
+ else if ( spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_REGEN
+ || spellInfo->EffectApplyAuraName[i] == SPELL_AURA_OBS_MOD_HEALTH)
return SPELL_FOOD;
}
// this may be a hack
else if((spellInfo->AttributesEx2 & SPELL_ATTR_EX2_FOOD)
&& !spellInfo->Category)
return SPELL_WELL_FED;
- break;
+ // scrolls effects
+ else
+ {
+ uint32 firstSpell = spellmgr.GetFirstSpellInChain(spellInfo->Id);
+ switch (firstSpell)
+ {
+ // Strength
+ case 8118:
+ // Stamina
+ case 8099:
+ // Spirit
+ case 8112:
+ //Intellect
+ case 8096:
+ // Agility
+ case 8115:
+ // Armor
+ case 8091:
+ return SPELL_SCROLL;
+ }
+ break;
+ }
}
case SPELLFAMILY_MAGE:
{
// family flags 18(Molten), 25(Frost/Ice), 28(Mage)
- if (spellInfo->SpellFamilyFlags & 0x12040000)
+ if (spellInfo->SpellFamilyFlags[0] & 0x12040000)
return SPELL_MAGE_ARMOR;
- if ((spellInfo->SpellFamilyFlags & 0x1000000) && spellInfo->EffectApplyAuraName[0]==SPELL_AURA_MOD_CONFUSE)
+ if ((spellInfo->SpellFamilyFlags[0] & 0x1000000) && spellInfo->EffectApplyAuraName[0]==SPELL_AURA_MOD_CONFUSE)
return SPELL_MAGE_POLYMORPH;
break;
}
case SPELLFAMILY_WARRIOR:
{
- if (spellInfo->SpellFamilyFlags & 0x00008000010000LL)
+ if (spellInfo->SpellFamilyFlags[1] & 0x000080 || spellInfo->SpellFamilyFlags[0] & 0x10000LL)
return SPELL_POSITIVE_SHOUT;
break;
@@ -350,12 +361,12 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
if (spellInfo->Dispel == DISPEL_CURSE)
return SPELL_CURSE;
- // family flag 37 (only part spells have family name)
- if (spellInfo->SpellFamilyFlags & 0x2000000000LL)
+ // Warlock (Demon Armor | Demon Skin | Fel Armor)
+ if (spellInfo->SpellFamilyFlags[1] & 0x20000020 || spellInfo->SpellFamilyFlags[2] & 0x00000010)
return SPELL_WARLOCK_ARMOR;
//seed of corruption and corruption
- if (spellInfo->SpellFamilyFlags & 0x1000000002LL)
+ if (spellInfo->SpellFamilyFlags[1] & 0x10 || spellInfo->SpellFamilyFlags[0] & 0x2)
return SPELL_WARLOCK_CORRUPTION;
break;
}
@@ -365,6 +376,10 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
if (spellInfo->Dispel == DISPEL_POISON)
return SPELL_STING;
+ // only hunter aspects have this
+ if( spellInfo->SpellFamilyFlags[1] & 0x00440000 || spellInfo->SpellFamilyFlags[0] & 0x00380000 || spellInfo->SpellFamilyFlags[2] & 0x00001010)
+ return SPELL_ASPECT;
+
break;
}
case SPELLFAMILY_PALADIN:
@@ -372,16 +387,16 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
if (IsSealSpell(spellInfo))
return SPELL_SEAL;
- if (spellInfo->SpellFamilyFlags & 0x10000100LL)
+ if (spellInfo->SpellFamilyFlags[0] & 0x11010002)
return SPELL_BLESSING;
- if ((spellInfo->SpellFamilyFlags & 0x00000820180400LL) && (spellInfo->AttributesEx3 & 0x200))
+ if ((spellInfo->SpellFamilyFlags[1] & 0x000008 || spellInfo->SpellFamilyFlags[0] & 0x20180400) && (spellInfo->AttributesEx3 & 0x200))
return SPELL_JUDGEMENT;
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 3; ++i)
{
- // only paladin auras have this
- if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY)
+ // only paladin auras have this (for palaldin class family)
+ if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID)
return SPELL_AURA;
}
break;
@@ -396,19 +411,11 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
case SPELLFAMILY_POTION:
return spellmgr.GetSpellElixirSpecific(spellInfo->Id);
- }
- // only warlock armor/skin have this (in additional to family cases)
- if( spellInfo->SpellVisual == 130 && spellInfo->SpellIconID == 89)
- {
- return SPELL_WARLOCK_ARMOR;
- }
-
- // only hunter aspects have this (but not all aspects in hunter family)
- if( spellInfo->activeIconID == 122 && (GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_NATURE) &&
- (spellInfo->Attributes & 0x50000) != 0 && (spellInfo->Attributes & 0x9000010) == 0)
- {
- return SPELL_ASPECT;
+ case SPELLFAMILY_DEATHKNIGHT:
+ if ((spellInfo->Attributes & 0x10) && (spellInfo->AttributesEx2 & 0x10) && (spellInfo->AttributesEx4 & 0x200000))
+ return SPELL_PRESENCE;
+ break;
}
for(int i = 0; i < 3; ++i)
@@ -417,18 +424,17 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
{
switch(spellInfo->EffectApplyAuraName[i])
{
- case SPELL_AURA_TRACK_CREATURES:
- case SPELL_AURA_TRACK_RESOURCES:
- case SPELL_AURA_TRACK_STEALTHED:
- return SPELL_TRACKER;
case SPELL_AURA_MOD_CHARM:
case SPELL_AURA_MOD_POSSESS_PET:
case SPELL_AURA_MOD_POSSESS:
return SPELL_CHARM;
+ case SPELL_AURA_TRACK_CREATURES:
+ case SPELL_AURA_TRACK_RESOURCES:
+ case SPELL_AURA_TRACK_STEALTHED:
+ return SPELL_TRACKER;
}
}
}
-
// elixirs can have different families, but potion most ofc.
if(SpellSpecific sp = spellmgr.GetSpellElixirSpecific(spellInfo->Id))
return sp;
@@ -464,10 +470,12 @@ bool IsSingleFromSpellSpecificPerTarget(uint32 spellSpec1,uint32 spellSpec2)
case SPELL_MAGE_ARMOR:
case SPELL_ELEMENTAL_SHIELD:
case SPELL_MAGE_POLYMORPH:
+ case SPELL_PRESENCE:
case SPELL_WELL_FED:
case SPELL_DRINK:
case SPELL_FOOD:
case SPELL_CHARM:
+ case SPELL_SCROLL:
return spellSpec1==spellSpec2;
case SPELL_BATTLE_ELIXIR:
return spellSpec2==SPELL_BATTLE_ELIXIR
@@ -497,8 +505,6 @@ bool IsPositiveTarget(uint32 targetA, uint32 targetB)
case TARGET_CURRENT_ENEMY_COORDINATES:
case TARGET_UNIT_CHANNEL:
return false;
- case TARGET_ALL_AROUND_CASTER:
- return (targetB == TARGET_ALL_PARTY || targetB == TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER);
default:
break;
}
@@ -507,27 +513,31 @@ bool IsPositiveTarget(uint32 targetA, uint32 targetB)
return true;
}
-bool IsPositiveEffect(uint32 spellId, uint32 effIndex)
+bool IsPositiveEffect(uint32 spellId, uint32 effIndex, bool deep)
{
SpellEntry const *spellproto = sSpellStore.LookupEntry(spellId);
if (!spellproto) return false;
switch(spellId)
{
- case 23333: // BG spell
- case 23335: // BG spell
- case 34976: // BG spell
- case 31579: // Arcane Empowerment Rank1 talent aura with one positive and one negative (check not needed in wotlk)
- case 31582: // Arcane Empowerment Rank2
- case 31583: // Arcane Empowerment Rank3
- return true;
case 28441: // not positive dummy spell
case 37675: // Chaos Blast
case 41519: // Mark of Stormrage
case 34877: // Custodian of Time
case 34700: // Allergic Reaction
case 31719: // Suspension
+ case 61987: // Avenging Wrath Marker
return false;
+ case 12042: // Arcane Power
+ return true;
+ }
+
+ switch(spellproto->Mechanic)
+ {
+ case MECHANIC_IMMUNE_SHIELD:
+ return true;
+ default:
+ break;
}
switch(spellproto->Effect[effIndex])
@@ -553,6 +563,7 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex)
{
case 13139: // net-o-matic special effect
case 23445: // evil twin
+ case 35679: // Protectorate Demolitionist
case 38637: // Nether Exhaustion (red)
case 38638: // Nether Exhaustion (green)
case 38639: // Nether Exhaustion (blue)
@@ -564,15 +575,17 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex)
case SPELL_AURA_MOD_STAT:
case SPELL_AURA_MOD_DAMAGE_DONE: // dependent from bas point sign (negative -> negative)
case SPELL_AURA_MOD_HEALING_DONE:
+ case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE:
{
- if(spellproto->EffectBasePoints[effIndex]+int32(spellproto->EffectBaseDice[effIndex]) < 0)
+ if(spellproto->CalculateSimpleValue(effIndex) < 0)
return false;
break;
}
case SPELL_AURA_ADD_TARGET_TRIGGER:
return true;
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
- if(spellId != spellproto->EffectTriggerSpell[effIndex])
+ if(!deep)
{
uint32 spellTriggeredId = spellproto->EffectTriggerSpell[effIndex];
SpellEntry const *spellTriggeredProto = sSpellStore.LookupEntry(spellTriggeredId);
@@ -582,14 +595,15 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex)
// non-positive targets of main spell return early
for(int i = 0; i < 3; ++i)
{
+ if (!spellTriggeredProto->Effect[i])
+ continue;
// if non-positive trigger cast targeted to positive target this main cast is non-positive
// this will place this spell auras as debuffs
- if(IsPositiveTarget(spellTriggeredProto->EffectImplicitTargetA[effIndex],spellTriggeredProto->EffectImplicitTargetB[effIndex]) && !IsPositiveEffect(spellTriggeredId,i))
+ if(IsPositiveTarget(spellTriggeredProto->EffectImplicitTargetA[effIndex],spellTriggeredProto->EffectImplicitTargetB[effIndex]) && !IsPositiveEffect(spellTriggeredId,i, true))
return false;
}
}
}
- break;
case SPELL_AURA_PROC_TRIGGER_SPELL:
// many positive auras have negative triggered spells at damage for example and this not make it negative (it can be canceled for example)
break;
@@ -663,19 +677,35 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex)
switch(spellproto->EffectMiscValue[effIndex])
{
case SPELLMOD_COST: // dependent from bas point sign (negative -> positive)
- if(spellproto->EffectBasePoints[effIndex]+int32(spellproto->EffectBaseDice[effIndex]) > 0)
- return false;
+ if(spellproto->CalculateSimpleValue(effIndex) > 0)
+ {
+ if (!deep)
+ {
+ bool negative = true;
+ for (uint8 i=0;i<MAX_SPELL_EFFECTS;++i)
+ {
+ if (i != effIndex)
+ if (IsPositiveEffect(spellId, i, true))
+ {
+ negative = false;
+ break;
+ }
+ }
+ if (negative)
+ return false;
+ }
+ }
break;
default:
break;
}
} break;
case SPELL_AURA_MOD_HEALING_PCT:
- if(spellproto->EffectBasePoints[effIndex]+int32(spellproto->EffectBaseDice[effIndex]) < 0)
+ if(spellproto->CalculateSimpleValue(effIndex) < 0)
return false;
break;
case SPELL_AURA_MOD_SKILL:
- if(spellproto->EffectBasePoints[effIndex]+int32(spellproto->EffectBaseDice[effIndex]) < 0)
+ if(spellproto->CalculateSimpleValue(effIndex) < 0)
return false;
break;
case SPELL_AURA_FORCE_REACTION:
@@ -699,23 +729,47 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex)
if(spellproto->AttributesEx & SPELL_ATTR_EX_NEGATIVE)
return false;
+ if (!deep && spellproto->EffectTriggerSpell[effIndex]
+ && !spellproto->EffectApplyAuraName[effIndex]
+ && IsPositiveTarget(spellproto->EffectImplicitTargetA[effIndex],spellproto->EffectImplicitTargetB[effIndex])
+ && !IsPositiveSpell(spellproto->EffectTriggerSpell[effIndex], true))
+ return false;
+
// ok, positive
return true;
}
-bool IsPositiveSpell(uint32 spellId)
+bool IsPositiveSpell(uint32 spellId, bool deep)
{
SpellEntry const *spellproto = sSpellStore.LookupEntry(spellId);
if (!spellproto) return false;
// spells with at least one negative effect are considered negative
// some self-applied spells have negative effects but in self casting case negative check ignored.
- for (int i = 0; i < 3; i++)
- if (!IsPositiveEffect(spellId, i))
+ for (int i = 0; i < 3; ++i)
+ if (!IsPositiveEffect(spellId, i, deep))
return false;
return true;
}
+bool IsDispelableBySpell(SpellEntry const * dispelSpell, uint32 spellId, bool def)
+{
+ if (!dispelSpell) return false;
+ SpellEntry const *spellproto = sSpellStore.LookupEntry(spellId);
+ if (!spellproto) return false;
+
+ if (spellproto->Mechanic == MECHANIC_IMMUNE_SHIELD)
+ {
+ if (dispelSpell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)
+ {
+ return true;
+ }
+ else
+ return false;
+ }
+ return def;
+}
+
bool IsSingleTargetSpell(SpellEntry const *spellInfo)
{
// all other single target spells have if it has AttributesEx5
@@ -766,19 +820,19 @@ bool IsAuraAddedBySpell(uint32 auraType, uint32 spellId)
SpellEntry const *spellproto = sSpellStore.LookupEntry(spellId);
if (!spellproto) return false;
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 3; ++i)
if (spellproto->EffectApplyAuraName[i] == auraType)
return true;
return false;
}
-uint8 GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form)
+SpellCastResult GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form)
{
// talents that learn spells can have stance requirements that need ignore
// (this requirement only for client-side stance show in talent description)
if( GetTalentSpellCost(spellInfo->Id) > 0 &&
(spellInfo->Effect[0]==SPELL_EFFECT_LEARN_SPELL || spellInfo->Effect[1]==SPELL_EFFECT_LEARN_SPELL || spellInfo->Effect[2]==SPELL_EFFECT_LEARN_SPELL) )
- return 0;
+ return SPELL_CAST_OK;
uint32 stanceMask = (form ? 1 << (form - 1) : 0);
@@ -786,7 +840,7 @@ uint8 GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form)
return SPELL_FAILED_NOT_SHAPESHIFT;
if (stanceMask & spellInfo->Stances) // can explicitly be casted in this stance
- return 0;
+ return SPELL_CAST_OK;
bool actAsShifted = false;
if (form > 0)
@@ -795,7 +849,7 @@ uint8 GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form)
if (!shapeInfo)
{
sLog.outError("GetErrorAtShapeshiftedCast: unknown shapeshift %u", form);
- return 0;
+ return SPELL_CAST_OK;
}
actAsShifted = !(shapeInfo->flags1 & 1); // shapeshift acts as normal form for spells
}
@@ -814,7 +868,7 @@ uint8 GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form)
return SPELL_FAILED_ONLY_SHAPESHIFT;
}
- return 0;
+ return SPELL_CAST_OK;
}
void SpellMgr::LoadSpellTargetPositions()
@@ -908,8 +962,8 @@ void SpellMgr::LoadSpellAffects()
uint32 count = 0;
- // 0 1 2
- QueryResult *result = WorldDatabase.Query("SELECT entry, effectId, SpellFamilyMask FROM spell_affect");
+ // 0 1 2 3 4
+ QueryResult *result = WorldDatabase.Query("SELECT entry, effectId, SpellClassMask0, SpellClassMask1, SpellClassMask2 FROM spell_affect");
if( !result )
{
@@ -956,26 +1010,22 @@ void SpellMgr::LoadSpellAffects()
continue;
}
- uint64 spellAffectMask = fields[2].GetUInt64();
+ flag96 affect(fields[2].GetUInt32(), fields[3].GetUInt32(), fields[4].GetUInt32());
- // Spell.dbc have own data for low part of SpellFamilyMask
- if( spellInfo->EffectItemType[effectId])
- {
- if(spellInfo->EffectItemType[effectId] == spellAffectMask)
- {
- sLog.outErrorDb("Spell %u listed in `spell_affect` have redundant (same with EffectItemType%d) data for effect index (%u) and not needed, skipped.", entry,effectId+1,effectId);
- continue;
- }
+ // Spell.dbc have own data
+ if (effectId>3)
+ continue;
- // 24429 have wrong data in EffectItemType and overwrites by DB, possible bug in client
- if(spellInfo->Id!=24429 && spellInfo->EffectItemType[effectId] != spellAffectMask)
- {
- sLog.outErrorDb("Spell %u listed in `spell_affect` have different low part from EffectItemType%d for effect index (%u) and not needed, skipped.", entry,effectId+1,effectId);
- continue;
- }
+ flag96 dbc_affect;
+ dbc_affect = spellInfo->EffectSpellClassMask[effectId];
+ if(dbc_affect[0] == affect[0] || dbc_affect[1] == affect[1] || dbc_affect[2] == affect[2])
+ {
+ char text[]="ABC";
+ sLog.outErrorDb("Spell %u listed in `spell_affect` have redundant (same with EffectSpellClassMask%c) data for effect index (%u) and not needed, skipped.", entry, text[effectId], effectId);
+ continue;
}
- mSpellAffectMap.insert(SpellAffectMap::value_type((entry<<8) + effectId,spellAffectMask));
+ mSpellAffectMap[(entry<<8) + effectId] = affect;
++count;
} while( result->NextRow() );
@@ -983,7 +1033,7 @@ void SpellMgr::LoadSpellAffects()
delete result;
sLog.outString();
- sLog.outString( ">> Loaded %u spell affect definitions", count );
+ sLog.outString( ">> Loaded %u custom spell affect definitions", count );
for (uint32 id = 0; id < sSpellStore.GetNumRows(); ++id)
{
@@ -999,7 +1049,9 @@ void SpellMgr::LoadSpellAffects()
spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_TARGET_TRIGGER) )
continue;
- if(spellInfo->EffectItemType[effectId] != 0)
+ flag96 dbc_affect;
+ dbc_affect = spellInfo->EffectSpellClassMask[effectId];
+ if(dbc_affect)
continue;
if(mSpellAffectMap.find((id<<8) + effectId) != mSpellAffectMap.end())
@@ -1010,33 +1062,19 @@ void SpellMgr::LoadSpellAffects()
}
}
-bool SpellMgr::IsAffectedBySpell(SpellEntry const *spellInfo, uint32 spellId, uint8 effectId, uint64 familyFlags) const
+bool SpellMgr::IsAffectedByMod(SpellEntry const *spellInfo, SpellModifier *mod) const
{
// false for spellInfo == NULL
- if (!spellInfo)
+ if (!spellInfo || !mod)
return false;
- SpellEntry const *affect_spell = sSpellStore.LookupEntry(spellId);
- // false for affect_spell == NULL
- if (!affect_spell)
+ SpellEntry const *affect_spell = sSpellStore.LookupEntry(mod->spellId);
+ // False if affect_spell == NULL or spellFamily not equal
+ if (!affect_spell || affect_spell->SpellFamilyName != spellInfo->SpellFamilyName)
return false;
- // False if spellFamily not equal
- if (affect_spell->SpellFamilyName != spellInfo->SpellFamilyName)
- return false;
-
- // If familyFlags == 0
- if (!familyFlags)
- {
- // Get it from spellAffect table
- familyFlags = GetSpellAffectMask(spellId,effectId);
- // false if familyFlags == 0
- if (!familyFlags)
- return false;
- }
-
// true
- if (familyFlags & spellInfo->SpellFamilyFlags)
+ if (mod->mask & spellInfo->SpellFamilyFlags)
return true;
return false;
@@ -1048,15 +1086,12 @@ void SpellMgr::LoadSpellProcEvents()
uint32 count = 0;
- // 0 1 2 3 4 5 6 7 8
- QueryResult *result = WorldDatabase.Query("SELECT entry, SchoolMask, SpellFamilyName, SpellFamilyMask, procFlags, procEx, ppmRate, CustomChance, Cooldown FROM spell_proc_event");
+ // 0 1 2 3 4 5 6 7 8 9 10
+ QueryResult *result = WorldDatabase.Query("SELECT entry, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, procFlags, procEx, ppmRate, CustomChance, Cooldown FROM spell_proc_event");
if( !result )
{
-
barGoLink bar( 1 );
-
bar.step();
-
sLog.outString();
sLog.outString( ">> Loaded %u spell proc event conditions", count );
return;
@@ -1070,7 +1105,7 @@ void SpellMgr::LoadSpellProcEvents()
bar.step();
- uint16 entry = fields[0].GetUInt16();
+ uint32 entry = fields[0].GetUInt32();
const SpellEntry *spell = sSpellStore.LookupEntry(entry);
if (!spell)
@@ -1083,12 +1118,14 @@ void SpellMgr::LoadSpellProcEvents()
spe.schoolMask = fields[1].GetUInt32();
spe.spellFamilyName = fields[2].GetUInt32();
- spe.spellFamilyMask = fields[3].GetUInt64();
- spe.procFlags = fields[4].GetUInt32();
- spe.procEx = fields[5].GetUInt32();
- spe.ppmRate = fields[6].GetFloat();
- spe.customChance = fields[7].GetFloat();
- spe.cooldown = fields[8].GetUInt32();
+ spe.spellFamilyMask[0] = fields[3].GetUInt32();
+ spe.spellFamilyMask[1] = fields[4].GetUInt32();
+ spe.spellFamilyMask[2] = fields[5].GetUInt32();
+ spe.procFlags = fields[6].GetUInt32();
+ spe.procEx = fields[7].GetUInt32();
+ spe.ppmRate = fields[8].GetFloat();
+ spe.customChance = fields[9].GetFloat();
+ spe.cooldown = fields[10].GetUInt32();
mSpellProcEventMap[entry] = spe;
@@ -1108,82 +1145,56 @@ void SpellMgr::LoadSpellProcEvents()
sLog.outString();
if (customProc)
- sLog.outString( ">> Loaded %u custom spell proc event conditions +%u custom", count, customProc );
+ sLog.outString( ">> Loaded %u extra spell proc event conditions +%u custom", count, customProc );
else
- sLog.outString( ">> Loaded %u spell proc event conditions", count );
+ sLog.outString( ">> Loaded %u extra spell proc event conditions", count );
+}
- /*
- // Commented for now, as it still produces many errors (still quite many spells miss spell_proc_event)
- for (uint32 id = 0; id < sSpellStore.GetNumRows(); ++id)
+void SpellMgr::LoadSpellBonusess()
+{
+ mSpellBonusMap.clear(); // need for reload case
+ uint32 count = 0;
+ // 0 1 2 3
+ QueryResult *result = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus FROM spell_bonus_data");
+ if( !result )
{
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(id);
- if (!spellInfo)
- continue;
-
- bool found = false;
- for (int effectId = 0; effectId < 3; ++effectId)
- {
- // at this moment check only SPELL_AURA_PROC_TRIGGER_SPELL
- if( spellInfo->EffectApplyAuraName[effectId] == SPELL_AURA_PROC_TRIGGER_SPELL )
- {
- found = true;
- break;
- }
- }
+ barGoLink bar( 1 );
+ bar.step();
+ sLog.outString();
+ sLog.outString( ">> Loaded %u spell bonus data", count);
+ return;
+ }
- if(!found)
- continue;
+ barGoLink bar( result->GetRowCount() );
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+ uint32 entry = fields[0].GetUInt32();
- if(GetSpellProcEvent(id))
+ const SpellEntry *spell = sSpellStore.LookupEntry(entry);
+ if (!spell)
+ {
+ sLog.outErrorDb("Spell %u listed in `spell_bonus_data` does not exist", entry);
continue;
+ }
- sLog.outErrorDb("Spell %u (%s) misses spell_proc_event",id,spellInfo->SpellName[sWorld.GetDBClang()]);
- }
- */
-}
-
-/*
-bool SpellMgr::IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, SpellEntry const * procSpell, uint32 procFlags )
-{
- if((procFlags & spellProcEvent->procFlags) == 0)
- return false;
+ SpellBonusEntry sbe;
- // Additional checks in case spell cast/hit/crit is the event
- // Check (if set) school, category, skill line, spell talent mask
- if(spellProcEvent->schoolMask && (!procSpell || (GetSpellSchoolMask(procSpell) & spellProcEvent->schoolMask) == 0))
- return false;
- if(spellProcEvent->category && (!procSpell || procSpell->Category != spellProcEvent->category))
- return false;
- if(spellProcEvent->skillId)
- {
- if (!procSpell)
- return false;
+ sbe.direct_damage = fields[1].GetFloat();
+ sbe.dot_damage = fields[2].GetFloat();
+ sbe.ap_bonus = fields[3].GetFloat();
- SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(procSpell->Id);
- SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(procSpell->Id);
+ mSpellBonusMap[entry] = sbe;
+ } while( result->NextRow() );
- bool found = false;
- for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
- {
- if(_spell_idx->second->skillId == spellProcEvent->skillId)
- {
- found = true;
- break;
- }
- }
- if (!found)
- return false;
- }
- if(spellProcEvent->spellFamilyName && (!procSpell || spellProcEvent->spellFamilyName != procSpell->SpellFamilyName))
- return false;
- if(spellProcEvent->spellFamilyMask && (!procSpell || (spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags) == 0))
- return false;
+ delete result;
- return true;
+ sLog.outString();
+ sLog.outString( ">> Loaded %u extra spell bonus data", count);
}
-*/
-bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active)
+bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active)
{
// No extra req need
uint32 procEvent_procEx = PROC_EX_NONE;
@@ -1193,9 +1204,8 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellP
return false;
// Always trigger for this
- if (EventProcFlag & (PROC_FLAG_KILLED | PROC_FLAG_KILL_AND_GET_XP))
+ if (EventProcFlag & (PROC_FLAG_KILLED | PROC_FLAG_KILL | PROC_FLAG_ON_TRAP_ACTIVATION))
return true;
-
if (spellProcEvent) // Exist event data
{
// Store extra req
@@ -1210,6 +1220,12 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellP
}
else // For spells need check school/spell family/family mask
{
+ // Item cast can trigger only with spells with spellfamily
+ if (procExtra & PROC_EX_INTERNAL_ITEM_CAST)
+ {
+ if (!spellProcEvent->spellFamilyName)
+ return false;
+ }
// Check (if set) for school
if(spellProcEvent->schoolMask && (spellProcEvent->schoolMask & procSpell->SchoolMask) == 0)
return false;
@@ -1221,12 +1237,16 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellP
// spellFamilyName is Ok need check for spellFamilyMask if present
if(spellProcEvent->spellFamilyMask)
{
- if ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags) == 0)
+ if ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags ) == 0)
return false;
active = true; // Spell added manualy -> so its active spell
}
}
}
+ // Item cast can trigger only with spells with spellfamily
+ else if (procExtra & PROC_EX_INTERNAL_ITEM_CAST)
+ return false;
+
// Check for extra req (if none) and hit/crit
if (procEvent_procEx == PROC_EX_NONE)
{
@@ -1237,7 +1257,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellP
else // Passive spells hits here only if resist/reflect/immune/evade
{
// Exist req for PROC_EX_EX_TRIGGER_ALWAYS
- if (procEvent_procEx & PROC_EX_EX_TRIGGER_ALWAYS)
+ if ((procExtra & AURA_SPELL_PROC_EX_MASK) && (procEvent_procEx & PROC_EX_EX_TRIGGER_ALWAYS))
return true;
// Passive spells can`t trigger if need hit
if ((procEvent_procEx & PROC_EX_NORMAL_HIT) && !active)
@@ -1320,36 +1340,44 @@ bool SpellMgr::IsRankSpellDueToSpell(SpellEntry const *spellInfo_1,uint32 spellI
bool SpellMgr::canStackSpellRanks(SpellEntry const *spellInfo)
{
+ if(IsPassiveSpell(spellInfo->Id)) // ranked passive spell
+ return false;
if(spellInfo->powerType != POWER_MANA && spellInfo->powerType != POWER_HEALTH)
return false;
- if(IsProfessionSpell(spellInfo->Id))
+ if(IsProfessionOrRidingSpell(spellInfo->Id))
+ return false;
+
+ if(spellmgr.IsSkillBonusSpell(spellInfo->Id))
return false;
// All stance spells. if any better way, change it.
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 3; ++i)
{
- // Paladin aura Spell
- if(spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN
- && spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AREA_AURA_PARTY)
- return false;
- // Druid form Spell
- if(spellInfo->SpellFamilyName == SPELLFAMILY_DRUID
- && spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA
- && spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
- return false;
- // Rogue Stealth
- if(spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE
- && spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA
- && spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
- return false;
+ switch(spellInfo->SpellFamilyName)
+ {
+ case SPELLFAMILY_PALADIN:
+ // Paladin aura Spell
+ if (spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AREA_AURA_RAID)
+ return false;
+ break;
+ case SPELLFAMILY_DRUID:
+ // Druid form Spell
+ if (spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA &&
+ spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
+ return false;
+ break;
+ case SPELLFAMILY_ROGUE:
+ // Rogue Stealth
+ if (spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA &&
+ spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
+ return false;
+ }
}
return true;
}
bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool sameCaster) const
{
- //if(spellId_1 == spellId_2) // auras due to the same spell
- // return false;
SpellEntry const *spellInfo_1 = sSpellStore.LookupEntry(spellId_1);
SpellEntry const *spellInfo_2 = sSpellStore.LookupEntry(spellId_2);
@@ -1363,29 +1391,9 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool
||(IsSingleFromSpellSpecificPerCaster(spellId_spec_1, spellId_spec_2) && sameCaster))
return true;
- // spells with different specific always stack
- if(spellId_spec_1 || spellId_spec_2)
- return false;
-
if(spellInfo_1->SpellFamilyName != spellInfo_2->SpellFamilyName)
return false;
- // generic spells
- if(!spellInfo_1->SpellFamilyName)
- {
- if(!spellInfo_1->SpellIconID
- || spellInfo_1->SpellIconID == 1
- || spellInfo_1->SpellIconID != spellInfo_2->SpellIconID)
- return false;
- }
-
- // check for class spells
- else
- {
- if (spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags)
- return false;
- }
-
if(!sameCaster)
{
for(uint32 i = 0; i < 3; ++i)
@@ -1402,7 +1410,7 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool
case SPELL_AURA_PERIODIC_MANA_LEECH:
case SPELL_AURA_PERIODIC_LEECH:
case SPELL_AURA_POWER_BURN_MANA:
- case SPELL_AURA_OBS_MOD_MANA:
+ case SPELL_AURA_OBS_MOD_ENERGY:
case SPELL_AURA_OBS_MOD_HEALTH:
return false;
default:
@@ -1410,23 +1418,61 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool
}
}
-// not needed now because we compare effects last rank of spells
-// if(spellInfo_1->SpellFamilyName && IsRankSpellDueToSpell(spellInfo_1, spellId_2))
-// return true;
+ // hack for Incanter's Absorption
+ if (spellInfo_1->Id==44413 && spellInfo_2->Id==44413)
+ return false;
+
+ spellId_2 = GetLastSpellInChain(spellId_2);
+ spellId_1 = GetLastSpellInChain(spellId_1);
+ if (spellId_1 == spellId_2)
+ return true;
+
+ // generic spells
+ if(!spellInfo_1->SpellFamilyName)
+ {
+ if(!spellInfo_1->SpellIconID
+ || spellInfo_1->SpellIconID == 1
+ || spellInfo_1->SpellIconID != spellInfo_2->SpellIconID)
+ return false;
+ }
+ // check for class spells
+ else
+ {
+ if (spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags)
+ return false;
+ }
//use data of highest rank spell(needed for spells which ranks have different effects)
- spellInfo_1=sSpellStore.LookupEntry(GetLastSpellInChain(spellId_1));
- spellInfo_2=sSpellStore.LookupEntry(GetLastSpellInChain(spellId_2));
+ spellInfo_1=sSpellStore.LookupEntry(spellId_1);
+ spellInfo_2=sSpellStore.LookupEntry(spellId_2);
//if spells have exactly the same effect they cannot stack
for(uint32 i = 0; i < 3; ++i)
if(spellInfo_1->Effect[i] != spellInfo_2->Effect[i]
+ // Allow dummy auras stack (needed by 31666 and 58428)
+ || spellInfo_1->EffectApplyAuraName[i] == SPELL_AURA_DUMMY
+ || spellInfo_1->EffectApplyAuraName[i] == SPELL_AURA_PERIODIC_DUMMY
|| spellInfo_1->EffectApplyAuraName[i] != spellInfo_2->EffectApplyAuraName[i]
|| spellInfo_1->EffectMiscValue[i] != spellInfo_2->EffectMiscValue[i]) // paladin resist aura
return false; // need itemtype check? need an example to add that check
return true;
}
+
+bool SpellMgr::IsProfessionOrRidingSpell(uint32 spellId)
+{
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
+ if(!spellInfo)
+ return false;
+
+ if(spellInfo->Effect[1] != SPELL_EFFECT_SKILL)
+ return false;
+
+ uint32 skill = spellInfo->EffectMiscValue[1];
+
+ return IsProfessionOrRidingSkill(skill);
+}
+
bool SpellMgr::IsProfessionSpell(uint32 spellId)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
@@ -1460,6 +1506,24 @@ bool SpellMgr::IsPrimaryProfessionFirstRankSpell(uint32 spellId) const
return IsPrimaryProfessionSpell(spellId) && GetSpellRank(spellId)==1;
}
+bool SpellMgr::IsSkillBonusSpell(uint32 spellId) const
+{
+ SkillLineAbilityMap::const_iterator lower = GetBeginSkillLineAbilityMap(spellId);
+ SkillLineAbilityMap::const_iterator upper = GetEndSkillLineAbilityMap(spellId);
+
+ for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
+ {
+ SkillLineAbilityEntry const *pAbility = _spell_idx->second;
+ if (!pAbility || pAbility->learnOnGetSkill != ABILITY_LEARNED_ON_GET_PROFESSION_SKILL)
+ continue;
+
+ if(pAbility->req_skill_value > 0)
+ return true;
+ }
+
+ return false;
+}
+
SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const
{
// ignore passive spells
@@ -1467,11 +1531,12 @@ SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spell
return spellInfo;
bool needRankSelection = false;
- for(int i=0;i<3;i++)
+ for(int i=0;i<3;++i)
{
if( IsPositiveEffect(spellInfo->Id, i) && (
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA ||
- spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY
+ spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
+ spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID
) )
{
needRankSelection = true;
@@ -1546,21 +1611,31 @@ struct SpellRankEntry
uint32 RangeIndex;
uint32 SpellVisual;
uint32 ProcFlags;
- uint64 SpellFamilyFlags;
+ flag96 SpellFamilyFlags;
uint32 TargetAuraState;
uint32 ManaCost;
-
- bool operator()(const SpellRankEntry & _Left,const SpellRankEntry & _Right)const
- {
- return (_Left.SkillId != _Right.SkillId ? _Left.SkillId < _Right.SkillId
- : _Left.SpellName!=_Right.SpellName ? _Left.SpellName < _Right.SpellName
- : _Left.ProcFlags!=_Right.ProcFlags ? _Left.ProcFlags < _Right.ProcFlags
- : _Left.SpellFamilyFlags!=_Right.SpellFamilyFlags ? _Left.SpellFamilyFlags < _Right.SpellFamilyFlags
- : (_Left.SpellVisual!=_Right.SpellVisual) && (!_Left.SpellVisual || !_Right.SpellVisual) ? _Left.SpellVisual < _Right.SpellVisual
- : (_Left.ManaCost!=_Right.ManaCost) && (!_Left.ManaCost || !_Right.ManaCost) ? _Left.ManaCost < _Right.ManaCost
- : (_Left.DurationIndex!=_Right.DurationIndex) && (!_Left.DurationIndex || !_Right.DurationIndex)? _Left.DurationIndex < _Right.DurationIndex
- : (_Left.RangeIndex!=_Right.RangeIndex) && (!_Left.RangeIndex || !_Right.RangeIndex || _Left.RangeIndex==1 || !_Right.RangeIndex==1) ? _Left.RangeIndex < _Right.RangeIndex
- : _Left.TargetAuraState < _Right.TargetAuraState
+ uint32 CastingTimeIndex;
+ flag96 Effect;
+ flag96 Aura;
+ uint16 TalentID;
+
+ bool operator < (const SpellRankEntry & _Right) const
+ {
+ return (SkillId != _Right.SkillId ? SkillId < _Right.SkillId
+ : SpellName!=_Right.SpellName ? SpellName < _Right.SpellName
+ : ProcFlags!=_Right.ProcFlags ? ProcFlags < _Right.ProcFlags
+
+ : Effect!=_Right.Effect ? Effect < _Right.Effect
+ : Aura!=_Right.Aura ? Aura < _Right.Aura
+ : TalentID!=_Right.TalentID ? TalentID < _Right.TalentID
+ : (CastingTimeIndex!=_Right.CastingTimeIndex) && (!CastingTimeIndex || !_Right.CastingTimeIndex || CastingTimeIndex==1 || !_Right.CastingTimeIndex==1) ? CastingTimeIndex < _Right.CastingTimeIndex
+
+ : SpellFamilyFlags!=_Right.SpellFamilyFlags ? SpellFamilyFlags < _Right.SpellFamilyFlags
+ : (SpellVisual!=_Right.SpellVisual) && (!SpellVisual || !_Right.SpellVisual) ? SpellVisual < _Right.SpellVisual
+ : (ManaCost!=_Right.ManaCost) && (!ManaCost || !_Right.ManaCost) ? ManaCost < _Right.ManaCost
+ : (DurationIndex!=_Right.DurationIndex) && (!DurationIndex || !_Right.DurationIndex)? DurationIndex < _Right.DurationIndex
+ : (RangeIndex!=_Right.RangeIndex) && (!RangeIndex || !_Right.RangeIndex || RangeIndex==1 || !_Right.RangeIndex==1) ? RangeIndex < _Right.RangeIndex
+ : TargetAuraState < _Right.TargetAuraState
);
}
};
@@ -1569,6 +1644,7 @@ struct SpellRankValue
{
uint32 Id;
char const *Rank;
+ bool strict;
};
void SpellMgr::LoadSpellChains()
@@ -1581,14 +1657,12 @@ void SpellMgr::LoadSpellChains()
SkillLineAbilityEntry const *AbilityInfo=sSkillLineAbilityStore.LookupEntry(ability_id);
if (!AbilityInfo)
continue;
- if (AbilityInfo->spellId==20154) //exception to these rules (not needed in 3.0.3)
- continue;
if (!AbilityInfo->forward_spellid)
continue;
ChainedSpells.push_back(AbilityInfo->forward_spellid);
}
- std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry> RankMap;
+ std::multimap<SpellRankEntry, SpellRankValue> RankMap;
for (uint32 ability_id=0;ability_id<sSkillLineAbilityStore.GetNumRows();ability_id++)
{
@@ -1598,8 +1672,6 @@ void SpellMgr::LoadSpellChains()
//get only spell with lowest ability_id to prevent doubles
uint32 spell_id=AbilityInfo->spellId;
- if (spell_id==20154) //exception to these rules (not needed in 3.0.3)
- continue;
bool found=false;
for (uint32 i=0; i<ChainedSpells.size(); i++)
{
@@ -1618,7 +1690,7 @@ void SpellMgr::LoadSpellChains()
if(sRank.empty())
continue;
//exception to polymorph spells-make pig and turtle other chain than sheep
- if ((SpellInfo->SpellFamilyName==SPELLFAMILY_MAGE) && (SpellInfo->SpellFamilyFlags & 0x1000000) && (SpellInfo->SpellIconID!=82))
+ if ((SpellInfo->SpellFamilyName==SPELLFAMILY_MAGE) && (SpellInfo->SpellFamilyFlags[0] & 0x1000000) && (SpellInfo->SpellIconID!=82))
continue;
SpellRankEntry entry;
@@ -1630,14 +1702,16 @@ void SpellMgr::LoadSpellChains()
entry.ProcFlags=SpellInfo->procFlags;
entry.SpellFamilyFlags=SpellInfo->SpellFamilyFlags;
entry.TargetAuraState=SpellInfo->TargetAuraState;
- entry.SpellVisual=SpellInfo->SpellVisual;
+ entry.SpellVisual=SpellInfo->SpellVisual[0];
entry.ManaCost=SpellInfo->manaCost;
-
+ entry.CastingTimeIndex=0;
+ entry.TalentID=0;
for (;;)
{
AbilityInfo=mSkillLineAbilityMap.lower_bound(spell_id)->second;
value.Id=spell_id;
value.Rank=SpellInfo->Rank[sWorld.GetDefaultDbcLocale()];
+ value.strict=false;
RankMap.insert(std::pair<SpellRankEntry, SpellRankValue>(entry,value));
spell_id=AbilityInfo->forward_spellid;
SpellInfo=sSpellStore.LookupEntry(spell_id);
@@ -1650,48 +1724,109 @@ void SpellMgr::LoadSpellChains()
uint32 count=0;
- for (std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator itr = RankMap.begin();itr!=RankMap.end();)
+ for (std::multimap<SpellRankEntry, SpellRankValue>::iterator itr = RankMap.begin();itr!=RankMap.end();)
{
SpellRankEntry entry=itr->first;
//trac errors in extracted data
- std::multimap<char const *, std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator> RankErrorMap;
- for (std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator itr2 = RankMap.lower_bound(entry);itr2!=RankMap.upper_bound(entry);itr2++)
+ std::multimap<char const *, std::multimap<SpellRankEntry, SpellRankValue>::iterator> RankErrorMap;
+ for (std::multimap<SpellRankEntry, SpellRankValue>::iterator itr2 = RankMap.lower_bound(entry);itr2!=RankMap.upper_bound(entry);itr2++)
{
bar.step();
- RankErrorMap.insert(std::pair<char const *, std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator>(itr2->second.Rank,itr2));
+ RankErrorMap.insert(std::pair<char const *, std::multimap<SpellRankEntry, SpellRankValue>::iterator>(itr2->second.Rank,itr2));
}
- for (std::multimap<char const *, std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator>::iterator itr2 = RankErrorMap.begin();itr2!=RankErrorMap.end();)
- {
- char const * err_entry=itr2->first;
- uint32 rank_count=RankErrorMap.count(itr2->first);
- if (rank_count>1)
- for (itr2 = RankErrorMap.lower_bound(err_entry);itr2!=RankErrorMap.upper_bound(err_entry);itr2++)
+
+ bool error=false;
+ //if strict == true strict check is not needed
+ if (!itr->second.strict)
+ //check for rank duplicates, if there are any do strict check
+ for (std::multimap<char const *, std::multimap<SpellRankEntry, SpellRankValue>::iterator>::iterator itr2 = RankErrorMap.begin();itr2!=RankErrorMap.end();)
{
- sLog.outDebug("There is a duplicate rank entry (%s) for spell: %u",itr2->first,itr2->second->second.Id);
- sLog.outDebug("Spell %u removed from chain data.",itr2->second->second.Id);
- RankMap.erase(itr2->second);
- itr=RankMap.lower_bound(entry);
+ char const * err_entry=itr2->first;
+ uint32 rank_count=RankErrorMap.count(itr2->first);
+ if (rank_count>1)
+ {
+ error=true;
+ break;
+ }
+ else
+ itr2++;
}
- else
- itr2++;
- }
- //do not proceed for spells with less than 2 ranks
- uint32 spell_max_rank=RankMap.count(entry);
- if (spell_max_rank<2)
+ bool allHaveTalents=true;
+ if (error)
{
- itr=RankMap.upper_bound(entry);
+ std::list<uint32> ConflictedSpells;
+ for (std::multimap<SpellRankEntry, SpellRankValue>::iterator itr2 = RankMap.lower_bound(entry);itr2!=RankMap.upper_bound(entry);itr2=RankMap.lower_bound(entry))
+ {
+ ConflictedSpells.push_back(itr2->second.Id);
+ if (!GetTalentSpellPos(itr2->second.Id))
+ allHaveTalents=false;
+ RankMap.erase(itr2);
+ }
+ SpellRankEntry nextEntry, currEntry;
+ for (;!ConflictedSpells.empty();ConflictedSpells.pop_front())
+ {
+ SpellEntry const *SpellInfo=sSpellStore.LookupEntry(ConflictedSpells.front());
+ currEntry.SkillId=entry.SkillId;
+ currEntry.SpellName=SpellInfo->SpellName[sWorld.GetDefaultDbcLocale()];
+ currEntry.DurationIndex=SpellInfo->DurationIndex;
+ currEntry.RangeIndex=SpellInfo->rangeIndex;
+ currEntry.ProcFlags=SpellInfo->procFlags;
+ currEntry.SpellFamilyFlags=SpellInfo->SpellFamilyFlags;
+ //compare talents only when all spells from chain have entry
+ //to prevent wrong results with spells which have first rank talented and other not
+ if (allHaveTalents)
+ currEntry.TalentID=GetTalentSpellPos(ConflictedSpells.front())->talent_id;
+ else
+ currEntry.TalentID=0;
+ currEntry.TargetAuraState=SpellInfo->TargetAuraState;
+ currEntry.SpellVisual=SpellInfo->SpellVisual[0];
+ currEntry.ManaCost=SpellInfo->manaCost;
+
+ //compare effects and casting time
+ currEntry.CastingTimeIndex=SpellInfo->CastingTimeIndex;
+ currEntry.Effect[0]=SpellInfo->Effect[0];
+ currEntry.Effect[1]=SpellInfo->Effect[1];
+ currEntry.Effect[2]=SpellInfo->Effect[2];
+
+ currEntry.Aura[0]=SpellInfo->EffectApplyAuraName[0];
+ currEntry.Aura[1]=SpellInfo->EffectApplyAuraName[1];
+ currEntry.Aura[2]=SpellInfo->EffectApplyAuraName[2];
+
+ SpellRankValue currValue;
+ currValue.Id=ConflictedSpells.front();
+ currValue.Rank=SpellInfo->Rank[sWorld.GetDefaultDbcLocale()];
+ currValue.strict=true;
+ RankMap.insert(std::pair<SpellRankEntry, SpellRankValue>(currEntry,currValue));
+ }
+ itr=RankMap.begin();
continue;
}
+ else
+ for (std::multimap<char const *, std::multimap<SpellRankEntry, SpellRankValue>::iterator>::iterator itr2 = RankErrorMap.begin();itr2!=RankErrorMap.end();)
+ {
+ char const * err_entry=itr2->first;
+ uint32 rank_count=RankErrorMap.count(itr2->first);
+ if (rank_count>1)
+ for (itr2 = RankErrorMap.lower_bound(err_entry);itr2!=RankErrorMap.upper_bound(err_entry);itr2++)
+ {
+ sLog.outDebug("There is a duplicate rank entry (%s) for spell: %u",itr2->first,itr2->second->second.Id);
+ if (!(itr2->second->second.Id==52375 || itr2->second->second.Id==45902))
+ {
+ sLog.outDebug("Spell %u removed from chain data.",itr2->second->second.Id);
+ RankMap.erase(itr2->second);
+ }
+ }
+ else
+ itr2++;
+ }
- itr=RankMap.upper_bound(entry);
-
- //order spells by spells by spellLevel
+ //order spells by spellLevel
std::list<uint32> RankedSpells;
uint32 min_spell_lvl=0;
- std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator min_itr;
+ std::multimap<SpellRankEntry, SpellRankValue>::iterator min_itr;
for (;RankMap.count(entry);)
{
- for (std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator itr2 = RankMap.lower_bound(entry);itr2!=RankMap.upper_bound(entry);itr2++)
+ for (std::multimap<SpellRankEntry, SpellRankValue>::iterator itr2 = RankMap.lower_bound(entry);itr2!=RankMap.upper_bound(entry);itr2++)
{
SpellEntry const *SpellInfo=sSpellStore.LookupEntry(itr2->second.Id);
if (SpellInfo->spellLevel<min_spell_lvl || itr2==RankMap.lower_bound(entry))
@@ -1727,9 +1862,13 @@ void SpellMgr::LoadSpellChains()
}
}
+ //do not proceed for spells with less than 2 ranks
+ itr=RankMap.begin();
+ if (RankedSpells.size()<2)
+ continue;
+
count++;
- itr=RankMap.upper_bound(entry);
uint32 spell_rank=1;
for(std::list<uint32>::iterator itr2 = RankedSpells.begin();itr2!=RankedSpells.end();spell_rank++)
{
@@ -1753,8 +1892,8 @@ void SpellMgr::LoadSpellChains()
}
//uncomment these two lines to print yourself list of spell_chains on startup
-// for (UNORDERED_MAP<uint32, SpellChainNode>::iterator itr=mSpellChains.begin();itr!=mSpellChains.end();itr++)
-// sLog.outString( "Id: %u, Rank: %d , %s",itr->first,itr->second.rank, sSpellStore.LookupEntry(itr->first)->Rank[sWorld.GetDefaultDbcLocale()]);
+ //for (UNORDERED_MAP<uint32, SpellChainNode>::iterator itr=mSpellChains.begin();itr!=mSpellChains.end();itr++)
+ //sLog.outString( "Id: %u, Rank: %d , %s, %u, %u, %u, %u",itr->first,itr->second.rank, sSpellStore.LookupEntry(itr->first)->Rank[sWorld.GetDefaultDbcLocale()], itr->second.first, itr->second.last,itr->second.next ,itr->second.prev);
sLog.outString();
sLog.outString( ">> Loaded %u spell chains",count);
@@ -1766,8 +1905,10 @@ void SpellMgr::LoadSpellLearnSkills()
// search auto-learned skills and add its to map also for use in unlearn spells/talents
uint32 dbc_count = 0;
+ barGoLink bar( sSpellStore.GetNumRows() );
for(uint32 spell = 0; spell < sSpellStore.GetNumRows(); ++spell)
{
+ bar.step();
SpellEntry const* entry = sSpellStore.LookupEntry(spell);
if(!entry)
@@ -1780,10 +1921,10 @@ void SpellMgr::LoadSpellLearnSkills()
SpellLearnSkillNode dbc_node;
dbc_node.skill = entry->EffectMiscValue[i];
if ( dbc_node.skill != SKILL_RIDING )
- dbc_node.value = 1;
+ dbc_node.value = 1;
else
- dbc_node.value = (entry->EffectBasePoints[i]+1)*75;
- dbc_node.maxvalue = (entry->EffectBasePoints[i]+1)*75;
+ dbc_node.value = entry->CalculateSimpleValue(i)*75;
+ dbc_node.maxvalue = entry->CalculateSimpleValue(i)*75;
SpellLearnSkillNode const* db_node = GetSpellLearnSkill(spell);
@@ -1802,7 +1943,8 @@ void SpellMgr::LoadSpellLearnSpells()
{
mSpellLearnSpells.clear(); // need for reload case
- QueryResult *result = WorldDatabase.Query("SELECT entry, SpellID FROM spell_learn_spell");
+ // 0 1 2
+ QueryResult *result = WorldDatabase.Query("SELECT entry, SpellID, Active FROM spell_learn_spell");
if(!result)
{
barGoLink bar( 1 );
@@ -1826,6 +1968,7 @@ void SpellMgr::LoadSpellLearnSpells()
SpellLearnSpellNode node;
node.spell = fields[1].GetUInt32();
+ node.active = fields[2].GetBool();
node.autoLearned= false;
if(!sSpellStore.LookupEntry(spell_id))
@@ -1862,7 +2005,16 @@ void SpellMgr::LoadSpellLearnSpells()
{
SpellLearnSpellNode dbc_node;
dbc_node.spell = entry->EffectTriggerSpell[i];
- dbc_node.autoLearned = true;
+ dbc_node.active = true; // all dbc based learned spells is active (show in spell book or hide by client itself)
+
+ // ignore learning not existed spells (broken/outdated/or generic learnig spell 483
+ if(!sSpellStore.LookupEntry(dbc_node.spell))
+ continue;
+
+ // talent or passive spells or skill-step spells auto-casted and not need dependent learning,
+ // pet teaching spells don't must be dependent learning (casted)
+ // other required explicit dependent learning
+ dbc_node.autoLearned = entry->EffectImplicitTargetA[i]==TARGET_PET || GetTalentSpellCost(spell) > 0 || IsPassiveSpell(spell) || IsSpellHaveEffect(entry,SPELL_EFFECT_SKILL_STEP);
SpellLearnSpellMap::const_iterator db_node_begin = GetBeginSpellLearnSpell(spell);
SpellLearnSpellMap::const_iterator db_node_end = GetEndSpellLearnSpell(spell);
@@ -2094,7 +2246,7 @@ void SpellMgr::LoadSpellPetAuras()
continue;
}
- PetAura pa(pet, aura, spellInfo->EffectImplicitTargetA[i] == TARGET_PET, spellInfo->EffectBasePoints[i] + spellInfo->EffectBaseDice[i]);
+ PetAura pa(pet, aura, spellInfo->EffectImplicitTargetA[i] == TARGET_PET, spellInfo->CalculateSimpleValue(i));
mSpellPetAuraMap[spell] = pa;
}
@@ -2175,13 +2327,24 @@ void SpellMgr::LoadSpellCustomAttr()
spellInfo->speed = SPEED_CHARGE;
mSpellCustomAttr[i] |= SPELL_ATTR_CU_CHARGE;
case SPELL_EFFECT_TRIGGER_SPELL:
- if(spellInfo->Targets & (TARGET_FLAG_SOURCE_LOCATION|TARGET_FLAG_DEST_LOCATION))
+ if (SpellTargetType[spellInfo->EffectImplicitTargetA[j]]== TARGET_TYPE_DEST_CASTER ||
+ SpellTargetType[spellInfo->EffectImplicitTargetA[j]]== TARGET_TYPE_DEST_TARGET ||
+ SpellTargetType[spellInfo->EffectImplicitTargetA[j]]== TARGET_TYPE_DEST_DEST ||
+ spellInfo->Targets & (TARGET_FLAG_SOURCE_LOCATION|TARGET_FLAG_DEST_LOCATION))
spellInfo->Effect[j] = SPELL_EFFECT_TRIGGER_MISSILE;
break;
}
+
+ switch(SpellTargetType[spellInfo->EffectImplicitTargetA[j]])
+ {
+ case TARGET_TYPE_UNIT_TARGET:
+ case TARGET_TYPE_DEST_TARGET:
+ spellInfo->Targets |= TARGET_FLAG_UNIT;
+ break;
+ }
}
- if(spellInfo->SpellVisual == 3879)
+ if(spellInfo->SpellVisual[0] == 3879)
mSpellCustomAttr[i] |= SPELL_ATTR_CU_CONE_BACK;
switch(i)
@@ -2209,7 +2372,7 @@ void SpellMgr::LoadSpellCustomAttr()
case 45027: // Revitalize
case 45976: // Muru Portal Channel
case 39365: // Thundering Storm
- case 41071: // Raise Dead
+ case 41071: // Raise Dead (HACK)
spellInfo->MaxAffectedTargets = 1;
break;
case 41376: // Spite
@@ -2220,6 +2383,7 @@ void SpellMgr::LoadSpellCustomAttr()
case 46771: //Flame Sear
case 45248: //Shadow Blades
case 41303: // Soul Drain
+ case 54172: // Divine Storm (heal)
spellInfo->MaxAffectedTargets = 3;
break;
case 38310: //Multi-Shot
@@ -2246,10 +2410,50 @@ void SpellMgr::LoadSpellCustomAttr()
spellInfo->MaxAffectedTargets = 1;
spellInfo->EffectTriggerSpell[0] = 33760;
break;
+ case 1122: // Inferno
+ case 18662: // Curse of Doom
+ spellInfo->EffectBasePoints[0] = 0; //prevent summon too many of them
+ break;
+ case 17941: // Shadow Trance
+ case 22008: // Netherwind Focus
+ case 31834: // Light's Grace
+ case 34754: // Clearcasting
+ case 34936: // Backlash
+ case 48108: // Hot Streak
+ case 51124: // Killing Machine
+ case 54741: // Firestarter
+ case 57761: // Fireball!
+ case 39805: // Lightning Overload
+ case 52437: // Sudden Death
+ spellInfo->procCharges=1;
+ break;
+ case 44544: // Fingers of Frost
+ spellInfo->procCharges=2;
+ break;
+ case 28200: // Ascendance (Talisman of Ascendance trinket)
+ spellInfo->procCharges=6;
+ break;
default:
break;
}
+
+ switch(spellInfo->SpellFamilyName)
+ {
+ case SPELLFAMILY_DRUID:
+ //starfall
+ if(spellInfo->SpellFamilyFlags[2] & 0x100)
+ spellInfo->MaxAffectedTargets = 2;
+ break;
+ // circle of healing
+ case SPELLFAMILY_PRIEST:
+ if(spellInfo->SpellFamilyFlags[0] & 0x10000000)
+ spellInfo->MaxAffectedTargets = 5;
+ break;
+ }
}
+
+ SummonPropertiesEntry *properties = const_cast<SummonPropertiesEntry*>(sSummonPropertiesStore.LookupEntry(121));
+ properties->Type = SUMMON_TYPE_TOTEM;
}
void SpellMgr::LoadSpellLinked()
@@ -2326,6 +2530,47 @@ void SpellMgr::LoadSpellLinked()
}
/// Some checks for spells, to prevent adding depricated/broken spells for trainers, spell book, etc
+void SpellMgr::LoadPetLevelupSpellMap()
+{
+ mPetLevelupSpellMap.clear(); // need for reload case
+
+ uint32 count=0;
+ for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i)
+ {
+ CreatureFamilyEntry const *creatureFamily=sCreatureFamilyStore.LookupEntry(i);
+ if(!creatureFamily) // not exist
+ continue;
+
+ for (uint8 j = 0; j < 2; ++j)
+ {
+ if (creatureFamily->skillLine[j]==0)
+ continue;
+
+ for (uint32 k=0;k<sSkillLineAbilityStore.GetNumRows();++k)
+ {
+ SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(k);
+ if (!skillLine)
+ continue;
+ if (creatureFamily->skillLine[j]!=skillLine->skillId)
+ continue;
+ SpellEntry const *spell = sSpellStore.LookupEntry(skillLine->spellId);
+ // not exist or triggered or talent
+ if(!spell || !spell->spellLevel || GetTalentSpellPos(spell->Id))
+ continue;
+ // TODO: some spells have no spellfamilyflag but should be learned
+ if (!spell->SpellFamilyName)
+ continue;
+ mPetLevelupSpellMap.insert(PetLevelupSpellMap::value_type(creatureFamily->ID, std::make_pair(spell->spellLevel , spell->Id )));
+ count++;
+ }
+ }
+ }
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u pet levelup spells", count );
+}
+
+/// Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book, etc
bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg)
{
// not exist
@@ -2400,82 +2645,329 @@ bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg)
return true;
}
-bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id)
+void SpellMgr::LoadSpellAreas()
{
- // normal case
- if( spellInfo->AreaId && spellInfo->AreaId != zone_id && spellInfo->AreaId != area_id )
- return false;
+ mSpellAreaMap.clear(); // need for reload case
+ mSpellAreaForQuestMap.clear();
+ mSpellAreaForActiveQuestMap.clear();
+ mSpellAreaForQuestEndMap.clear();
+ mSpellAreaForAuraMap.clear();
+
+ uint32 count = 0;
+
+ // 0 1 2 3 4 5 6 7 8
+ QueryResult *result = WorldDatabase.Query("SELECT spell, area, quest_start, quest_start_active, quest_end, aura_spell, racemask, gender, autocast FROM spell_area");
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u spell area requirements", count );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
- // elixirs (all area dependent elixirs have family SPELLFAMILY_POTION, use this for speedup)
- if(spellInfo->SpellFamilyName==SPELLFAMILY_POTION)
+ do
{
- if(uint32 mask = spellmgr.GetSpellElixirMask(spellInfo->Id))
+ Field *fields = result->Fetch();
+
+ bar.step();
+
+ uint32 spell = fields[0].GetUInt32();
+ SpellArea spellArea;
+ spellArea.spellId = spell;
+ spellArea.areaId = fields[1].GetUInt32();
+ spellArea.questStart = fields[2].GetUInt32();
+ spellArea.questStartCanActive = fields[3].GetBool();
+ spellArea.questEnd = fields[4].GetUInt32();
+ spellArea.auraSpell = fields[5].GetInt32();
+ spellArea.raceMask = fields[6].GetUInt32();
+ spellArea.gender = Gender(fields[7].GetUInt8());
+ spellArea.autocast = fields[8].GetBool();
+
+ if(!sSpellStore.LookupEntry(spell))
+ {
+ sLog.outErrorDb("Spell %u listed in `spell_area` does not exist", spell);
+ continue;
+ }
+
{
- if(mask & ELIXIR_BATTLE_MASK)
+ bool ok = true;
+ SpellAreaMapBounds sa_bounds = GetSpellAreaMapBounds(spellArea.spellId);
+ for(SpellAreaMap::const_iterator itr = sa_bounds.first; itr != sa_bounds.second; ++itr)
{
- if(spellInfo->Id==45373) // Bloodberry Elixir
- return zone_id==4075;
+ if(spellArea.spellId && itr->second.spellId && spellArea.spellId != itr->second.spellId)
+ continue;
+ if(spellArea.areaId && itr->second.areaId && spellArea.areaId!= itr->second.areaId)
+ continue;
+ if(spellArea.questStart && itr->second.questStart && spellArea.questStart!= itr->second.questStart)
+ continue;
+ if(spellArea.auraSpell && itr->second.auraSpell && spellArea.auraSpell!= itr->second.auraSpell)
+ continue;
+ if(spellArea.raceMask && itr->second.raceMask && (spellArea.raceMask & itr->second.raceMask)==0)
+ continue;
+ if(spellArea.gender != GENDER_NONE && itr->second.gender != GENDER_NONE && spellArea.gender!= itr->second.gender)
+ continue;
+
+ // duplicate by requirements
+ ok =false;
+ break;
}
- if(mask & ELIXIR_UNSTABLE_MASK)
+
+ if(!ok)
{
- // in the Blade's Edge Mountains Plateaus and Gruul's Lair.
- return zone_id ==3522 || map_id==565;
+ sLog.outErrorDb("Spell %u listed in `spell_area` already listed with similar requirements.", spell);
+ continue;
}
- if(mask & ELIXIR_SHATTRATH_MASK)
+
+ }
+
+ if(spellArea.areaId && !GetAreaEntryByAreaID(spellArea.areaId))
+ {
+ sLog.outErrorDb("Spell %u listed in `spell_area` have wrong area (%u) requirement", spell,spellArea.areaId);
+ continue;
+ }
+
+ if(spellArea.questStart && !objmgr.GetQuestTemplate(spellArea.questStart))
+ {
+ sLog.outErrorDb("Spell %u listed in `spell_area` have wrong start quest (%u) requirement", spell,spellArea.questStart);
+ continue;
+ }
+
+ if(spellArea.questEnd)
+ {
+ if(!objmgr.GetQuestTemplate(spellArea.questEnd))
{
- // in Tempest Keep, Serpentshrine Cavern, Caverns of Time: Mount Hyjal, Black Temple, Sunwell Plateau
- if(zone_id ==3607 || map_id==534 || map_id==564 || zone_id==4075)
- return true;
+ sLog.outErrorDb("Spell %u listed in `spell_area` have wrong end quest (%u) requirement", spell,spellArea.questEnd);
+ continue;
+ }
- MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
- if(!mapEntry)
- return false;
+ if(spellArea.questEnd==spellArea.questStart && !spellArea.questStartCanActive)
+ {
+ sLog.outErrorDb("Spell %u listed in `spell_area` have quest (%u) requirement for start and end in same time", spell,spellArea.questEnd);
+ continue;
+ }
+ }
- return mapEntry->multimap_id==206;
+ if(spellArea.auraSpell)
+ {
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(abs(spellArea.auraSpell));
+ if(!spellInfo)
+ {
+ sLog.outErrorDb("Spell %u listed in `spell_area` have wrong aura spell (%u) requirement", spell,abs(spellArea.auraSpell));
+ continue;
}
- // elixirs not have another limitations
- return true;
+ if(spellInfo->EffectApplyAuraName[0]!=SPELL_AURA_DUMMY && spellInfo->EffectApplyAuraName[0]!=SPELL_AURA_PHASE)
+ {
+ sLog.outErrorDb("Spell %u listed in `spell_area` have aura spell requirement (%u) without dummy/phase aura in effect 0", spell,abs(spellArea.auraSpell));
+ continue;
+ }
+
+ if(abs(spellArea.auraSpell)==spellArea.spellId)
+ {
+ sLog.outErrorDb("Spell %u listed in `spell_area` have aura spell (%u) requirement for itself", spell,abs(spellArea.auraSpell));
+ continue;
+ }
+
+ // not allow autocast chains by auraSpell field (but allow use as alternative if not present)
+ if(spellArea.autocast && spellArea.auraSpell > 0)
+ {
+ bool chain = false;
+ SpellAreaForAuraMapBounds saBound = GetSpellAreaForAuraMapBounds(spellArea.spellId);
+ for(SpellAreaForAuraMap::const_iterator itr = saBound.first; itr != saBound.second; ++itr)
+ {
+ if(itr->second->autocast && itr->second->auraSpell > 0)
+ {
+ chain = true;
+ break;
+ }
+ }
+
+ if(chain)
+ {
+ sLog.outErrorDb("Spell %u listed in `spell_area` have aura spell (%u) requirement that itself autocast from aura", spell,spellArea.auraSpell);
+ continue;
+ }
+
+ SpellAreaMapBounds saBound2 = GetSpellAreaMapBounds(spellArea.auraSpell);
+ for(SpellAreaMap::const_iterator itr2 = saBound2.first; itr2 != saBound2.second; ++itr2)
+ {
+ if(itr2->second.autocast && itr2->second.auraSpell > 0)
+ {
+ chain = true;
+ break;
+ }
+ }
+
+ if(chain)
+ {
+ sLog.outErrorDb("Spell %u listed in `spell_area` have aura spell (%u) requirement that itself autocast from aura", spell,spellArea.auraSpell);
+ continue;
+ }
+ }
+ }
+
+ if(spellArea.raceMask && (spellArea.raceMask & RACEMASK_ALL_PLAYABLE)==0)
+ {
+ sLog.outErrorDb("Spell %u listed in `spell_area` have wrong race mask (%u) requirement", spell,spellArea.raceMask);
+ continue;
+ }
+
+ if(spellArea.gender!=GENDER_NONE && spellArea.gender!=GENDER_FEMALE && spellArea.gender!=GENDER_MALE)
+ {
+ sLog.outErrorDb("Spell %u listed in `spell_area` have wrong gender (%u) requirement", spell,spellArea.gender);
+ continue;
+ }
+
+ SpellArea const* sa = &mSpellAreaMap.insert(SpellAreaMap::value_type(spell,spellArea))->second;
+
+ // for search by current zone/subzone at zone/subzone change
+ if(spellArea.areaId)
+ mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(spellArea.areaId,sa));
+
+ // for search at quest start/reward
+ if(spellArea.questStart)
+ {
+ if(spellArea.questStartCanActive)
+ mSpellAreaForActiveQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart,sa));
+ else
+ mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart,sa));
+ }
+
+ // for search at quest start/reward
+ if(spellArea.questEnd)
+ mSpellAreaForQuestEndMap.insert(SpellAreaForQuestMap::value_type(spellArea.questEnd,sa));
+
+ // for search at aura apply
+ if(spellArea.auraSpell)
+ mSpellAreaForAuraMap.insert(SpellAreaForAuraMap::value_type(abs(spellArea.auraSpell),sa));
+
+ ++count;
+ } while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u spell area requirements", count );
+}
+
+SpellCastResult SpellMgr::GetSpellAllowedInLocationError(SpellEntry const *spellInfo, uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player)
+{
+ // normal case
+ if( spellInfo->AreaGroupId > 0)
+ {
+ bool found = false;
+ AreaGroupEntry const* groupEntry = sAreaGroupStore.LookupEntry(spellInfo->AreaGroupId);
+ while (groupEntry)
+ {
+ for (uint32 i=0; i<6; ++i)
+ if( groupEntry->AreaId[i] == zone_id || groupEntry->AreaId[i] == area_id )
+ found = true;
+ if (found || !groupEntry->nextGroup)
+ break;
+ // Try search in next group
+ groupEntry = sAreaGroupStore.LookupEntry(groupEntry->nextGroup);
+ }
+
+ if(!found)
+ return SPELL_FAILED_INCORRECT_AREA;
+ }
+
+ // DB base check (if non empty then must fit at least single for allow)
+ SpellAreaMapBounds saBounds = spellmgr.GetSpellAreaMapBounds(spellInfo->Id);
+ if(saBounds.first != saBounds.second)
+ {
+ for(SpellAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
+ {
+ if(itr->second.IsFitToRequirements(player,zone_id,area_id))
+ return SPELL_CAST_OK;
}
+ return SPELL_FAILED_INCORRECT_AREA;
}
- // special cases zone check (maps checked by multimap common id)
+ // bg spell checks
switch(spellInfo->Id)
{
- case 41618: // Bottled Nethergon Energy
- case 41620: // Bottled Nethergon Vapor
+ case 23333: // Warsong Flag
+ case 23335: // Silverwing Flag
+ return map_id == 489 && player && player->InBattleGround() ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
+ case 34976: // Netherstorm Flag
+ return map_id == 566 && player && player->InBattleGround() ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
+ case 2584: // Waiting to Resurrect
+ case 22011: // Spirit Heal Channel
+ case 22012: // Spirit Heal
+ case 24171: // Resurrection Impact Visual
+ case 42792: // Recently Dropped Flag
+ case 43681: // Inactive
+ case 44535: // Spirit Heal (mana)
{
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
if(!mapEntry)
- return false;
+ return SPELL_FAILED_INCORRECT_AREA;
- return mapEntry->multimap_id==206;
+ return mapEntry->IsBattleGround() && player && player->InBattleGround() ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
}
- case 41617: // Cenarion Mana Salve
- case 41619: // Cenarion Healing Salve
+ case 44521: // Preparation
{
+ if(!player)
+ return SPELL_FAILED_REQUIRES_AREA;
+
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
if(!mapEntry)
- return false;
+ return SPELL_FAILED_INCORRECT_AREA;
+
+ if(!mapEntry->IsBattleGround())
+ return SPELL_FAILED_REQUIRES_AREA;
+
+ BattleGround* bg = player->GetBattleGround();
+ return bg && bg->GetStatus()==STATUS_WAIT_JOIN ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
+ }
+ case 32724: // Gold Team (Alliance)
+ case 32725: // Green Team (Alliance)
+ case 35774: // Gold Team (Horde)
+ case 35775: // Green Team (Horde)
+ {
+ MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
+ if(!mapEntry)
+ return SPELL_FAILED_INCORRECT_AREA;
+
+ return mapEntry->IsBattleArena() && player && player->InBattleGround() ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
+ }
+ case 32727: // Arena Preparation
+ {
+ if(!player)
+ return SPELL_FAILED_REQUIRES_AREA;
+
+ MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
+ if(!mapEntry)
+ return SPELL_FAILED_INCORRECT_AREA;
+
+ if(!mapEntry->IsBattleArena())
+ return SPELL_FAILED_REQUIRES_AREA;
- return mapEntry->multimap_id==207;
+ BattleGround* bg = player->GetBattleGround();
+ return bg && bg->GetStatus()==STATUS_WAIT_JOIN ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
}
- case 40216: // Dragonmaw Illusion
- case 42016: // Dragonmaw Illusion
- return area_id == 3759 || area_id == 3966 || area_id == 3939;
}
- return true;
+ return SPELL_CAST_OK;
}
void SpellMgr::LoadSkillLineAbilityMap()
{
mSkillLineAbilityMap.clear();
+ barGoLink bar( sSkillLineAbilityStore.GetNumRows() );
uint32 count = 0;
- for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); i++)
+ for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); ++i)
{
+ bar.step();
SkillLineAbilityEntry const *SkillInfo = sSkillLineAbilityStore.LookupEntry(i);
if(!SkillInfo)
continue;
@@ -2485,7 +2977,7 @@ void SpellMgr::LoadSkillLineAbilityMap()
}
sLog.outString();
- sLog.outString(">> Loaded %u SkillLineAbility MultiMap", count);
+ sLog.outString(">> Loaded %u SkillLineAbility MultiMap Data", count);
}
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto, bool triggered)
@@ -2493,56 +2985,49 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto
// Explicit Diminishing Groups
switch(spellproto->SpellFamilyName)
{
- case SPELLFAMILY_MAGE:
- {
- // Polymorph
- if ((spellproto->SpellFamilyFlags & 0x00001000000LL) && spellproto->EffectApplyAuraName[0]==SPELL_AURA_MOD_CONFUSE)
- return DIMINISHING_POLYMORPH;
- break;
- }
case SPELLFAMILY_ROGUE:
{
// Kidney Shot
- if (spellproto->SpellFamilyFlags & 0x00000200000LL)
+ if (spellproto->SpellFamilyFlags[0] & 0x200000)
return DIMINISHING_KIDNEYSHOT;
// Sap
- else if (spellproto->SpellFamilyFlags & 0x00000000080LL)
+ else if (spellproto->SpellFamilyFlags[0] & 0x80)
return DIMINISHING_POLYMORPH;
// Gouge
- else if (spellproto->SpellFamilyFlags & 0x00000000008LL)
+ else if (spellproto->SpellFamilyFlags[0] & 0x8)
return DIMINISHING_POLYMORPH;
// Blind
- else if (spellproto->SpellFamilyFlags & 0x00001000000LL)
+ else if (spellproto->SpellFamilyFlags[0] & 0x00001000000)
return DIMINISHING_BLIND_CYCLONE;
break;
}
case SPELLFAMILY_WARLOCK:
{
// Death Coil
- if (spellproto->SpellFamilyFlags & 0x00000080000LL)
+ if (spellproto->SpellFamilyFlags[0] & 0x00000080000)
return DIMINISHING_DEATHCOIL;
// Seduction
- if (spellproto->SpellFamilyFlags & 0x00040000000LL)
+ if (spellproto->SpellFamilyFlags[0] & 0x00040000000)
return DIMINISHING_FEAR;
// Fear
//else if (spellproto->SpellFamilyFlags & 0x40840000000LL)
// return DIMINISHING_WARLOCK_FEAR;
// Curses/etc
- else if (spellproto->SpellFamilyFlags & 0x00080000000LL)
+ else if (spellproto->SpellFamilyFlags[0] & 0x80000000)
return DIMINISHING_LIMITONLY;
break;
}
case SPELLFAMILY_DRUID:
{
// Cyclone
- if (spellproto->SpellFamilyFlags & 0x02000000000LL)
+ if (spellproto->SpellFamilyFlags[1] & 0x020)
return DIMINISHING_BLIND_CYCLONE;
break;
}
case SPELLFAMILY_WARRIOR:
{
// Hamstring - limit duration to 10s in PvP
- if (spellproto->SpellFamilyFlags & 0x00000000002LL)
+ if (spellproto->SpellFamilyFlags[0] & 0x00000000002)
return DIMINISHING_LIMITONLY;
break;
}
@@ -2551,30 +3036,21 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto
}
// Get by mechanic
- for (uint8 i=0;i<3;++i)
- {
- if (spellproto->Mechanic == MECHANIC_STUN || spellproto->EffectMechanic[i] == MECHANIC_STUN)
- return triggered ? DIMINISHING_TRIGGER_STUN : DIMINISHING_CONTROL_STUN;
- else if (spellproto->Mechanic == MECHANIC_SLEEP || spellproto->EffectMechanic[i] == MECHANIC_SLEEP)
- return DIMINISHING_SLEEP;
- else if (spellproto->Mechanic == MECHANIC_ROOT || spellproto->EffectMechanic[i] == MECHANIC_ROOT)
- return triggered ? DIMINISHING_TRIGGER_ROOT : DIMINISHING_CONTROL_ROOT;
- else if (spellproto->Mechanic == MECHANIC_FEAR || spellproto->EffectMechanic[i] == MECHANIC_FEAR)
- return DIMINISHING_FEAR;
- else if (spellproto->Mechanic == MECHANIC_CHARM || spellproto->EffectMechanic[i] == MECHANIC_CHARM)
- return DIMINISHING_CHARM;
- else if (spellproto->Mechanic == MECHANIC_SILENCE || spellproto->EffectMechanic[i] == MECHANIC_SILENCE)
- return DIMINISHING_SILENCE;
- else if (spellproto->Mechanic == MECHANIC_DISARM || spellproto->EffectMechanic[i] == MECHANIC_DISARM)
- return DIMINISHING_DISARM;
- else if (spellproto->Mechanic == MECHANIC_FREEZE || spellproto->EffectMechanic[i] == MECHANIC_FREEZE)
- return DIMINISHING_FREEZE;
- else if (spellproto->Mechanic == MECHANIC_KNOCKOUT|| spellproto->EffectMechanic[i] == MECHANIC_KNOCKOUT ||
- spellproto->Mechanic == MECHANIC_SAPPED || spellproto->EffectMechanic[i] == MECHANIC_SAPPED)
- return DIMINISHING_KNOCKOUT;
- else if (spellproto->Mechanic == MECHANIC_BANISH || spellproto->EffectMechanic[i] == MECHANIC_BANISH)
- return DIMINISHING_BANISH;
- }
+ uint32 mechanic = GetAllSpellMechanicMask(spellproto);
+ if (mechanic == MECHANIC_NONE) return DIMINISHING_NONE;
+ if (mechanic & (1<<MECHANIC_STUN)) return triggered ? DIMINISHING_TRIGGER_STUN : DIMINISHING_CONTROL_STUN;
+ if (mechanic & (1<<MECHANIC_SLEEP)) return DIMINISHING_SLEEP;
+ if (mechanic & (1<<MECHANIC_POLYMORPH)) return DIMINISHING_POLYMORPH;
+ if (mechanic & (1<<MECHANIC_ROOT)) return triggered ? DIMINISHING_TRIGGER_ROOT : DIMINISHING_CONTROL_ROOT;
+ if (mechanic & (1<<MECHANIC_FEAR)) return DIMINISHING_FEAR;
+ if (mechanic & (1<<MECHANIC_CHARM)) return DIMINISHING_CHARM;
+ if (mechanic & (1<<MECHANIC_SILENCE)) return DIMINISHING_SILENCE;
+ if (mechanic & (1<<MECHANIC_DISARM)) return DIMINISHING_DISARM;
+ if (mechanic & (1<<MECHANIC_FREEZE)) return DIMINISHING_FREEZE;
+ if (mechanic & ((1<<MECHANIC_KNOCKOUT) | (1<<MECHANIC_SAPPED))) return DIMINISHING_KNOCKOUT;
+ if (mechanic & (1<<MECHANIC_BANISH)) return DIMINISHING_BANISH;
+ if (mechanic & (1<<MECHANIC_HORROR)) return DIMINISHING_DEATHCOIL;
+
return DIMINISHING_NONE;
}
@@ -2631,3 +3107,55 @@ DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
return DRTYPE_NONE;
}
+bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 newArea) const
+{
+ if(gender!=GENDER_NONE)
+ {
+ // not in expected gender
+ if(!player || gender != player->getGender())
+ return false;
+ }
+
+ if(raceMask)
+ {
+ // not in expected race
+ if(!player || !(raceMask & player->getRaceMask()))
+ return false;
+ }
+
+ if(areaId)
+ {
+ // not in expected zone
+ if(newZone!=areaId && newArea!=areaId)
+ return false;
+ }
+
+ if(questStart)
+ {
+ // not in expected required quest state
+ if(!player || (!questStartCanActive || !player->IsActiveQuest(questStart)) && !player->GetQuestRewardStatus(questStart))
+ return false;
+ }
+
+ if(questEnd)
+ {
+ // not in expected forbidden quest state
+ if(!player || player->GetQuestRewardStatus(questEnd))
+ return false;
+ }
+
+ if(auraSpell)
+ {
+ // not have expected aura
+ if(!player)
+ return false;
+ if(auraSpell > 0)
+ // have expected aura
+ return player->HasAura(auraSpell);
+ else
+ // not have expected aura
+ return !player->HasAura(-auraSpell);
+ }
+
+ return true;
+}
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 35d867dce2b..934326fe6d1 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -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 _SPELLMGR_H
@@ -25,10 +25,13 @@
// For more high level function for sSpellStore data
#include "SharedDefines.h"
-#include "Database/DBCStructure.h"
+#include "DBCStructure.h"
#include "Database/SQLStorage.h"
#include "Utilities/UnorderedMap.h"
+
+#include "Player.h"
+
#include <map>
class Player;
@@ -36,177 +39,11 @@ class Spell;
extern SQLStorage sSpellThreatStore;
-enum SpellFailedReason
-{
- SPELL_FAILED_AFFECTING_COMBAT = 0x00,
- SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 0x01,
- SPELL_FAILED_ALREADY_AT_FULL_MANA = 0x02,
- SPELL_FAILED_ALREADY_AT_FULL_POWER = 0x03,
- SPELL_FAILED_ALREADY_BEING_TAMED = 0x04,
- SPELL_FAILED_ALREADY_HAVE_CHARM = 0x05,
- SPELL_FAILED_ALREADY_HAVE_SUMMON = 0x06,
- SPELL_FAILED_ALREADY_OPEN = 0x07,
- SPELL_FAILED_AURA_BOUNCED = 0x08,
- SPELL_FAILED_AUTOTRACK_INTERRUPTED = 0x09,
- SPELL_FAILED_BAD_IMPLICIT_TARGETS = 0x0A,
- SPELL_FAILED_BAD_TARGETS = 0x0B,
- SPELL_FAILED_CANT_BE_CHARMED = 0x0C,
- SPELL_FAILED_CANT_BE_DISENCHANTED = 0x0D,
- SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 0x0E,
- SPELL_FAILED_CANT_BE_PROSPECTED = 0x0F,
- SPELL_FAILED_CANT_CAST_ON_TAPPED = 0x10,
- SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 0x11,
- SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 0x12,
- SPELL_FAILED_CANT_STEALTH = 0x13,
- SPELL_FAILED_CASTER_AURASTATE = 0x14,
- SPELL_FAILED_CASTER_DEAD = 0x15,
- SPELL_FAILED_CHARMED = 0x16,
- SPELL_FAILED_CHEST_IN_USE = 0x17,
- SPELL_FAILED_CONFUSED = 0x18,
- SPELL_FAILED_DONT_REPORT = 0x19,
- SPELL_FAILED_EQUIPPED_ITEM = 0x1A,
- SPELL_FAILED_EQUIPPED_ITEM_CLASS = 0x1B,
- SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 0x1C,
- SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 0x1D,
- SPELL_FAILED_ERROR = 0x1E,
- SPELL_FAILED_FIZZLE = 0x1F,
- SPELL_FAILED_FLEEING = 0x20,
- SPELL_FAILED_FOOD_LOWLEVEL = 0x21,
- SPELL_FAILED_HIGHLEVEL = 0x22,
- SPELL_FAILED_HUNGER_SATIATED = 0x23,
- SPELL_FAILED_IMMUNE = 0x24,
- SPELL_FAILED_INTERRUPTED = 0x25,
- SPELL_FAILED_INTERRUPTED_COMBAT = 0x26,
- SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 0x27,
- SPELL_FAILED_ITEM_GONE = 0x28,
- SPELL_FAILED_ITEM_NOT_FOUND = 0x29,
- SPELL_FAILED_ITEM_NOT_READY = 0x2A,
- SPELL_FAILED_LEVEL_REQUIREMENT = 0x2B,
- SPELL_FAILED_LINE_OF_SIGHT = 0x2C,
- SPELL_FAILED_LOWLEVEL = 0x2D,
- SPELL_FAILED_LOW_CASTLEVEL = 0x2E,
- SPELL_FAILED_MAINHAND_EMPTY = 0x2F,
- SPELL_FAILED_MOVING = 0x30,
- SPELL_FAILED_NEED_AMMO = 0x31,
- SPELL_FAILED_NEED_AMMO_POUCH = 0x32,
- SPELL_FAILED_NEED_EXOTIC_AMMO = 0x33,
- SPELL_FAILED_NOPATH = 0x34,
- SPELL_FAILED_NOT_BEHIND = 0x35,
- SPELL_FAILED_NOT_FISHABLE = 0x36,
- SPELL_FAILED_NOT_FLYING = 0x37,
- SPELL_FAILED_NOT_HERE = 0x38,
- SPELL_FAILED_NOT_INFRONT = 0x39,
- SPELL_FAILED_NOT_IN_CONTROL = 0x3A,
- SPELL_FAILED_NOT_KNOWN = 0x3B,
- SPELL_FAILED_NOT_MOUNTED = 0x3C,
- SPELL_FAILED_NOT_ON_TAXI = 0x3D,
- SPELL_FAILED_NOT_ON_TRANSPORT = 0x3E,
- SPELL_FAILED_NOT_READY = 0x3F,
- SPELL_FAILED_NOT_SHAPESHIFT = 0x40,
- SPELL_FAILED_NOT_STANDING = 0x41,
- SPELL_FAILED_NOT_TRADEABLE = 0x42,
- SPELL_FAILED_NOT_TRADING = 0x43,
- SPELL_FAILED_NOT_UNSHEATHED = 0x44,
- SPELL_FAILED_NOT_WHILE_GHOST = 0x45,
- SPELL_FAILED_NO_AMMO = 0x46,
- SPELL_FAILED_NO_CHARGES_REMAIN = 0x47,
- SPELL_FAILED_NO_CHAMPION = 0x48,
- SPELL_FAILED_NO_COMBO_POINTS = 0x49,
- SPELL_FAILED_NO_DUELING = 0x4A,
- SPELL_FAILED_NO_ENDURANCE = 0x4B,
- SPELL_FAILED_NO_FISH = 0x4C,
- SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 0x4D,
- SPELL_FAILED_NO_MOUNTS_ALLOWED = 0x4E,
- SPELL_FAILED_NO_PET = 0x4F,
- SPELL_FAILED_NO_POWER = 0x50,
- SPELL_FAILED_NOTHING_TO_DISPEL = 0x51,
- SPELL_FAILED_NOTHING_TO_STEAL = 0x52,
- SPELL_FAILED_ONLY_ABOVEWATER = 0x53,
- SPELL_FAILED_ONLY_DAYTIME = 0x54,
- SPELL_FAILED_ONLY_INDOORS = 0x55,
- SPELL_FAILED_ONLY_MOUNTED = 0x56,
- SPELL_FAILED_ONLY_NIGHTTIME = 0x57,
- SPELL_FAILED_ONLY_OUTDOORS = 0x58,
- SPELL_FAILED_ONLY_SHAPESHIFT = 0x59,
- SPELL_FAILED_ONLY_STEALTHED = 0x5A,
- SPELL_FAILED_ONLY_UNDERWATER = 0x5B,
- SPELL_FAILED_OUT_OF_RANGE = 0x5C,
- SPELL_FAILED_PACIFIED = 0x5D,
- SPELL_FAILED_POSSESSED = 0x5E,
- SPELL_FAILED_REAGENTS = 0x5F,
- SPELL_FAILED_REQUIRES_AREA = 0x60,
- SPELL_FAILED_REQUIRES_SPELL_FOCUS = 0x61,
- SPELL_FAILED_ROOTED = 0x62,
- SPELL_FAILED_SILENCED = 0x63,
- SPELL_FAILED_SPELL_IN_PROGRESS = 0x64,
- SPELL_FAILED_SPELL_LEARNED = 0x65,
- SPELL_FAILED_SPELL_UNAVAILABLE = 0x66,
- SPELL_FAILED_STUNNED = 0x67,
- SPELL_FAILED_TARGETS_DEAD = 0x68,
- SPELL_FAILED_TARGET_AFFECTING_COMBAT = 0x69,
- SPELL_FAILED_TARGET_AURASTATE = 0x6A,
- SPELL_FAILED_TARGET_DUELING = 0x6B,
- SPELL_FAILED_TARGET_ENEMY = 0x6C,
- SPELL_FAILED_TARGET_ENRAGED = 0x6D,
- SPELL_FAILED_TARGET_FRIENDLY = 0x6E,
- SPELL_FAILED_TARGET_IN_COMBAT = 0x6F,
- SPELL_FAILED_TARGET_IS_PLAYER = 0x70,
- SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 0x71,
- SPELL_FAILED_TARGET_NOT_DEAD = 0x72,
- SPELL_FAILED_TARGET_NOT_IN_PARTY = 0x73,
- SPELL_FAILED_TARGET_NOT_LOOTED = 0x74,
- SPELL_FAILED_TARGET_NOT_PLAYER = 0x75,
- SPELL_FAILED_TARGET_NO_POCKETS = 0x76,
- SPELL_FAILED_TARGET_NO_WEAPONS = 0x77,
- SPELL_FAILED_TARGET_UNSKINNABLE = 0x78,
- SPELL_FAILED_THIRST_SATIATED = 0x79,
- SPELL_FAILED_TOO_CLOSE = 0x7A,
- SPELL_FAILED_TOO_MANY_OF_ITEM = 0x7B,
- SPELL_FAILED_TOTEM_CATEGORY = 0x7C,
- SPELL_FAILED_TOTEMS = 0x7D,
- SPELL_FAILED_TRAINING_POINTS = 0x7E,
- SPELL_FAILED_TRY_AGAIN = 0x7F,
- SPELL_FAILED_UNIT_NOT_BEHIND = 0x80,
- SPELL_FAILED_UNIT_NOT_INFRONT = 0x81,
- SPELL_FAILED_WRONG_PET_FOOD = 0x82,
- SPELL_FAILED_NOT_WHILE_FATIGUED = 0x83,
- SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 0x84,
- SPELL_FAILED_NOT_WHILE_TRADING = 0x85,
- SPELL_FAILED_TARGET_NOT_IN_RAID = 0x86,
- SPELL_FAILED_DISENCHANT_WHILE_LOOTING = 0x87,
- SPELL_FAILED_PROSPECT_WHILE_LOOTING = 0x88,
- SPELL_FAILED_PROSPECT_NEED_MORE = 0x89,
- SPELL_FAILED_TARGET_FREEFORALL = 0x8A,
- SPELL_FAILED_NO_EDIBLE_CORPSES = 0x8B,
- SPELL_FAILED_ONLY_BATTLEGROUNDS = 0x8C,
- SPELL_FAILED_TARGET_NOT_GHOST = 0x8D,
- SPELL_FAILED_TOO_MANY_SKILLS = 0x8E,
- SPELL_FAILED_TRANSFORM_UNUSABLE = 0x8F,
- SPELL_FAILED_WRONG_WEATHER = 0x90,
- SPELL_FAILED_DAMAGE_IMMUNE = 0x91,
- SPELL_FAILED_PREVENTED_BY_MECHANIC = 0x92,
- SPELL_FAILED_PLAY_TIME = 0x93,
- SPELL_FAILED_REPUTATION = 0x94,
- SPELL_FAILED_MIN_SKILL = 0x95,
- SPELL_FAILED_NOT_IN_ARENA = 0x96,
- SPELL_FAILED_NOT_ON_SHAPESHIFT = 0x97,
- SPELL_FAILED_NOT_ON_STEALTHED = 0x98,
- SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 0x99,
- SPELL_FAILED_NOT_ON_MOUNTED = 0x9A,
- SPELL_FAILED_TOO_SHALLOW = 0x9B,
- SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 0x9C,
- SPELL_FAILED_TARGET_IS_TRIVIAL = 0x9D,
- SPELL_FAILED_BM_OR_INVISGOD = 0x9E,
- SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 0x9F,
- SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 0xA0,
- SPELL_FAILED_NOT_IDLE = 0xA1,
- SPELL_FAILED_NOT_INACTIVE = 0xA2,
- SPELL_FAILED_PARTIAL_PLAYTIME = 0xA3,
- SPELL_FAILED_NO_PLAYTIME = 0xA4,
- SPELL_FAILED_NOT_IN_BATTLEGROUND = 0xA5,
- SPELL_FAILED_ONLY_IN_ARENA = 0xA6,
- SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 0xA7,
- SPELL_FAILED_UNKNOWN = 0xA8,
+// only used in code
+enum SpellCategories
+{
+ SPELLCATEGORY_HEALTH_MANA_POTIONS = 4,
+ SPELLCATEGORY_DEVOUR_MAGIC = 12
};
enum SpellFamilyNames
@@ -223,8 +60,12 @@ enum SpellFamilyNames
SPELLFAMILY_HUNTER = 9,
SPELLFAMILY_PALADIN = 10,
SPELLFAMILY_SHAMAN = 11,
- SPELLFAMILY_UNK2 = 12,
- SPELLFAMILY_POTION = 13
+ SPELLFAMILY_UNK2 = 12, // 2 spells (silence resistance)
+ SPELLFAMILY_POTION = 13,
+ // 14 - unused
+ SPELLFAMILY_DEATHKNIGHT = 15,
+ // 16 - unused
+ SPELLFAMILY_PET = 17
};
enum SpellDisableTypes
@@ -256,15 +97,15 @@ enum SpellSelectTargetTypes
};
//Some SpellFamilyFlags
-#define SPELLFAMILYFLAG_ROGUE_VANISH 0x000000800LL
-#define SPELLFAMILYFLAG_ROGUE_STEALTH 0x000400000LL
-#define SPELLFAMILYFLAG_ROGUE_BACKSTAB 0x000800004LL
-#define SPELLFAMILYFLAG_ROGUE_SAP 0x000000080LL
-#define SPELLFAMILYFLAG_ROGUE_FEINT 0x008000000LL
-#define SPELLFAMILYFLAG_ROGUE_KIDNEYSHOT 0x000200000LL
-#define SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE 0x9003E0000LL
-#define SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR 0x000004000LL
-#define SPELLFAMILYFLAG_SHAMAN_FROST_SHOCK 0x080000000LL
+#define SPELLFAMILYFLAG_ROGUE_VANISH 0x00000800
+#define SPELLFAMILYFLAG_ROGUE_STEALTH 0x00400000
+#define SPELLFAMILYFLAG_ROGUE_BACKSTAB 0x00800004
+#define SPELLFAMILYFLAG_ROGUE_SAP 0x00000080
+#define SPELLFAMILYFLAG_ROGUE_FEINT 0x08000000
+#define SPELLFAMILYFLAG_ROGUE_KIDNEYSHOT 0x00200000
+//#define SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE 0x9003E0000LL
+#define SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR 0x00004000
+#define SPELLFAMILYFLAG_SHAMAN_FROST_SHOCK 0x80000000
// Spell clasification
enum SpellSpecific
@@ -290,7 +131,9 @@ enum SpellSpecific
SPELL_WELL_FED = 18,
SPELL_DRINK = 19,
SPELL_FOOD = 20,
- SPELL_CHARM = 21,
+ SPELL_PRESENCE = 21,
+ SPELL_CHARM = 22,
+ SPELL_SCROLL = 23
};
#define SPELL_LINKED_MAX_SPELLS 200000
@@ -306,19 +149,36 @@ enum SpellLinkedType
SpellSpecific GetSpellSpecific(uint32 spellId);
// Different spell properties
-inline float GetSpellRadius(SpellRadiusEntry const *radius) { return (radius ? radius->Radius : 0); }
+inline float GetSpellRadiusForHostile(SpellRadiusEntry const *radius) { return (radius ? radius->radiusHostile : 0); }
+inline float GetSpellRadiusForFriend(SpellRadiusEntry const *radius) { return (radius ? radius->radiusFriend : 0); }
uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell = NULL);
-inline float GetSpellMinRange(SpellRangeEntry const *range) { return (range ? range->minRange : 0); }
-inline float GetSpellMaxRange(SpellRangeEntry const *range) { return (range ? range->maxRange : 0); }
+bool GetDispelChance(Unit* caster, uint32 spellId);
+inline float GetSpellMinRangeForHostile(SpellRangeEntry const *range) { return (range ? range->minRangeHostile : 0); }
+inline float GetSpellMaxRangeForHostile(SpellRangeEntry const *range) { return (range ? range->maxRangeHostile : 0); }
+inline float GetSpellMinRangeForFriend(SpellRangeEntry const *range) { return (range ? range->minRangeFriend : 0); }
+inline float GetSpellMaxRangeForFriend(SpellRangeEntry const *range) { return (range ? range->maxRangeFriend : 0); }
inline uint32 GetSpellRangeType(SpellRangeEntry const *range) { return (range ? range->type : 0); }
inline uint32 GetSpellRecoveryTime(SpellEntry const *spellInfo) { return spellInfo->RecoveryTime > spellInfo->CategoryRecoveryTime ? spellInfo->RecoveryTime : spellInfo->CategoryRecoveryTime; }
int32 GetSpellDuration(SpellEntry const *spellInfo);
int32 GetSpellMaxDuration(SpellEntry const *spellInfo);
+/*struct DispelEntry
+{
+ uint64 casterGuid;
+ uint32 spellId;
+ Unit * caster;
+ uint8 stackAmount;
+
+ bool operator < (const DispelEntry & _Right) const
+ {
+ return (spellId != _Right.spellId ? spellId < _Right.spellId : casterGuid < _Right.casterGuid);
+ }
+};*/
+
inline bool IsSpellHaveEffect(SpellEntry const *spellInfo, SpellEffects effect)
{
for(int i= 0; i < 3; ++i)
- if(spellInfo->Effect[i]==effect)
+ if(SpellEffects(spellInfo->Effect[i])==effect)
return true;
return false;
}
@@ -329,30 +189,46 @@ inline bool IsSealSpell(SpellEntry const *spellInfo)
{
//Collection of all the seal family flags. No other paladin spell has any of those.
return spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN &&
- ( spellInfo->SpellFamilyFlags & 0x4000A000200LL );
+ ( spellInfo->SpellFamilyFlags[1] & 0x26000C00
+ || spellInfo->SpellFamilyFlags[0] & 0x0A000000 );
}
inline bool IsElementalShield(SpellEntry const *spellInfo)
{
// family flags 10 (Lightning), 42 (Earth), 37 (Water), proc shield from T2 8 pieces bonus
- return (spellInfo->SpellFamilyFlags & 0x42000000400LL) || spellInfo->Id == 23552;
+ return (spellInfo->SpellFamilyFlags[1] & 0x420
+ || spellInfo->SpellFamilyFlags[0] & 0x00000400)
+ || spellInfo->Id == 23552;
+}
+
+inline bool IsExplicitDiscoverySpell(SpellEntry const *spellInfo)
+{
+ return spellInfo->Effect[0]==SPELL_EFFECT_CREATE_ITEM_2 && spellInfo->Effect[1]==SPELL_EFFECT_SCRIPT_EFFECT;
}
-int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2);
+inline bool IsLootCraftingSpell(SpellEntry const *spellInfo)
+{
+ return spellInfo->Effect[0]==SPELL_EFFECT_CREATE_ITEM_2 &&
+ (spellInfo->Effect[1]==SPELL_EFFECT_SCRIPT_EFFECT || !spellInfo->EffectItemType[0]);
+}
+
+bool IsHigherHankOfSpell(uint32 spellId_1,uint32 spellId_2);
bool IsSingleFromSpellSpecificPerCaster(uint32 spellSpec1, uint32 spellSpec2);
bool IsSingleFromSpellSpecificPerTarget(uint32 spellSpec1, uint32 spellSpec2);
bool IsPassiveSpell(uint32 spellId);
+bool IsAutocastableSpell(uint32 spellId);
-inline bool IsDeathPersistentSpell(SpellEntry const *spellInfo)
+inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto)
{
- switch(spellInfo->Id)
- {
- case 40214: // Dragonmaw Illusion
- case 35480: case 35481: case 35482: // Human Illusion
- case 35483: case 39824: // Human Illusion
- return true;
- }
+ if(!IsPassiveSpell(spellProto->Id))
+ return false;
+
+ return !IsSpellHaveEffect(spellProto,SPELL_EFFECT_APPLY_AURA);
+}
+
+inline bool IsDeathPersistentSpell(SpellEntry const *spellInfo)
+{
return spellInfo->AttributesEx3 & SPELL_ATTR_EX3_DEATH_PERSISTENT;
}
@@ -361,18 +237,18 @@ inline bool IsNonCombatSpell(SpellEntry const *spellInfo)
return (spellInfo->Attributes & SPELL_ATTR_CANT_USED_IN_COMBAT) != 0;
}
-bool IsPositiveSpell(uint32 spellId);
-bool IsPositiveEffect(uint32 spellId, uint32 effIndex);
+bool IsPositiveSpell(uint32 spellId, bool deep = false);
+bool IsPositiveEffect(uint32 spellId, uint32 effIndex, bool deep = false);
bool IsPositiveTarget(uint32 targetA, uint32 targetB);
+bool IsDispelableBySpell(SpellEntry const * dispelSpell, uint32 spellId, bool def = false);
bool IsSingleTargetSpell(SpellEntry const *spellInfo);
bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellInfo2);
bool IsAuraAddedBySpell(uint32 auraType, uint32 spellId);
-bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id);
-
extern bool IsAreaEffectTarget[TOTAL_SPELL_TARGETS];
+
inline bool IsAreaOfEffectSpell(SpellEntry const *spellInfo)
{
if(IsAreaEffectTarget[spellInfo->EffectImplicitTargetA[0]] || IsAreaEffectTarget[spellInfo->EffectImplicitTargetB[0]])
@@ -387,6 +263,7 @@ inline bool IsAreaOfEffectSpell(SpellEntry const *spellInfo)
inline bool IsAreaAuraEffect(uint32 effect)
{
if( effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
+ effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID ||
effect == SPELL_EFFECT_APPLY_AREA_AURA_FRIEND ||
effect == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY ||
effect == SPELL_EFFECT_APPLY_AREA_AURA_PET ||
@@ -419,7 +296,12 @@ inline bool isSpellBreakStealth(SpellEntry const* spellInfo)
return !(spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH);
}
-uint8 GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form);
+inline bool IsAutoRepeatRangedSpell(SpellEntry const* spellInfo)
+{
+ return (spellInfo->Attributes & SPELL_ATTR_RANGED) && (spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG);
+}
+
+SpellCastResult GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form);
inline bool IsChanneledSpell(SpellEntry const* spellInfo)
{
@@ -446,6 +328,17 @@ inline uint32 GetSpellMechanicMask(SpellEntry const* spellInfo, int32 effect)
return mask;
}
+inline uint32 GetAllSpellMechanicMask(SpellEntry const* spellInfo)
+{
+ uint32 mask = 0;
+ if (spellInfo->Mechanic)
+ mask |= 1<<spellInfo->Mechanic;
+ for (int i=0; i< 3; ++i)
+ if (spellInfo->EffectMechanic[i])
+ mask |= 1<<spellInfo->EffectMechanic[i];
+ return mask;
+}
+
inline Mechanics GetEffectMechanic(SpellEntry const* spellInfo, int32 effect)
{
if (spellInfo->EffectMechanic[effect])
@@ -470,7 +363,7 @@ bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group);
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group);
// Spell affects related declarations (accessed using SpellMgr functions)
-typedef std::map<uint32, uint64> SpellAffectMap;
+typedef UNORDERED_MAP<uint32, flag96> SpellAffectMap;
// Spell proc event related declarations (accessed using SpellMgr functions)
enum ProcFlags
@@ -478,16 +371,16 @@ enum ProcFlags
PROC_FLAG_NONE = 0x00000000,
PROC_FLAG_KILLED = 0x00000001, // 00 Killed by agressor
- PROC_FLAG_KILL_AND_GET_XP = 0x00000002, // 01 Kill that yields experience or honor
+ PROC_FLAG_KILL = 0x00000002, // 01 Kill target (in most cases need XP/Honor reward)
- PROC_FLAG_SUCCESSFUL_MILEE_HIT = 0x00000004, // 02 Successful melee attack
- PROC_FLAG_TAKEN_MELEE_HIT = 0x00000008, // 03 Taken damage from melee strike hit
+ PROC_FLAG_SUCCESSFUL_MILEE_HIT = 0x00000004, // 02 Successful melee auto attack
+ PROC_FLAG_TAKEN_MELEE_HIT = 0x00000008, // 03 Taken damage from melee auto attack hit
PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT = 0x00000010, // 04 Successful attack by Spell that use melee weapon
PROC_FLAG_TAKEN_MELEE_SPELL_HIT = 0x00000020, // 05 Taken damage by Spell that use melee weapon
- PROC_FLAG_SUCCESSFUL_RANGED_HIT = 0x00000040, // 06 Successful Ranged attack (all ranged attack deal as spell so newer set :( )
- PROC_FLAG_TAKEN_RANGED_HIT = 0x00000080, // 07 Taken damage from ranged attack (all ranged attack deal as spell so newer set :( )
+ PROC_FLAG_SUCCESSFUL_RANGED_HIT = 0x00000040, // 06 Successful Ranged auto attack
+ PROC_FLAG_TAKEN_RANGED_HIT = 0x00000080, // 07 Taken damage from ranged auto attack
PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT = 0x00000100, // 08 Successful Ranged attack by Spell that use ranged weapon
PROC_FLAG_TAKEN_RANGED_SPELL_HIT = 0x00000200, // 09 Taken damage by Spell that use ranged weapon
@@ -512,6 +405,7 @@ enum ProcFlags
PROC_FLAG_TAKEN_OFFHAND_HIT = 0x00400000, // 22 Taken off-hand melee attacks(not used)
PROC_FLAG_SUCCESSFUL_OFFHAND_HIT = 0x00800000 // 23 Successful off-hand melee attacks
+// PROC_FLAG_DEATH = 0x01000000
};
#define MELEE_BASED_TRIGGER_MASK (PROC_FLAG_SUCCESSFUL_MILEE_HIT | \
@@ -538,19 +432,28 @@ enum ProcFlagsEx
PROC_EX_DEFLECT = 0x0000200,
PROC_EX_ABSORB = 0x0000400,
PROC_EX_REFLECT = 0x0000800,
- PROC_EX_INTERRUPT = 0x0001000, // Melle hit result can be Interrupt (not used)
- PROC_EX_RESERVED1 = 0x0002000,
- PROC_EX_RESERVED2 = 0x0004000,
- PROC_EX_RESERVED3 = 0x0008000,
+ PROC_EX_INTERRUPT = 0x0001000, // Melee hit result can be Interrupt (not used)
+ PROC_EX_AURA_REMOVE_DESTROY = 0x0002000, // aura absorb destroy or dispel
+ PROC_EX_AURA_REMOVE_EXPIRE = 0x0004000, // aura remove by default and by cancel
PROC_EX_EX_TRIGGER_ALWAYS = 0x0010000, // If set trigger always ( no matter another flags) used for drop charges
- PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000 // If set trigger always but only one time
+ PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000, // If set trigger always but only one time (not used)
+ PROC_EX_INTERNAL_TRIGGERED = 0x4000000, // Only for internal use
+ PROC_EX_INTERNAL_ITEM_CAST = 0x8000000
};
+#define AURA_REMOVE_PROC_EX_MASK \
+ (PROC_EX_AURA_REMOVE_DESTROY | PROC_EX_AURA_REMOVE_EXPIRE)
+
+#define AURA_SPELL_PROC_EX_MASK \
+ (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT | PROC_EX_MISS | \
+ PROC_EX_RESIST | PROC_EX_DODGE | PROC_EX_PARRY | PROC_EX_BLOCK | \
+ PROC_EX_EVADE | PROC_EX_IMMUNE | PROC_EX_DEFLECT | \
+ PROC_EX_ABSORB | PROC_EX_REFLECT | PROC_EX_INTERRUPT)
struct SpellProcEventEntry
{
uint32 schoolMask; // if nonzero - bit mask for matching proc condition based on spell candidate's school: Fire=2, Mask=1<<(2-1)=2
uint32 spellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyNamer value
- uint64 spellFamilyMask; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do)
+ flag96 spellFamilyMask; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do)
uint32 procFlags; // bitmask for matching proc event
uint32 procEx; // proc Extend info (see ProcFlagsEx)
float ppmRate; // for melee (ranged?) damage spells - proc rate per minute. if zero, falls back to flat chance from Spell.dbc
@@ -558,7 +461,15 @@ struct SpellProcEventEntry
uint32 cooldown; // hidden cooldown used for some spell proc events, applied to _triggered_spell_
};
+struct SpellBonusEntry
+{
+ float direct_damage;
+ float dot_damage;
+ float ap_bonus;
+};
+
typedef UNORDERED_MAP<uint32, SpellProcEventEntry> SpellProcEventMap;
+typedef UNORDERED_MAP<uint32, SpellBonusEntry> SpellBonusMap;
#define ELIXIR_BATTLE_MASK 0x1
#define ELIXIR_GUARDIAN_MASK 0x2
@@ -621,9 +532,9 @@ class PetAura
return itr->second;
else
{
- std::map<uint16, uint16>::const_iterator itr = auras.find(0);
- if(itr != auras.end())
- return itr->second;
+ std::map<uint16, uint16>::const_iterator itr2 = auras.find(0);
+ if(itr2 != auras.end())
+ return itr2->second;
else
return 0;
}
@@ -651,6 +562,32 @@ class PetAura
};
typedef std::map<uint16, PetAura> SpellPetAuraMap;
+struct SpellArea
+{
+ uint32 spellId;
+ uint32 areaId; // zone/subzone/or 0 is not limited to zone
+ uint32 questStart; // quest start (quest must be active or rewarded for spell apply)
+ uint32 questEnd; // quest end (quest don't must be rewarded for spell apply)
+ int32 auraSpell; // spell aura must be applied for spell apply )if possitive) and it don't must be applied in other case
+ uint32 raceMask; // can be applied only to races
+ Gender gender; // can be applied only to gender
+ bool questStartCanActive; // if true then quest start can be active (not only rewarded)
+ bool autocast; // if true then auto applied at area enter, in other case just allowed to cast
+
+ // helpers
+ bool IsFitToRequirements(Player const* player, uint32 newZone, uint32 newArea) const;
+};
+
+typedef std::multimap<uint32,SpellArea> SpellAreaMap;
+typedef std::multimap<uint32,SpellArea const*> SpellAreaForQuestMap;
+typedef std::multimap<uint32,SpellArea const*> SpellAreaForAuraMap;
+typedef std::multimap<uint32,SpellArea const*> SpellAreaForAreaMap;
+typedef std::pair<SpellAreaMap::const_iterator,SpellAreaMap::const_iterator> SpellAreaMapBounds;
+typedef std::pair<SpellAreaForQuestMap::const_iterator,SpellAreaForQuestMap::const_iterator> SpellAreaForQuestMapBounds;
+typedef std::pair<SpellAreaForAuraMap::const_iterator, SpellAreaForAuraMap::const_iterator> SpellAreaForAuraMapBounds;
+typedef std::pair<SpellAreaForAreaMap::const_iterator, SpellAreaForAreaMap::const_iterator> SpellAreaForAreaMapBounds;
+
+
// Spell rank chain (accessed using SpellMgr functions)
struct SpellChainNode
{
@@ -681,6 +618,7 @@ typedef std::map<uint32, SpellLearnSkillNode> SpellLearnSkillMap;
struct SpellLearnSpellNode
{
uint32 spell;
+ bool active; // show in spellbook or not
bool autoLearned;
};
@@ -688,6 +626,9 @@ typedef std::multimap<uint32, SpellLearnSpellNode> SpellLearnSpellMap;
typedef std::multimap<uint32, SkillLineAbilityEntry const*> SkillLineAbilityMap;
+typedef std::multimap<uint32, std::pair < uint32,uint32 > >PetLevelupSpellMap;
+//typedef std::map<uint32, PetLevelupSpellSet> PetLevelupSpellMap;
+
inline bool IsPrimaryProfessionSkill(uint32 skill)
{
SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(skill);
@@ -725,6 +666,11 @@ typedef std::vector<uint32> SpellCustomAttribute;
typedef std::map<int32, std::vector<int32> > SpellLinkedMap;
+inline bool IsProfessionOrRidingSkill(uint32 skill)
+{
+ return IsProfessionSkill(skill) || skill == SKILL_RIDING;
+}
+
class SpellMgr
{
// Constructors
@@ -732,18 +678,18 @@ class SpellMgr
SpellMgr();
~SpellMgr();
- // Accessors (const or static functions)
+ // Accessors (const or static functions)
public:
// Spell affects
- uint64 GetSpellAffectMask(uint16 spellId, uint8 effectId) const
+ flag96 const*GetSpellAffect(uint16 spellId, uint8 effectId) const
{
SpellAffectMap::const_iterator itr = mSpellAffectMap.find((spellId<<8) + effectId);
if( itr != mSpellAffectMap.end( ) )
- return itr->second;
+ return &itr->second;
return 0;
}
- bool IsAffectedBySpell(SpellEntry const *spellInfo, uint32 spellId, uint8 effectId, uint64 familyFlags) const;
+ bool IsAffectedByMod(SpellEntry const *spellInfo, SpellModifier *mod) const;
SpellElixirMap const& GetSpellElixirMap() const { return mSpellElixirs; }
@@ -778,7 +724,24 @@ class SpellMgr
return NULL;
}
- static bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active);
+ bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active);
+
+ // Spell bonus data
+ SpellBonusEntry const* GetSpellBonusData(uint32 spellId) const
+ {
+ // Lookup data
+ SpellBonusMap::const_iterator itr = mSpellBonusMap.find(spellId);
+ if( itr != mSpellBonusMap.end( ) )
+ return &itr->second;
+ // Not found, try lookup for 1 spell rank if exist
+ if (uint32 rank_1 = GetFirstSpellInChain(spellId))
+ {
+ SpellBonusMap::const_iterator itr2 = mSpellBonusMap.find(rank_1);
+ if( itr2 != mSpellBonusMap.end( ) )
+ return &itr2->second;
+ }
+ return NULL;
+ }
// Spell target coordinates
SpellTargetPosition const* GetSpellTargetPosition(uint32 spell_id) const
@@ -824,6 +787,14 @@ class SpellMgr
return 0;
}
+ uint32 GetNextSpellInChain(uint32 spell_id) const
+ {
+ if(SpellChainNode const* node = GetSpellChainNode(spell_id))
+ return node->next;
+
+ return 0;
+ }
+
SpellsRequiringSpellMap const& GetSpellsRequiringSpell() const { return mSpellsReqSpell; }
// Note: not use rank for compare to spell ranks: spell chains isn't linear order
@@ -880,7 +851,7 @@ class SpellMgr
bool IsSpellLearnSpell(uint32 spell_id) const
{
- return mSpellLearnSpells.count(spell_id)!=0;
+ return mSpellLearnSpells.find(spell_id) != mSpellLearnSpells.end();
}
SpellLearnSpellMap::const_iterator GetBeginSpellLearnSpell(uint32 spell_id) const
@@ -903,10 +874,14 @@ class SpellMgr
return false;
}
+ static bool IsProfessionOrRidingSpell(uint32 spellId);
static bool IsProfessionSpell(uint32 spellId);
static bool IsPrimaryProfessionSpell(uint32 spellId);
bool IsPrimaryProfessionFirstRankSpell(uint32 spellId) const;
+ bool IsSkillBonusSpell(uint32 spellId) const;
+
+
// Spell script targets
SpellScriptTarget::const_iterator GetBeginSpellScriptTarget(uint32 spell_id) const
{
@@ -946,11 +921,6 @@ class SpellMgr
return 0;
else
return mSpellCustomAttr[spell_id];
- /*SpellCustomAttrMap::const_iterator itr = mSpellCustomAttrMap.find(spell_id);
- if(itr != mSpellCustomAttrMap.end())
- return itr->second;
- else
- return 0;*/
}
const std::vector<int32> *GetSpellLinked(int32 spell_id) const
@@ -962,7 +932,42 @@ class SpellMgr
SpellEffectTargetTypes EffectTargetType[TOTAL_SPELL_EFFECTS];
SpellSelectTargetTypes SpellTargetType[TOTAL_SPELL_TARGETS];
- // Modifiers
+ SpellCastResult GetSpellAllowedInLocationError(SpellEntry const *spellInfo, uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player = NULL);
+
+ SpellAreaMapBounds GetSpellAreaMapBounds(uint32 spell_id) const
+ {
+ return SpellAreaMapBounds(mSpellAreaMap.lower_bound(spell_id),mSpellAreaMap.upper_bound(spell_id));
+ }
+
+ SpellAreaForQuestMapBounds GetSpellAreaForQuestMapBounds(uint32 quest_id, bool active) const
+ {
+ if(active)
+ return SpellAreaForQuestMapBounds(mSpellAreaForActiveQuestMap.lower_bound(quest_id),mSpellAreaForActiveQuestMap.upper_bound(quest_id));
+ else
+ return SpellAreaForQuestMapBounds(mSpellAreaForQuestMap.lower_bound(quest_id),mSpellAreaForQuestMap.upper_bound(quest_id));
+ }
+
+ SpellAreaForQuestMapBounds GetSpellAreaForQuestEndMapBounds(uint32 quest_id) const
+ {
+ return SpellAreaForQuestMapBounds(mSpellAreaForQuestEndMap.lower_bound(quest_id),mSpellAreaForQuestEndMap.upper_bound(quest_id));
+ }
+
+ SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds(uint32 spell_id) const
+ {
+ return SpellAreaForAuraMapBounds(mSpellAreaForAuraMap.lower_bound(spell_id),mSpellAreaForAuraMap.upper_bound(spell_id));
+ }
+
+ SpellAreaForAreaMapBounds GetSpellAreaForAreaMapBounds(uint32 area_id) const
+ {
+ return SpellAreaForAreaMapBounds(mSpellAreaForAreaMap.lower_bound(area_id),mSpellAreaForAreaMap.upper_bound(area_id));
+ }
+
+ PetLevelupSpellMap const * GetPetLevelupSpellMap() const
+ {
+ return &mPetLevelupSpellMap;
+ }
+
+ // Modifiers
public:
static SpellMgr& Instance();
@@ -975,12 +980,15 @@ class SpellMgr
void LoadSpellAffects();
void LoadSpellElixirs();
void LoadSpellProcEvents();
+ void LoadSpellBonusess();
void LoadSpellTargetPositions();
void LoadSpellThreats();
void LoadSkillLineAbilityMap();
void LoadSpellPetAuras();
void LoadSpellCustomAttr();
void LoadSpellLinked();
+ void LoadPetLevelupSpellMap();
+ void LoadSpellAreas();
private:
SpellScriptTarget mSpellScriptTarget;
@@ -993,10 +1001,18 @@ class SpellMgr
SpellAffectMap mSpellAffectMap;
SpellElixirMap mSpellElixirs;
SpellProcEventMap mSpellProcEventMap;
+ SpellBonusMap mSpellBonusMap;
SkillLineAbilityMap mSkillLineAbilityMap;
SpellPetAuraMap mSpellPetAuraMap;
SpellCustomAttribute mSpellCustomAttr;
SpellLinkedMap mSpellLinkedMap;
+ PetLevelupSpellMap mPetLevelupSpellMap;
+ SpellAreaMap mSpellAreaMap;
+ SpellAreaForQuestMap mSpellAreaForQuestMap;
+ SpellAreaForQuestMap mSpellAreaForActiveQuestMap;
+ SpellAreaForQuestMap mSpellAreaForQuestEndMap;
+ SpellAreaForAuraMap mSpellAreaForAuraMap;
+ SpellAreaForAreaMap mSpellAreaForAreaMap;
};
#define spellmgr SpellMgr::Instance()
diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp
index ae96953e337..4cf93760957 100644
--- a/src/game/StatSystem.cpp
+++ b/src/game/StatSystem.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -51,24 +51,17 @@ bool Player::UpdateStats(Stats stat)
switch(stat)
{
case STAT_STRENGTH:
- UpdateAttackPowerAndDamage();
UpdateShieldBlockValue();
break;
case STAT_AGILITY:
UpdateArmor();
- UpdateAttackPowerAndDamage(true);
- if(getClass() == CLASS_ROGUE || getClass() == CLASS_HUNTER || getClass() == CLASS_DRUID && m_form==FORM_CAT)
- UpdateAttackPowerAndDamage();
-
UpdateAllCritPercentages();
UpdateDodgePercentage();
break;
-
case STAT_STAMINA: UpdateMaxHealth(); break;
case STAT_INTELLECT:
UpdateMaxPower(POWER_MANA);
UpdateAllSpellCritChances();
- UpdateAttackPowerAndDamage(true); //SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT, only intellect currently
UpdateArmor(); //SPELL_AURA_MOD_RESISTANCE_OF_INTELLECT_PERCENT, only armor currently
break;
@@ -78,11 +71,60 @@ bool Player::UpdateStats(Stats stat)
default:
break;
}
+
+ if (stat == STAT_STRENGTH)
+ {
+ UpdateAttackPowerAndDamage(false);
+ if (HasAuraTypeWithMiscvalue(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT, stat))
+ UpdateAttackPowerAndDamage(true);
+ }
+ else if (stat == STAT_AGILITY)
+ {
+ UpdateAttackPowerAndDamage(false);
+ UpdateAttackPowerAndDamage(true);
+ }
+ else
+ {
+ // Need update (exist AP from stat auras)
+ if (HasAuraTypeWithMiscvalue(SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT, stat))
+ UpdateAttackPowerAndDamage(false);
+ if (HasAuraTypeWithMiscvalue(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT, stat))
+ UpdateAttackPowerAndDamage(true);
+ }
+
UpdateSpellDamageAndHealingBonus();
UpdateManaRegen();
+
+ // Update ratings in exist SPELL_AURA_MOD_RATING_FROM_STAT and only depends from stat
+ uint32 mask = 0;
+ AuraEffectList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT);
+ for(AuraEffectList::const_iterator i = modRatingFromStat.begin();i != modRatingFromStat.end(); ++i)
+ if (Stats((*i)->GetMiscBValue()) == stat)
+ mask |= (*i)->GetMiscValue();
+ if (mask)
+ {
+ for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
+ if (mask & (1 << rating))
+ ApplyRatingMod(CombatRating(rating), 0, true);
+ }
return true;
}
+void Player::ApplySpellDamageBonus(int32 amount, bool apply)
+{
+ m_baseSpellDamage+=apply?amount:-amount;
+ // For speed just update for client
+ for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
+ ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, amount, apply);
+}
+
+void Player::ApplySpellHealingBonus(int32 amount, bool apply)
+{
+ m_baseSpellHealing+=apply?amount:-amount;
+ // For speed just update for client
+ ApplyModUInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, amount, apply);
+}
+
void Player::UpdateSpellDamageAndHealingBonus()
{
// Magic damage modifiers implemented in Unit::SpellDamageBonus
@@ -90,13 +132,13 @@ void Player::UpdateSpellDamageAndHealingBonus()
// Get healing bonus for all schools
SetStatInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, SpellBaseHealingBonus(SPELL_SCHOOL_MASK_ALL));
// Get damage bonus for all schools
- for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
+ for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
SetStatInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, SpellBaseDamageBonus(SpellSchoolMask(1 << i)));
}
bool Player::UpdateAllStats()
{
- for (int i = STAT_STRENGTH; i < MAX_STATS; i++)
+ for (int i = STAT_STRENGTH; i < MAX_STATS; ++i)
{
float value = GetTotalStatValue(Stats(i));
SetStat(Stats(i), (int32)value);
@@ -107,7 +149,7 @@ bool Player::UpdateAllStats()
UpdateArmor();
UpdateMaxHealth();
- for(int i = POWER_MANA; i < MAX_POWERS; i++)
+ for(int i = POWER_MANA; i < MAX_POWERS; ++i)
UpdateMaxPower(Powers(i));
UpdateAllCritPercentages();
@@ -118,7 +160,7 @@ bool Player::UpdateAllStats()
UpdateManaRegen();
UpdateExpertise(BASE_ATTACK);
UpdateExpertise(OFF_ATTACK);
- for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
+ for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
UpdateResistances(i);
return true;
@@ -150,12 +192,11 @@ void Player::UpdateArmor()
value += GetModifierValue(unitMod, TOTAL_VALUE);
//add dynamic flat mods
- AuraList const& mResbyIntellect = GetAurasByType(SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT);
- for(AuraList::const_iterator i = mResbyIntellect.begin();i != mResbyIntellect.end(); ++i)
+ AuraEffectList const& mResbyIntellect = GetAurasByType(SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT);
+ for(AuraEffectList::const_iterator i = mResbyIntellect.begin();i != mResbyIntellect.end(); ++i)
{
- Modifier* mod = (*i)->GetModifier();
- if(mod->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL)
- value += int32(GetStat(Stats((*i)->GetMiscBValue())) * (*i)->GetModifierValue() / 100.0f);
+ if((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
+ value += int32(GetStat(Stats((*i)->GetMiscBValue())) * (*i)->GetAmount() / 100.0f);
}
value *= GetModifierValue(unitMod, TOTAL_PCT);
@@ -213,6 +254,12 @@ void Player::UpdateMaxPower(Powers power)
SetMaxPower(power, uint32(value));
}
+void Player::ApplyFeralAPBonus(int32 amount, bool apply)
+{
+ m_baseFeralAP+= apply ? amount:-amount;
+ UpdateAttackPowerAndDamage();
+}
+
void Player::UpdateAttackPowerAndDamage(bool ranged )
{
float val2 = 0.0f;
@@ -253,11 +300,12 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
{
switch(getClass())
{
- case CLASS_WARRIOR: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break;
- case CLASS_PALADIN: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break;
- case CLASS_ROGUE: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break;
- case CLASS_HUNTER: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break;
- case CLASS_SHAMAN: val2 = level*2.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break;
+ case CLASS_WARRIOR: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break;
+ case CLASS_PALADIN: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break;
+ case CLASS_DEATH_KNIGHT: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break;
+ case CLASS_ROGUE: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break;
+ case CLASS_HUNTER: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break;
+ case CLASS_SHAMAN: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break;
case CLASS_DRUID:
{
//Check if Predatory Strikes is skilled
@@ -269,13 +317,13 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
case FORM_DIREBEAR:
case FORM_MOONKIN:
{
- Unit::AuraList const& mDummy = GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr)
+ Unit::AuraEffectList const& mDummy = GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraEffectList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr)
{
// Predatory Strikes
if ((*itr)->GetSpellProto()->SpellIconID == 1563)
{
- mLevelMult = (*itr)->GetModifier()->m_amount / 100.0f;
+ mLevelMult = (*itr)->GetAmount() / 100.0f;
break;
}
}
@@ -286,12 +334,12 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
switch(m_form)
{
case FORM_CAT:
- val2 = getLevel()*(mLevelMult+2.0f) + GetStat(STAT_STRENGTH)*2.0f + GetStat(STAT_AGILITY) - 20.0f; break;
+ val2 = getLevel()*(mLevelMult+2.0f) + GetStat(STAT_STRENGTH)*2.0f + GetStat(STAT_AGILITY) - 20.0f + m_baseFeralAP; break;
case FORM_BEAR:
case FORM_DIREBEAR:
- val2 = getLevel()*(mLevelMult+3.0f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break;
+ val2 = getLevel()*(mLevelMult+3.0f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f + m_baseFeralAP; break;
case FORM_MOONKIN:
- val2 = getLevel()*(mLevelMult+1.5f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break;
+ val2 = getLevel()*(mLevelMult+1.5f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f + m_baseFeralAP; break;
default:
val2 = GetStat(STAT_STRENGTH)*2.0f - 20.0f; break;
}
@@ -309,17 +357,26 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
//add dynamic flat mods
- if( ranged && (getClassMask() & CLASSMASK_WAND_USERS)==0)
+ if( ranged )
{
- AuraList const& mRAPbyIntellect = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT);
- for(AuraList::const_iterator i = mRAPbyIntellect.begin();i != mRAPbyIntellect.end(); ++i)
- attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifierValue() / 100.0f);
+ if ((getClassMask() & CLASSMASK_WAND_USERS)==0)
+ {
+ AuraEffectList const& mRAPbyStat = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT);
+ for(AuraEffectList::const_iterator i = mRAPbyStat.begin();i != mRAPbyStat.end(); ++i)
+ attPowerMod += int32(GetStat(Stats((*i)->GetMiscValue())) * (*i)->GetAmount() / 100.0f);
+ }
+ }
+ else
+ {
+ AuraEffectList const& mAPbyStat = GetAurasByType(SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT);
+ for(AuraEffectList::const_iterator i = mAPbyStat.begin();i != mAPbyStat.end(); ++i)
+ attPowerMod += int32(GetStat(Stats((*i)->GetMiscValue())) * (*i)->GetAmount() / 100.0f);
}
float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
- SetUInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field
- SetUInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field
+ SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field
+ SetInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field
SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field
//automatically update weapon damage after attack power modification
@@ -386,8 +443,15 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, fl
weapon_mindamage = lvl*0.85*att_speed;
weapon_maxdamage = lvl*1.25*att_speed;
}
- else if(!IsUseEquipedWeapon(attType==BASE_ATTACK)) //check if player not in form but still can't use weapon (broken/etc)
+ else if(!CanUseAttackType(attType)) //check if player not in form but still can't use (disarm case)
{
+ //cannot use ranged/off attack, set values to 0
+ if (attType != BASE_ATTACK)
+ {
+ min_damage=0;
+ max_damage=0;
+ return;
+ }
weapon_mindamage = BASE_MINDAMAGE;
weapon_maxdamage = BASE_MAXDAMAGE;
}
@@ -554,9 +618,27 @@ void Player::UpdateSpellCritChance(uint32 school)
SetFloatValue(PLAYER_SPELL_CRIT_PERCENTAGE1 + school, crit);
}
+void Player::UpdateMeleeHitChances()
+{
+ m_modMeleeHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
+ m_modMeleeHitChance+= GetRatingBonusValue(CR_HIT_MELEE);
+}
+
+void Player::UpdateRangedHitChances()
+{
+ m_modRangedHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
+ m_modRangedHitChance+= GetRatingBonusValue(CR_HIT_RANGED);
+}
+
+void Player::UpdateSpellHitChances()
+{
+ m_modSpellHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ m_modSpellHitChance+= GetRatingBonusValue(CR_HIT_SPELL);
+}
+
void Player::UpdateAllSpellCritChances()
{
- for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
+ for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
UpdateSpellCritChance(i);
}
@@ -569,15 +651,15 @@ void Player::UpdateExpertise(WeaponAttackType attack)
Item *weapon = GetWeaponForAttack(attack);
- AuraList const& expAuras = GetAurasByType(SPELL_AURA_MOD_EXPERTISE);
- for(AuraList::const_iterator itr = expAuras.begin(); itr != expAuras.end(); ++itr)
+ AuraEffectList const& expAuras = GetAurasByType(SPELL_AURA_MOD_EXPERTISE);
+ for(AuraEffectList::const_iterator itr = expAuras.begin(); itr != expAuras.end(); ++itr)
{
// item neutral spell
if((*itr)->GetSpellProto()->EquippedItemClass == -1)
- expertise += (*itr)->GetModifierValue();
+ expertise += (*itr)->GetAmount();
// item dependent spell
else if(weapon && weapon->IsFitToSpellRequirements((*itr)->GetSpellProto()))
- expertise += (*itr)->GetModifierValue();
+ expertise += (*itr)->GetAmount();
}
if(expertise < 0)
@@ -591,6 +673,12 @@ void Player::UpdateExpertise(WeaponAttackType attack)
}
}
+void Player::ApplyManaRegenBonus(int32 amount, bool apply)
+{
+ m_baseManaRegen+= apply ? amount : -amount;
+ UpdateManaRegen();
+}
+
void Player::UpdateManaRegen()
{
float Intellect = GetStat(STAT_INTELLECT);
@@ -600,33 +688,22 @@ void Player::UpdateManaRegen()
power_regen *= GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, POWER_MANA);
// Mana regen from SPELL_AURA_MOD_POWER_REGEN aura
- float power_regen_mp5 = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) / 5.0f;
+ float power_regen_mp5 = (GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) + m_baseManaRegen) / 5.0f;
// Get bonus from SPELL_AURA_MOD_MANA_REGEN_FROM_STAT aura
- AuraList const& regenAura = GetAurasByType(SPELL_AURA_MOD_MANA_REGEN_FROM_STAT);
- for(AuraList::const_iterator i = regenAura.begin();i != regenAura.end(); ++i)
+ AuraEffectList const& regenAura = GetAurasByType(SPELL_AURA_MOD_MANA_REGEN_FROM_STAT);
+ for(AuraEffectList::const_iterator i = regenAura.begin();i != regenAura.end(); ++i)
{
- Modifier* mod = (*i)->GetModifier();
- power_regen_mp5 += GetStat(Stats(mod->m_miscvalue)) * (*i)->GetModifierValue() / 500.0f;
+ power_regen_mp5 += GetStat(Stats((*i)->GetMiscValue())) * (*i)->GetAmount() / 500.0f;
}
- // Bonus from some dummy auras
- AuraList const& mDummyAuras = GetAurasByType(SPELL_AURA_PERIODIC_DUMMY);
- for(AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
- if((*i)->GetId() == 34074) // Aspect of the Viper
- {
- power_regen_mp5 += (*i)->GetModifier()->m_amount * Intellect / 500.0f;
- // Add regen bonus from level in this dummy
- power_regen_mp5 += getLevel() * 35 / 100;
- }
-
// Set regen rate in cast state apply only on spirit based regen
int32 modManaRegenInterrupt = GetTotalAuraModifier(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT);
if (modManaRegenInterrupt > 100)
modManaRegenInterrupt = 100;
- SetStatFloatValue(PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT, power_regen_mp5 + power_regen * modManaRegenInterrupt / 100.0f);
+ SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER, power_regen_mp5 + power_regen * modManaRegenInterrupt / 100.0f);
- SetStatFloatValue(PLAYER_FIELD_MOD_MANA_REGEN, power_regen_mp5 + power_regen);
+ SetStatFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER, power_regen_mp5 + power_regen);
}
void Player::_ApplyAllStatBonuses()
@@ -712,6 +789,27 @@ void Creature::UpdateMaxPower(Powers power)
void Creature::UpdateAttackPowerAndDamage(bool ranged)
{
+ UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER;
+
+ uint16 index = UNIT_FIELD_ATTACK_POWER;
+ uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MODS;
+ uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER;
+
+ if(ranged)
+ {
+ index = UNIT_FIELD_RANGED_ATTACK_POWER;
+ index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS;
+ index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER;
+ }
+
+ float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT);
+ float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
+ float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
+
+ SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field
+ SetInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field
+ SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field
+
//automatically update weapon damage after attack power modification
if(ranged)
UpdateDamagePhysical(RANGED_ATTACK);
@@ -755,7 +853,7 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType)
float total_value = GetModifierValue(unitMod, TOTAL_VALUE);
float total_pct = GetModifierValue(unitMod, TOTAL_PCT);
- if(attType == BASE_ATTACK && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED))
+ if(!CanUseAttackType(attType))
{
weapon_mindamage = 0;
weapon_maxdamage = 0;
@@ -827,13 +925,13 @@ bool Pet::UpdateStats(Stats stat)
bool Pet::UpdateAllStats()
{
- for (int i = STAT_STRENGTH; i < MAX_STATS; i++)
+ for (int i = STAT_STRENGTH; i < MAX_STATS; ++i)
UpdateStats(Stats(i));
- for(int i = POWER_MANA; i < MAX_POWERS; i++)
+ for(int i = POWER_MANA; i < MAX_POWERS; ++i)
UpdateMaxPower(Powers(i));
- for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
+ for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
UpdateResistances(i);
return true;
@@ -923,7 +1021,7 @@ void Pet::UpdateAttackPowerAndDamage(bool ranged)
if(getPetType() == HUNTER_PET) //hunter pets benefit from owner's attack power
{
bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f;
- SetBonusDamage( int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.125f));
+ SetBonusDamage( int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f));
}
//demons benefit from warlocks shadow or fire damage
else if(getPetType() == SUMMON_PET && owner->getClass() == CLASS_WARLOCK)
@@ -954,9 +1052,9 @@ void Pet::UpdateAttackPowerAndDamage(bool ranged)
float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
//UNIT_FIELD_(RANGED)_ATTACK_POWER field
- SetUInt32Value(UNIT_FIELD_ATTACK_POWER, (uint32)base_attPower);
+ SetInt32Value(UNIT_FIELD_ATTACK_POWER, (int32)base_attPower);
//UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field
- SetUInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, (uint32)attPowerMod);
+ SetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, (int32)attPowerMod);
//UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field
SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, attPowerMultiplier);
diff --git a/src/game/TargetedMovementGenerator.cpp b/src/game/TargetedMovementGenerator.cpp
index acdf7762b71..6aa4be19765 100644
--- a/src/game/TargetedMovementGenerator.cpp
+++ b/src/game/TargetedMovementGenerator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,7 +22,6 @@
#include "TargetedMovementGenerator.h"
#include "Errors.h"
#include "Creature.h"
-#include "MapManager.h"
#include "DestinationHolderImp.h"
#include "World.h"
@@ -95,8 +94,6 @@ template<class T>
void
TargetedMovementGenerator<T>::Initialize(T &owner)
{
- if(!&owner)
- return;
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
diff --git a/src/game/TargetedMovementGenerator.h b/src/game/TargetedMovementGenerator.h
index 609e517078c..2083dd95369 100644
--- a/src/game/TargetedMovementGenerator.h
+++ b/src/game/TargetedMovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/TaxiHandler.cpp b/src/game/TaxiHandler.cpp
index c65a4214892..24c6aca147a 100644
--- a/src/game/TaxiHandler.cpp
+++ b/src/game/TaxiHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -24,7 +24,6 @@
#include "WorldSession.h"
#include "Opcodes.h"
#include "Log.h"
-#include "World.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "UpdateMask.h"
@@ -49,14 +48,14 @@ void WorldSession::HandleTaxiNodeStatusQueryOpcode( WorldPacket & recv_data )
void WorldSession::SendTaxiStatus( uint64 guid )
{
// cheating checks
- Creature *unit = ObjectAccessor::GetCreature(*_player, guid);
+ Creature *unit = GetPlayer()->GetMap()->GetCreature(guid);
if (!unit)
{
sLog.outDebug( "WorldSession::SendTaxiStatus - Unit (GUID: %u) not found.", uint32(GUID_LOPART(guid)) );
return;
}
- uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId());
+ uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId(),GetPlayer( )->GetTeam());
// not found nearest
if(curloc == 0)
@@ -71,7 +70,7 @@ void WorldSession::SendTaxiStatus( uint64 guid )
sLog.outDebug( "WORLD: Sent SMSG_TAXINODE_STATUS" );
}
-void WorldSession::HandleTaxiQueryAvailableNodesOpcode( WorldPacket & recv_data )
+void WorldSession::HandleTaxiQueryAvailableNodes( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data,8);
@@ -81,7 +80,7 @@ void WorldSession::HandleTaxiQueryAvailableNodesOpcode( WorldPacket & recv_data
recv_data >> guid;
// cheating checks
- Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_FLIGHTMASTER);
+ Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_FLIGHTMASTER);
if (!unit)
{
sLog.outDebug( "WORLD: HandleTaxiQueryAvailableNodes - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
@@ -90,7 +89,7 @@ void WorldSession::HandleTaxiQueryAvailableNodesOpcode( WorldPacket & recv_data
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
// unknown taxi node case
if( SendLearnNewTaxiNode(unit) )
@@ -103,7 +102,7 @@ void WorldSession::HandleTaxiQueryAvailableNodesOpcode( WorldPacket & recv_data
void WorldSession::SendTaxiMenu( Creature* unit )
{
// find current node
- uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId());
+ uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId(),GetPlayer( )->GetTeam());
if ( curloc == 0 )
return;
@@ -124,7 +123,7 @@ void WorldSession::SendDoFlight( uint16 MountId, uint32 path, uint32 pathNode )
{
// remove fake death
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
while(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()==FLIGHT_MOTION_TYPE)
GetPlayer()->GetMotionMaster()->MovementExpired(false);
@@ -136,7 +135,7 @@ void WorldSession::SendDoFlight( uint16 MountId, uint32 path, uint32 pathNode )
bool WorldSession::SendLearnNewTaxiNode( Creature* unit )
{
// find current node
- uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId());
+ uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId(),GetPlayer( )->GetTeam());
if ( curloc == 0 )
return true; // `true` send to avoid WorldSession::SendTaxiMenu call with one more curlock seartch with same false result.
@@ -168,7 +167,7 @@ void WorldSession::HandleActivateTaxiFarOpcode ( WorldPacket & recv_data )
recv_data >> guid >> _totalcost >> node_count;
- Creature *npc = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_FLIGHTMASTER);
+ Creature *npc = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_FLIGHTMASTER);
if (!npc)
{
sLog.outDebug( "WORLD: HandleActivateTaxiFarOpcode - Unit (GUID: %u) not found or you can't interact with it.", uint32(GUID_LOPART(guid)) );
@@ -269,7 +268,7 @@ void WorldSession::HandleActivateTaxiOpcode( WorldPacket & recv_data )
recv_data >> guid >> nodes[0] >> nodes[1];
sLog.outDebug( "WORLD: Received CMSG_ACTIVATETAXI from %d to %d" ,nodes[0],nodes[1]);
- Creature *npc = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_FLIGHTMASTER);
+ Creature *npc = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_FLIGHTMASTER);
if (!npc)
{
sLog.outDebug( "WORLD: HandleActivateTaxiOpcode - Unit (GUID: %u) not found or you can't interact with it.", uint32(GUID_LOPART(guid)) );
diff --git a/src/game/TemporarySummon.cpp b/src/game/TemporarySummon.cpp
index bbe8fa9c104..cfbc2a65920 100644
--- a/src/game/TemporarySummon.cpp
+++ b/src/game/TemporarySummon.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -18,19 +18,26 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "TemporarySummon.h"
-#include "WorldPacket.h"
-#include "MapManager.h"
#include "Log.h"
#include "ObjectAccessor.h"
#include "CreatureAI.h"
+#include "ObjectMgr.h"
+#include "TemporarySummon.h"
+
+TempSummon::TempSummon(SummonPropertiesEntry const *properties, Unit *owner) :
+Creature(), m_type(TEMPSUMMON_MANUAL_DESPAWN), m_timer(0), m_lifetime(0)
+, m_Properties(properties)
+{
+ m_summonerGUID = owner ? owner->GetGUID() : 0;
+ m_summonMask |= SUMMON_MASK_SUMMON;
+}
-TemporarySummon::TemporarySummon( uint64 summoner ) :
-Creature(), m_type(TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN), m_timer(0), m_lifetime(0), m_summoner(summoner)
+Unit* TempSummon::GetSummoner() const
{
+ return m_summonerGUID ? ObjectAccessor::GetUnit(*this, m_summonerGUID) : NULL;
}
-void TemporarySummon::Update( uint32 diff )
+void TempSummon::Update( uint32 diff )
{
if (m_deathState == DEAD)
{
@@ -159,30 +166,155 @@ void TemporarySummon::Update( uint32 diff )
Creature::Update( diff );
}
-void TemporarySummon::Summon(TempSummonType type, uint32 lifetime)
+void TempSummon::InitSummon(uint32 duration)
{
- m_type = type;
- m_timer = lifetime;
- m_lifetime = lifetime;
+ assert(!isPet());
+
+ m_timer = duration;
+ m_lifetime = duration;
+
+ if(m_type == TEMPSUMMON_MANUAL_DESPAWN)
+ m_type = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
+
+ Unit* owner = GetSummoner();
+ if(owner)
+ {
+ if(owner->GetTypeId()==TYPEID_UNIT && ((Creature*)owner)->IsAIEnabled)
+ ((Creature*)owner)->AI()->JustSummoned(this);
- MapManager::Instance().GetMap(GetMapId(), this)->Add((Creature*)this);
+ if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER && m_spells[0])
+ {
+ setFaction(owner->getFaction());
+ if(m_spells[1] && GetMap()->IsHeroic())
+ CastSpell(this, m_spells[1], false, 0, 0, m_summonerGUID);
+ else
+ CastSpell(this, m_spells[0], false, 0, 0, m_summonerGUID);
+ }
+ }
- AIM_Initialize();
+ if(!m_Properties)
+ return;
+
+ if(uint32 slot = m_Properties->Slot)
+ {
+ if(owner)
+ {
+ if(owner->m_SummonSlot[slot] && owner->m_SummonSlot[slot] != GetGUID())
+ {
+ Creature *oldSummon = GetMap()->GetCreature(owner->m_SummonSlot[slot]);
+ if(oldSummon && oldSummon->isSummon())
+ ((TempSummon*)oldSummon)->UnSummon();
+ }
+ owner->m_SummonSlot[slot] = GetGUID();
+ }
+ }
+
+ if(m_Properties->Faction)
+ setFaction(m_Properties->Faction);
}
-void TemporarySummon::UnSummon()
+void TempSummon::SetTempSummonType(TempSummonType type)
{
+ m_type = type;
+}
+
+void TempSummon::UnSummon()
+{
+ assert(!isPet());
+
+ Unit* owner = GetSummoner();
+ if(owner && owner->GetTypeId() == TYPEID_UNIT && ((Creature*)owner)->IsAIEnabled)
+ ((Creature*)owner)->AI()->SummonedCreatureDespawn(this);
+
CleanupsBeforeDelete();
AddObjectToRemoveList();
+}
+
+void TempSummon::RemoveFromWorld()
+{
+ if(!IsInWorld())
+ return;
- Unit* sum = m_summoner ? ObjectAccessor::GetUnit(*this, m_summoner) : NULL;
- if (sum && sum->GetTypeId() == TYPEID_UNIT && ((Creature*)sum)->IsAIEnabled)
+ if(m_Properties)
{
- ((Creature*)sum)->AI()->SummonedCreatureDespawn(this);
+ if(uint32 slot = m_Properties->Slot)
+ {
+ if(Unit* owner = GetSummoner())
+ {
+ if(owner->m_SummonSlot[slot] = GetGUID())
+ owner->m_SummonSlot[slot] = 0;
+ }
+ }
+ }
+
+ //if(GetOwnerGUID())
+ // sLog.outError("Unit %u has owner guid when removed from world", GetEntry());
+
+ Creature::RemoveFromWorld();
+}
+
+void TempSummon::SaveToDB()
+{
+}
+
+bool TempSummon::SetOwner(Unit *owner, bool apply)
+{
+ if(apply)
+ {
+ if(!AddUInt64Value(UNIT_FIELD_SUMMONEDBY, owner->GetGUID()))
+ {
+ sLog.outCrash("Unit %u is summoned by %u but it already has a owner", GetEntry(), owner->GetEntry());
+ return false;
+ }
+ if(owner->GetTypeId() == TYPEID_PLAYER)
+ {
+ m_ControlledByPlayer = true;
+ SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+ }
+ }
+ else
+ {
+ if(!RemoveUInt64Value(UNIT_FIELD_SUMMONEDBY, owner->GetGUID()))
+ {
+ sLog.outCrash("Unit %u is unsummoned by %u but it has another owner", GetEntry(), owner->GetEntry());
+ return false;
+ }
}
+
+ return true;
}
-void TemporarySummon::SaveToDB()
+Guardian::Guardian(SummonPropertiesEntry const *properties, Unit *owner) : TempSummon(properties, owner)
+, m_owner(owner), m_bonusdamage(0)
{
+ m_summonMask |= SUMMON_MASK_GUARDIAN;
+ InitCharmInfo();
+}
+
+void Guardian::InitSummon(uint32 duration)
+{
+ TempSummon::InitSummon(duration);
+
+ SetReactState(REACT_AGGRESSIVE);
+
+ SetCreatorGUID(m_owner->GetGUID());
+ setFaction(m_owner->getFaction());
+
+ if(m_owner->GetTypeId() == TYPEID_PLAYER)
+ {
+ m_charmInfo->InitCharmCreateSpells();
+ //((Player*)m_owner)->CharmSpellInitialize();
+ }
+
+ m_owner->SetGuardian(this, true);
+}
+
+void Guardian::RemoveFromWorld()
+{
+ if(!IsInWorld())
+ return;
+
+ m_owner->SetGuardian(this, false);
+ TempSummon::RemoveFromWorld();
}
diff --git a/src/game/TemporarySummon.h b/src/game/TemporarySummon.h
index fe9763f5301..c4f24d93273 100644
--- a/src/game/TemporarySummon.h
+++ b/src/game/TemporarySummon.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,23 +22,47 @@
#define TRINITYCORE_TEMPSUMMON_H
#include "Creature.h"
-#include "ObjectAccessor.h"
-class TemporarySummon : public Creature
+class TempSummon : public Creature
{
public:
- explicit TemporarySummon(uint64 summoner = 0);
- virtual ~TemporarySummon(){};
+ explicit TempSummon(SummonPropertiesEntry const *properties, Unit *owner);
+ virtual ~TempSummon(){};
void Update(uint32 time);
- void Summon(TempSummonType type, uint32 lifetime);
+ virtual void InitSummon(uint32 lifetime);
void UnSummon();
+ void RemoveFromWorld();
+ void SetTempSummonType(TempSummonType type);
void SaveToDB();
- Unit* GetSummoner() const { return m_summoner ? ObjectAccessor::GetUnit(*this, m_summoner) : NULL; }
+ Unit* GetSummoner() const;
+
+ SummonPropertiesEntry const *m_Properties;
+
+ bool SetOwner(Unit *owner, bool apply);
private:
TempSummonType m_type;
uint32 m_timer;
uint32 m_lifetime;
- uint64 m_summoner;
+ uint64 m_summonerGUID;
};
+
+class Guardian : public TempSummon
+{
+ public:
+ Guardian(SummonPropertiesEntry const *properties, Unit *owner);
+ bool Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number);
+ void InitSummon(uint32 duration);
+ void RemoveFromWorld();
+ bool InitStatsForLevel(uint32 level);
+
+ int32 GetBonusDamage() { return m_bonusdamage; }
+ void SetBonusDamage(int32 damage) { m_bonusdamage = damage; }
+
+ Unit *GetOwner() { return m_owner; }
+ protected:
+ Unit *m_owner;
+ int32 m_bonusdamage;
+};
+
#endif
diff --git a/src/game/ThreatManager.cpp b/src/game/ThreatManager.cpp
index ac124da6951..ab989ad9598 100644
--- a/src/game/ThreatManager.cpp
+++ b/src/game/ThreatManager.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -23,7 +23,6 @@
#include "Creature.h"
#include "CreatureAI.h"
#include "Map.h"
-#include "MapManager.h"
#include "Player.h"
#include "ObjectAccessor.h"
#include "UnitEvents.h"
@@ -84,7 +83,7 @@ void HostilReference::sourceObjectDestroyLink()
//============================================================
// Inform the source, that the status of the reference changed
-void HostilReference::fireStatusChanged(const ThreatRefStatusChangeEvent& pThreatRefStatusChangeEvent)
+void HostilReference::fireStatusChanged(ThreatRefStatusChangeEvent& pThreatRefStatusChangeEvent)
{
if(getSource())
getSource()->processThreatEvent(&pThreatRefStatusChangeEvent);
@@ -100,7 +99,11 @@ void HostilReference::addThreat(float pMod)
if(!isOnline())
updateOnlineStatus();
if(pMod != 0.0f)
- fireStatusChanged(ThreatRefStatusChangeEvent(UEV_THREAT_REF_THREAT_CHANGE, this, pMod));
+ {
+ ThreatRefStatusChangeEvent event(UEV_THREAT_REF_THREAT_CHANGE, this, pMod);
+ fireStatusChanged(event);
+ }
+
if(isValid() && pMod >= 0)
{
Unit* victim_owner = getTarget()->GetCharmerOrOwner();
@@ -155,8 +158,10 @@ void HostilReference::setOnlineOfflineState(bool pIsOnline)
{
iOnline = pIsOnline;
if(!iOnline)
- setAccessibleState(false); // if not online that not accessible as well
- fireStatusChanged(ThreatRefStatusChangeEvent(UEV_THREAT_REF_ONLINE_STATUS, this));
+ setAccessibleState(false); // if not online that not accessable as well
+
+ ThreatRefStatusChangeEvent event(UEV_THREAT_REF_ONLINE_STATUS, this);
+ fireStatusChanged(event);
}
}
@@ -167,7 +172,9 @@ void HostilReference::setAccessibleState(bool pIsAccessible)
if(iAccessible != pIsAccessible)
{
iAccessible = pIsAccessible;
- fireStatusChanged(ThreatRefStatusChangeEvent(UEV_THREAT_REF_ASSECCIBLE_STATUS, this));
+
+ ThreatRefStatusChangeEvent event(UEV_THREAT_REF_ASSECCIBLE_STATUS, this);
+ fireStatusChanged(event);
}
}
@@ -178,7 +185,9 @@ void HostilReference::setAccessibleState(bool pIsAccessible)
void HostilReference::removeReference()
{
invalidate();
- fireStatusChanged(ThreatRefStatusChangeEvent(UEV_THREAT_REF_REMOVE_FROM_LIST, this));
+
+ ThreatRefStatusChangeEvent event(UEV_THREAT_REF_REMOVE_FROM_LIST, this);
+ fireStatusChanged(event);
}
//============================================================
@@ -194,7 +203,7 @@ Unit* HostilReference::getSourceUnit()
void ThreatContainer::clearReferences()
{
- for(std::list<HostilReference*>::iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
+ for(std::list<HostilReference*>::const_iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
{
(*i)->unlink();
delete (*i);
@@ -208,7 +217,7 @@ HostilReference* ThreatContainer::getReferenceByTarget(Unit* pVictim)
{
HostilReference* result = NULL;
uint64 guid = pVictim->GetGUID();
- for(std::list<HostilReference*>::iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
+ for(std::list<HostilReference*>::const_iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
{
if((*i)->getUnitGuid() == guid)
{
@@ -267,26 +276,36 @@ HostilReference* ThreatContainer::selectNextVictim(Creature* pAttacker, HostilRe
{
HostilReference* currentRef = NULL;
bool found = false;
+ bool noPriorityTargetFound = false;
- std::list<HostilReference*>::iterator lastRef = iThreatList.end();
+ std::list<HostilReference*>::const_iterator lastRef = iThreatList.end();
lastRef--;
- for(std::list<HostilReference*>::iterator iter = iThreatList.begin(); iter != iThreatList.end() && !found; ++iter)
+ for(std::list<HostilReference*>::const_iterator iter = iThreatList.begin(); iter != iThreatList.end() && !found;)
{
currentRef = (*iter);
Unit* target = currentRef->getTarget();
assert(target); // if the ref has status online the target must be there !
- // some units are preferred in comparison to others
- if(iter != lastRef && (target->IsImmunedToDamage(pAttacker->GetMeleeDamageSchoolMask(), false) ||
- target->hasUnitState(UNIT_STAT_CONFUSED)
- ) )
+ // some units are prefered in comparison to others
+ if(!noPriorityTargetFound && (target->IsImmunedToDamage(pAttacker->GetMeleeDamageSchoolMask()) || target->hasNegativeAuraWithInterruptFlag(AURA_INTERRUPT_FLAG_DAMAGE)) )
{
- // current victim is a second choice target, so don't compare threat with it below
- if(currentRef == pCurrentVictim)
- pCurrentVictim = NULL;
- continue;
+ if(iter != lastRef)
+ {
+ // current victim is a second choice target, so don't compare threat with it below
+ if(currentRef == pCurrentVictim)
+ pCurrentVictim = NULL;
+ ++iter;
+ continue;
+ }
+ else
+ {
+ // if we reached to this point, everyone in the threatlist is a second choice target. In such a situation the target with the highest threat should be attacked.
+ noPriorityTargetFound = true;
+ iter = iThreatList.begin();
+ continue;
+ }
}
if(!pAttacker->IsOutOfThreatArea(target)) // skip non attackable currently targets
@@ -314,6 +333,7 @@ HostilReference* ThreatContainer::selectNextVictim(Creature* pAttacker, HostilRe
break;
}
}
+ ++iter;
}
if(!found)
currentRef = NULL;
@@ -347,12 +367,18 @@ void ThreatManager::addThreat(Unit* pVictim, float pThreat, SpellSchoolMask scho
//players and pets have only InHateListOf
//HateOfflineList is used co contain unattackable victims (in-flight, in-water, GM etc.)
- if (pVictim == getOwner()) // only for same creatures :)
+ // not to self
+ if (pVictim == getOwner())
return;
+ // not to GM
if(!pVictim || (pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->isGameMaster()) )
return;
+ // not to dead and not for dead
+ if(!pVictim->isAlive() || !getOwner()->isAlive() )
+ return;
+
assert(getOwner()->GetTypeId()== TYPEID_UNIT);
float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, schoolMask, pThreatSpell);
@@ -450,18 +476,13 @@ void ThreatManager::setCurrentVictim(HostilReference* pHostilReference)
// The hated unit is gone, dead or deleted
// return true, if the event is consumed
-bool ThreatManager::processThreatEvent(const UnitBaseEvent* pUnitBaseEvent)
+void ThreatManager::processThreatEvent(ThreatRefStatusChangeEvent* threatRefStatusChangeEvent)
{
- bool consumed = false;
-
- ThreatRefStatusChangeEvent* threatRefStatusChangeEvent;
- HostilReference* hostilReference;
-
- threatRefStatusChangeEvent = (ThreatRefStatusChangeEvent*) pUnitBaseEvent;
threatRefStatusChangeEvent->setThreatManager(this); // now we can set the threat manager
- hostilReference = threatRefStatusChangeEvent->getReference();
- switch(pUnitBaseEvent->getType())
+ HostilReference* hostilReference = threatRefStatusChangeEvent->getReference();
+
+ switch(threatRefStatusChangeEvent->getType())
{
case UEV_THREAT_REF_THREAT_CHANGE:
if((getCurrentVictim() == hostilReference && threatRefStatusChangeEvent->getFValue()<0.0f) ||
@@ -499,6 +520,5 @@ bool ThreatManager::processThreatEvent(const UnitBaseEvent* pUnitBaseEvent)
iThreatOfflineContainer.remove(hostilReference);
break;
}
- return consumed;
}
diff --git a/src/game/ThreatManager.h b/src/game/ThreatManager.h
index 56281b9f8f3..aa84cb7d52c 100644
--- a/src/game/ThreatManager.h
+++ b/src/game/ThreatManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -45,20 +45,8 @@ class ThreatCalcHelper
};
//==============================================================
-
class TRINITY_DLL_SPEC HostilReference : public Reference<Unit, ThreatManager>
{
- private:
- float iThreat;
- float iTempThreatModifyer; // used for taunt
- uint64 iUnitGuid;
- bool iOnline;
- bool iAccessible;
- private:
- // Inform the source, that the status of that reference was changed
- void fireStatusChanged(const ThreatRefStatusChangeEvent& pThreatRefStatusChangeEvent);
-
- Unit* getSourceUnit();
public:
HostilReference(Unit* pUnit, ThreatManager *pThreatManager, float pThreat);
@@ -125,6 +113,17 @@ class TRINITY_DLL_SPEC HostilReference : public Reference<Unit, ThreatManager>
// Tell our refFrom (source) object, that the link is cut (Target destroyed)
void sourceObjectDestroyLink();
+ private:
+ // Inform the source, that the status of that reference was changed
+ void fireStatusChanged(ThreatRefStatusChangeEvent& pThreatRefStatusChangeEvent);
+
+ Unit* getSourceUnit();
+ private:
+ float iThreat;
+ float iTempThreatModifyer; // used for taunt
+ uint64 iUnitGuid;
+ bool iOnline;
+ bool iAccessible;
};
//==============================================================
@@ -170,14 +169,9 @@ class TRINITY_DLL_SPEC ThreatContainer
class TRINITY_DLL_SPEC ThreatManager
{
- private:
- HostilReference* iCurrentVictim;
- Unit* iOwner;
- ThreatContainer iThreatContainer;
- ThreatContainer iThreatOfflineContainer;
-
- void _addThreat(Unit* target, float threat);
public:
+ friend class HostilReference;
+
explicit ThreatManager(Unit *pOwner);
~ThreatManager() { clearReferences(); }
@@ -191,7 +185,7 @@ class TRINITY_DLL_SPEC ThreatManager
bool isThreatListEmpty() { return iThreatContainer.empty();}
- bool processThreatEvent(const UnitBaseEvent* pUnitBaseEvent);
+ void processThreatEvent(ThreatRefStatusChangeEvent* threatRefStatusChangeEvent);
HostilReference* getCurrentVictim() { return iCurrentVictim; }
@@ -208,10 +202,17 @@ class TRINITY_DLL_SPEC ThreatManager
// methods to access the lists from the outside to do sume dirty manipulation (scriping and such)
// I hope they are used as little as possible.
- inline std::list<HostilReference*>& getThreatList() { return iThreatContainer.getThreatList(); }
- inline std::list<HostilReference*>& getOfflieThreatList() { return iThreatOfflineContainer.getThreatList(); }
- inline ThreatContainer& getOnlineContainer() { return iThreatContainer; }
- inline ThreatContainer& getOfflineContainer() { return iThreatOfflineContainer; }
+ std::list<HostilReference*>& getThreatList() { return iThreatContainer.getThreatList(); }
+ std::list<HostilReference*>& getOfflieThreatList() { return iThreatOfflineContainer.getThreatList(); }
+ ThreatContainer& getOnlineContainer() { return iThreatContainer; }
+ ThreatContainer& getOfflineContainer() { return iThreatOfflineContainer; }
+ private:
+ void _addThreat(Unit *pVictim, float threat);
+
+ HostilReference* iCurrentVictim;
+ Unit* iOwner;
+ ThreatContainer iThreatContainer;
+ ThreatContainer iThreatOfflineContainer;
};
//=================================================
diff --git a/src/game/TicketHandler.cpp b/src/game/TicketHandler.cpp
index 640faacc155..f4af95bb169 100644
--- a/src/game/TicketHandler.cpp
+++ b/src/game/TicketHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS
+ * Copyright (C) 2005-2009 MaNGOS
*
- * Copyright (C) 2008 Trinity
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/TicketMgr.cpp b/src/game/TicketMgr.cpp
index ff26d3ba0f4..52cf1ff0db6 100644
--- a/src/game/TicketMgr.cpp
+++ b/src/game/TicketMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS
+ * Copyright (C) 2005-2009 MaNGOS
*
- * Copyright (C) 2008 Trinity
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/TicketMgr.h b/src/game/TicketMgr.h
index 4cf1b46d97e..491e6657f40 100644
--- a/src/game/TicketMgr.h
+++ b/src/game/TicketMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS
+ * Copyright (C) 2005-2009 MaNGOS
*
- * Copyright (C) 2008 Trinity
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/Tools.cpp b/src/game/Tools.cpp
index e553b86f8e9..d1728c78c9e 100644
--- a/src/game/Tools.cpp
+++ b/src/game/Tools.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/Tools.h b/src/game/Tools.h
index 2a71121129b..bdb3ad8e762 100644
--- a/src/game/Tools.h
+++ b/src/game/Tools.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/Totem.cpp b/src/game/Totem.cpp
index de58a7ef15f..1b23b40fa37 100644
--- a/src/game/Totem.cpp
+++ b/src/game/Totem.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -20,16 +20,15 @@
#include "Totem.h"
#include "WorldPacket.h"
-#include "MapManager.h"
#include "Log.h"
#include "Group.h"
#include "Player.h"
#include "ObjectMgr.h"
#include "SpellMgr.h"
-Totem::Totem() : Creature()
+Totem::Totem(SummonPropertiesEntry const *properties, Unit *owner) : TempSummon(properties, owner)
{
- m_isTotem = true;
+ m_summonMask |= SUMMON_MASK_TOTEM;
m_duration = 0;
m_type = TOTEM_PASSIVE;
}
@@ -37,7 +36,7 @@ Totem::Totem() : Creature()
void Totem::Update( uint32 time )
{
Unit *owner = GetOwner();
- if (!owner || !owner->isAlive() || !this->isAlive())
+ if (!owner || !owner->isAlive() || !isAlive())
{
UnSummon(); // remove self
return;
@@ -54,8 +53,12 @@ void Totem::Update( uint32 time )
Creature::Update( time );
}
-void Totem::Summon(Unit* owner)
+void Totem::InitSummon(uint32 duration)
{
+ Unit *owner = GetOwner();
+ if(!owner)
+ return;
+
CreatureInfo const *cinfo = GetCreatureInfo();
if (owner->GetTypeId()==TYPEID_PLAYER && cinfo)
{
@@ -80,26 +83,32 @@ void Totem::Summon(Unit* owner)
sLog.outErrorDb("Totem::Summon: Missing modelid information for entry %u, team %u, totem will use default values.",GetEntry(),((Player*)owner)->GetTeam());
}
- // Only add if a display exists.
- sLog.outDebug("AddObject at Totem.cpp line 49");
- SetInstanceId(owner->GetInstanceId());
- owner->GetMap()->Add((Creature*)this);
-
WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8);
data << GetGUID();
SendMessageToSet(&data,true);
- AIM_Initialize();
+ if(m_type == TOTEM_PASSIVE)
+ CastSpell(this, GetSpell(), true);
+
+ if(GetEntry() == SENTRY_TOTEM_ENTRY)
+ SetReactState(REACT_AGGRESSIVE);
+
+ m_duration = duration;
+
+ SetCreatorGUID(owner->GetGUID());
+ setFaction(owner->getFaction());
+ SetLevel(owner->getLevel());
- switch(m_type)
+ // Get spell casted by totem
+ SpellEntry const * totemSpell = sSpellStore.LookupEntry(GetSpell());
+ if (totemSpell)
{
- case TOTEM_PASSIVE: CastSpell(this, GetSpell(), true); break;
- case TOTEM_STATUE: CastSpell(GetOwner(), GetSpell(), true); break;
- default: break;
+ // If spell have cast time -> so its active totem
+ if (GetSpellCastTime(totemSpell))
+ m_type = TOTEM_ACTIVE;
}
- if(GetEntry() == SENTRY_TOTEM_ENTRY)
- SetReactState(REACT_AGGRESSIVE);
+ TempSummon::InitSummon(duration);
}
void Totem::UnSummon()
@@ -108,15 +117,15 @@ void Totem::UnSummon()
CombatStop();
RemoveAurasDueToSpell(GetSpell());
- Unit *owner = this->GetOwner();
+ Unit *owner = GetOwner();
if (owner)
{
// clear owenr's totem slot
- for(int i = 0; i < MAX_TOTEM; ++i)
+ for(int i = SUMMON_SLOT_TOTEM; i < MAX_TOTEM_SLOT; ++i)
{
- if(owner->m_TotemSlot[i]==GetGUID())
+ if(owner->m_SummonSlot[i]==GetGUID())
{
- owner->m_TotemSlot[i] = 0;
+ owner->m_SummonSlot[i] = 0;
break;
}
}
@@ -145,52 +154,24 @@ void Totem::UnSummon()
AddObjectToRemoveList();
}
-void Totem::SetOwner(uint64 guid)
-{
- SetCreatorGUID(guid);
- SetOwnerGUID(guid);
- if (Unit *owner = GetOwner())
- {
- this->setFaction(owner->getFaction());
- this->SetLevel(owner->getLevel());
- }
-}
-
Unit *Totem::GetOwner()
{
- uint64 ownerid = GetOwnerGUID();
- if(!ownerid)
- return NULL;
- return ObjectAccessor::GetUnit(*this, ownerid);
+ return GetSummoner();
}
-void Totem::SetTypeBySummonSpell(SpellEntry const * spellProto)
+bool Totem::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const
{
- // Get spell casted by totem
- SpellEntry const * totemSpell = sSpellStore.LookupEntry(GetSpell());
- if (totemSpell)
+ // TODO: possibly all negative auras immuned?
+ switch(spellInfo->EffectApplyAuraName[index])
{
- // If spell have cast time -> so its active totem
- if (GetSpellCastTime(totemSpell))
- m_type = TOTEM_ACTIVE;
+ case SPELL_AURA_PERIODIC_DAMAGE:
+ case SPELL_AURA_PERIODIC_LEECH:
+ case SPELL_AURA_MOD_FEAR:
+ case SPELL_AURA_TRANSFORM:
+ return true;
+ default:
+ break;
}
- if(spellProto->SpellIconID==2056)
- m_type = TOTEM_STATUE; //Jewelery statue
-}
-
-bool Totem::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges)
-{
-/* for (int i=0;i<3;i++)
- {
- switch(spellInfo->EffectApplyAuraName[i])
- {
- case SPELL_AURA_PERIODIC_DAMAGE:
- case SPELL_AURA_PERIODIC_LEECH:
- return true;
- default:
- continue;
- }
- }*/
- return Creature::IsImmunedToSpell(spellInfo, useCharges);
+ return Creature::IsImmunedToSpellEffect(spellInfo, index);
}
diff --git a/src/game/Totem.h b/src/game/Totem.h
index 82b183d5d62..4738e5d00b7 100644
--- a/src/game/Totem.h
+++ b/src/game/Totem.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,32 +21,28 @@
#ifndef TRINITYCORE_TOTEM_H
#define TRINITYCORE_TOTEM_H
-#include "Creature.h"
+#include "TemporarySummon.h"
enum TotemType
{
TOTEM_PASSIVE = 0,
TOTEM_ACTIVE = 1,
- TOTEM_STATUE = 2
};
#define SENTRY_TOTEM_ENTRY 3968
-class Totem : public Creature
+class Totem : public TempSummon
{
public:
- explicit Totem();
+ explicit Totem(SummonPropertiesEntry const *properties, Unit *owner);
virtual ~Totem(){};
void Update( uint32 time );
- void Summon(Unit* owner);
+ void InitSummon(uint32 duration);
void UnSummon();
uint32 GetSpell() const { return m_spells[0]; }
uint32 GetTotemDuration() const { return m_duration; }
Unit *GetOwner();
TotemType GetTotemType() const { return m_type; }
- void SetTypeBySummonSpell(SpellEntry const * spellProto);
- void SetDuration(uint32 dur) { m_duration = dur; }
- void SetOwner(uint64 guid);
bool UpdateStats(Stats /*stat*/) { return true; }
bool UpdateAllStats() { return true; }
@@ -57,7 +53,7 @@ class Totem : public Creature
void UpdateAttackPowerAndDamage(bool /*ranged*/ ) {}
void UpdateDamagePhysical(WeaponAttackType /*attType*/) {}
- bool IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges = false);
+ bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const;
protected:
TotemType m_type;
diff --git a/src/game/TotemAI.cpp b/src/game/TotemAI.cpp
index 3593f8396a1..08c70308d1c 100644
--- a/src/game/TotemAI.cpp
+++ b/src/game/TotemAI.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,9 +21,7 @@
#include "TotemAI.h"
#include "Totem.h"
#include "Creature.h"
-#include "Player.h"
-#include "Database/DBCStores.h"
-#include "MapManager.h"
+#include "DBCStores.h"
#include "ObjectAccessor.h"
#include "SpellMgr.h"
@@ -40,8 +38,9 @@ TotemAI::Permissible(const Creature *creature)
return PERMIT_BASE_NO;
}
-TotemAI::TotemAI(Creature *c) : CreatureAI(c), i_totem(static_cast<Totem&>(*c)), i_victimGuid(0)
+TotemAI::TotemAI(Creature *c) : CreatureAI(c), i_victimGuid(0)
{
+ assert(c->isTotem());
}
void
@@ -51,52 +50,41 @@ TotemAI::MoveInLineOfSight(Unit *)
void TotemAI::EnterEvadeMode()
{
- i_totem.CombatStop();
+ m_creature->CombatStop(true);
}
void
TotemAI::UpdateAI(const uint32 /*diff*/)
{
- if (i_totem.GetTotemType() != TOTEM_ACTIVE)
+ if (((Totem*)m_creature)->GetTotemType() != TOTEM_ACTIVE)
return;
- if (!i_totem.isAlive() || i_totem.IsNonMeleeSpellCasted(false))
+ if (!m_creature->isAlive() || m_creature->IsNonMeleeSpellCasted(false))
return;
// Search spell
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_totem.GetSpell());
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(((Totem*)m_creature)->GetSpell());
if (!spellInfo)
return;
- // Get spell rangy
+ // Get spell range
SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);
- float max_range = GetSpellMaxRange(srange);
+ float max_range = GetSpellMaxRangeForHostile(srange);
// SPELLMOD_RANGE not applied in this place just because not existence range mods for attacking totems
// pointer to appropriate target if found any
- Unit* victim = i_victimGuid ? ObjectAccessor::GetUnit(i_totem, i_victimGuid) : NULL;
+ Unit* victim = i_victimGuid ? ObjectAccessor::GetUnit(*m_creature, i_victimGuid) : NULL;
// Search victim if no, not attackable, or out of range, or friendly (possible in case duel end)
if( !victim ||
- !victim->isTargetableForAttack() || !i_totem.IsWithinDistInMap(victim, max_range) ||
- i_totem.IsFriendlyTo(victim) || !victim->isVisibleForOrDetect(&i_totem,false) )
+ !victim->isTargetableForAttack() || !m_creature->IsWithinDistInMap(victim, max_range) ||
+ m_creature->IsFriendlyTo(victim) || !victim->isVisibleForOrDetect(m_creature,false) )
{
- CellPair p(Trinity::ComputeCellPair(i_totem.GetPositionX(),i_totem.GetPositionY()));
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
-
victim = NULL;
-
- Trinity::NearestAttackableUnitInObjectRangeCheck u_check(&i_totem, &i_totem, max_range);
- Trinity::UnitLastSearcher<Trinity::NearestAttackableUnitInObjectRangeCheck> checker(victim, u_check);
-
- TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestAttackableUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
- TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestAttackableUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
-
- CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(i_totem.GetMapId(), &i_totem));
- cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(i_totem.GetMapId(), &i_totem));
+ Trinity::NearestAttackableUnitInObjectRangeCheck u_check(m_creature, m_creature, max_range);
+ Trinity::UnitLastSearcher<Trinity::NearestAttackableUnitInObjectRangeCheck> checker(m_creature, victim, u_check);
+ m_creature->VisitNearbyObject(max_range, checker);
}
// If have target
@@ -106,30 +94,23 @@ TotemAI::UpdateAI(const uint32 /*diff*/)
i_victimGuid = victim->GetGUID();
// attack
- i_totem.SetInFront(victim); // client change orientation by self
- i_totem.CastSpell(victim, i_totem.GetSpell(), false);
+ m_creature->SetInFront(victim); // client change orientation by self
+ m_creature->CastSpell(victim, ((Totem*)m_creature)->GetSpell(), false);
}
else
i_victimGuid = 0;
}
-bool
-TotemAI::IsVisible(Unit *) const
-{
- return false;
-}
-
void
TotemAI::AttackStart(Unit *)
{
// Sentry totem sends ping on attack
- if (i_totem.GetEntry() == SENTRY_TOTEM_ENTRY && i_totem.GetOwner()->GetTypeId() == TYPEID_PLAYER)
+ if (m_creature->GetEntry() == SENTRY_TOTEM_ENTRY && m_creature->GetOwner()->GetTypeId() == TYPEID_PLAYER)
{
WorldPacket data(MSG_MINIMAP_PING, (8+4+4));
- data << i_totem.GetGUID();
- data << i_totem.GetPositionX();
- data << i_totem.GetPositionY();
- ((Player*)i_totem.GetOwner())->GetSession()->SendPacket(&data);
+ data << m_creature->GetGUID();
+ data << m_creature->GetPositionX();
+ data << m_creature->GetPositionY();
+ ((Player*)m_creature->GetOwner())->GetSession()->SendPacket(&data);
}
}
-
diff --git a/src/game/TotemAI.h b/src/game/TotemAI.h
index 50ea764abfd..003f5d5ca13 100644
--- a/src/game/TotemAI.h
+++ b/src/game/TotemAI.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -31,18 +31,16 @@ class TRINITY_DLL_DECL TotemAI : public CreatureAI
{
public:
- TotemAI(Creature *c);
+ explicit TotemAI(Creature *c);
void MoveInLineOfSight(Unit *);
void AttackStart(Unit *);
void EnterEvadeMode();
- bool IsVisible(Unit *) const;
void UpdateAI(const uint32);
static int Permissible(const Creature *);
private:
- Totem &i_totem;
uint64 i_victimGuid;
};
#endif
diff --git a/src/game/TradeHandler.cpp b/src/game/TradeHandler.cpp
index 278bb37c81c..439626861fd 100644
--- a/src/game/TradeHandler.cpp
+++ b/src/game/TradeHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -134,7 +134,7 @@ void WorldSession::SendUpdateTrade()
data << (uint32) _player->pTrader->tradeGold; // trader gold
data << (uint32) 0; // spell casted on lowest slot item
- for(uint8 i = 0; i < TRADE_SLOT_COUNT; i++)
+ for(uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
{
item = (_player->pTrader->tradeItems[i] != NULL_SLOT ? _player->pTrader->GetItemByPos( _player->pTrader->tradeItems[i] ) : NULL);
@@ -179,7 +179,7 @@ void WorldSession::SendUpdateTrade()
void WorldSession::moveItems(Item* myItems[], Item* hisItems[])
{
- for(int i=0; i<TRADE_SLOT_TRADED_COUNT; i++)
+ for(int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i)
{
ItemPosCountVec traderDst;
ItemPosCountVec playerDst;
@@ -278,7 +278,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
}
// not accept if some items now can't be trade (cheating)
- for(int i=0; i<TRADE_SLOT_TRADED_COUNT; i++)
+ for(int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i)
{
if(_player->tradeItems[i] != NULL_SLOT )
{
@@ -311,7 +311,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
_player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT);
// store items in local list and set 'in-trade' flag
- for(int i=0; i<TRADE_SLOT_TRADED_COUNT; i++)
+ for(int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i)
{
if(_player->tradeItems[i] != NULL_SLOT )
{
@@ -336,7 +336,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
myCanCompleteTrade = (_player->CanStoreItems( hisItems,TRADE_SLOT_TRADED_COUNT ) == EQUIP_ERR_OK);
// clear 'in-trade' flag
- for(int i=0; i<TRADE_SLOT_TRADED_COUNT; i++)
+ for(int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i)
{
if(myItems[i]) myItems[i]->SetInTrade(false);
if(hisItems[i]) hisItems[i]->SetInTrade(false);
@@ -361,7 +361,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
}
// execute trade: 1. remove
- for(int i=0; i<TRADE_SLOT_TRADED_COUNT; i++)
+ for(int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i)
{
if(myItems[i])
{
diff --git a/src/game/Transports.cpp b/src/game/Transports.cpp
index df2ad178550..c0006ba2d52 100644
--- a/src/game/Transports.cpp
+++ b/src/game/Transports.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -26,7 +26,7 @@
#include "Path.h"
#include "WorldPacket.h"
-#include "Database/DBCStores.h"
+#include "DBCStores.h"
#include "ProgressBar.h"
#include "World.h"
@@ -89,8 +89,6 @@ void MapManager::LoadTransports()
continue;
}
- t->m_name = goinfo->name;
-
float x, y, z, o;
uint32 mapid;
x = t->m_WayPoints[0].x; y = t->m_WayPoints[0].y; z = t->m_WayPoints[0].z; mapid = t->m_WayPoints[0].mapid; o = 1;
@@ -104,7 +102,7 @@ void MapManager::LoadTransports()
m_Transports.insert(t);
- for (std::set<uint32>::iterator i = mapsUsed.begin(); i != mapsUsed.end(); ++i)
+ for (std::set<uint32>::const_iterator i = mapsUsed.begin(); i != mapsUsed.end(); ++i)
m_TransportsByMap[*i].insert(t);
//If we someday decide to use the grid to track transports, here:
@@ -139,7 +137,7 @@ void MapManager::LoadTransports()
Transport::Transport() : GameObject()
{
// 2.3.2 - 0x5A
- m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION);
+ m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);
}
bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags)
@@ -147,10 +145,11 @@ bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z,
Relocate(x,y,z,ang);
SetMapId(mapid);
+ // instance id and phaseMask isn't set to values different from std.
if(!IsPositionValid())
{
- sLog.outError("ERROR: Transport (GUID: %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
+ sLog.outError("Transport (GUID: %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
guidlow,x,y);
return false;
}
@@ -170,18 +169,21 @@ bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z,
SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size);
SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
- SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
-
- SetUInt32Value(OBJECT_FIELD_ENTRY, goinfo->id);
+ //SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
+ SetUInt32Value(GAMEOBJECT_FLAGS, MAKE_PAIR32(0x28, 0x64));
+ SetUInt32Value(GAMEOBJECT_LEVEL, m_period);
+ SetEntry(goinfo->id);
SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId);
- SetGoState(1);
+ SetGoState(GO_STATE_READY);
SetGoType(GameobjectTypes(goinfo->type));
SetGoAnimProgress(animprogress);
if(dynflags)
- SetUInt32Value(GAMEOBJECT_DYN_FLAGS, dynflags);
+ SetUInt32Value(GAMEOBJECT_DYNAMIC, MAKE_PAIR32(0, dynflags));
+
+ SetName(goinfo->name);
return true;
}
@@ -217,7 +219,7 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids)
std::vector<keyFrame> keyFrames;
int mapChange = 0;
mapids.clear();
- for (size_t i = 1; i < path.Size() - 1; i++)
+ for (size_t i = 1; i < path.Size() - 1; ++i)
{
if (mapChange == 0)
{
@@ -249,7 +251,7 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids)
}
// find the rest of the distances between key points
- for (size_t i = 1; i < keyFrames.size(); i++)
+ for (size_t i = 1; i < keyFrames.size(); ++i)
{
if ((keyFrames[i].actionflag == 1) || (keyFrames[i].mapid != keyFrames[i-1].mapid))
{
@@ -272,7 +274,7 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids)
}
float tmpDist = 0;
- for (size_t i = 0; i < keyFrames.size(); i++)
+ for (size_t i = 0; i < keyFrames.size(); ++i)
{
int j = (i + lastStop) % keyFrames.size();
if (keyFrames[j].actionflag == 2)
@@ -291,7 +293,7 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids)
tmpDist = 0;
}
- for (size_t i = 0; i < keyFrames.size(); i++)
+ for (size_t i = 0; i < keyFrames.size(); ++i)
{
if (keyFrames[i].distSinceStop < (30 * 30 * 0.5f))
keyFrames[i].tFrom = sqrt(2 * keyFrames[i].distSinceStop);
@@ -307,7 +309,7 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids)
keyFrames[i].tTo *= 1000;
}
- // for (int i = 0; i < keyFrames.size(); i++) {
+ // for (int i = 0; i < keyFrames.size(); ++i) {
// sLog.outString("%f, %f, %f, %f, %f, %f, %f", keyFrames[i].x, keyFrames[i].y, keyFrames[i].distUntilStop, keyFrames[i].distSinceStop, keyFrames[i].distFromPrev, keyFrames[i].tFrom, keyFrames[i].tTo);
// }
@@ -323,7 +325,7 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids)
t += keyFrames[0].delay * 1000;
uint32 cM = keyFrames[0].mapid;
- for (size_t i = 0; i < keyFrames.size() - 1; i++)
+ for (size_t i = 0; i < keyFrames.size() - 1; ++i)
{
float d = 0;
float tFrom = keyFrames[i].tFrom;
@@ -414,7 +416,7 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids)
uint32 timer = t;
- // sLog.outDetail(" Generated %d waypoints, total time %u.", m_WayPoints.size(), timer);
+ // sLog.outDetail(" Generated %lu waypoints, total time %u.", (unsigned long)m_WayPoints.size(), timer);
m_curr = m_WayPoints.begin();
m_curr = GetNextWayPoint();
@@ -426,9 +428,9 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids)
return true;
}
-Transport::WayPointMap::iterator Transport::GetNextWayPoint()
+Transport::WayPointMap::const_iterator Transport::GetNextWayPoint()
{
- WayPointMap::iterator iter = m_curr;
+ WayPointMap::const_iterator iter = m_curr;
++iter;
if (iter == m_WayPoints.end())
iter = m_WayPoints.begin();
@@ -437,24 +439,15 @@ Transport::WayPointMap::iterator Transport::GetNextWayPoint()
void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
{
- //MapManager::Instance().GetMap(oldMapid)->Remove((GameObject *)this, false);
+ Map const* oldMap = GetMap();
SetMapId(newMapid);
- //MapManager::Instance().LoadGrid(newMapid,x,y,true);
Relocate(x, y, z);
- //MapManager::Instance().GetMap(newMapid)->Add<GameObject>((GameObject *)this);
- for(PlayerSet::iterator itr = m_passengers.begin(); itr != m_passengers.end();)
+ for(PlayerSet::const_iterator itr = m_passengers.begin(); itr != m_passengers.end();)
{
- PlayerSet::iterator it2 = itr;
+ Player *plr = *itr;
++itr;
- Player *plr = *it2;
- if(!plr)
- {
- m_passengers.erase(it2);
- continue;
- }
-
if (plr->isDead() && !plr->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
{
plr->ResurrectPlayer(1.0);
@@ -465,25 +458,27 @@ void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
//data << uint32(0);
//plr->GetSession()->SendPacket(&data);
}
+
+ Map const* newMap = GetMap();
+
+ if(oldMap != newMap)
+ {
+ UpdateForMap(oldMap);
+ UpdateForMap(newMap);
+ }
}
bool Transport::AddPassenger(Player* passenger)
{
- if (m_passengers.find(passenger) == m_passengers.end())
- {
- sLog.outDetail("Player %s boarded transport %s.", passenger->GetName(), this->m_name.c_str());
- m_passengers.insert(passenger);
- }
+ if(m_passengers.insert(passenger).second)
+ sLog.outDetail("Player %s boarded transport %s.", passenger->GetName(), GetName());
return true;
}
bool Transport::RemovePassenger(Player* passenger)
{
- if (m_passengers.find(passenger) != m_passengers.end())
- {
- sLog.outDetail("Player %s removed from transport %s.", passenger->GetName(), this->m_name.c_str());
- m_passengers.erase(passenger);
- }
+ if (m_passengers.erase(passenger))
+ sLog.outDetail("Player %s removed from transport %s.", passenger->GetName(), GetName());
return true;
}
@@ -512,7 +507,6 @@ void Transport::Update(uint32 /*p_time*/)
}
else
{
- //MapManager::Instance().GetMap(m_curr->second.mapid)->GameobjectRelocation((GameObject *)this, m_curr->second.x, m_curr->second.y, m_curr->second.z, this->m_orientation);
Relocate(m_curr->second.x, m_curr->second.y, m_curr->second.z);
}
/*
@@ -537,9 +531,9 @@ void Transport::Update(uint32 /*p_time*/)
}
*/
/*
- for(PlayerSet::iterator itr = m_passengers.begin(); itr != m_passengers.end();)
+ for(PlayerSet::const_iterator itr = m_passengers.begin(); itr != m_passengers.end();)
{
- PlayerSet::iterator it2 = itr;
+ PlayerSet::const_iterator it2 = itr;
++itr;
//(*it2)->SetPosition( m_curr->second.x + (*it2)->GetTransOffsetX(), m_curr->second.y + (*it2)->GetTransOffsetY(), m_curr->second.z + (*it2)->GetTransOffsetZ(), (*it2)->GetTransOffsetO() );
}
@@ -550,10 +544,6 @@ void Transport::Update(uint32 /*p_time*/)
if (m_curr == m_WayPoints.begin() && (sLog.getLogFilter() & LOG_FILTER_TRANSPORT_MOVES)==0)
sLog.outDetail(" ************ BEGIN ************** %s", this->m_name.c_str());
- // MapManager::Instance().GetMap(m_curr->second.mapid)->Add(&this); // -> // ->Add(t);
- //MapManager::Instance().GetMap(m_curr->second.mapid)->Remove((GameObject *)this, false); // -> // ->Add(t);
- //MapManager::Instance().GetMap(m_curr->second.mapid)->Add((GameObject *)this); // -> // ->Add(t);
-
if ((sLog.getLogFilter() & LOG_FILTER_TRANSPORT_MOVES)==0)
sLog.outDetail("%s moved to %d %f %f %f %d", this->m_name.c_str(), m_curr->second.id, m_curr->second.x, m_curr->second.y, m_curr->second.z, m_curr->second.mapid);
@@ -562,3 +552,36 @@ void Transport::Update(uint32 /*p_time*/)
}
}
+void Transport::UpdateForMap(Map const* targetMap)
+{
+ Map::PlayerList const& pl = targetMap->GetPlayers();
+ if(pl.isEmpty())
+ return;
+
+ if(GetMapId()==targetMap->GetId())
+ {
+ for(Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr)
+ {
+ if(this != itr->getSource()->GetTransport())
+ {
+ UpdateData transData;
+ BuildCreateUpdateBlockForPlayer(&transData, itr->getSource());
+ WorldPacket packet;
+ transData.BuildPacket(&packet, true);
+ itr->getSource()->SendDirectMessage(&packet);
+ }
+ }
+ }
+ else
+ {
+ UpdateData transData;
+ BuildOutOfRangeUpdateBlock(&transData);
+ WorldPacket out_packet;
+ transData.BuildPacket(&out_packet, true);
+
+ for(Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr)
+ if(this != itr->getSource()->GetTransport())
+ itr->getSource()->SendDirectMessage(&out_packet);
+ }
+}
+
diff --git a/src/game/Transports.h b/src/game/Transports.h
index a814a0f70b9..2df39f401e7 100644
--- a/src/game/Transports.h
+++ b/src/game/Transports.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -38,16 +38,16 @@ class TransportPath
uint32 delay;
};
- inline void SetLength(const unsigned int sz)
+ void SetLength(const unsigned int sz)
{
i_nodes.resize( sz );
}
- inline unsigned int Size(void) const { return i_nodes.size(); }
- inline bool Empty(void) const { return i_nodes.empty(); }
- inline void Resize(unsigned int sz) { i_nodes.resize(sz); }
- inline void Clear(void) { i_nodes.clear(); }
- inline PathNode* GetNodes(void) { return static_cast<PathNode *>(&i_nodes[0]); }
+ unsigned int Size(void) const { return i_nodes.size(); }
+ bool Empty(void) const { return i_nodes.empty(); }
+ void Resize(unsigned int sz) { i_nodes.resize(sz); }
+ void Clear(void) { i_nodes.clear(); }
+ PathNode* GetNodes(void) { return static_cast<PathNode *>(&i_nodes[0]); }
PathNode& operator[](const unsigned int idx) { return i_nodes[idx]; }
const PathNode& operator()(const unsigned int idx) const { return i_nodes[idx]; }
@@ -56,7 +56,7 @@ class TransportPath
std::vector<PathNode> i_nodes;
};
-class Transport : private GameObject
+class Transport : protected GameObject
{
public:
explicit Transport();
@@ -83,7 +83,6 @@ class Transport : private GameObject
typedef std::set<Player*> PlayerSet;
PlayerSet const& GetPassengers() const { return m_passengers; }
- std::string m_name;
private:
struct WayPoint
{
@@ -100,8 +99,8 @@ class Transport : private GameObject
typedef std::map<uint32, WayPoint> WayPointMap;
- WayPointMap::iterator m_curr;
- WayPointMap::iterator m_next;
+ WayPointMap::const_iterator m_curr;
+ WayPointMap::const_iterator m_next;
uint32 m_pathTime;
uint32 m_timer;
@@ -114,7 +113,8 @@ class Transport : private GameObject
private:
void TeleportTransport(uint32 newMapid, float x, float y, float z);
- WayPointMap::iterator GetNextWayPoint();
+ void UpdateForMap(Map const* map);
+ WayPointMap::const_iterator GetNextWayPoint();
};
#endif
diff --git a/src/game/Traveller.h b/src/game/Traveller.h
index ee2ec55833f..702cc6413b0 100644
--- a/src/game/Traveller.h
+++ b/src/game/Traveller.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,11 +21,9 @@
#ifndef TRINITY_TRAVELLER_H
#define TRINITY_TRAVELLER_H
-#include "MapManager.h"
#include "Creature.h"
#include "Player.h"
#include <cassert>
-#include "CreatureGroups.h"
/** Traveller is a wrapper for units (creatures or players) that
* travel from point A to point B using the destination holder.
@@ -47,22 +45,39 @@ struct TRINITY_DLL_DECL Traveller
operator T&(void) { return i_traveller; }
operator const T&(void) { return i_traveller; }
- inline float GetPositionX() const { return i_traveller.GetPositionX(); }
- inline float GetPositionY() const { return i_traveller.GetPositionY(); }
- inline float GetPositionZ() const { return i_traveller.GetPositionZ(); }
- inline T& GetTraveller(void) { return i_traveller; }
+ float GetPositionX() const { return i_traveller.GetPositionX(); }
+ float GetPositionY() const { return i_traveller.GetPositionY(); }
+ float GetPositionZ() const { return i_traveller.GetPositionZ(); }
+ T& GetTraveller(void) { return i_traveller; }
float Speed(void) { assert(false); return 0.0f; }
+ float GetMoveDestinationTo(float x, float y, float z);
+ uint32 GetTotalTrevelTimeTo(float x, float y, float z);
+
void Relocation(float x, float y, float z, float orientation) {}
void Relocation(float x, float y, float z) { Relocation(x, y, z, i_traveller.GetOrientation()); }
void MoveTo(float x, float y, float z, uint32 t) {}
};
+template<class T>
+inline uint32 Traveller<T>::GetTotalTrevelTimeTo(float x, float y, float z)
+{
+ float dist = GetMoveDestinationTo(x,y,z);
+ float speed = 0.001f;
+ if (Speed() <= 0.0f)
+ return 0xfffffffe; // almost infinity-unit should stop
+ else
+ speed *= Speed(); // speed is in seconds so convert from second to millisecond
+ return static_cast<uint32>(dist/speed);
+}
+
// specialization for creatures
template<>
inline float Traveller<Creature>::Speed()
{
- if(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE))
+ if(i_traveller.hasUnitState(UNIT_STAT_CHARGING))
+ return i_traveller.m_TempSpeed;
+ else if(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE))
return i_traveller.GetSpeed(MOVE_WALK);
else if(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_FLYING2))
return i_traveller.GetSpeed(MOVE_FLIGHT);
@@ -73,29 +88,59 @@ inline float Traveller<Creature>::Speed()
template<>
inline void Traveller<Creature>::Relocation(float x, float y, float z, float orientation)
{
- MapManager::Instance().GetMap(i_traveller.GetMapId(), &i_traveller)->CreatureRelocation(&i_traveller, x, y, z, orientation);
+ i_traveller.GetMap()->CreatureRelocation(&i_traveller, x, y, z, orientation);
+}
+
+template<>
+inline float Traveller<Creature>::GetMoveDestinationTo(float x, float y, float z)
+{
+ float dx = x - GetPositionX();
+ float dy = y - GetPositionY();
+ float dz = z - GetPositionZ();
+
+ if(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_FLYING2))
+ return sqrt((dx*dx) + (dy*dy) + (dz*dz));
+ else //Walking on the ground
+ return sqrt((dx*dx) + (dy*dy));
}
+
template<>
inline void Traveller<Creature>::MoveTo(float x, float y, float z, uint32 t)
{
- i_traveller.AI_SendMoveToPacket(x, y, z, t, i_traveller.GetUnitMovementFlags(), 0);
+ //i_traveller.AI_SendMoveToPacket(x, y, z, t, i_traveller.GetUnitMovementFlags(), 0);
+ i_traveller.SendMonsterMove(x, y, z, t);
}
// specialization for players
template<>
inline float Traveller<Player>::Speed()
{
- if (i_traveller.isInFlight())
+ if(i_traveller.hasUnitState(UNIT_STAT_CHARGING))
+ return i_traveller.m_TempSpeed;
+ else if(i_traveller.isInFlight())
return PLAYER_FLIGHT_SPEED;
else
return i_traveller.GetSpeed(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE) ? MOVE_WALK : MOVE_RUN);
}
template<>
+inline float Traveller<Player>::GetMoveDestinationTo(float x, float y, float z)
+{
+ float dx = x - GetPositionX();
+ float dy = y - GetPositionY();
+ float dz = z - GetPositionZ();
+
+ if (i_traveller.isInFlight())
+ return sqrt((dx*dx) + (dy*dy) + (dz*dz));
+ else //Walking on the ground
+ return sqrt((dx*dx) + (dy*dy));
+}
+
+template<>
inline void Traveller<Player>::Relocation(float x, float y, float z, float orientation)
{
- MapManager::Instance().GetMap(i_traveller.GetMapId(), &i_traveller)->PlayerRelocation(&i_traveller, x, y, z, orientation);
+ i_traveller.GetMap()->PlayerRelocation(&i_traveller, x, y, z, orientation);
}
template<>
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 756a1ac7d43..b1a39c30cce 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -49,6 +49,10 @@
#include "CreatureGroups.h"
#include "PetAI.h"
#include "NullCreatureAI.h"
+#include "Traveller.h"
+#include "TemporarySummon.h"
+#include "Vehicle.h"
+#include "Transports.h"
#include <math.h>
@@ -62,102 +66,28 @@ float baseMoveSpeed[MAX_MOVE_TYPE] =
3.141594f, // MOVE_TURN_RATE
7.0f, // MOVE_FLIGHT
4.5f, // MOVE_FLIGHT_BACK
+ 3.14f // MOVE_PITCH_RATE
};
-void InitTriggerAuraData();
-
-// auraTypes contains attacker auras capable of proc'ing cast auras
-static Unit::AuraTypeSet GenerateAttakerProcCastAuraTypes()
-{
- static Unit::AuraTypeSet auraTypes;
- auraTypes.insert(SPELL_AURA_DUMMY);
- auraTypes.insert(SPELL_AURA_PROC_TRIGGER_SPELL);
- auraTypes.insert(SPELL_AURA_MOD_HASTE);
- auraTypes.insert(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- return auraTypes;
-}
-
-// auraTypes contains victim auras capable of proc'ing cast auras
-static Unit::AuraTypeSet GenerateVictimProcCastAuraTypes()
-{
- static Unit::AuraTypeSet auraTypes;
- auraTypes.insert(SPELL_AURA_DUMMY);
- auraTypes.insert(SPELL_AURA_PRAYER_OF_MENDING);
- auraTypes.insert(SPELL_AURA_PROC_TRIGGER_SPELL);
- return auraTypes;
-}
-
-// auraTypes contains auras capable of proc effect/damage (but not cast) for attacker
-static Unit::AuraTypeSet GenerateAttakerProcEffectAuraTypes()
-{
- static Unit::AuraTypeSet auraTypes;
- auraTypes.insert(SPELL_AURA_MOD_DAMAGE_DONE);
- auraTypes.insert(SPELL_AURA_PROC_TRIGGER_DAMAGE);
- auraTypes.insert(SPELL_AURA_MOD_CASTING_SPEED);
- auraTypes.insert(SPELL_AURA_MOD_RATING);
- return auraTypes;
-}
-
-// auraTypes contains auras capable of proc effect/damage (but not cast) for victim
-static Unit::AuraTypeSet GenerateVictimProcEffectAuraTypes()
-{
- static Unit::AuraTypeSet auraTypes;
- auraTypes.insert(SPELL_AURA_MOD_RESISTANCE);
- auraTypes.insert(SPELL_AURA_PROC_TRIGGER_DAMAGE);
- auraTypes.insert(SPELL_AURA_MOD_PARRY_PERCENT);
- auraTypes.insert(SPELL_AURA_MOD_BLOCK_PERCENT);
- auraTypes.insert(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
- return auraTypes;
-}
-
-static Unit::AuraTypeSet attackerProcCastAuraTypes = GenerateAttakerProcCastAuraTypes();
-static Unit::AuraTypeSet attackerProcEffectAuraTypes = GenerateAttakerProcEffectAuraTypes();
-
-static Unit::AuraTypeSet victimProcCastAuraTypes = GenerateVictimProcCastAuraTypes();
-static Unit::AuraTypeSet victimProcEffectAuraTypes = GenerateVictimProcEffectAuraTypes();
-
-// auraTypes contains auras capable of proc'ing for attacker and victim
-static Unit::AuraTypeSet GenerateProcAuraTypes()
-{
- InitTriggerAuraData();
-
- Unit::AuraTypeSet auraTypes;
- auraTypes.insert(attackerProcCastAuraTypes.begin(),attackerProcCastAuraTypes.end());
- auraTypes.insert(attackerProcEffectAuraTypes.begin(),attackerProcEffectAuraTypes.end());
- auraTypes.insert(victimProcCastAuraTypes.begin(),victimProcCastAuraTypes.end());
- auraTypes.insert(victimProcEffectAuraTypes.begin(),victimProcEffectAuraTypes.end());
- return auraTypes;
-}
-
-static Unit::AuraTypeSet procAuraTypes = GenerateProcAuraTypes();
-
-bool IsPassiveStackableSpell( uint32 spellId )
-{
- if(!IsPassiveSpell(spellId))
- return false;
-
- SpellEntry const* spellProto = sSpellStore.LookupEntry(spellId);
- if(!spellProto)
- return false;
-
- for(int j = 0; j < 3; ++j)
- {
- if(std::find(procAuraTypes.begin(),procAuraTypes.end(),spellProto->EffectApplyAuraName[j])!=procAuraTypes.end())
- return false;
- }
-
- return true;
-}
+// Used for prepare can/can`t triggr aura
+static bool InitTriggerAuraData();
+// Define can trigger auras
+static bool isTriggerAura[TOTAL_AURAS];
+// Define can`t trigger auras (need for disable second trigger)
+static bool isNonTriggerAura[TOTAL_AURAS];
+// Prepare lists
+static bool procPrepared = InitTriggerAuraData();
Unit::Unit()
: WorldObject(), i_motionMaster(this), m_ThreatManager(this), m_HostilRefManager(this)
, m_IsInNotifyList(false), m_Notified(false), IsAIEnabled(false), NeedChangeAI(false)
-, i_AI(NULL), i_disabledAI(NULL), m_procDeep(0)
+, i_AI(NULL), i_disabledAI(NULL), m_removedAurasCount(0), m_Vehicle(NULL)
+, m_ControlledByPlayer(false)
{
m_objectType |= TYPEMASK_UNIT;
m_objectTypeId = TYPEID_UNIT;
// 2.3.2 - 0x70
- m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HASPOSITION);
+ m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION);
m_attackTimer[BASE_ATTACK] = 0;
m_attackTimer[OFF_ATTACK] = 0;
@@ -178,15 +108,14 @@ Unit::Unit()
m_addDmgOnce = 0;
- for(int i = 0; i < MAX_TOTEM; ++i)
- m_TotemSlot[i] = 0;
+ for(int i = 0; i < MAX_SUMMON_SLOT; ++i)
+ m_SummonSlot[i] = 0;
m_ObjectSlot[0] = m_ObjectSlot[1] = m_ObjectSlot[2] = m_ObjectSlot[3] = 0;
//m_Aura = NULL;
//m_AurasCheck = 2000;
//m_removeAuraTimer = 4;
//tmpAura = NULL;
- waterbreath = false;
m_Visibility = VISIBILITY_ON;
@@ -209,7 +138,7 @@ Unit::Unit()
// implement 50% base damage from offhand
m_auraModifiersGroup[UNIT_MOD_DAMAGE_OFFHAND][TOTAL_PCT] = 0.5f;
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < MAX_ATTACK; ++i)
{
m_weaponDamage[i][MINDAMAGE] = BASE_MINDAMAGE;
m_weaponDamage[i][MAXDAMAGE] = BASE_MAXDAMAGE;
@@ -233,7 +162,6 @@ Unit::Unit()
for (int i = 0; i < MAX_MOVE_TYPE; ++i)
m_speed_rate[i] = 1.0f;
- m_removedAuras = 0;
m_charmInfo = NULL;
m_unit_movement_flags = 0;
m_reducedThreatPercent = 0;
@@ -264,6 +192,7 @@ Unit::~Unit()
assert(!m_attacking);
assert(m_attackers.empty());
assert(m_sharedVision.empty());
+ assert(m_Controlled.empty());
}
void Unit::Update( uint32 p_time )
@@ -313,6 +242,7 @@ void Unit::Update( uint32 p_time )
ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, GetHealth() < GetMaxHealth()*0.20f);
ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, GetHealth() < GetMaxHealth()*0.35f);
+ ModifyAuraState(AURA_STATE_HEALTH_ABOVE_75_PERCENT, GetHealth() > GetMaxHealth()*0.75f);
i_motionMaster.UpdateMotion(p_time);
}
@@ -329,28 +259,23 @@ void Unit::SendMonsterMoveWithSpeedToCurrentDestination(Player* player)
{
float x, y, z;
if(GetMotionMaster()->GetDestination(x, y, z))
- SendMonsterMoveWithSpeed(x, y, z, GetUnitMovementFlags(), 0, player);
+ SendMonsterMoveWithSpeed(x, y, z, 0, player);
}
-void Unit::SendMonsterMoveWithSpeed(float x, float y, float z, uint32 MovementFlags, uint32 transitTime, Player* player)
+void Unit::SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime, Player* player)
{
if (!transitTime)
{
- float dx = x - GetPositionX();
- float dy = y - GetPositionY();
- float dz = z - GetPositionZ();
-
- float dist = ((dx*dx) + (dy*dy) + (dz*dz));
- if(dist<0)
- dist = 0;
+ if(GetTypeId()==TYPEID_PLAYER)
+ {
+ Traveller<Player> traveller(*(Player*)this);
+ transitTime = traveller.GetTotalTrevelTimeTo(x,y,z);
+ }
else
- dist = sqrt(dist);
-
- double speed = GetSpeed((MovementFlags & MOVEMENTFLAG_WALK_MODE) ? MOVE_WALK : MOVE_RUN);
- if(speed<=0)
- speed = 2.5f;
- speed *= 0.001f;
- transitTime = static_cast<uint32>(dist / speed + 0.5);
+ {
+ Traveller<Creature> traveller(*(Creature*)this);
+ transitTime = traveller.GetTotalTrevelTimeTo(x,y,z);
+ }
}
//float orientation = (float)atan2((double)dy, (double)dx);
SendMonsterMove(x, y, z, transitTime, player);
@@ -368,7 +293,7 @@ void Unit::SendMonsterStop()
void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 Time, Player* player)
{
- WorldPacket data( SMSG_MONSTER_MOVE, (41 + GetPackGUID().size()) );
+ WorldPacket data( SMSG_MONSTER_MOVE, 12+4+1+4+4+4+12+GetPackGUID().size());
data.append(GetPackGUID());
data << GetPositionX() << GetPositionY() << GetPositionZ();
@@ -387,38 +312,66 @@ void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 T
SendMessageToSet( &data, true );
}
+void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 MoveFlags, uint32 time, float speedZ, Player *player)
+{
+ WorldPacket data( SMSG_MONSTER_MOVE, 12+4+1+4+4+4+12+GetPackGUID().size());
+ data.append(GetPackGUID());
+
+ data << GetPositionX() << GetPositionY() << GetPositionZ();
+ data << getMSTime();
+
+ data << uint8(0);
+ data << MoveFlags;
+
+ if(MoveFlags & MOVEFLAG_JUMP)
+ {
+ data << time;
+ data << speedZ;
+ data << (uint32)0; // walk time after jump
+ }
+ else
+ data << time;
+
+ data << uint32(1); // 1 single waypoint
+ data << NewPosX << NewPosY << NewPosZ; // the single waypoint Point B
+
+ if(player)
+ player->GetSession()->SendPacket(&data);
+ else
+ SendMessageToSet( &data, true );
+}
+
/*void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player)
{
WorldPacket data( SMSG_MONSTER_MOVE, (41 + GetPackGUID().size()) );
data.append(GetPackGUID());
- // Point A, starting location
data << GetPositionX() << GetPositionY() << GetPositionZ();
- // unknown field - unrelated to orientation
- // seems to increment about 1000 for every 1.7 seconds
- // for now, we'll just use mstime
- data << getMSTime();
+ data << uint32(getMSTime());
data << uint8(type); // unknown
switch(type)
{
case 0: // normal packet
break;
- case 1: // stop packet
+ case 1: // stop packet (raw pos?)
SendMessageToSet( &data, true );
return;
+ case 2: // facing spot, not used currently
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ break;
case 3: // not used currently
- data << uint64(0); // probably target guid
+ data << uint64(0); // probably target guid (facing target?)
break;
case 4: // not used currently
- data << float(0); // probably orientation
+ data << float(0); // facing angle
break;
}
- //Movement Flags (0x0 = walk, 0x100 = run, 0x200 = fly/swim)
- data << uint32((MovementFlags & MOVEMENTFLAG_LEVITATING) ? MOVEFLAG_FLY : MOVEFLAG_WALK);
-
- data << Time; // Time in between points
+ data << uint32(MovementFlags);
+ data << uint32(Time); // Time in between points
data << uint32(1); // 1 single waypoint
data << NewPosX << NewPosY << NewPosZ; // the single waypoint Point B
@@ -439,16 +392,12 @@ void Unit::SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end)
data << GetPositionX();
data << GetPositionY();
data << GetPositionZ();
-
data << getMSTime();
-
data << uint8( 0 );
data << uint32(((GetUnitMovementFlags() & MOVEMENTFLAG_LEVITATING) || isInFlight())? (MOVEFLAG_FLY|MOVEFLAG_WALK) : MOVEFLAG_WALK);
data << uint32( traveltime );
data << uint32( pathSize );
data.append( (char*)path.GetNodes(start), pathSize * 4 * 3 );
-
- //WPAssert( data.size() == 37 + pathnodes.Size( ) * 4 * 3 );
SendMessageToSet(&data, true);
}
@@ -503,71 +452,22 @@ void Unit::GetRandomContactPoint( const Unit* obj, float &x, float &y, float &z,
, GetAngle(obj) + (attacker_number ? (M_PI/2 - M_PI * rand_norm()) * (float)attacker_number / combat_reach / 3 : 0));
}
-void Unit::RemoveSpellsCausingAura(AuraType auraType)
-{
- if (auraType >= TOTAL_AURAS) return;
- AuraList::iterator iter, next;
- for (iter = m_modAuras[auraType].begin(); iter != m_modAuras[auraType].end(); iter = next)
- {
- next = iter;
- ++next;
-
- if (*iter)
- {
- RemoveAurasDueToSpell((*iter)->GetId());
- if (!m_modAuras[auraType].empty())
- next = m_modAuras[auraType].begin();
- else
- return;
- }
- }
-}
-
-void Unit::RemoveAuraTypeByCaster(AuraType auraType, uint64 casterGUID)
-{
- if (auraType >= TOTAL_AURAS) return;
- AuraList::iterator iter, next;
- for(iter = m_modAuras[auraType].begin(); iter != m_modAuras[auraType].end(); iter = next)
- {
- next = iter;
- ++next;
-
- if (*iter)
- {
- RemoveAurasByCasterSpell((*iter)->GetId(), casterGUID);
- if (!m_modAuras[auraType].empty())
- next = m_modAuras[auraType].begin();
- else
- return;
- }
- }
-}
-
void Unit::RemoveAurasWithInterruptFlags(uint32 flag, uint32 except)
{
if(!(m_interruptMask & flag))
return;
// interrupt auras
- AuraList::iterator iter, next;
- for (iter = m_interruptableAuras.begin(); iter != m_interruptableAuras.end(); iter = next)
+ for (AuraList::iterator iter = m_interruptableAuras.begin(); iter != m_interruptableAuras.end();)
{
- next = iter;
- ++next;
-
- //sLog.outDetail("auraflag:%u flag:%u = %u",(*iter)->GetSpellProto()->AuraInterruptFlags,flag,(*iter)->GetSpellProto()->AuraInterruptFlags & flag);
- if(*iter && ((*iter)->GetSpellProto()->AuraInterruptFlags & flag))
+ Aura * aur = *iter;
+ ++iter;
+ if ((aur->GetSpellProto()->AuraInterruptFlags & flag) && (!except || aur->GetId() != except))
{
- if((*iter)->IsInUse())
- sLog.outError("Aura %u is trying to remove itself! Flag %u. May cause crash!", (*iter)->GetId(), flag);
- else if(!except || (*iter)->GetId() != except)
- {
- RemoveAurasDueToSpell((*iter)->GetId());
- if (!m_interruptableAuras.empty())
- next = m_interruptableAuras.begin();
- else
- break;
- }
+ uint32 removedAuras = m_removedAurasCount;
+ RemoveAura(aur, AURA_REMOVE_BY_ENEMY_SPELL);
+ if (removedAuras+1 < m_removedAurasCount)
+ iter=m_interruptableAuras.begin();
}
}
@@ -594,11 +494,6 @@ void Unit::UpdateInterruptMask()
m_interruptMask |= spell->m_spellInfo->ChannelInterruptFlags;
}
-bool Unit::HasAuraType(AuraType auraType) const
-{
- return (!m_modAuras[auraType].empty());
-}
-
/* Called by DealDamage for auras that have a chance to be dispelled on damage taken. */
void Unit::RemoveSpellbyDamageTaken(uint32 damage, uint32 spell)
{
@@ -606,26 +501,25 @@ void Unit::RemoveSpellbyDamageTaken(uint32 damage, uint32 spell)
uint32 max_dmg = getLevel() > 8 ? 25 * getLevel() - 150 : 50;
float chance = float(damage) / max_dmg * 100.0f;
- AuraList::iterator i, next;
- for(i = m_ccAuras.begin(); i != m_ccAuras.end(); i = next)
+ std::queue < std::pair < uint32, uint64 > > remove_list;
+
+ for (AuraList::iterator iter = m_ccAuras.begin(); iter != m_ccAuras.end();++iter)
{
- next = i;
- ++next;
+ if((!spell || (*iter)->GetId() != spell) && roll_chance_f(chance))
+ {
+ remove_list.push(std::make_pair((*iter)->GetId(), (*iter)->GetCasterGUID() ) );
+ }
+ }
- if(*i && (!spell || (*i)->GetId() != spell) && roll_chance_f(chance))
- {
- RemoveAurasDueToSpell((*i)->GetId());
- if (!m_ccAuras.empty())
- next = m_ccAuras.begin();
- else
- return;
- }
+ for(;remove_list.size();remove_list.pop())
+ {
+ RemoveAura(remove_list.front().first, remove_list.front().second, AURA_REMOVE_BY_ENEMY_SPELL);
}
}
uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss)
{
- if (!pVictim->isAlive() || pVictim->isInFlight() || pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
+ if (!pVictim->isAlive() || pVictim->hasUnitState(UNIT_STAT_UNATTACKABLE) || pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
return 0;
//You don't lose health from damage taken from another player while in a sanctuary
@@ -684,30 +578,27 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
return 0;
}
- if(pVictim->GetTypeId() != TYPEID_PLAYER)
+ // no xp,health if type 8 /critters/
+ if(pVictim->GetTypeId() != TYPEID_PLAYER && pVictim->GetCreatureType() == CREATURE_TYPE_CRITTER)
{
- // no xp,health if type 8 /critters/
- if ( pVictim->GetCreatureType() == CREATURE_TYPE_CRITTER)
+ // allow loot only if has loot_id in creature_template
+ if(damage >= pVictim->GetHealth())
{
- // allow loot only if has loot_id in creature_template
- if(damage >= pVictim->GetHealth())
- {
- pVictim->setDeathState(JUST_DIED);
- pVictim->SetHealth(0);
+ pVictim->setDeathState(JUST_DIED);
+ pVictim->SetHealth(0);
- CreatureInfo const* cInfo = ((Creature*)pVictim)->GetCreatureInfo();
- if(cInfo && cInfo->lootid)
- pVictim->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
-
- // some critters required for quests
- if(GetTypeId() == TYPEID_PLAYER)
- ((Player*)this)->KilledMonster(pVictim->GetEntry(),pVictim->GetGUID());
- }
- else
- pVictim->ModifyHealth(- (int32)damage);
+ CreatureInfo const* cInfo = ((Creature*)pVictim)->GetCreatureInfo();
+ if(cInfo && cInfo->lootid)
+ pVictim->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
- return damage;
+ // some critters required for quests
+ if(GetTypeId() == TYPEID_PLAYER)
+ ((Player*)this)->KilledMonster(pVictim->GetEntry(),pVictim->GetGUID());
}
+ else
+ pVictim->ModifyHealth(- (int32)damage);
+
+ return damage;
}
DEBUG_LOG("DealDamageStart");
@@ -760,46 +651,208 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
}
}
- if(pVictim->GetTypeId() == TYPEID_PLAYER && GetTypeId() == TYPEID_PLAYER)
+ if (GetTypeId() == TYPEID_PLAYER && this != pVictim)
{
- if(((Player*)pVictim)->InBattleGround())
+ Player *killer = ((Player*)this);
+
+ // in bg, count dmg if victim is also a player
+ if (pVictim->GetTypeId()==TYPEID_PLAYER)
{
- Player *killer = ((Player*)this);
- if(killer != ((Player*)pVictim))
- if(BattleGround *bg = killer->GetBattleGround())
- bg->UpdatePlayerScore(killer, SCORE_DAMAGE_DONE, damage);
+ if (BattleGround *bg = killer->GetBattleGround())
+ {
+ // FIXME: kept by compatibility. don't know in BG if the restriction apply.
+ bg->UpdatePlayerScore(killer, SCORE_DAMAGE_DONE, damage);
+ }
}
+
+ killer->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE, damage, 0, pVictim);
+ killer->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT, damage);
}
+ if (pVictim->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)pVictim)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED, damage);
+
if (pVictim->GetTypeId() == TYPEID_UNIT && !((Creature*)pVictim)->isPet() && !((Creature*)pVictim)->hasLootRecipient())
((Creature*)pVictim)->SetLootRecipient(this);
if (health <= damage)
{
DEBUG_LOG("DealDamage: victim just died");
+
+ if (pVictim->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)pVictim)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED, health);
+
Kill(pVictim, durabilityLoss);
- }
- else // if (health <= damage)
- {
- DEBUG_LOG("DealDamageAlive");
- pVictim->ModifyHealth(- (int32)damage);
+ /*// find player: owner of controlled `this` or `this` itself maybe
+ Player *player = GetCharmerOrOwnerPlayerOrPlayerItself();
- if(damagetype != DOT)
+ if(pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->GetLootRecipient())
+ player = ((Creature*)pVictim)->GetLootRecipient();
+ // Reward player, his pets, and group/raid members
+ // call kill spell proc event (before real die and combat stop to triggering auras removed at death/combat stop)
+ if(player && player!=pVictim)
{
- if(!getVictim())
- /*{
- // if have target and damage pVictim just call AI reaction
- if(pVictim != getVictim() && pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->IsAIEnabled)
- ((Creature*)pVictim)->AI()->AttackedBy(this);
+ player->RewardPlayerAndGroupAtKill(pVictim);
+ player->ProcDamageAndSpell(pVictim, PROC_FLAG_KILL, PROC_FLAG_KILLED, PROC_EX_NONE, 0);
+ }
+
+ DEBUG_LOG("DealDamageAttackStop");
+
+ // stop combat
+ pVictim->CombatStop();
+ pVictim->getHostilRefManager().deleteReferences();
+
+ bool damageFromSpiritOfRedemtionTalent = spellProto && spellProto->Id == 27795;
+
+ // if talent known but not triggered (check priest class for speedup check)
+ Aura* spiritOfRedemtionTalentReady = NULL;
+ if( !damageFromSpiritOfRedemtionTalent && // not called from SPELL_AURA_SPIRIT_OF_REDEMPTION
+ pVictim->GetTypeId()==TYPEID_PLAYER && pVictim->getClass()==CLASS_PRIEST )
+ {
+ AuraList const& vDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
+ for(AuraList::const_iterator itr = vDummyAuras.begin(); itr != vDummyAuras.end(); ++itr)
+ {
+ if((*itr)->GetSpellProto()->SpellIconID==1654)
+ {
+ spiritOfRedemtionTalentReady = *itr;
+ break;
+ }
}
- else*/
+ }
+
+ DEBUG_LOG("SET JUST_DIED");
+ if(!spiritOfRedemtionTalentReady)
+ pVictim->setDeathState(JUST_DIED);
+
+ DEBUG_LOG("DealDamageHealth1");
+
+ if(spiritOfRedemtionTalentReady)
+ {
+ // save value before aura remove
+ uint32 ressSpellId = pVictim->GetUInt32Value(PLAYER_SELF_RES_SPELL);
+ if(!ressSpellId)
+ ressSpellId = ((Player*)pVictim)->GetResurrectionSpellId();
+
+ //Remove all expected to remove at death auras (most important negative case like DoT or periodic triggers)
+ pVictim->RemoveAllAurasOnDeath();
+
+ // restore for use at real death
+ pVictim->SetUInt32Value(PLAYER_SELF_RES_SPELL,ressSpellId);
+
+ // FORM_SPIRITOFREDEMPTION and related auras
+ pVictim->CastSpell(pVictim,27827,true,NULL,spiritOfRedemtionTalentReady);
+ }
+ else
+ pVictim->SetHealth(0);
+
+ // remember victim PvP death for corpse type and corpse reclaim delay
+ // at original death (not at SpiritOfRedemtionTalent timeout)
+ if( pVictim->GetTypeId()==TYPEID_PLAYER && !damageFromSpiritOfRedemtionTalent )
+ ((Player*)pVictim)->SetPvPDeath(player!=NULL);
+
+ // Call KilledUnit for creatures
+ if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI())
+ ((Creature*)this)->AI()->KilledUnit(pVictim);
+
+ // achievement stuff
+ if (pVictim->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (GetTypeId() == TYPEID_UNIT)
+ ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE, GetEntry());
+ else if(GetTypeId() == TYPEID_PLAYER && pVictim != this)
+ ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1, ((Player*)this)->GetTeam());
+ }
+
+ // 10% durability loss on death
+ // clean InHateListOf
+ if (pVictim->GetTypeId() == TYPEID_PLAYER)
+ {
+ // only if not player and not controlled by player pet. And not at BG
+ if (durabilityLoss && !player && !((Player*)pVictim)->InBattleGround())
+ {
+ DEBUG_LOG("We are dead, loosing 10 percents durability");
+ ((Player*)pVictim)->DurabilityLossAll(0.10f,false);
+ // durability lost message
+ WorldPacket data(SMSG_DURABILITY_DAMAGE_DEATH, 0);
+ ((Player*)pVictim)->GetSession()->SendPacket(&data);
+ }
+ }
+ else // creature died
+ {
+ DEBUG_LOG("DealDamageNotPlayer");
+ Creature *cVictim = (Creature*)pVictim;
+
+ if(!cVictim->isPet())
{
- // if not have main target then attack state with target (including AI call)
- //start melee attacks only after melee hit
- Attack(pVictim,(damagetype == DIRECT_DAMAGE));
+ cVictim->DeleteThreatList();
+ cVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ // Call creature just died function
+ if (cVictim->AI())
+ cVictim->AI()->JustDied(this);
+
+ // Dungeon specific stuff, only applies to players killing creatures
+ if(cVictim->GetInstanceId())
+ {
+ Map *m = cVictim->GetMap();
+ Player *creditedPlayer = GetCharmerOrOwnerPlayerOrPlayerItself();
+ // TODO: do instance binding anyway if the charmer/owner is offline
+
+ if(m->IsDungeon() && creditedPlayer)
+ {
+ if(m->IsRaid() || m->IsHeroic())
+ {
+ if(cVictim->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND)
+ ((InstanceMap *)m)->PermBindAllPlayers(creditedPlayer);
+ }
+ else
+ {
+ // the reset time is set but not added to the scheduler
+ // until the players leave the instance
+ time_t resettime = cVictim->GetRespawnTimeEx() + 2 * HOUR;
+ if(InstanceSave *save = sInstanceSaveManager.GetInstanceSave(cVictim->GetInstanceId()))
+ if(save->GetResetTime() < resettime) save->SetResetTime(resettime);
+ }
+ }
}
}
+ // last damage from non duel opponent or opponent controlled creature
+ if(duel_hasEnded)
+ {
+ assert(pVictim->GetTypeId()==TYPEID_PLAYER);
+ Player *he = (Player*)pVictim;
+
+ assert(he->duel);
+
+ he->duel->opponent->CombatStopWithPets(true);
+ he->CombatStopWithPets(true);
+
+ he->DuelComplete(DUEL_INTERUPTED);
+ }
+
+ // battleground things (do this at the end, so the death state flag will be properly set to handle in the bg->handlekill)
+ if(pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->InBattleGround())
+ {
+ Player *killed = ((Player*)pVictim);
+ if(BattleGround *bg = killed->GetBattleGround())
+ if(player)
+ bg->HandleKillPlayer(killed, player);
+ //later we can add support for creature->player kills here i'm
+ //not sure, but i guess those kills also get counted in av
+ //else if(GetTypeId() == TYPEID_UNIT)
+ // bg->HandleKillPlayer(killed,(Creature*)this);
+ }*/
+ }
+ else // if (health <= damage)
+ {
+ DEBUG_LOG("DealDamageAlive");
+
+ if (pVictim->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)pVictim)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED, damage);
+
+ pVictim->ModifyHealth(- (int32)damage);
+
if(damagetype == DIRECT_DAMAGE || damagetype == SPELL_DIRECT_DAMAGE)
{
//TODO: This is from procflag, I do not know which spell needs this
@@ -807,7 +860,6 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
//if (!spellProto || !(spellProto->AuraInterruptFlags&AURA_INTERRUPT_FLAG_DIRECT_DAMAGE))
pVictim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DIRECT_DAMAGE, spellProto ? spellProto->Id : 0);
}
-
if (pVictim->GetTypeId() != TYPEID_PLAYER)
{
if(spellProto && IsDamageToThreatSpell(spellProto))
@@ -874,7 +926,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
if(spell->getState() == SPELL_STATE_PREPARING)
{
uint32 interruptFlags = spell->m_spellInfo->InterruptFlags;
- if(interruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE)
+ if(interruptFlags & SPELL_INTERRUPT_FLAG_ABORT_ON_DMG)
pVictim->InterruptNonMeleeSpells(false);
else if(interruptFlags & SPELL_INTERRUPT_FLAG_PUSH_BACK)
spell->Delayed();
@@ -924,7 +976,7 @@ void Unit::CastStop(uint32 except_spellid)
InterruptSpell(i,false);
}
-void Unit::CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castItem, Aura* triggeredByAura, uint64 originalCaster)
+void Unit::CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
@@ -937,7 +989,7 @@ void Unit::CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castIte
CastSpell(Victim,spellInfo,triggered,castItem,triggeredByAura, originalCaster);
}
-void Unit::CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, Item *castItem, Aura* triggeredByAura, uint64 originalCaster)
+void Unit::CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
{
if(!spellInfo)
{
@@ -945,6 +997,11 @@ void Unit::CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, I
return;
}
+ if (!originalCaster && GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem())
+ if (Unit * owner = GetOwner())
+ if (owner->GetTypeId()==TYPEID_PLAYER)
+ originalCaster=owner->GetGUID();
+
SpellCastTargets targets;
uint32 targetMask = spellInfo->Targets;
//if(targetMask & (TARGET_FLAG_UNIT|TARGET_FLAG_UNK2))
@@ -991,7 +1048,7 @@ void Unit::CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, I
spell->prepare(&targets, triggeredByAura);
}
-void Unit::CastCustomSpell(Unit* target, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem, Aura* triggeredByAura, uint64 originalCaster)
+void Unit::CastCustomSpell(Unit* target, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
{
CustomSpellValues values;
if(bp0) values.AddSpellMod(SPELLVALUE_BASE_POINT0, *bp0);
@@ -1000,14 +1057,14 @@ void Unit::CastCustomSpell(Unit* target, uint32 spellId, int32 const* bp0, int32
CastCustomSpell(spellId, values, target, triggered, castItem, triggeredByAura, originalCaster);
}
-void Unit::CastCustomSpell(uint32 spellId, SpellValueMod mod, uint32 value, Unit* target, bool triggered, Item *castItem, Aura* triggeredByAura, uint64 originalCaster)
+void Unit::CastCustomSpell(uint32 spellId, SpellValueMod mod, uint32 value, Unit* target, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
{
CustomSpellValues values;
values.AddSpellMod(mod, value);
CastCustomSpell(spellId, values, target, triggered, castItem, triggeredByAura, originalCaster);
}
-void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* Victim, bool triggered, Item *castItem, Aura* triggeredByAura, uint64 originalCaster)
+void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* Victim, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
if(!spellInfo)
@@ -1064,7 +1121,7 @@ void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit*
}
// used for scripting
-void Unit::CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item *castItem, Aura* triggeredByAura, uint64 originalCaster)
+void Unit::CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
@@ -1089,7 +1146,7 @@ void Unit::CastSpell(float x, float y, float z, uint32 spellId, bool triggered,
}
// used for scripting
-void Unit::CastSpell(GameObject *go, uint32 spellId, bool triggered, Item *castItem, Aura* triggeredByAura, uint64 originalCaster)
+void Unit::CastSpell(GameObject *go, uint32 spellId, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
{
if(!go)
return;
@@ -1196,6 +1253,9 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 dama
if (blocked)
{
damageInfo->blocked = uint32(pVictim->GetShieldBlockValue());
+ //double blocked amount if block is critical
+ if (isBlockCritical())
+ damageInfo->blocked+=damageInfo->blocked;
if (damage < damageInfo->blocked)
damageInfo->blocked = damage;
damage-=damageInfo->blocked;
@@ -1210,7 +1270,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 dama
if (crit)
{
damageInfo->HitInfo|= SPELL_HIT_TYPE_CRIT;
- damage = SpellCriticalBonus(spellInfo, damage, pVictim);
+ damage = SpellCriticalDamageBonus(spellInfo, damage, pVictim);
// Resilience - reduce crit damage
if (pVictim->GetTypeId()==TYPEID_PLAYER)
damage -= ((Player*)pVictim)->GetSpellCritDamageReduction(damage);
@@ -1220,12 +1280,12 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 dama
}
if( damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL )
- damage = CalcArmorReducedDamage(pVictim, damage);
+ damage = CalcArmorReducedDamage(pVictim, damage, spellInfo, attackType);
// Calculate absorb resist
if(damage > 0)
{
- CalcAbsorbResist(pVictim, damageSchoolMask, SPELL_DIRECT_DAMAGE, damage, &damageInfo->absorb, &damageInfo->resist);
+ CalcAbsorbResist(pVictim, damageSchoolMask, SPELL_DIRECT_DAMAGE, damage, &damageInfo->absorb, &damageInfo->resist, spellInfo);
damage-= damageInfo->absorb + damageInfo->resist;
}
else
@@ -1233,6 +1293,37 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 dama
damageInfo->damage = damage;
}
+int32 Unit::GetIgnoredArmorMultiplier(SpellEntry const *spellInfo, WeaponAttackType attackType)
+{
+ if (GetTypeId() != TYPEID_PLAYER)
+ return 0;
+ //check if spell uses weapon
+ if (!spellInfo || spellInfo->EquippedItemClass!=ITEM_CLASS_WEAPON)
+ return 0;
+ Item *item = NULL;
+ if(attackType == BASE_ATTACK)
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
+ else if (attackType == OFF_ATTACK)
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ else if (attackType == RANGED_ATTACK)
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
+ if (!item)
+ return 0;
+
+ AuraEffectList const& armAuras = GetAurasByType(SPELL_AURA_MOD_WEAPONTYPE_IGNORE_TARGET_RESISTANCE);
+ int32 armorIgnored = 0;
+ for(AuraEffectList::const_iterator i = armAuras.begin();i != armAuras.end(); ++i)
+ {
+ if (!((*i)->GetSpellProto()->EquippedItemClass==item->GetProto()->Class
+ && (*i)->GetSpellProto()->EquippedItemSubClassMask & (1<<item->GetProto()->SubClass)))
+ continue;
+
+ if((*i)->GetAmount())
+ armorIgnored += (*i)->GetAmount();
+ }
+ return (-armorIgnored);
+}
+
void Unit::DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss)
{
if (damageInfo==0)
@@ -1243,7 +1334,7 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss)
if(!this || !pVictim)
return;
- if (!pVictim->isAlive() || pVictim->isInFlight() || pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
+ if (!pVictim->isAlive() || pVictim->hasUnitState(UNIT_STAT_UNATTACKABLE) || pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
return;
SpellEntry const *spellProto = sSpellStore.LookupEntry(damageInfo->SpellID);
@@ -1262,20 +1353,6 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss)
return;
}
- // update at damage Judgement aura duration that applied by attacker at victim
- if(damageInfo->damage && spellProto->Id == 35395)
- {
- AuraMap& vAuras = pVictim->GetAuras();
- for(AuraMap::iterator itr = vAuras.begin(); itr != vAuras.end(); ++itr)
- {
- SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
- if( spellInfo->AttributesEx3 & 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && ((*itr).second->GetCasterGUID() == GetGUID()))
- {
- (*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration());
- (*itr).second->UpdateAuraDuration();
- }
- }
- }
// Call default DealDamage
CleanDamage cleanDamage(damageInfo->cleanDamage, BASE_ATTACK, MELEE_HIT_NORMAL);
DealDamage(pVictim, damageInfo->damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SpellSchoolMask(damageInfo->schoolMask), spellProto, durabilityLoss);
@@ -1329,7 +1406,7 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
}
// Physical Immune check
- if(damageInfo->target->IsImmunedToDamage(SpellSchoolMask(damageInfo->damageSchoolMask),true))
+ if(damageInfo->target->IsImmunedToDamage(SpellSchoolMask(damageInfo->damageSchoolMask)))
{
damageInfo->HitInfo |= HITINFO_NORMALSWING;
damageInfo->TargetState = VICTIMSTATE_IS_IMMUNE;
@@ -1343,7 +1420,7 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
// Add melee damage bonus
MeleeDamageBonus(damageInfo->target, &damage, damageInfo->attackType);
// Calculate armor reduction
- damageInfo->damage = CalcArmorReducedDamage(damageInfo->target, damage);
+ damageInfo->damage = CalcArmorReducedDamage(damageInfo->target, damage, NULL , damageInfo->attackType);
damageInfo->cleanDamage += damage - damageInfo->damage;
damageInfo->hitOutCome = RollMeleeOutcomeAgainst(damageInfo->target, damageInfo->attackType);
@@ -1431,8 +1508,12 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
case MELEE_HIT_BLOCK:
{
damageInfo->TargetState = VICTIMSTATE_NORMAL;
+ damageInfo->HitInfo |= HITINFO_BLOCK;
damageInfo->procEx|=PROC_EX_BLOCK;
damageInfo->blocked_amount = damageInfo->target->GetShieldBlockValue();
+ //double blocked amount if block is critical
+ if (isBlockCritical())
+ damageInfo->blocked_amount+=damageInfo->blocked_amount;
if (damageInfo->blocked_amount >= damageInfo->damage)
{
damageInfo->TargetState = VICTIMSTATE_BLOCKS;
@@ -1496,7 +1577,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
if(!this || !pVictim)
return;
- if (!pVictim->isAlive() || pVictim->isInFlight() || pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
+ if (!pVictim->isAlive() || pVictim->hasUnitState(UNIT_STAT_UNATTACKABLE) || pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
return;
//You don't lose health from damage taken from another player while in a sanctuary
@@ -1522,29 +1603,29 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
// Reduce attack time
if (pVictim->haveOffhandWeapon() && offtime < basetime)
{
- float percent20 = pVictim->GetAttackTime(OFF_ATTACK) * 0.20;
- float percent60 = 3 * percent20;
+ float percent20 = pVictim->GetAttackTime(OFF_ATTACK) * 0.20f;
+ float percent60 = 3.0f * percent20;
if(offtime > percent20 && offtime <= percent60)
{
pVictim->setAttackTimer(OFF_ATTACK, uint32(percent20));
}
else if(offtime > percent60)
{
- offtime -= 2 * percent20;
+ offtime -= 2.0f * percent20;
pVictim->setAttackTimer(OFF_ATTACK, uint32(offtime));
}
}
else
{
float percent20 = pVictim->GetAttackTime(BASE_ATTACK) * 0.20;
- float percent60 = 3 * percent20;
+ float percent60 = 3.0f * percent20;
if(basetime > percent20 && basetime <= percent60)
{
pVictim->setAttackTimer(BASE_ATTACK, uint32(percent20));
}
else if(basetime > percent60)
{
- basetime -= 2 * percent20;
+ basetime -= 2.0f * percent20;
pVictim->setAttackTimer(BASE_ATTACK, uint32(basetime));
}
}
@@ -1556,64 +1637,49 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
// If this is a creature and it attacks from behind it has a probability to daze it's victim
if( (damageInfo->hitOutCome==MELEE_HIT_CRIT || damageInfo->hitOutCome==MELEE_HIT_CRUSHING || damageInfo->hitOutCome==MELEE_HIT_NORMAL || damageInfo->hitOutCome==MELEE_HIT_GLANCING) &&
- GetTypeId() != TYPEID_PLAYER && !((Creature*)this)->GetCharmerOrOwnerGUID() && !pVictim->HasInArc(M_PI, this)
+ GetTypeId() != TYPEID_PLAYER && !((Creature*)this)->IsControlledByPlayer() && !pVictim->HasInArc(M_PI, this)
&& (pVictim->GetTypeId() == TYPEID_PLAYER || !((Creature*)pVictim)->isWorldBoss()))
{
// -probability is between 0% and 40%
// 20% base chance
- float Probability = 20;
+ float Probability = 20.0f;
//there is a newbie protection, at level 10 just 7% base chance; assuming linear function
if( pVictim->getLevel() < 30 )
- Probability = 0.65f*pVictim->getLevel()+0.5;
+ Probability = 0.65f*pVictim->getLevel()+0.5f;
uint32 VictimDefense=pVictim->GetDefenseSkillValue();
uint32 AttackerMeleeSkill=GetUnitMeleeSkill();
Probability *= AttackerMeleeSkill/(float)VictimDefense;
- if(Probability > 40)
- Probability = 40;
+ if(Probability > 40.0f)
+ Probability = 40.0f;
if(roll_chance_f(Probability))
CastSpell(pVictim, 1604, true);
}
- // update at damage Judgement aura duration that applied by attacker at victim
- if(damageInfo->damage)
- {
- AuraMap& vAuras = pVictim->GetAuras();
- for(AuraMap::iterator itr = vAuras.begin(); itr != vAuras.end(); ++itr)
- {
- SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
- if( spellInfo->AttributesEx3 & 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && ((*itr).second->GetCasterGUID() == GetGUID()))
- {
- (*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration());
- (*itr).second->UpdateAuraDuration();
- }
- }
- }
-
// If not miss
if (!(damageInfo->HitInfo & HITINFO_MISS))
{
if(GetTypeId() == TYPEID_PLAYER && pVictim->isAlive())
{
for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++)
- ((Player*)this)->CastItemCombatSpell(((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0,i), pVictim, damageInfo->attackType);
+ ((Player*)this)->CastItemCombatSpell(((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0,i), pVictim, damageInfo->attackType);
}
// victim's damage shield
- std::set<Aura*> alreadyDone;
- uint32 removedAuras = pVictim->m_removedAuras;
- AuraList const& vDamageShields = pVictim->GetAurasByType(SPELL_AURA_DAMAGE_SHIELD);
- for(AuraList::const_iterator i = vDamageShields.begin(), next = vDamageShields.begin(); i != vDamageShields.end(); i = next)
+ std::set<AuraEffect*> alreadyDone;
+ uint32 removedAuras = pVictim->m_removedAurasCount;
+ AuraEffectList const& vDamageShields = pVictim->GetAurasByType(SPELL_AURA_DAMAGE_SHIELD);
+ for(AuraEffectList::const_iterator i = vDamageShields.begin(), next = vDamageShields.begin(); i != vDamageShields.end(); i = next)
{
next++;
if (alreadyDone.find(*i) == alreadyDone.end())
{
alreadyDone.insert(*i);
- uint32 damage=(*i)->GetModifier()->m_amount;
+ uint32 damage=(*i)->GetAmount();
SpellEntry const *spellProto = sSpellStore.LookupEntry((*i)->GetId());
if(!spellProto)
continue;
@@ -1623,18 +1689,20 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
//CalcAbsorbResist(pVictim, SpellSchools(spellProto->School), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
//damage-=absorb + resist;
- WorldPacket data(SMSG_SPELLDAMAGESHIELD,(8+8+4+4));
+ WorldPacket data(SMSG_SPELLDAMAGESHIELD,(8+8+4+4+4+4));
data << uint64(pVictim->GetGUID());
data << uint64(GetGUID());
+ data << uint32(spellProto->Id);
+ data << uint32(damage); // Damage
+ data << uint32(0); // Overkill
data << uint32(spellProto->SchoolMask);
- data << uint32(damage);
pVictim->SendMessageToSet(&data, true );
pVictim->DealDamage(this, damage, 0, SPELL_DIRECT_DAMAGE, GetSpellSchoolMask(spellProto), spellProto, true);
- if (pVictim->m_removedAuras > removedAuras)
+ if (pVictim->m_removedAurasCount > removedAuras)
{
- removedAuras = pVictim->m_removedAuras;
+ removedAuras = pVictim->m_removedAurasCount;
next = vDamageShields.begin();
}
}
@@ -1646,28 +1714,50 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
void Unit::HandleEmoteCommand(uint32 anim_id)
{
WorldPacket data( SMSG_EMOTE, 12 );
- data << anim_id << GetGUID();
- WPAssert(data.size() == 12);
-
+ data << uint32(anim_id);
+ data << uint64(GetGUID());
SendMessageToSet(&data, true);
}
-uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage)
+uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType)
{
uint32 newdamage = 0;
float armor = pVictim->GetArmor();
// Ignore enemy armor by SPELL_AURA_MOD_TARGET_RESISTANCE aura
armor += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, SPELL_SCHOOL_MASK_NORMAL);
- if (armor<0.0f) armor=0.0f;
+ armor *= float((GetIgnoredArmorMultiplier(spellInfo, attackType)+100.0f)/100.0f);
+ if(spellInfo)
+ if(Player *modOwner = GetSpellModOwner())
+ modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_IGNORE_ARMOR, armor);
- float tmpvalue = 0.0f;
- if(getLevel() <= 59) //Level 1-59
- tmpvalue = armor / (armor + 400.0f + 85.0f * getLevel());
- else if(getLevel() < 70) //Level 60-69
- tmpvalue = armor / (armor - 22167.5f + 467.5f * getLevel());
- else //Level 70+
- tmpvalue = armor / (armor + 10557.5f);
+ AuraEffectList const& ResIgnoreAurasAb = GetAurasByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST);
+ for(AuraEffectList::const_iterator j = ResIgnoreAurasAb.begin();j != ResIgnoreAurasAb.end(); ++j)
+ {
+ if( (*j)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL
+ && (*j)->isAffectedOnSpell(spellInfo))
+ armor= int32(float(armor) * (float(100-(*j)->GetAmount())/100.0f));
+ }
+
+ AuraEffectList const& ResIgnoreAuras = GetAurasByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
+ for(AuraEffectList::const_iterator j = ResIgnoreAuras.begin();j != ResIgnoreAuras.end(); ++j)
+ {
+ if( (*j)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
+ armor= int32(float(armor) * (float(100-(*j)->GetAmount())/100.0f));
+ }
+
+ // Apply Player CR_ARMOR_PENETRATION rating
+ if (GetTypeId()==TYPEID_PLAYER)
+ armor *= 1.0f - ((Player*)this)->GetRatingBonusValue(CR_ARMOR_PENETRATION) / 100.0f;
+
+ if (armor < 0.0f) armor=0.0f;
+
+ float levelModifier = getLevel();
+ if ( levelModifier > 59 )
+ levelModifier = levelModifier + (4.5f * (levelModifier-59));
+
+ float tmpvalue = 0.1f * armor / (8.5f * levelModifier + 40);
+ tmpvalue = tmpvalue/(1.0f + tmpvalue);
if(tmpvalue < 0.0f)
tmpvalue = 0.0f;
@@ -1678,7 +1768,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage)
return (newdamage > 1) ? newdamage : 1;
}
-void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist)
+void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, SpellEntry const *spellInfo)
{
if(!pVictim || !pVictim->isAlive() || !damage)
return;
@@ -1714,124 +1804,336 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
*resist += uint32(damage * m / 4);
if(*resist > damage)
*resist = damage;
+
+ AuraEffectList const& ResIgnoreAurasAb = GetAurasByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST);
+ for(AuraEffectList::const_iterator j = ResIgnoreAurasAb.begin();j != ResIgnoreAurasAb.end(); ++j)
+ {
+ if( (*j)->GetMiscValue() & schoolMask
+ && (*j)->isAffectedOnSpell(spellInfo))
+ *resist= int32(float(*resist) * (float(100-(*j)->GetAmount())/100.0f));
+ }
+
+ AuraEffectList const& ResIgnoreAuras = GetAurasByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
+ for(AuraEffectList::const_iterator j = ResIgnoreAuras.begin();j != ResIgnoreAuras.end(); ++j)
+ {
+ if( (*j)->GetMiscValue() & schoolMask)
+ *resist= int32(float(*resist) * (float(100-(*j)->GetAmount())/100.0f));
+ }
}
else
*resist = 0;
int32 RemainingDamage = damage - *resist;
-
+ int32 TotalAbsorb = RemainingDamage;
+ // Get unit state (need for some absorb check)
+ uint32 unitflag = pVictim->GetUInt32Value(UNIT_FIELD_FLAGS);
+ // Reflect damage spells (not cast any damage spell in aura lookup)
+ uint32 reflectSpell = 0;
+ int32 reflectDamage = 0;
+ uint32 healSpell = 0;
+ int32 healAmount = 0;
+ Unit * healCaster = NULL;
+ // Need remove expired auras after
+ bool existExpired = false;
// absorb without mana cost
- int32 reflectDamage = 0;
- Aura* reflectAura = NULL;
- AuraList const& vSchoolAbsorb = pVictim->GetAurasByType(SPELL_AURA_SCHOOL_ABSORB);
- for(AuraList::const_iterator i = vSchoolAbsorb.begin(), next; i != vSchoolAbsorb.end() && RemainingDamage > 0; i = next)
+ AuraEffectList const& vSchoolAbsorb = pVictim->GetAurasByType(SPELL_AURA_SCHOOL_ABSORB);
+ for(AuraEffectList::const_iterator i = vSchoolAbsorb.begin(); i != vSchoolAbsorb.end() && RemainingDamage > 0; ++i)
{
- next = i; ++next;
-
- if (((*i)->GetModifier()->m_miscvalue & schoolMask)==0)
+ if (!((*i)->GetMiscValue() & schoolMask))
continue;
- // Cheat Death
- if((*i)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && (*i)->GetSpellProto()->SpellIconID == 2109)
+ SpellEntry const* spellProto = (*i)->GetSpellProto();
+
+ // Max Amount can be absorbed by this aura
+ int32 currentAbsorb = (*i)->GetAmount();
+
+ // Found empty aura (impossible but..)
+ if (currentAbsorb <=0)
{
- if (((Player*)pVictim)->HasSpellCooldown(31231))
- continue;
- if (pVictim->GetHealth() <= RemainingDamage)
+ existExpired = true;
+ continue;
+ }
+ // Handle custom absorb auras
+ // TODO: try find better way
+ switch(spellProto->SpellFamilyName)
+ {
+ case SPELLFAMILY_GENERIC:
{
- int32 chance = (*i)->GetModifier()->m_amount;
- if (roll_chance_i(chance))
+ // Astral Shift
+ if (spellProto->SpellIconID == 3066)
{
- pVictim->CastSpell(pVictim,31231,true);
- ((Player*)pVictim)->AddSpellCooldown(31231,0,time(NULL)+60);
-
- // with health > 10% lost health until health==10%, in other case no losses
- uint32 health10 = pVictim->GetMaxHealth()/10;
- RemainingDamage = pVictim->GetHealth() > health10 ? pVictim->GetHealth() - health10 : 0;
+ //reduces all damage taken while stun, fear or silence
+ if (unitflag & (UNIT_FLAG_STUNNED|UNIT_FLAG_FLEEING|UNIT_FLAG_SILENCED))
+ RemainingDamage -= RemainingDamage * currentAbsorb / 100;
+ continue;
+ }
+ // Nerves of Steel
+ if (spellProto->SpellIconID == 2115)
+ {
+ // while affected by Stun and Fear
+ if (unitflag&(UNIT_FLAG_STUNNED|UNIT_FLAG_FLEEING))
+ RemainingDamage -= RemainingDamage * currentAbsorb / 100;
+ continue;
+ }
+ // Spell Deflection
+ if (spellProto->SpellIconID == 3006)
+ {
+ // You have a chance equal to your Parry chance
+ if (damagetype == DIRECT_DAMAGE && // Only for direct damage
+ roll_chance_f(pVictim->GetUnitParryChance())) // Roll chance
+ RemainingDamage -= RemainingDamage * currentAbsorb / 100;
+ continue;
+ }
+ // Reflective Shield (Lady Malande boss)
+ if (spellProto->Id == 41475)
+ {
+ if(RemainingDamage < currentAbsorb)
+ reflectDamage = RemainingDamage / 2;
+ else
+ reflectDamage = currentAbsorb / 2;
+ reflectSpell = 33619;
+ break;
}
+ if (spellProto->Id == 39228 || // Argussian Compass
+ spellProto->Id == 60218) // Essence of Gossamer
+ {
+ // Max absorb stored in 1 dummy effect
+ if (spellProto->EffectBasePoints[1] < currentAbsorb)
+ currentAbsorb = spellProto->EffectBasePoints[1];
+ break;
+ }
+ break;
}
- continue;
- }
-
- int32 currentAbsorb;
-
- //Reflective Shield
- if ((pVictim != this) && (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST && (*i)->GetSpellProto()->SpellFamilyFlags == 0x1)
- {
- if(Unit* caster = (*i)->GetCaster())
+ case SPELLFAMILY_DRUID:
{
- AuraList const& vOverRideCS = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(AuraList::const_iterator k = vOverRideCS.begin(); k != vOverRideCS.end(); ++k)
+ // Primal Tenacity
+ if (spellProto->SpellIconID == 2253)
{
- switch((*k)->GetModifier()->m_miscvalue)
+ //reduces all damage taken while Stunned
+ if (unitflag & UNIT_FLAG_STUNNED)
+ RemainingDamage -= RemainingDamage * currentAbsorb / 100;
+ continue;
+ }
+ break;
+ }
+ case SPELLFAMILY_ROGUE:
+ {
+ // Cheat Death
+ if(spellProto->SpellIconID == 2109)
+ {
+ if (pVictim->GetTypeId()==TYPEID_PLAYER && // Only players
+ pVictim->GetHealth() <= RemainingDamage && // Only if damage kill
+ !((Player*)pVictim)->HasSpellCooldown(31231) && // Only if no cooldown
+ roll_chance_i(currentAbsorb)) // Only if roll
{
- case 5065: // Rank 1
- case 5064: // Rank 2
- case 5063: // Rank 3
- case 5062: // Rank 4
- case 5061: // Rank 5
- {
- if(RemainingDamage >= (*i)->GetModifier()->m_amount)
- reflectDamage = (*i)->GetModifier()->m_amount * (*k)->GetModifier()->m_amount/100;
- else
- reflectDamage = (*k)->GetModifier()->m_amount * RemainingDamage/100;
- reflectAura = *i;
-
- } break;
- default: break;
+ pVictim->CastSpell(pVictim,31231,true);
+ ((Player*)pVictim)->AddSpellCooldown(31231,0,time(NULL)+60);
+ // with health > 10% lost health until health==10%, in other case no losses
+ uint32 health10 = pVictim->GetMaxHealth()/10;
+ RemainingDamage = pVictim->GetHealth() > health10 ? pVictim->GetHealth() - health10 : 0;
}
+ continue;
+ }
+ break;
+ }
+ case SPELLFAMILY_PRIEST:
+ {
+ // Guardian Spirit
+ if (spellProto->Id==47788)
+ {
+ if (pVictim->GetHealth() <= RemainingDamage) // Killing Blow
+ {
+ healAmount = pVictim->GetMaxHealth()/2;
+ healCaster = pVictim;
+ healSpell = 48153;
+ (*i)->SetAmount(0);
+ RemainingDamage=0;
+ }
+ continue;
+ }
- if(reflectDamage)
+ // Reflective Shield
+ if (spellProto->SpellFamilyFlags.IsEqual(0x1, 0, 0x400))
+ {
+ if (pVictim == this)
+ break;
+ Unit* caster = (*i)->GetCaster();
+ if (!caster)
+ break;
+ AuraEffectList const& vOverRideCS = caster->GetAurasByType(SPELL_AURA_DUMMY);
+ for(AuraEffectList::const_iterator k = vOverRideCS.begin(); k != vOverRideCS.end(); ++k)
+ {
+ if((*k)->GetSpellProto()->SpellFamilyName != SPELLFAMILY_PRIEST)
+ continue;
+ switch((*k)->GetMiscValue())
+ {
+ case 5065: // Rank 1
+ case 5064: // Rank 2
+ case 5063: // Rank 3
+ {
+ if(RemainingDamage >= currentAbsorb)
+ reflectDamage = (*k)->GetAmount() * currentAbsorb/100;
+ else
+ reflectDamage = (*k)->GetAmount() * RemainingDamage/100;
+ reflectSpell = 33619;
+ } break;
+ }
+ }
+ }
+ // no break here, rapture can proc with reflective shield
+ // Rapture
+ if (spellProto->SpellFamilyFlags.HasFlag(0x1, 0x1000000))
+ {
+ if (pVictim == this)
+ break;
+ healCaster = (*i)->GetCaster();
+ if (!healCaster)
break;
+
+ AuraEffectList const& lOverRideCS = pVictim->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ for(AuraEffectList::const_iterator k = lOverRideCS.begin(); k != lOverRideCS.end(); ++k)
+ {
+ switch((*k)->GetMiscValue())
+ {
+ case 7556: // Rank 1
+ case 7555: // Rank 2
+ case 7554: // Rank 3
+ case 7553: // Rank 4
+ case 7552: // Rank 5
+ {
+ healSpell = 47755;
+ healAmount += ((pVictim->getLevel() * (-0.2) + 18) / 1000000) * currentAbsorb * pVictim->GetMaxPower(POWER_MANA);
+ // limitation based on aura amount
+ if(healAmount > pVictim->GetMaxPower(POWER_MANA) * (*k)->GetAmount() / 1000)
+ healAmount = pVictim->GetMaxPower(POWER_MANA) * (*k)->GetAmount() / 1000;
+ } break;
+ }
+ }
+ }
+ break;
+ }
+ case SPELLFAMILY_SHAMAN:
+ {
+ // Astral Shift
+ if (spellProto->SpellIconID == 3066)
+ {
+ //reduces all damage taken while stun, fear or silence
+ if (unitflag & (UNIT_FLAG_STUNNED|UNIT_FLAG_FLEEING|UNIT_FLAG_SILENCED))
+ RemainingDamage -= RemainingDamage * currentAbsorb / 100;
+ continue;
+ }
+ break;
+ }
+ case SPELLFAMILY_DEATHKNIGHT:
+ {
+ // Shadow of Death
+ if (spellProto->SpellIconID == 1958)
+ {
+ // TODO: absorb only while transform
+ continue;
+ }
+ // Anti-Magic Shell (on self)
+ if (spellProto->Id == 48707)
+ {
+ // damage absorbed by Anti-Magic Shell energizes the DK with additional runic power.
+ // This, if I'm not mistaken, shows that we get back ~2% of the absorbed damage as runic power.
+ int32 absorbed = RemainingDamage * currentAbsorb / 100;
+ int32 regen = absorbed * 2 / 10;
+ pVictim->CastCustomSpell(pVictim, 49088, &regen, 0, 0, true, 0, (*i));
+ RemainingDamage -= absorbed;
+ continue;
+ }
+ // Anti-Magic Shell (on single party/raid member)
+ if (spellProto->Id == 50462)
+ {
+ RemainingDamage -= RemainingDamage * currentAbsorb / 100;
+ continue;
+ }
+ // Anti-Magic Zone
+ if (spellProto->Id == 50461)
+ {
+ Unit* caster = (*i)->GetCaster();
+ if (!caster)
+ continue;
+ int32 absorbed = RemainingDamage * currentAbsorb / 100;
+ int32 canabsorb = caster->GetHealth();
+ if (canabsorb < absorbed)
+ absorbed = canabsorb;
+ DealDamage(caster, absorbed, NULL, damagetype, schoolMask, 0, false);
+ RemainingDamage -= absorbed;
+ continue;
}
+ break;
}
+ default:
+ break;
}
- if (RemainingDamage >= (*i)->GetModifier()->m_amount)
- {
- currentAbsorb = (*i)->GetModifier()->m_amount;
- pVictim->RemoveAurasDueToSpell((*i)->GetId());
- next = vSchoolAbsorb.begin();
- }
- else
- {
+ // currentAbsorb - damage can be absorbed by shield
+ // If need absorb less damage
+ if (RemainingDamage < currentAbsorb)
currentAbsorb = RemainingDamage;
- (*i)->GetModifier()->m_amount -= RemainingDamage;
- }
RemainingDamage -= currentAbsorb;
+
+ // Reduce shield amount
+ (*i)->SetAmount((*i)->GetAmount() -currentAbsorb);
+ // Need remove it later
+ if ((*i)->GetAmount()<=0)
+ existExpired = true;
+ }
+ if(healSpell && healCaster)
+ healCaster->CastCustomSpell(healCaster, healSpell, &healAmount, NULL, NULL, true);
+
+ // Remove all expired absorb auras
+ if (existExpired)
+ {
+ for(AuraEffectList::const_iterator i = vSchoolAbsorb.begin(); i != vSchoolAbsorb.end();)
+ {
+ Aura *aura=(*i)->GetParentAura();
+ AuraEffect *auraeff =(*i);
+ ++i;
+ if (auraeff->GetAmount()<=0)
+ {
+ uint32 removedAuras = pVictim->m_removedAurasCount;
+ pVictim->RemoveAura(aura, AURA_REMOVE_BY_ENEMY_SPELL);
+ if (removedAuras+1<pVictim->m_removedAurasCount)
+ i=vSchoolAbsorb.begin();
+ }
+ }
}
- // do not cast spells while looping auras; auras can get invalid otherwise
- if (reflectDamage)
- pVictim->CastCustomSpell(this, 33619, &reflectDamage, NULL, NULL, true, NULL, reflectAura);
+ // Cast back reflect damage spell
+ if (reflectSpell)
+ pVictim->CastCustomSpell(this, reflectSpell, &reflectDamage, NULL, NULL, true);
// absorb by mana cost
- AuraList const& vManaShield = pVictim->GetAurasByType(SPELL_AURA_MANA_SHIELD);
- for(AuraList::const_iterator i = vManaShield.begin(), next; i != vManaShield.end() && RemainingDamage > 0; i = next)
+ AuraEffectList const& vManaShield = pVictim->GetAurasByType(SPELL_AURA_MANA_SHIELD);
+ for(AuraEffectList::const_iterator i = vManaShield.begin(), next; i != vManaShield.end() && RemainingDamage > 0; i = next)
{
next = i; ++next;
// check damage school mask
- if(((*i)->GetModifier()->m_miscvalue & schoolMask)==0)
+ if(((*i)->GetMiscValue() & schoolMask)==0)
continue;
int32 currentAbsorb;
- if (RemainingDamage >= (*i)->GetModifier()->m_amount)
- currentAbsorb = (*i)->GetModifier()->m_amount;
+ if (RemainingDamage >= (*i)->GetAmount())
+ currentAbsorb = (*i)->GetAmount();
else
currentAbsorb = RemainingDamage;
float manaMultiplier = (*i)->GetSpellProto()->EffectMultipleValue[(*i)->GetEffIndex()];
- if(Player *modOwner = GetSpellModOwner())
+ if(Player *modOwner = pVictim->GetSpellModOwner())
modOwner->ApplySpellMod((*i)->GetId(), SPELLMOD_MULTIPLE_VALUE, manaMultiplier);
int32 maxAbsorb = int32(pVictim->GetPower(POWER_MANA) / manaMultiplier);
if (currentAbsorb > maxAbsorb)
currentAbsorb = maxAbsorb;
- (*i)->GetModifier()->m_amount -= currentAbsorb;
- if((*i)->GetModifier()->m_amount <= 0)
+ (*i)->SetAmount((*i)->GetAmount()-currentAbsorb);
+ if((*i)->GetAmount() <= 0)
{
- pVictim->RemoveAurasDueToSpell((*i)->GetId());
+ pVictim->RemoveAura((*i)->GetParentAura(), AURA_REMOVE_BY_ENEMY_SPELL);
next = vManaShield.begin();
}
@@ -1844,13 +2146,13 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
// only split damage if not damaging yourself
if(pVictim != this)
{
- AuraList const& vSplitDamageFlat = pVictim->GetAurasByType(SPELL_AURA_SPLIT_DAMAGE_FLAT);
- for(AuraList::const_iterator i = vSplitDamageFlat.begin(), next; i != vSplitDamageFlat.end() && RemainingDamage >= 0; i = next)
+ AuraEffectList const& vSplitDamageFlat = pVictim->GetAurasByType(SPELL_AURA_SPLIT_DAMAGE_FLAT);
+ for(AuraEffectList::const_iterator i = vSplitDamageFlat.begin(), next; i != vSplitDamageFlat.end() && RemainingDamage >= 0; i = next)
{
next = i; ++next;
// check damage school mask
- if(((*i)->GetModifier()->m_miscvalue & schoolMask)==0)
+ if(((*i)->GetMiscValue() & schoolMask)==0)
continue;
// Damage can be splitted only if aura has an alive caster
@@ -1859,8 +2161,8 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
continue;
int32 currentAbsorb;
- if (RemainingDamage >= (*i)->GetModifier()->m_amount)
- currentAbsorb = (*i)->GetModifier()->m_amount;
+ if (RemainingDamage >= (*i)->GetAmount())
+ currentAbsorb = (*i)->GetAmount();
else
currentAbsorb = RemainingDamage;
@@ -1872,13 +2174,13 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
DealDamage(caster, currentAbsorb, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*i)->GetSpellProto(), false);
}
- AuraList const& vSplitDamagePct = pVictim->GetAurasByType(SPELL_AURA_SPLIT_DAMAGE_PCT);
- for(AuraList::const_iterator i = vSplitDamagePct.begin(), next; i != vSplitDamagePct.end() && RemainingDamage >= 0; i = next)
+ AuraEffectList const& vSplitDamagePct = pVictim->GetAurasByType(SPELL_AURA_SPLIT_DAMAGE_PCT);
+ for(AuraEffectList::const_iterator i = vSplitDamagePct.begin(), next; i != vSplitDamagePct.end() && RemainingDamage >= 0; i = next)
{
next = i; ++next;
// check damage school mask
- if(((*i)->GetModifier()->m_miscvalue & schoolMask)==0)
+ if(((*i)->GetMiscValue() & schoolMask)==0)
continue;
// Damage can be splitted only if aura has an alive caster
@@ -1886,7 +2188,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
if(!caster || caster == pVictim || !caster->IsInWorld() || !caster->isAlive())
continue;
- int32 splitted = int32(RemainingDamage * (*i)->GetModifier()->m_amount / 100.0f);
+ int32 splitted = int32(RemainingDamage * (*i)->GetAmount() / 100.0f);
RemainingDamage -= splitted;
@@ -1897,409 +2199,53 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
}
}
- *absorb = damage - RemainingDamage - *resist;
-}
-
-/*
-void Unit::DoAttackDamage (Unit *pVictim, uint32 *damage, CleanDamage *cleanDamage, uint32 *blocked_amount, SpellSchoolMask damageSchoolMask, uint32 *hitInfo, VictimState *victimState, uint32 *absorbDamage, uint32 *resistDamage, WeaponAttackType attType, SpellEntry const *spellCasted, bool isTriggeredSpell)
-{
- MeleeHitOutcome outcome;
-
- // If is casted Melee spell, calculate like physical
- if(!spellCasted)
- outcome = RollMeleeOutcomeAgainst (pVictim, attType);
- else
- outcome = RollPhysicalOutcomeAgainst (pVictim, attType, spellCasted);
-
- if(outcome == MELEE_HIT_MISS ||outcome == MELEE_HIT_DODGE ||outcome == MELEE_HIT_BLOCK ||outcome == MELEE_HIT_PARRY)
- pVictim->AddThreat(this, 0.0f);
- switch(outcome)
+ TotalAbsorb = (TotalAbsorb - RemainingDamage > 0) ? TotalAbsorb - RemainingDamage : 0;
+ // TODO: School should be checked for absorbing auras or for attacks?
+ int32 auraAbsorbMod = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL);
+ AuraEffectList const& AbsIgnoreAurasAb = GetAurasByType(SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL);
+ for(AuraEffectList::const_iterator i = AbsIgnoreAurasAb.begin();i != AbsIgnoreAurasAb.end(); ++i)
{
- case MELEE_HIT_EVADE:
- {
- *hitInfo |= HITINFO_MISS;
- *damage = 0;
- cleanDamage->damage = 0;
- return;
- }
- case MELEE_HIT_MISS:
- {
- *hitInfo |= HITINFO_MISS;
- *damage = 0;
- cleanDamage->damage = 0;
- if(GetTypeId()== TYPEID_PLAYER)
- ((Player*)this)->UpdateWeaponSkill(attType);
- return;
- }
+ if ((*i)->GetAmount() > auraAbsorbMod
+ && (*i)->isAffectedOnSpell(spellInfo))
+ auraAbsorbMod = (*i)->GetAmount();
}
- /// If this is a creature and it attacks from behind it has a probability to daze it's victim
- if( (outcome==MELEE_HIT_CRIT || outcome==MELEE_HIT_CRUSHING || outcome==MELEE_HIT_NORMAL || outcome==MELEE_HIT_GLANCING) &&
- GetTypeId() != TYPEID_PLAYER && !((Creature*)this)->GetCharmerOrOwnerGUID() && !pVictim->HasInArc(M_PI, this)
- && pVictim->GetTypeId() == TYPEID_PLAYER)
- {
- // -probability is between 0% and 40%
- // 20% base chance
- float Probability = 20;
-
- //there is a newbie protection, at level 10 just 7% base chance; assuming linear function
- if( pVictim->getLevel() < 30 )
- Probability = 0.65f*pVictim->getLevel()+0.5;
-
- uint32 VictimDefense=pVictim->GetDefenseSkillValue(this);
- uint32 AttackerMeleeSkill=GetUnitMeleeSkill(pVictim);
-
- Probability *= AttackerMeleeSkill/(float)VictimDefense;
+ // Ignore absorb - add reduced amount again to damage
+ RemainingDamage += auraAbsorbMod * TotalAbsorb / 100;
- if(Probability > 40.0f)
- Probability = 40.0f;
-
- if(roll_chance_f(Probability))
- CastSpell(pVictim, 1604, true);
- }
-
- //Calculate the damage after armor mitigation if SPELL_SCHOOL_NORMAL
- if (damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL)
- {
- uint32 damageAfterArmor = CalcArmorReducedDamage(pVictim, *damage);
-
- // random durability for main hand weapon (ABSORB)
- if(damageAfterArmor < *damage)
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_ABSORB)))
- ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EquipmentSlots(urand(EQUIPMENT_SLOT_START,EQUIPMENT_SLOT_BACK)));
-
- cleanDamage->damage += *damage - damageAfterArmor;
- *damage = damageAfterArmor;
- }
-
- if(GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() != TYPEID_PLAYER && pVictim->GetCreatureType() != CREATURE_TYPE_CRITTER )
- ((Player*)this)->UpdateCombatSkills(pVictim, attType, outcome, false);
-
- if(GetTypeId() != TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER)
- ((Player*)pVictim)->UpdateCombatSkills(this, attType, outcome, true);
+ *absorb = damage - RemainingDamage - *resist;
- switch (outcome)
+ if (*absorb)
{
- case MELEE_HIT_BLOCK_CRIT:
- case MELEE_HIT_CRIT:
- {
- //*hitInfo = 0xEA;
- // 0xEA
- *hitInfo = HITINFO_CRITICALHIT | HITINFO_NORMALSWING2 | 0x8;
-
- // Crit bonus calc
- uint32 crit_bonus;
- crit_bonus = *damage;
-
- // Apply crit_damage bonus for melee spells
- if (spellCasted)
- {
- if(Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellCasted->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus);
-
- uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
- AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS);
- for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i)
- if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- crit_bonus = uint32(crit_bonus * ((*i)->GetModifierValue()+100.0f)/100.0f);
- }
-
- *damage += crit_bonus;
-
- uint32 resilienceReduction = 0;
-
- if(attType == RANGED_ATTACK)
- {
- int32 mod = pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE);
- *damage = int32((*damage) * float((100.0f + mod)/100.0f));
- // Resilience - reduce crit damage
- if (pVictim->GetTypeId()==TYPEID_PLAYER)
- resilienceReduction = ((Player*)pVictim)->GetRangedCritDamageReduction(*damage);
- }
- else
- {
- int32 mod = pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE);
- mod += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE);
- *damage = int32((*damage) * float((100.0f + mod)/100.0f));
- // Resilience - reduce crit damage
- if (pVictim->GetTypeId()==TYPEID_PLAYER)
- resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(*damage);
- }
-
- *damage -= resilienceReduction;
- cleanDamage->damage += resilienceReduction;
-
- if(GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() != TYPEID_PLAYER && pVictim->GetCreatureType() != CREATURE_TYPE_CRITTER )
- ((Player*)this)->UpdateWeaponSkill(attType);
-
- ModifyAuraState(AURA_STATE_CRIT, true);
- StartReactiveTimer( REACTIVE_CRIT );
-
- if(getClass()==CLASS_HUNTER)
- {
- ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, true);
- StartReactiveTimer( REACTIVE_HUNTER_CRIT );
- }
-
- if ( outcome == MELEE_HIT_BLOCK_CRIT )
- {
- *blocked_amount = pVictim->GetShieldBlockValue();
-
- if (pVictim->GetUnitBlockChance())
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYSHIELD);
- else
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
-
- //Only set VICTIMSTATE_BLOCK on a full block
- if (*blocked_amount >= uint32(*damage))
- {
- *victimState = VICTIMSTATE_BLOCKS;
- *blocked_amount = uint32(*damage);
- }
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- {
- // Update defense
- ((Player*)pVictim)->UpdateDefense();
-
- // random durability for main hand weapon (BLOCK)
- if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_BLOCK)))
- ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_OFFHAND);
- }
-
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE,true);
- pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
- break;
- }
-
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_WOUNDCRITICAL);
- break;
- }
- case MELEE_HIT_PARRY:
+ bool found = false;
+ int32 spell_dmg=0;
+ // Incanter's Absorption
+ AuraEffectList const& DummmyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
+ for(AuraEffectList::const_iterator i = DummmyAuras.begin(); i != DummmyAuras.end(); ++i)
{
- if(attType == RANGED_ATTACK) //range attack - no parry
+ SpellEntry const* spellInfo = (*i)->GetSpellProto();
+ if (spellmgr.GetFirstSpellInChain(spellInfo->Id) == 44394)
{
- outcome = MELEE_HIT_NORMAL;
- break;
- }
-
- cleanDamage->damage += *damage;
- *damage = 0;
- *victimState = VICTIMSTATE_PARRY;
-
- // instant (maybe with small delay) counter attack
- {
- float offtime = float(pVictim->getAttackTimer(OFF_ATTACK));
- float basetime = float(pVictim->getAttackTimer(BASE_ATTACK));
-
- // after parry nearest next attack time will reduced at %40 from full attack time.
- // The delay cannot be reduced to less than 20% of your weapon base swing delay.
- if (pVictim->haveOffhandWeapon() && offtime < basetime)
- {
- float percent20 = pVictim->GetAttackTime(OFF_ATTACK)*0.20;
- float percent60 = 3*percent20;
- // set to 20% if in range 20%...20+40% of full time
- if(offtime > percent20 && offtime <= percent60)
- {
- pVictim->setAttackTimer(OFF_ATTACK,uint32(percent20));
- }
- // decrease at %40 from full time
- else if(offtime > percent60)
- {
- offtime -= 2*percent20;
- pVictim->setAttackTimer(OFF_ATTACK,uint32(offtime));
- }
- // ELSE not changed
- }
- else
+ int32 total_dmg=0;
+ // Get total bonus from auras
+ AuraEffectList const& BonusAuras = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE);
+ for(AuraEffectList::const_iterator itr = BonusAuras.begin(); itr != BonusAuras.end(); ++itr)
{
- float percent20 = pVictim->GetAttackTime(BASE_ATTACK)*0.20;
- float percent60 = 3*percent20;
- // set to 20% if in range 20%...20+40% of full time
- if(basetime > percent20 && basetime <= percent60)
- {
- pVictim->setAttackTimer(BASE_ATTACK,uint32(percent20));
- }
- // decrease at %40 from full time
- else if(basetime > percent60)
- {
- basetime -= 2*percent20;
- pVictim->setAttackTimer(BASE_ATTACK,uint32(basetime));
- }
- // ELSE not changed
+ if ((*itr)->GetId()==44413)
+ total_dmg += (*itr)->GetMiscValue();
}
- }
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- {
- // Update victim defense ?
- ((Player*)pVictim)->UpdateDefense();
-
- // random durability for main hand weapon (PARRY)
- if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_PARRY)))
- ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_MAINHAND);
- }
-
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
-
- if (pVictim->getClass() == CLASS_HUNTER)
- {
- pVictim->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true);
- pVictim->StartReactiveTimer( REACTIVE_HUNTER_PARRY );
- }
- else
- {
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
- pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
- }
-
- CastMeleeProcDamageAndSpell(pVictim, 0, damageSchoolMask, attType, outcome, spellCasted, isTriggeredSpell);
- return;
- }
- case MELEE_HIT_DODGE:
- {
- if(attType == RANGED_ATTACK) //range attack - no dodge
- {
- outcome = MELEE_HIT_NORMAL;
+ spell_dmg = int32(*absorb * (*i)->GetAmount() / 100);
+ // Do not apply more auras if more than 5% hp
+ if(total_dmg+spell_dmg > int32(GetMaxHealth() * 5 / 100))
+ break;
+ found=true;
break;
- }
-
- cleanDamage->damage += *damage;
- *damage = 0;
- *victimState = VICTIMSTATE_DODGE;
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- ((Player*)pVictim)->UpdateDefense();
-
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
-
- if (pVictim->getClass() != CLASS_ROGUE) // Riposte
- {
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
- pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
- }
-
- // Overpower
- if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR)
- {
- ((Player*)this)->AddComboPoints(pVictim, 1);
- StartReactiveTimer( REACTIVE_OVERPOWER );
- }
-
- CastMeleeProcDamageAndSpell(pVictim, 0, damageSchoolMask, attType, outcome, spellCasted, isTriggeredSpell);
- return;
- }
- case MELEE_HIT_BLOCK:
- {
- *blocked_amount = pVictim->GetShieldBlockValue();
-
- if (pVictim->GetUnitBlockChance())
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYSHIELD);
- else
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
-
- //Only set VICTIMSTATE_BLOCK on a full block
- if (*blocked_amount >= uint32(*damage))
- {
- *victimState = VICTIMSTATE_BLOCKS;
- *blocked_amount = uint32(*damage);
- }
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- {
- // Update defense
- ((Player*)pVictim)->UpdateDefense();
-
- // random durability for main hand weapon (BLOCK)
- if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_BLOCK)))
- ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_OFFHAND);
- }
-
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE,true);
- pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
-
- break;
- }
- case MELEE_HIT_GLANCING:
- {
- int32 leveldif = int32(pVictim->getLevel()) - int32(getLevel());
- if (leveldif > 3) leveldif = 3;
- *damage *= (1 - leveldif * 0.1f);
- cleanDamage->damage = *damage;
- *hitInfo |= HITINFO_GLANCING;
- break;
- }
- case MELEE_HIT_CRUSHING:
- {
- // 150% normal damage
- *damage += (*damage / 2);
- cleanDamage->damage = *damage;
- *hitInfo |= HITINFO_CRUSHING;
- // TODO: victimState, victim animation?
- break;
- }
- default:
- break;
- }
-
- // apply melee damage bonus and absorb only if base damage not fully blocked to prevent negative damage or damage with full block
- if(*victimState != VICTIMSTATE_BLOCKS)
- {
- MeleeDamageBonus(pVictim, damage,attType,spellCasted);
- CalcAbsorbResist(pVictim, damageSchoolMask, DIRECT_DAMAGE, *damage-*blocked_amount, absorbDamage, resistDamage);
- }
-
- if (*absorbDamage) *hitInfo |= HITINFO_ABSORB;
- if (*resistDamage) *hitInfo |= HITINFO_RESIST;
-
- cleanDamage->damage += *blocked_amount;
-
- if (*damage <= *absorbDamage + *resistDamage + *blocked_amount)
- {
- //*hitInfo = 0x00010020;
- //*hitInfo |= HITINFO_SWINGNOHITSOUND;
- //*damageType = 0;
- CastMeleeProcDamageAndSpell(pVictim, 0, damageSchoolMask, attType, outcome, spellCasted, isTriggeredSpell);
- return;
- }
-
- // update at damage Judgement aura duration that applied by attacker at victim
- if(*damage)
- {
- AuraMap const& vAuras = pVictim->GetAuras();
- for(AuraMap::const_iterator itr = vAuras.begin(); itr != vAuras.end(); ++itr)
- {
- SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
- if( (spellInfo->AttributesEx3 & 0x40000) && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN &&
- ((*itr).second->GetCasterGUID() == GetGUID() && (!spellCasted || spellCasted->Id == 35395)) )
- {
- (*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration());
- (*itr).second->UpdateAuraDuration();
- }
- }
- }
-
- CastMeleeProcDamageAndSpell(pVictim, (*damage - *absorbDamage pVictim->SpellNonMeleeDamageLog(this, (*i)->GetId(), (*i)->GetModifier()->m_amount, false, false);eld
- // yet another hack to fix crashes related to the aura getting removed during iteration
- std::set<Aura*> alreadyDone;
- uint32 removedAuras = pVictim->m_removedAuras;
- AuraList const& vDamageShields = pVictim->GetAurasByType(SPELL_AURA_DAMAGE_SHIELD);
- for(AuraList::const_iterator i = vDamageShields.begin(), next = vDamageShields.begin(); i != vDamageShields.end(); i = next)
- {
- ++next;
- if (alreadyDone.find(*i) == alreadyDone.end())
- {
- alreadyDone.insert(*i);
- pVictim->SpellNonMeleeDamageLog(this, (*i)->GetId(), (*i)->GetModifierValue(), false, false);
- if (pVictim->m_removedAuras > removedAuras)
- {
- removedAuras = pVictim->m_removedAuras;
- next = vDamageShields.begin();
- }
+ }
}
+ if (found)
+ pVictim->CastCustomSpell(pVictim, 44413, &spell_dmg, NULL, NULL, false);
}
-}*/
+}
void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool extra )
{
@@ -2337,10 +2283,12 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex
--m_extraAttacks;
}
}
-
return;
}
+ // attack can be redirected to another target
+ pVictim = SelectMagnetTarget(pVictim);
+
CalcDamageInfo damageInfo;
CalculateMeleeDamage(pVictim, 0, &damageInfo, attType);
// Send log damage message to client
@@ -2355,6 +2303,10 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex
DEBUG_LOG("AttackerStateUpdate: (NPC) %u attacked %u (TypeId: %u) for %u dmg, absorbed %u, blocked %u, resisted %u.",
GetGUIDLow(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist);
+ // if damage pVictim call AI reaction
+ //if(pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->AI())
+ // ((Creature*)pVictim)->AI()->AttackedBy(this);
+
// extra attack only at any non extra attack (normal case)
if(!extra && extraAttacks)
{
@@ -2367,67 +2319,6 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex
}
}
-/*
-MeleeHitOutcome Unit::RollPhysicalOutcomeAgainst (Unit const *pVictim, WeaponAttackType attType, SpellEntry const *spellInfo)
-{
- // Miss chance based on melee
- float miss_chance = MeleeMissChanceCalc(pVictim, attType);
-
- // Critical hit chance
- float crit_chance = GetUnitCriticalChance(attType, pVictim);
- // this is to avoid compiler issue when declaring variables inside if
- float block_chance, parry_chance, dodge_chance;
-
- // cannot be dodged/parried/blocked
- if(spellInfo->Attributes & SPELL_ATTR_IMPOSSIBLE_DODGE_PARRY_BLOCK)
- {
- block_chance = 0.0f;
- parry_chance = 0.0f;
- dodge_chance = 0.0f;
- }
- else
- {
- // parry can be avoided only by some abilities
- parry_chance = pVictim->GetUnitParryChance();
- // block might be bypassed by it as well
- block_chance = pVictim->GetUnitBlockChance();
- // stunned target cannot dodge and this is check in GetUnitDodgeChance()
- dodge_chance = pVictim->GetUnitDodgeChance();
- }
-
- // Only players can have Talent&Spell bonuses
- if (GetTypeId() == TYPEID_PLAYER)
- {
- // Increase from SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL aura
- crit_chance += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, spellInfo->SchoolMask);
-
- if( dodge_chance != 0.0f ) // if dodge chance is already 0, ignore talents for speed
- {
- AuraList const& mCanNotBeDodge = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
- for(AuraList::const_iterator i = mCanNotBeDodge.begin(); i != mCanNotBeDodge.end(); ++i)
- {
- // can't be dodged rogue finishing move
- if((*i)->GetModifier()->m_miscvalue == VICTIMSTATE_DODGE)
- {
- if(spellInfo->SpellFamilyName==SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE))
- {
- dodge_chance = 0.0f;
- break;
- }
- }
- }
- }
- }
-
- // Spellmods
- if(Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRITICAL_CHANCE, crit_chance);
-
- DEBUG_LOG("PHYSICAL OUTCOME: miss %f crit %f dodge %f parry %f block %f",miss_chance,crit_chance,dodge_chance,parry_chance, block_chance);
-
- return RollMeleeOutcomeAgainst(pVictim, attType, int32(crit_chance*100), int32(miss_chance*100),int32(dodge_chance*100),int32(parry_chance*100),int32(block_chance*100), true);
-}*/
-
MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit *pVictim, WeaponAttackType attType) const
{
// This is only wrapper
@@ -2447,10 +2338,10 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit *pVictim, WeaponAttackT
// Useful if want to specify crit & miss chances for melee, else it could be removed
DEBUG_LOG("MELEE OUTCOME: miss %f crit %f dodge %f parry %f block %f", miss_chance,crit_chance,dodge_chance,parry_chance,block_chance);
- return RollMeleeOutcomeAgainst(pVictim, attType, int32(crit_chance*100), int32(miss_chance*100), int32(dodge_chance*100),int32(parry_chance*100),int32(block_chance*100), false);
+ return RollMeleeOutcomeAgainst(pVictim, attType, int32(crit_chance*100), int32(miss_chance*100), int32(dodge_chance*100),int32(parry_chance*100),int32(block_chance*100));
}
-MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance, bool SpellCasted ) const
+MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance) const
{
if(pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
return MELEE_HIT_EVADE;
@@ -2463,7 +2354,6 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
// bonus from skills is 0.04%
int32 skillBonus = 4 * ( attackerWeaponSkill - victimMaxSkillValueForLevel );
- int32 skillBonus2 = 4 * ( attackerMaxSkillValueForLevel - victimDefenseSkill );
int32 sum = 0, tmp = 0;
int32 roll = urand (0, 10000);
@@ -2501,6 +2391,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
// Modify dodge chance by attacker SPELL_AURA_MOD_COMBAT_RESULT_CHANCE
dodge_chance+= GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE);
+ dodge_chance = int32 (float (dodge_chance) * GetTotalAuraMultiplier(SPELL_AURA_MOD_ENEMY_DODGE));
tmp = dodge_chance;
if ( (tmp > 0) // check if unit _can_ dodge
@@ -2527,12 +2418,12 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
if(pVictim->GetTypeId()==TYPEID_PLAYER || !(((Creature*)pVictim)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_PARRY) )
{
- int32 tmp = int32(parry_chance);
- if ( (tmp > 0) // check if unit _can_ parry
- && ((tmp -= skillBonus) > 0)
- && (roll < (sum += tmp)))
+ int32 tmp2 = int32(parry_chance);
+ if ( (tmp2 > 0) // check if unit _can_ parry
+ && ((tmp2 -= skillBonus) > 0)
+ && (roll < (sum += tmp2)))
{
- DEBUG_LOG ("RollMeleeOutcomeAgainst: PARRY <%d, %d)", sum-tmp, sum);
+ DEBUG_LOG ("RollMeleeOutcomeAgainst: PARRY <%d, %d)", sum-tmp2, sum);
return MELEE_HIT_PARRY;
}
}
@@ -2544,16 +2435,6 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
&& ((tmp -= skillBonus) > 0)
&& (roll < (sum += tmp)))
{
- // Critical chance
- tmp = crit_chance + skillBonus2;
- if ( GetTypeId() == TYPEID_PLAYER && SpellCasted && tmp > 0 )
- {
- if ( roll_chance_i(tmp/100))
- {
- DEBUG_LOG ("RollMeleeOutcomeAgainst: BLOCKED CRIT");
- return MELEE_HIT_BLOCK_CRIT;
- }
- }
DEBUG_LOG ("RollMeleeOutcomeAgainst: BLOCK <%d, %d)", sum-tmp, sum);
return MELEE_HIT_BLOCK;
}
@@ -2561,7 +2442,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
}
// Critical chance
- tmp = crit_chance + skillBonus2;
+ tmp = crit_chance;
if (tmp > 0 && roll < (sum += tmp))
{
@@ -2573,7 +2454,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
}
// Max 40% chance to score a glancing blow against mobs that are higher level (can do only players and pets and not with ranged weapon)
- if( attType != RANGED_ATTACK && !SpellCasted &&
+ if( attType != RANGED_ATTACK &&
(GetTypeId() == TYPEID_PLAYER || ((Creature*)this)->isPet()) &&
pVictim->GetTypeId() != TYPEID_PLAYER && !((Creature*)pVictim)->isPet() &&
getLevel() < pVictim->getLevelForTarget(this) )
@@ -2592,10 +2473,13 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
}
}
- if(GetTypeId()!=TYPEID_PLAYER && !(((Creature*)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_CRUSH) && !((Creature*)this)->isPet() && !SpellCasted /*Only autoattack can be crushing blow*/ )
+ // mobs can score crushing blows if they're 4 or more levels above victim
+ if (getLevelForTarget(pVictim) >= pVictim->getLevelForTarget(this) + 4 &&
+ // can be from by creature (if can) or from controlled player that considered as creature
+ !IsControlledByPlayer() &&
+ !(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_CRUSH))
{
- // mobs can score crushing blows if they're 3 or more levels above victim
- // or when their weapon skill is 15 or more above victim's defense skill
+ // when their weapon skill is 15 or more above victim's defense skill
tmp = victimDefenseSkill;
int32 tmpmax = victimMaxSkillValueForLevel;
// having defense above your maximum (from items, talents etc.) has no effect
@@ -2705,32 +2589,52 @@ bool Unit::isSpellBlocked(Unit *pVictim, SpellEntry const *spellProto, WeaponAtt
{
if (pVictim->HasInArc(M_PI,this))
{
- float blockChance = GetUnitBlockChance();
- blockChance += (GetWeaponSkillValue(attackType) - pVictim->GetMaxSkillValueForLevel() )*0.04;
+ /* Currently not exist spells with ignore block
+ // Ignore combat result aura (parry/dodge check on prepare)
+ AuraList const& ignore = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
+ for(AuraList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
+ {
+ if (!(*i)->isAffectedOnSpell(spellProto))
+ continue;
+ if ((*i)->GetMiscValue() == )
+ return false;
+ }
+ */
+
+ // Check creatures flags_extra for disable block
+ if(pVictim->GetTypeId()==TYPEID_UNIT &&
+ ((Creature*)pVictim)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_BLOCK )
+ return false;
+
+ float blockChance = pVictim->GetUnitBlockChance();
+ blockChance += (int32(GetWeaponSkillValue(attackType)) - int32(pVictim->GetMaxSkillValueForLevel()))*0.04f;
if (roll_chance_f(blockChance))
return true;
}
return false;
}
+bool Unit::isBlockCritical()
+{
+ if (roll_chance_i(GetTotalAuraModifier(SPELL_AURA_MOD_BLOCK_CRIT_CHANCE)))
+ return true;
+ return false;
+}
+
// Melee based spells can be miss, parry or dodge on this step
// Crit or block - determined on damage calculation phase! (and can be both in some time)
-float Unit::MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const
+/*float Unit::MeleeSpellMissChance(Unit *pVictim, WeaponAttackType attType, int32 skillDiff, SpellEntry const *spell)
{
// Calculate hit chance (more correct for chance mod)
int32 HitChance;
// PvP - PvE melee chances
- /*int32 lchance = pVictim->GetTypeId() == TYPEID_PLAYER ? 5 : 7;
+ int32 lchance = pVictim->GetTypeId() == TYPEID_PLAYER ? 5 : 7;
int32 leveldif = pVictim->getLevelForTarget(this) - getLevelForTarget(pVictim);
if(leveldif < 3)
HitChance = 95 - leveldif;
else
- HitChance = 93 - (leveldif - 2) * lchance;*/
- if (spellId || attType == RANGED_ATTACK || !haveOffhandWeapon())
- HitChance = 95.0f;
- else
- HitChance = 76.0f;
+ HitChance = 93 - (leveldif - 2) * lchance;
// Hit chance depends from victim auras
if(attType == RANGED_ATTACK)
@@ -2739,11 +2643,8 @@ float Unit::MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType,
HitChance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE);
// Spellmod from SPELLMOD_RESIST_MISS_CHANCE
- if(spellId)
- {
- if(Player *modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellId, SPELLMOD_RESIST_MISS_CHANCE, HitChance);
- }
+ if(Player *modOwner = GetSpellModOwner())
+ modOwner->ApplySpellMod(spell->Id, SPELLMOD_RESIST_MISS_CHANCE, HitChance);
// Miss = 100 - hit
float miss_chance= 100.0f - HitChance;
@@ -2755,12 +2656,7 @@ float Unit::MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType,
miss_chance -= m_modMeleeHitChance;
// bonus from skills is 0.04%
- //miss_chance -= skillDiff * 0.04f;
- int32 diff = -skillDiff;
- if(pVictim->GetTypeId()==TYPEID_PLAYER)
- miss_chance += diff > 0 ? diff * 0.04 : diff * 0.02;
- else
- miss_chance += diff > 10 ? 2 + (diff - 10) * 0.4 : diff * 0.1;
+ miss_chance -= skillDiff * 0.04f;
// Limit miss chance from 0 to 60%
if (miss_chance < 0.0f)
@@ -2768,7 +2664,7 @@ float Unit::MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType,
if (miss_chance > 60.0f)
return 60.0f;
return miss_chance;
-}
+}*/
// Melee based spells hit result calculations
SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell)
@@ -2784,68 +2680,117 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell)
int32 fullSkillDiff = attackerWeaponSkill - int32(pVictim->GetDefenseSkillValue(this));
uint32 roll = urand (0, 10000);
- uint32 missChance = uint32(MeleeSpellMissChance(pVictim, attType, fullSkillDiff, spell->Id)*100.0f);
+ uint32 missChance = uint32(MeleeSpellMissChance(pVictim, attType, fullSkillDiff, spell->Id)*100.0f);
// Roll miss
uint32 tmp = missChance;
if (roll < tmp)
return SPELL_MISS_MISS;
+ // Chance resist mechanic (select max value from every mechanic spell effect)
+ int32 resist_mech = 0;
+ // Get effects mechanic and chance
+ for(int eff = 0; eff < 3; ++eff)
+ {
+ int32 effect_mech = GetEffectMechanic(spell, eff);
+ if (effect_mech)
+ {
+ int32 temp = pVictim->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MECHANIC_RESISTANCE, effect_mech);
+ if (resist_mech < temp*100)
+ resist_mech = temp*100;
+ }
+ }
+ // Roll chance
+ tmp += resist_mech;
+ if (roll < tmp)
+ return SPELL_MISS_RESIST;
+
+ bool canDodge = true;
+ bool canParry = true;
+
// Same spells cannot be parry/dodge
if (spell->Attributes & SPELL_ATTR_IMPOSSIBLE_DODGE_PARRY_BLOCK)
return SPELL_MISS_NONE;
- // Ranged attack can`t miss too
+ // Ranged attack cannot be parry/dodge only deflect
if (attType == RANGED_ATTACK)
+ {
+ // only if in front
+ if (pVictim->HasInArc(M_PI,this))
+ {
+ int32 deflect_chance = pVictim->GetTotalAuraModifier(SPELL_AURA_DEFLECT_SPELLS)*100;
+ tmp+=deflect_chance;
+ if (roll < tmp)
+ return SPELL_MISS_DEFLECT;
+ }
return SPELL_MISS_NONE;
+ }
- bool attackFromBehind = !pVictim->HasInArc(M_PI,this);
-
- // Roll dodge
- int32 dodgeChance = int32(pVictim->GetUnitDodgeChance()*100.0f) - skillDiff * 4;
- // Reduce enemy dodge chance by SPELL_AURA_MOD_COMBAT_RESULT_CHANCE
- dodgeChance+= GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE);
-
- // Reduce dodge chance by attacker expertise rating
- if (GetTypeId() == TYPEID_PLAYER)
- dodgeChance-=int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
- if (dodgeChance < 0)
- dodgeChance = 0;
-
- // Can`t dodge from behind in PvP (but its possible in PvE)
- if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER && attackFromBehind)
- dodgeChance = 0;
-
- // Rogue talent`s cant be dodged
- AuraList const& mCanNotBeDodge = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
- for(AuraList::const_iterator i = mCanNotBeDodge.begin(); i != mCanNotBeDodge.end(); ++i)
+ // Check for attack from behind
+ if (!pVictim->HasInArc(M_PI,this))
{
- if((*i)->GetModifier()->m_miscvalue == VICTIMSTATE_DODGE) // can't be dodged rogue finishing move
+ // Can`t dodge from behind in PvP (but its possible in PvE)
+ if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER)
+ canDodge = false;
+ // Can`t parry
+ canParry = false;
+ }
+ // Check creatures flags_extra for disable parry
+ if(pVictim->GetTypeId()==TYPEID_UNIT)
+ {
+ uint32 flagEx = ((Creature*)pVictim)->GetCreatureInfo()->flags_extra;
+ if( flagEx & CREATURE_FLAG_EXTRA_NO_PARRY )
+ canParry = false;
+ }
+ // Ignore combat result aura
+ AuraEffectList const& ignore = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
+ for(AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
+ {
+ if (!(*i)->isAffectedOnSpell(spell))
+ continue;
+ switch((*i)->GetMiscValue())
{
- if(spell->SpellFamilyName==SPELLFAMILY_ROGUE && (spell->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE))
- {
- dodgeChance = 0;
+ case MELEE_HIT_DODGE: canDodge = false; break;
+ case MELEE_HIT_BLOCK: break; // Block check in hit step
+ case MELEE_HIT_PARRY: canParry = false; break;
+ default:
+ DEBUG_LOG("Spell %u SPELL_AURA_IGNORE_COMBAT_RESULT have unhandled state %d", (*i)->GetId(), (*i)->GetMiscValue());
break;
- }
}
}
- tmp += dodgeChance;
- if (roll < tmp)
- return SPELL_MISS_DODGE;
+ if (canDodge)
+ {
+ // Roll dodge
+ int32 dodgeChance = int32(pVictim->GetUnitDodgeChance()*100.0f) - skillDiff * 4;
+ // Reduce enemy dodge chance by SPELL_AURA_MOD_COMBAT_RESULT_CHANCE
+ dodgeChance+= GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE)*100;
+ dodgeChance = int32 (float (dodgeChance) * GetTotalAuraMultiplier(SPELL_AURA_MOD_ENEMY_DODGE));
+ // Reduce dodge chance by attacker expertise rating
+ if (GetTypeId() == TYPEID_PLAYER)
+ dodgeChance-=int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
+ if (dodgeChance < 0)
+ dodgeChance = 0;
- // Roll parry
- int32 parryChance = int32(pVictim->GetUnitParryChance()*100.0f) - skillDiff * 4;
- // Reduce parry chance by attacker expertise rating
- if (GetTypeId() == TYPEID_PLAYER)
- parryChance-=int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
- // Can`t parry from behind
- if (parryChance < 0 || attackFromBehind)
- parryChance = 0;
+ tmp += dodgeChance;
+ if (roll < tmp)
+ return SPELL_MISS_DODGE;
+ }
- tmp += parryChance;
- if (roll < tmp)
- return SPELL_MISS_PARRY;
+ if (canParry)
+ {
+ // Roll parry
+ int32 parryChance = int32(pVictim->GetUnitParryChance()*100.0f) - skillDiff * 4;
+ // Reduce parry chance by attacker expertise rating
+ if (GetTypeId() == TYPEID_PLAYER)
+ parryChance-=int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
+ if (parryChance < 0)
+ parryChance = 0;
+
+ tmp += parryChance;
+ if (roll < tmp)
+ return SPELL_MISS_PARRY;
+ }
return SPELL_MISS_NONE;
}
@@ -2910,11 +2855,24 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell)
HitChance -= int32(((Player*)pVictim)->GetRatingBonusValue(CR_HIT_TAKEN_SPELL)*100.0f);
if (HitChance < 100) HitChance = 100;
- if (HitChance > 9900) HitChance = 9900;
+ if (HitChance > 10000) HitChance = 10000;
+
+ int32 tmp = 10000 - HitChance;
uint32 rand = urand(0,10000);
- if (rand > HitChance)
+
+ if (rand < tmp)
return SPELL_MISS_RESIST;
+
+ // cast by caster in front of victim
+ if (pVictim->HasInArc(M_PI,this))
+ {
+ int32 deflect_chance = pVictim->GetTotalAuraModifier(SPELL_AURA_DEFLECT_SPELLS)*100;
+ tmp+=deflect_chance;
+ if (rand < tmp)
+ return SPELL_MISS_DEFLECT;
+ }
+
return SPELL_MISS_NONE;
}
@@ -2932,12 +2890,8 @@ SpellMissInfo Unit::SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool
if (pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
return SPELL_MISS_EVADE;
- // If Spel has this flag cannot be resisted/immuned/etc
- if (spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)
- return SPELL_MISS_NONE;
-
- // Check for immune (use charges)
- if (pVictim->IsImmunedToSpell(spell,true))
+ // Check for immune
+ if (pVictim->IsImmunedToSpell(spell))
return SPELL_MISS_IMMUNE;
// All positive spells can`t miss
@@ -2945,9 +2899,8 @@ SpellMissInfo Unit::SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool
if (IsPositiveSpell(spell->Id)
&&(!IsHostileTo(pVictim))) //prevent from affecting enemy by "positive" spell
return SPELL_MISS_NONE;
-
- // Check for immune (use charges)
- if (pVictim->IsImmunedToDamage(GetSpellSchoolMask(spell),true))
+ // Check for immune
+ if (pVictim->IsImmunedToDamage(spell))
return SPELL_MISS_IMMUNE;
if(this == pVictim)
@@ -2957,10 +2910,10 @@ SpellMissInfo Unit::SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool
if (CanReflect)
{
int32 reflectchance = pVictim->GetTotalAuraModifier(SPELL_AURA_REFLECT_SPELLS);
- Unit::AuraList const& mReflectSpellsSchool = pVictim->GetAurasByType(SPELL_AURA_REFLECT_SPELLS_SCHOOL);
- for(Unit::AuraList::const_iterator i = mReflectSpellsSchool.begin(); i != mReflectSpellsSchool.end(); ++i)
- if((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spell))
- reflectchance = (*i)->GetModifierValue();
+ Unit::AuraEffectList const& mReflectSpellsSchool = pVictim->GetAurasByType(SPELL_AURA_REFLECT_SPELLS_SCHOOL);
+ for(Unit::AuraEffectList::const_iterator i = mReflectSpellsSchool.begin(); i != mReflectSpellsSchool.end(); ++i)
+ if((*i)->GetMiscValue() & GetSpellSchoolMask(spell))
+ reflectchance += (*i)->GetAmount();
if (reflectchance > 0 && roll_chance_i(reflectchance))
{
// Start triggers for remove charges if need (trigger only for victim, and mark as active spell)
@@ -3135,7 +3088,7 @@ float Unit::GetUnitBlockChance() const
Player const* player = (Player const*)this;
if(player->CanBlock() )
{
- Item *tmpitem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ Item *tmpitem = player->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
if(tmpitem && !tmpitem->IsBroken() && tmpitem->GetProto()->Block)
return GetFloatValue(PLAYER_BLOCK_PERCENTAGE);
}
@@ -3201,6 +3154,9 @@ float Unit::GetUnitCriticalChance(WeaponAttackType attackType, const Unit *pVict
crit -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE);
}
+ // Apply crit chance from defence skill
+ crit += (int32(GetMaxSkillValueForLevel(pVictim)) - int32(pVictim->GetDefenseSkillValue(this))) * 0.04f;
+
if (crit < 0.0f)
crit = 0.0f;
return crit;
@@ -3221,7 +3177,7 @@ uint32 Unit::GetWeaponSkillValue (WeaponAttackType attType, Unit const* target)
return 0;
}
- if(((Player*)this)->IsInFeralForm())
+ if(IsInFeralForm())
return GetMaxSkillValueForLevel(); // always maximized SKILL_FERAL_COMBAT in fact
// weapon skill or (unarmed for base attack)
@@ -3245,6 +3201,17 @@ uint32 Unit::GetWeaponSkillValue (WeaponAttackType attType, Unit const* target)
return value;
}
+void Unit::_DeleteAuras()
+{
+ for (AuraList::iterator i = m_removedAuras.begin(); i != m_removedAuras.end();i = m_removedAuras.begin())
+ {
+ Aura * Aur = *i;
+ sLog.outDebug("Aura %d is deleted from unit %d", Aur->GetId(), GetGUIDLow());
+ m_removedAuras.pop_front();
+ delete (Aur);
+ }
+}
+
void Unit::_UpdateSpells( uint32 time )
{
if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL])
@@ -3261,54 +3228,48 @@ void Unit::_UpdateSpells( uint32 time )
}
// TODO: Find a better way to prevent crash when multiple auras are removed.
- m_removedAuras = 0;
for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end(); ++i)
- if ((*i).second)
- (*i).second->SetUpdated(false);
+ i->second->SetUpdated(false);
- for (AuraMap::iterator i = m_Auras.begin(), next; i != m_Auras.end(); i = next)
+ for(AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end();)
{
- next = i;
- ++next;
- if ((*i).second)
+ Aura *aur = i->second;
+
+ // prevent double update
+ if(aur->IsUpdated())
{
- // prevent double update
- if ((*i).second->IsUpdated())
- continue;
- (*i).second->SetUpdated(true);
- (*i).second->Update( time );
- // several auras can be deleted due to update
- if (m_removedAuras)
- {
- if (m_Auras.empty()) break;
- next = m_Auras.begin();
- m_removedAuras = 0;
- }
+ ++i;
+ continue;
}
- }
- for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end();)
- {
- if ((*i).second)
+ aur->SetUpdated(true);
+
+ m_removedAurasCount = 0;
+ aur->Update( time );
+
+ // several auras can be deleted due to update
+ if(m_removedAurasCount)
{
- if ( !(*i).second->GetAuraDuration() && !((*i).second->IsPermanent() || ((*i).second->IsPassive())) )
- {
- RemoveAura(i);
- }
- else
- {
- ++i;
- }
+ m_removedAurasCount = 0;
+ i = m_Auras.begin();
}
else
- {
++i;
- }
}
+ for(AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end();)
+ {
+ if(!i->second->GetAuraDuration() && !(i->second->IsPermanent() || (i->second->IsPassive())))
+ RemoveAura(i, AURA_REMOVE_BY_EXPIRE);
+ else
+ ++i;
+ }
+
+ _DeleteAuras();
+
if(!m_gameObj.empty())
{
- std::list<GameObject*>::iterator ite1, dnext1;
+ GameObjectList::iterator ite1, dnext1;
for (ite1 = m_gameObj.begin(); ite1 != m_gameObj.end(); ite1 = dnext1)
{
dnext1 = ite1;
@@ -3332,7 +3293,7 @@ void Unit::_UpdateAutoRepeatSpell()
if ( (GetTypeId() == TYPEID_PLAYER && ((Player*)this)->isMoving()) || IsNonMeleeSpellCasted(false,false,true) )
{
// cancel wand shoot
- if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351)
+ if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != SPELL_ID_AUTOSHOT)
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
m_AutoRepeatFirstCast = true;
return;
@@ -3347,7 +3308,7 @@ void Unit::_UpdateAutoRepeatSpell()
if (isAttackReady(RANGED_ATTACK))
{
// Check if able to cast
- if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CanCast(true))
+ if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CheckCast(true) != SPELL_CAST_OK)
{
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
return;
@@ -3366,7 +3327,7 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell )
{
assert(pSpell); // NULL may be never passed here, use InterruptSpell or InterruptNonMeleeSpells
- uint32 CSpellType = pSpell->GetCurrentContainer();
+ CurrentSpellTypes CSpellType = pSpell->GetCurrentContainer();
if (pSpell == m_currentSpells[CSpellType]) return; // avoid breaking self
@@ -3385,7 +3346,7 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell )
if ( m_currentSpells[CURRENT_AUTOREPEAT_SPELL] )
{
// break autorepeat if not Auto Shot
- if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351)
+ if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != SPELL_ID_AUTOSHOT)
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
m_AutoRepeatFirstCast = true;
}
@@ -3400,7 +3361,7 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell )
// it also does break autorepeat if not Auto Shot
if ( m_currentSpells[CURRENT_AUTOREPEAT_SPELL] &&
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351 )
+ m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != SPELL_ID_AUTOSHOT )
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
addUnitState(UNIT_STAT_CASTING);
} break;
@@ -3408,7 +3369,7 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell )
case CURRENT_AUTOREPEAT_SPELL:
{
// only Auto Shoot does not break anything
- if (pSpell->m_spellInfo->Category == 351)
+ if (pSpell->m_spellInfo->Id != SPELL_ID_AUTOSHOT)
{
// generic autorepeats break generic non-delayed and channeled non-delayed spells
InterruptSpell(CURRENT_GENERIC_SPELL,false);
@@ -3557,9 +3518,9 @@ int32 Unit::GetTotalAuraModifier(AuraType auratype) const
{
int32 modifier = 0;
- AuraList const& mTotalAuraList = GetAurasByType(auratype);
- for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
- modifier += (*i)->GetModifierValue();
+ AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
+ for(AuraEffectList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
+ modifier += (*i)->GetAmount();
return modifier;
}
@@ -3568,23 +3529,22 @@ float Unit::GetTotalAuraMultiplier(AuraType auratype) const
{
float multiplier = 1.0f;
- AuraList const& mTotalAuraList = GetAurasByType(auratype);
- for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
- multiplier *= (100.0f + (*i)->GetModifierValue())/100.0f;
+ AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
+ for(AuraEffectList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
+ multiplier *= (100.0f + (*i)->GetAmount())/100.0f;
return multiplier;
}
-int32 Unit::GetMaxPositiveAuraModifier(AuraType auratype) const
+int32 Unit::GetMaxPositiveAuraModifier(AuraType auratype)
{
int32 modifier = 0;
- AuraList const& mTotalAuraList = GetAurasByType(auratype);
- for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
+ AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
+ for(AuraEffectList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
{
- int32 amount = (*i)->GetModifierValue();
- if (amount > modifier)
- modifier = amount;
+ if ((*i)->GetAmount() > modifier)
+ modifier = (*i)->GetAmount();
}
return modifier;
@@ -3594,13 +3554,10 @@ int32 Unit::GetMaxNegativeAuraModifier(AuraType auratype) const
{
int32 modifier = 0;
- AuraList const& mTotalAuraList = GetAurasByType(auratype);
- for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
- {
- int32 amount = (*i)->GetModifierValue();
- if (amount < modifier)
- modifier = amount;
- }
+ AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
+ for(AuraEffectList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
+ if ((*i)->GetAmount() < modifier)
+ modifier = (*i)->GetAmount();
return modifier;
}
@@ -3609,12 +3566,11 @@ int32 Unit::GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask)
{
int32 modifier = 0;
- AuraList const& mTotalAuraList = GetAurasByType(auratype);
- for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
+ AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
+ for(AuraEffectList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
{
- Modifier* mod = (*i)->GetModifier();
- if (mod->m_miscvalue & misc_mask)
- modifier += (*i)->GetModifierValue();
+ if ((*i)->GetMiscValue()& misc_mask)
+ modifier += (*i)->GetAmount();
}
return modifier;
}
@@ -3623,12 +3579,11 @@ float Unit::GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask
{
float multiplier = 1.0f;
- AuraList const& mTotalAuraList = GetAurasByType(auratype);
- for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
+ AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
+ for(AuraEffectList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
{
- Modifier* mod = (*i)->GetModifier();
- if (mod->m_miscvalue & misc_mask)
- multiplier *= (100.0f + (*i)->GetModifierValue())/100.0f;
+ if ((*i)->GetMiscValue()& misc_mask)
+ multiplier *= (100.0f + (*i)->GetAmount())/100.0f;
}
return multiplier;
}
@@ -3637,13 +3592,11 @@ int32 Unit::GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_
{
int32 modifier = 0;
- AuraList const& mTotalAuraList = GetAurasByType(auratype);
- for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
+ AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
+ for(AuraEffectList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
{
- Modifier* mod = (*i)->GetModifier();
- int32 amount = (*i)->GetModifierValue();
- if (mod->m_miscvalue & misc_mask && amount > modifier)
- modifier = amount;
+ if ((*i)->GetMiscValue()& misc_mask && (*i)->GetAmount() > modifier)
+ modifier = (*i)->GetAmount();
}
return modifier;
@@ -3653,13 +3606,11 @@ int32 Unit::GetMaxNegativeAuraModifierByMiscMask(AuraType auratype, uint32 misc_
{
int32 modifier = 0;
- AuraList const& mTotalAuraList = GetAurasByType(auratype);
- for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
+ AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
+ for(AuraEffectList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
{
- Modifier* mod = (*i)->GetModifier();
- int32 amount = (*i)->GetModifierValue();
- if (mod->m_miscvalue & misc_mask && amount < modifier)
- modifier = amount;
+ if ((*i)->GetMiscValue()& misc_mask && (*i)->GetAmount() < modifier)
+ modifier = (*i)->GetAmount();
}
return modifier;
@@ -3669,12 +3620,11 @@ int32 Unit::GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value)
{
int32 modifier = 0;
- AuraList const& mTotalAuraList = GetAurasByType(auratype);
- for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
+ AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
+ for(AuraEffectList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
{
- Modifier* mod = (*i)->GetModifier();
- if (mod->m_miscvalue == misc_value)
- modifier += (*i)->GetModifierValue();
+ if ((*i)->GetMiscValue()== misc_value)
+ modifier += (*i)->GetAmount();
}
return modifier;
}
@@ -3683,12 +3633,11 @@ float Unit::GetTotalAuraMultiplierByMiscValue(AuraType auratype, int32 misc_valu
{
float multiplier = 1.0f;
- AuraList const& mTotalAuraList = GetAurasByType(auratype);
- for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
+ AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
+ for(AuraEffectList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
{
- Modifier* mod = (*i)->GetModifier();
- if (mod->m_miscvalue == misc_value)
- multiplier *= (100.0f + (*i)->GetModifierValue())/100.0f;
+ if ((*i)->GetMiscValue()== misc_value)
+ multiplier *= (100.0f + (*i)->GetAmount())/100.0f;
}
return multiplier;
}
@@ -3697,13 +3646,11 @@ int32 Unit::GetMaxPositiveAuraModifierByMiscValue(AuraType auratype, int32 misc_
{
int32 modifier = 0;
- AuraList const& mTotalAuraList = GetAurasByType(auratype);
- for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
+ AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
+ for(AuraEffectList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
{
- Modifier* mod = (*i)->GetModifier();
- int32 amount = (*i)->GetModifierValue();
- if (mod->m_miscvalue == misc_value && amount > modifier)
- modifier = amount;
+ if ((*i)->GetMiscValue()== misc_value && (*i)->GetAmount() > modifier)
+ modifier = (*i)->GetAmount();
}
return modifier;
@@ -3713,13 +3660,11 @@ int32 Unit::GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_
{
int32 modifier = 0;
- AuraList const& mTotalAuraList = GetAurasByType(auratype);
- for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
+ AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
+ for(AuraEffectList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
{
- Modifier* mod = (*i)->GetModifier();
- int32 amount = (*i)->GetModifierValue();
- if (mod->m_miscvalue == misc_value && amount < modifier)
- modifier = amount;
+ if ((*i)->GetMiscValue()== misc_value && (*i)->GetAmount() < modifier)
+ modifier = (*i)->GetAmount();
}
return modifier;
@@ -3727,6 +3672,13 @@ int32 Unit::GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_
bool Unit::AddAura(Aura *Aur)
{
+ // aura doesn't apply effects-return
+ if (!Aur->GetEffectMask())
+ {
+ delete Aur;
+ return false;
+ }
+
// ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load)
if( !isAlive() && Aur->GetId() != 20584 && Aur->GetId() != 8326 && Aur->GetId() != 2584 &&
(GetTypeId()!=TYPEID_PLAYER || !((Player*)this)->GetSession()->PlayerLoading()) )
@@ -3737,8 +3689,8 @@ bool Unit::AddAura(Aura *Aur)
if(Aur->GetTarget() != this)
{
- sLog.outError("Aura (spell %u eff %u) add to aura list of %s (lowguid: %u) but Aura target is %s (lowguid: %u)",
- Aur->GetId(),Aur->GetEffIndex(),(GetTypeId()==TYPEID_PLAYER?"player":"creature"),GetGUIDLow(),
+ sLog.outError("Aura (spell %u) add to aura list of %s (lowguid: %u) but Aura target is %s (lowguid: %u)",
+ Aur->GetId(),(GetTypeId()==TYPEID_PLAYER?"player":"creature"),GetGUIDLow(),
(Aur->GetTarget()->GetTypeId()==TYPEID_PLAYER?"player":"creature"),Aur->GetTarget()->GetGUIDLow());
delete Aur;
return false;
@@ -3746,66 +3698,30 @@ bool Unit::AddAura(Aura *Aur)
SpellEntry const* aurSpellInfo = Aur->GetSpellProto();
- spellEffectPair spair = spellEffectPair(Aur->GetId(), Aur->GetEffIndex());
-
- bool stackModified=false;
// passive and persistent auras can stack with themselves any number of times
- if (!Aur->IsPassive() && !Aur->IsPersistent())
+ if (!Aur->IsPassive() && !Aur->IsPersistent() && aurSpellInfo->StackAmount>1)
{
- for(AuraMap::iterator i2 = m_Auras.lower_bound(spair); i2 != m_Auras.upper_bound(spair);)
+ // find current aura from spell and change it's stackamount
+ if (Aura * foundAura = GetAura(aurSpellInfo->Id,Aur->GetCasterGUID()))
{
- if(i2->second->GetCasterGUID()==Aur->GetCasterGUID())
- {
- if (!stackModified)
- {
- // replace aura if next will > spell StackAmount
- if(aurSpellInfo->StackAmount)
- {
- // prevent adding stack more than once
- stackModified=true;
- Aur->SetStackAmount(i2->second->GetStackAmount());
- if(Aur->GetStackAmount() < aurSpellInfo->StackAmount)
- Aur->SetStackAmount(Aur->GetStackAmount()+1);
- }
- RemoveAura(i2,AURA_REMOVE_BY_STACK);
- i2=m_Auras.lower_bound(spair);
- continue;
- }
- }
- switch(aurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()])
- {
- // DOT or HOT from different casters will stack
- case SPELL_AURA_PERIODIC_DAMAGE:
- case SPELL_AURA_PERIODIC_HEAL:
- case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
- case SPELL_AURA_PERIODIC_ENERGIZE:
- case SPELL_AURA_PERIODIC_MANA_LEECH:
- case SPELL_AURA_PERIODIC_LEECH:
- case SPELL_AURA_POWER_BURN_MANA:
- case SPELL_AURA_OBS_MOD_MANA:
- case SPELL_AURA_OBS_MOD_HEALTH:
- ++i2;
- continue;
- }
- RemoveAura(i2,AURA_REMOVE_BY_STACK);
- i2=m_Auras.lower_bound(spair);
- continue;
+ if(foundAura->GetStackAmount() < aurSpellInfo->StackAmount)
+ foundAura->SetStackAmount(foundAura->GetStackAmount()+1);
+ else
+ foundAura->RefreshAura();
+ delete Aur;
+ return false;
}
}
- // passive auras stack with all (except passive spell proc auras)
- if ((!Aur->IsPassive() || !IsPassiveStackableSpell(Aur->GetId())) &&
- !(Aur->GetId() == 20584 || Aur->GetId() == 8326))
+ // passive auras not stacable with other ranks
+ if (!RemoveNoStackAurasDueToAura(Aur))
{
- if (!RemoveNoStackAurasDueToAura(Aur))
- {
- delete Aur;
- return false; // couldn't remove conflicting aura with higher rank
- }
+ delete Aur;
+ return false; // couldn't remove conflicting aura with higher rank
}
// update single target auras list (before aura add to aura list, to prevent unexpected remove recently added aura)
- if (IsSingleTargetSpell(aurSpellInfo) && Aur->GetTarget())
+ if (Aur->IsSingleTarget() && Aur->GetTarget())
{
// caster pointer can be deleted in time aura remove, find it by guid at each iteration
for(;;)
@@ -3821,12 +3737,7 @@ bool Unit::AddAura(Aura *Aur)
if( (*itr)->GetTarget() != Aur->GetTarget() &&
IsSingleTargetSpells((*itr)->GetSpellProto(),aurSpellInfo) )
{
- if ((*itr)->IsInUse())
- {
- sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for IsSingleTargetSpell", (*itr)->GetId(), (*itr)->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex());
- continue;
- }
- (*itr)->GetTarget()->RemoveAura((*itr)->GetId(), (*itr)->GetEffIndex());
+ (*itr)->GetTarget()->RemoveAurasDueToSpell((*itr)->GetId(), caster->GetGUID(), AURA_REMOVE_BY_STACK);
restart = true;
break;
}
@@ -3843,63 +3754,24 @@ bool Unit::AddAura(Aura *Aur)
// add aura, register in lists and arrays
Aur->_AddAura();
- m_Auras.insert(AuraMap::value_type(spellEffectPair(Aur->GetId(), Aur->GetEffIndex()), Aur));
- if (Aur->GetModifier()->m_auraname < TOTAL_AURAS)
+ m_Auras.insert(AuraMap::value_type(Aur->GetId(), Aur));
+
+ if(Aur->GetSpellProto()->AuraInterruptFlags)
{
- m_modAuras[Aur->GetModifier()->m_auraname].push_back(Aur);
- if(Aur->GetSpellProto()->AuraInterruptFlags)
- {
- m_interruptableAuras.push_back(Aur);
- AddInterruptMask(Aur->GetSpellProto()->AuraInterruptFlags);
- }
- if((Aur->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE)
- && (Aur->GetModifier()->m_auraname != SPELL_AURA_MOD_POSSESS)) //only dummy aura is breakable
- {
- m_ccAuras.push_back(Aur);
- }
+ m_interruptableAuras.push_back(Aur);
+ AddInterruptMask(Aur->GetSpellProto()->AuraInterruptFlags);
}
-
- Aur->ApplyModifier(true,true);
-
- uint32 id = Aur->GetId();
- if(spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_AURA)
+ if((Aur->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE
+ && !Aur->IsAuraType(SPELL_AURA_MOD_POSSESS)) //only dummy aura is breakable
+ || ((GetAllSpellMechanicMask(Aur->GetSpellProto()) & 1<<MECHANIC_KNOCKOUT) && Aur->IsAuraType(SPELL_AURA_MOD_STUN)))
{
- if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(id + SPELL_LINK_AURA))
- for(std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
- if(*itr < 0)
- ApplySpellImmune(id, IMMUNITY_ID, -(*itr), true);
- else if(Unit* caster = Aur->GetCaster())
- caster->AddAura(*itr, this);
+ m_ccAuras.push_back(Aur);
}
- sLog.outDebug("Aura %u now is in use", Aur->GetModifier()->m_auraname);
- return true;
-}
-
-void Unit::RemoveRankAurasDueToSpell(uint32 spellId)
-{
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
- if(!spellInfo)
- return;
- AuraMap::iterator i,next;
- for (i = m_Auras.begin(); i != m_Auras.end(); i = next)
- {
- next = i;
- ++next;
- uint32 i_spellId = (*i).second->GetId();
- if((*i).second && i_spellId && i_spellId != spellId)
- {
- if(spellmgr.IsRankSpellDueToSpell(spellInfo,i_spellId))
- {
- RemoveAurasDueToSpell(i_spellId);
+ Aur->HandleEffects(true);
- if( m_Auras.empty() )
- break;
- else
- next = m_Auras.begin();
- }
- }
- }
+ sLog.outDebug("Aura %u now is in use", Aur->GetId());
+ return true;
}
bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
@@ -3908,34 +3780,34 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
return false;
SpellEntry const* spellProto = Aur->GetSpellProto();
- if (!spellProto)
- return false;
uint32 spellId = Aur->GetId();
- uint32 effIndex = Aur->GetEffIndex();
+
+ // passive spell special case (only non stackable with ranks)
+ if(IsPassiveSpell(spellId))
+ {
+ if(IsPassiveSpellStackableWithRanks(spellProto))
+ return true;
+ }
SpellSpecific spellId_spec = GetSpellSpecific(spellId);
+ //bool linked = spellmgr.GetSpellCustomAttr(spellId) & SPELL_ATTR_CU_LINK_AURA? true : false;
+
AuraMap::iterator i,next;
for (i = m_Auras.begin(); i != m_Auras.end(); i = next)
{
next = i;
++next;
- if (!(*i).second) continue;
SpellEntry const* i_spellProto = (*i).second->GetSpellProto();
- if (!i_spellProto)
- continue;
-
uint32 i_spellId = i_spellProto->Id;
- if (spellId==i_spellId)
- continue;
-
if(IsPassiveSpell(i_spellId))
{
- if(IsPassiveStackableSpell(i_spellId))
+ // passive non-stackable spells not stackable only for same caster
+ if(Aur->GetCasterGUID()!=i->second->GetCasterGUID())
continue;
// passive non-stackable spells not stackable only with another rank of same spell
@@ -3943,180 +3815,132 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
continue;
}
- uint32 i_effIndex = (*i).second->GetEffIndex();
-
bool is_triggered_by_spell = false;
// prevent triggered aura of removing aura that triggered it
for(int j = 0; j < 3; ++j)
if (i_spellProto->EffectTriggerSpell[j] == spellProto->Id)
is_triggered_by_spell = true;
- if (is_triggered_by_spell) continue;
- for(int j = 0; j < 3; ++j)
- {
- // prevent remove dummy triggered spells at next effect aura add
- switch(spellProto->Effect[j]) // main spell auras added added after triggered spell
- {
- case SPELL_EFFECT_DUMMY:
- switch(spellId)
- {
- case 5420: if(i_spellId==34123) is_triggered_by_spell = true; break;
- }
- break;
- }
-
- if(is_triggered_by_spell)
- break;
+ // check if they can stack
+ bool sameCaster = Aur->GetCasterGUID() == (*i).second->GetCasterGUID();
- // prevent remove form main spell by triggered passive spells
- switch(i_spellProto->EffectApplyAuraName[j]) // main aura added before triggered spell
- {
- case SPELL_AURA_MOD_SHAPESHIFT:
- switch(i_spellId)
+ /*// Dont remove by stack with linked auras
+ // Not needed for now
+ if(sameCaster && linked)
+ {
+ if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(spellId + SPELL_LINK_AURA))
+ for(std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
+ if(*itr>0 && *itr==i_spellId)
{
- case 24858: if(spellId==24905) is_triggered_by_spell = true; break;
- case 33891: if(spellId==5420 || spellId==34123) is_triggered_by_spell = true; break;
- case 34551: if(spellId==22688) is_triggered_by_spell = true; break;
+ is_triggered_by_spell=true;
+ break;
}
- break;
- }
- }
+ }*/
- if(!is_triggered_by_spell)
- {
- bool sameCaster = Aur->GetCasterGUID() == (*i).second->GetCasterGUID();
- if( spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId, sameCaster) )
- {
- //some spells should be not removed by lower rank of them (totem, paladin aura)
- if (!sameCaster
- &&(spellProto->Effect[effIndex]==SPELL_EFFECT_APPLY_AREA_AURA_PARTY)
- &&(spellProto->DurationIndex==21)
- &&(spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId))
- &&(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0))
- return false;
+ if (is_triggered_by_spell)
+ continue;
- // Its a parent aura (create this aura in ApplyModifier)
- if ((*i).second->IsInUse())
- {
- sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex());
- continue;
- }
+ if(!spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId, sameCaster))
+ continue;
- uint64 caster = (*i).second->GetCasterGUID();
- // Remove all auras by aura caster
- for (uint8 a=0;a<3;++a)
- {
- spellEffectPair spair = spellEffectPair(i_spellId, a);
- for(AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair);)
- {
- if(iter->second->GetCasterGUID()==caster)
- {
- RemoveAura(iter, AURA_REMOVE_BY_STACK);
- iter = m_Auras.lower_bound(spair);
- }
- else
- ++iter;
- }
- }
+ //some spells should be not removed by lower rank of them (totem, paladin aura)
+ if (!sameCaster
+ &&(Aur->IsAreaAura())
+ &&(spellProto->DurationIndex==21)
+ &&(spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId))
+ &&(IsHigherHankOfSpell(spellId,i_spellId)))
+ return false;
- if( m_Auras.empty() )
- break;
- else
- next = m_Auras.begin();
- }
- }
+ // Remove all auras by aura caster
+ RemoveAura(i, AURA_REMOVE_BY_STACK);
+ next=i;
}
return true;
}
-void Unit::RemoveAura(uint32 spellId, uint32 effindex, Aura* except)
+void Unit::RemoveAura(uint32 spellId, uint64 caster ,AuraRemoveMode removeMode)
{
- spellEffectPair spair = spellEffectPair(spellId, effindex);
- for(AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair);)
+ for(AuraMap::iterator iter = m_Auras.lower_bound(spellId); iter != m_Auras.upper_bound(spellId);)
{
- if(iter->second!=except)
+ if (!caster || iter->second->GetCasterGUID()==caster)
{
- RemoveAura(iter);
- iter = m_Auras.lower_bound(spair);
+ RemoveAura(iter, removeMode);
+ return;
}
else
++iter;
}
}
-void Unit::RemoveAurasByCasterSpell(uint32 spellId, uint64 casterGUID)
+void Unit::RemoveAura(Aura * aur ,AuraRemoveMode mode)
{
- for(int k = 0; k < 3; ++k)
+ // no need to remove
+ if (!aur || aur->IsRemoved())
+ return;
+ for(AuraMap::iterator iter = m_Auras.lower_bound(aur->GetId()); iter != m_Auras.upper_bound(aur->GetId());)
{
- spellEffectPair spair = spellEffectPair(spellId, k);
- for (AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair);)
+ if (aur == iter->second)
{
- if (iter->second->GetCasterGUID() == casterGUID)
- {
- RemoveAura(iter);
- iter = m_Auras.upper_bound(spair); // overwrite by more appropriate
- }
- else
- ++iter;
+ RemoveAura(iter, mode);
+ return;
}
+ else
+ ++iter;
}
}
-void Unit::SetAurasDurationByCasterSpell(uint32 spellId, uint64 casterGUID, int32 duration)
+void Unit::RemoveAurasDueToSpell(uint32 spellId, uint64 caster ,AuraRemoveMode removeMode)
{
- for(uint8 i = 0; i < 3; ++i)
+ for(AuraMap::iterator iter = m_Auras.lower_bound(spellId); iter != m_Auras.upper_bound(spellId);)
{
- spellEffectPair spair = spellEffectPair(spellId, i);
- for(AuraMap::const_iterator itr = GetAuras().lower_bound(spair); itr != GetAuras().upper_bound(spair); ++itr)
+ if (!caster || iter->second->GetCasterGUID()==caster)
{
- if(itr->second->GetCasterGUID()==casterGUID)
- {
- itr->second->SetAuraDuration(duration);
- break;
- }
+ RemoveAura(iter, removeMode);
+ iter = m_Auras.lower_bound(spellId);
}
+ else
+ ++iter;
}
}
-Aura* Unit::GetAuraByCasterSpell(uint32 spellId, uint64 casterGUID)
+void Unit::RemoveAuraFromStack(uint32 spellId, uint64 caster ,AuraRemoveMode removeMode)
{
- // Returns first found aura from spell-use only in cases where effindex of spell doesn't matter!
- for(uint8 i = 0; i < 3; ++i)
+ for(AuraMap::iterator iter = m_Auras.lower_bound(spellId); iter != m_Auras.upper_bound(spellId);)
{
- spellEffectPair spair = spellEffectPair(spellId, i);
- for(AuraMap::const_iterator itr = GetAuras().lower_bound(spair); itr != GetAuras().upper_bound(spair); ++itr)
+ if (!caster || iter->second->GetCasterGUID()==caster)
{
- if(itr->second->GetCasterGUID()==casterGUID)
- return itr->second;
+ RemoveAuraFromStack(iter, removeMode);
+ return;
}
+ else
+ ++iter;
}
- return NULL;
+}
+
+inline void Unit::RemoveAuraFromStack(AuraMap::iterator &iter,AuraRemoveMode removeMode)
+{
+ if (iter->second->modStackAmount(-1))
+ RemoveAura(iter, removeMode);
}
void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler)
{
- for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); )
+ for(AuraMap::iterator iter = m_Auras.lower_bound(spellId); iter != m_Auras.upper_bound(spellId);)
{
- Aura *aur = iter->second;
- if (aur->GetId() == spellId && aur->GetCasterGUID() == casterGUID)
+ Aura * aur= iter->second;
+ if (casterGUID == aur->GetCasterGUID())
{
- // Custom dispel case
// Unstable Affliction
- if (aur->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (aur->GetSpellProto()->SpellFamilyFlags & 0x010000000000LL))
+ if (aur->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (aur->GetSpellProto()->SpellFamilyFlags[1] & 0x0100))
{
- int32 damage = aur->GetModifier()->m_amount*9;
- uint64 caster_guid = aur->GetCasterGUID();
-
- // Remove aura
- RemoveAura(iter, AURA_REMOVE_BY_DISPEL);
-
+ int32 damage = aur->GetPartAura(0)->GetAmount()*9;
+ RemoveAuraFromStack(iter, AURA_REMOVE_BY_ENEMY_SPELL);
// backfire damage and silence
- dispeler->CastCustomSpell(dispeler, 31117, &damage, NULL, NULL, true, NULL, NULL,caster_guid);
-
- iter = m_Auras.begin(); // iterator can be invalidate at cast if self-dispel
+ dispeler->CastCustomSpell(dispeler, 31117, &damage, NULL, NULL, true, NULL, NULL,GetGUID());
+ return;
}
- else
- RemoveAura(iter, AURA_REMOVE_BY_DISPEL);
+ RemoveAuraFromStack(iter, AURA_REMOVE_BY_ENEMY_SPELL);
+ return;
}
else
++iter;
@@ -4125,131 +3949,86 @@ void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit
void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer)
{
- for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); )
+ if (casterGUID == stealer->GetGUID())
+ return;
+
+ for(AuraMap::iterator iter = m_Auras.lower_bound(spellId); iter != m_Auras.upper_bound(spellId);)
{
- Aura *aur = iter->second;
- if (aur->GetId() == spellId && aur->GetCasterGUID() == casterGUID)
+ Aura * aur= iter->second;
+ if (casterGUID == aur->GetCasterGUID())
{
- int32 basePoints = aur->GetBasePoints();
- // construct the new aura for the attacker
- Aura * new_aur = CreateAura(aur->GetSpellProto(), aur->GetEffIndex(), NULL/*&basePoints*/, stealer);
- if(!new_aur)
- continue;
-
- // set its duration and maximum duration
- // max duration 2 minutes (in msecs)
- int32 dur = aur->GetAuraDuration();
- const int32 max_dur = 2*MINUTE*1000;
- new_aur->SetAuraMaxDuration( max_dur > dur ? dur : max_dur );
- new_aur->SetAuraDuration( max_dur > dur ? dur : max_dur );
+ int32 damage[3];
+ for (uint8 i=0;i<3;++i)
+ {
+ if (aur->GetPartAura(i))
+ damage[i]=aur->GetPartAura(i)->GetAmount();
+ else
+ damage[i]=NULL;
+ }
+ int32 dur = 2*MINUTE*IN_MILISECONDS < aur->GetAuraDuration() ? 2*MINUTE*IN_MILISECONDS : aur->GetAuraDuration();
+ Aura * new_aur = new Aura(aur->GetSpellProto(),aur->GetEffectMask(), NULL, stealer, stealer, NULL);
+ new_aur->SetLoadedState(aur->GetCasterGUID(), dur, dur, aur->GetAuraCharges(), aur->GetStackAmount(), &damage[0]);
- // add the new aura to stealer
+ // Unregister _before_ adding to stealer
+ aur->UnregisterSingleCastAura();
+ // strange but intended behaviour: Stolen single target auras won't be treated as single targeted
+ new_aur->SetIsSingleTarget(false);
stealer->AddAura(new_aur);
-
- // Remove aura as dispel
- RemoveAura(iter, AURA_REMOVE_BY_DISPEL);
+ RemoveAuraFromStack(iter, AURA_REMOVE_BY_ENEMY_SPELL);
+ return;
}
else
++iter;
}
}
-void Unit::RemoveAurasDueToSpellByCancel(uint32 spellId)
-{
- for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); )
- {
- if (iter->second->GetId() == spellId)
- RemoveAura(iter, AURA_REMOVE_BY_CANCEL);
- else
- ++iter;
- }
-}
-
-void Unit::RemoveAurasWithDispelType( DispelType type )
+void Unit::RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId)
{
- // Create dispel mask by dispel type
- uint32 dispelMask = GetDispellMask(type);
- // Dispel all existing auras vs current dispel type
- AuraMap& auras = GetAuras();
- for(AuraMap::iterator itr = auras.begin(); itr != auras.end(); )
+ for (AuraMap::iterator iter = m_Auras.lower_bound(spellId); iter != m_Auras.upper_bound(spellId);)
{
- SpellEntry const* spell = itr->second->GetSpellProto();
- if( (1<<spell->Dispel) & dispelMask )
+ if (!castItem || iter->second->GetCastItemGUID()==castItem->GetGUID())
{
- // Dispel aura
- RemoveAurasDueToSpell(spell->Id);
- itr = auras.begin();
+ RemoveAura(iter);
+ iter = m_Auras.upper_bound(spellId); // overwrite by more appropriate
}
else
- ++itr;
+ ++iter;
}
}
-void Unit::RemoveSingleAuraFromStackByDispel(uint32 spellId)
+void Unit::RemoveAurasByType(AuraType auraType, uint64 casterGUID, Aura * except)
{
- for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); )
+ if (auraType >= TOTAL_AURAS) return;
+ for (AuraEffectList::iterator iter = m_modAuras[auraType].begin(); iter != m_modAuras[auraType].end();)
{
- Aura *aur = iter->second;
- if (aur->GetId() == spellId)
+ Aura * aur = (*iter)->GetParentAura();
+ ++iter;
+ if (aur != except && (!casterGUID || aur->GetCasterGUID()==casterGUID))
{
- if(iter->second->GetStackAmount() > 1)
- {
- // reapply modifier with reduced stack amount
- iter->second->ApplyModifier(false,true);
- iter->second->SetStackAmount(iter->second->GetStackAmount()-1);
- iter->second->ApplyModifier(true,true);
-
- iter->second->UpdateSlotCounterAndDuration();
- return; // not remove aura if stack amount > 1
- }
- else
- RemoveAura(iter,AURA_REMOVE_BY_DISPEL);
+ uint32 removedAuras = m_removedAurasCount;
+ RemoveAura(aur);
+ if (removedAuras+1< m_removedAurasCount)
+ iter=m_modAuras[auraType].begin();
}
- else
- ++iter;
}
}
-void Unit::RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex)
+void Unit::RemoveAurasByTypeWithDispel(AuraType auraType, Spell * spell)
{
- AuraMap::iterator iter = m_Auras.find(spellEffectPair(spellId, effindex));
- if(iter != m_Auras.end())
- {
- if(iter->second->GetStackAmount() > 1)
- {
- // reapply modifier with reduced stack amount
- iter->second->ApplyModifier(false,true);
- iter->second->SetStackAmount(iter->second->GetStackAmount()-1);
- iter->second->ApplyModifier(true,true);
+ if (auraType >= TOTAL_AURAS) return;
+ std::queue < std::pair < uint32, uint64 > > remove_list;
- iter->second->UpdateSlotCounterAndDuration();
- return; // not remove aura if stack amount > 1
- }
- RemoveAura(iter);
+ for (AuraEffectList::iterator iter = m_modAuras[auraType].begin(); iter != m_modAuras[auraType].end();++iter)
+ {
+ if(GetDispelChance((*iter)->GetCaster(), (*iter)->GetId()))
+ {
+ remove_list.push(std::make_pair((*iter)->GetId(), (*iter)->GetCasterGUID() ) );
+ }
}
-}
-void Unit::RemoveAurasDueToSpell(uint32 spellId, Aura* except)
-{
- for (int i = 0; i < 3; ++i)
- RemoveAura(spellId,i,except);
-}
-
-void Unit::RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId)
-{
- for (int k=0; k < 3; ++k)
+ for(;remove_list.size();remove_list.pop())
{
- spellEffectPair spair = spellEffectPair(spellId, k);
- for (AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair);)
- {
- if (iter->second->GetCastItemGUID() == castItem->GetGUID())
- {
- RemoveAura(iter);
- iter = m_Auras.upper_bound(spair); // overwrite by more appropriate
- }
- else
- ++iter;
- }
+ RemoveAura(remove_list.front().first, remove_list.front().second, AURA_REMOVE_BY_ENEMY_SPELL);
}
}
@@ -4266,182 +4045,63 @@ void Unit::RemoveNotOwnSingleTargetAuras()
// single target auras at other targets
AuraList& scAuras = GetSingleCastAuras();
- for (AuraList::iterator iter = scAuras.begin(); iter != scAuras.end(); )
+ for (AuraList::iterator iter = scAuras.begin(); iter != scAuras.end();)
{
- Aura* aura = *iter;
- if (aura->GetTarget()!=this)
+ Aura * aur=*iter;
+ ++iter;
+ if (aur->GetTarget()!=this)
{
- scAuras.erase(iter); // explicitly remove, instead waiting remove in RemoveAura
- aura->GetTarget()->RemoveAura(aura->GetId(),aura->GetEffIndex());
- iter = scAuras.begin();
+ uint32 removedAuras = m_removedAurasCount;
+ aur->GetTarget()->RemoveAura(aur->GetId(),aur->GetCasterGUID());
+ if (removedAuras+1<m_removedAurasCount)
+ iter=scAuras.begin();
}
- else
- ++iter;
}
-
}
void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
{
Aura* Aur = i->second;
- SpellEntry const* AurSpellInfo = Aur->GetSpellProto();
// some ShapeshiftBoosts at remove trigger removing other auras including parent Shapeshift aura
// remove aura from list before to prevent deleting it before
m_Auras.erase(i);
- ++m_removedAuras; // internal count used by unit update
+ m_removedAurasCount += 1;
+
+ Aur->UnregisterSingleCastAura();
- Unit* caster = NULL;
- if (IsSingleTargetSpell(AurSpellInfo))
+ if(Aur->GetSpellProto()->AuraInterruptFlags)
{
- caster = Aur->GetCaster();
- if(caster)
- {
- AuraList& scAuras = caster->GetSingleCastAuras();
- scAuras.remove(Aur);
- }
- else
- {
- sLog.outError("Couldn't find the caster of the single target aura, may crash later!");
- assert(false);
- }
+ m_interruptableAuras.remove(Aur);
+ UpdateInterruptMask();
}
- // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order)
- if (Aur->GetModifier()->m_auraname < TOTAL_AURAS)
+ if((Aur->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE
+ && !Aur->IsAuraType(SPELL_AURA_MOD_POSSESS)) //only dummy aura is breakable
+ || ((GetAllSpellMechanicMask(Aur->GetSpellProto()) & 1<<MECHANIC_KNOCKOUT) && Aur->IsAuraType(SPELL_AURA_MOD_STUN)))
{
- m_modAuras[Aur->GetModifier()->m_auraname].remove(Aur);
-
- if(Aur->GetSpellProto()->AuraInterruptFlags)
- {
- m_interruptableAuras.remove(Aur);
- UpdateInterruptMask();
- }
-
- if((Aur->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE)
- && (Aur->GetModifier()->m_auraname != SPELL_AURA_MOD_POSSESS)) //only dummy aura is breakable
- {
- m_ccAuras.remove(Aur);
- }
+ m_ccAuras.remove(Aur);
}
- // Set remove mode
Aur->SetRemoveMode(mode);
- // Statue unsummoned at aura remove
- Totem* statue = NULL;
- bool channeled = false;
- if(Aur->GetAuraDuration() && !Aur->IsPersistent() && IsChanneledSpell(AurSpellInfo))
- {
- if(!caster) // can be already located for IsSingleTargetSpell case
- caster = Aur->GetCaster();
-
- if(caster && caster->isAlive())
- {
- // stop caster chanelling state
- if(caster->m_currentSpells[CURRENT_CHANNELED_SPELL]
- //prevent recurential call
- && caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED)
- {
- if (caster==this || !IsAreaOfEffectSpell(AurSpellInfo))
- {
- // remove auras only for non-aoe spells or when chanelled aura is removed
- // because aoe spells don't require aura on target to continue
- if (AurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()]!=SPELL_AURA_PERIODIC_DUMMY
- && AurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()]!= SPELL_AURA_DUMMY)
- //don't stop channeling of scripted spells (this is actually a hack)
- {
- caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel();
- caster->m_currentSpells[CURRENT_CHANNELED_SPELL]=NULL;
-
- }
- }
-
- if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE)
- statue = ((Totem*)caster);
- }
-
- // Unsummon summon as possessed creatures on spell cancel
- if(caster->GetTypeId() == TYPEID_PLAYER)
- {
- for(int i = 0; i < 3; ++i)
- {
- if(AurSpellInfo->Effect[i] == SPELL_EFFECT_SUMMON &&
- (AurSpellInfo->EffectMiscValueB[i] == SUMMON_TYPE_POSESSED ||
- AurSpellInfo->EffectMiscValueB[i] == SUMMON_TYPE_POSESSED2 ||
- AurSpellInfo->EffectMiscValueB[i] == SUMMON_TYPE_POSESSED3))
- {
- ((Player*)caster)->StopCastingCharm();
- break;
- }
- }
- }
- }
- }
+ sLog.outDebug("Aura %u now is remove mode %d", Aur->GetId(), mode);
+ Aur->HandleEffects(false);
- sLog.outDebug("Aura %u (%u) now is remove mode %d", Aur->GetId(), Aur->GetModifier()->m_auraname, mode);
- assert(!Aur->IsInUse());
- Aur->ApplyModifier(false,true);
-
- Aur->SetStackAmount(0);
+ // set aura to be removed during unit::_updatespells
+ m_removedAuras.push_back(Aur);
Aur->_RemoveAura();
- bool stack = false;
- spellEffectPair spair = spellEffectPair(Aur->GetId(), Aur->GetEffIndex());
- for(AuraMap::const_iterator itr = GetAuras().lower_bound(spair); itr != GetAuras().upper_bound(spair); ++itr)
- {
- if (itr->second->GetCasterGUID()==GetGUID())
- {
- stack = true;
- }
- }
- if (!stack)
- {
- // Remove all triggered by aura spells vs unlimited duration
- Aur->CleanupTriggeredSpells();
-
- // Remove Linked Auras
- uint32 id = Aur->GetId();
- if(spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_REMOVE)
- {
- if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(-(int32)id))
- for(std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
- if(*itr < 0)
- RemoveAurasDueToSpell(-(*itr));
- else if(Unit* caster = Aur->GetCaster())
- CastSpell(this, *itr, true, 0, 0, caster->GetGUID());
- }
- if(spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_AURA)
- {
- if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(id + SPELL_LINK_AURA))
- for(std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
- if(*itr < 0)
- ApplySpellImmune(id, IMMUNITY_ID, -(*itr), false);
- else
- RemoveAurasDueToSpell(*itr);
- }
- }
-
- delete Aur;
-
- if(statue)
- statue->UnSummon();
-
// only way correctly remove all auras from list
- if( m_Auras.empty() )
- i = m_Auras.end();
- else
- i = m_Auras.begin();
+ i = m_Auras.begin();
}
void Unit::RemoveAllAuras()
{
+ AuraMap::iterator iter = m_Auras.begin();
while (!m_Auras.empty())
- {
- AuraMap::iterator iter = m_Auras.begin();
RemoveAura(iter);
- }
}
void Unit::RemoveArenaAuras(bool onleave)
@@ -4473,17 +4133,17 @@ void Unit::RemoveAllAurasOnDeath()
}
}
-void Unit::DelayAura(uint32 spellId, uint32 effindex, int32 delaytime)
+void Unit::DelayAura(uint32 spellId, uint64 caster, int32 delaytime)
{
- AuraMap::iterator iter = m_Auras.find(spellEffectPair(spellId, effindex));
- if (iter != m_Auras.end())
+ if (Aura * aur = GetAura(spellId, caster))
{
- if (iter->second->GetAuraDuration() < delaytime)
- iter->second->SetAuraDuration(0);
+ if (aur->GetAuraDuration() < delaytime)
+ aur->SetAuraDuration(0);
else
- iter->second->SetAuraDuration(iter->second->GetAuraDuration() - delaytime);
- iter->second->UpdateAuraDuration();
- sLog.outDebug("Aura %u partially interrupted on unit %u, new duration: %u ms",iter->second->GetModifier()->m_auraname, GetGUIDLow(), iter->second->GetAuraDuration());
+ aur->SetAuraDuration(aur->GetAuraDuration() - delaytime);
+ // update for out of range group members (on 1 slot use)
+ UpdateAuraForGroup(aur->GetAuraSlot());
+ sLog.outDebug("Aura %u partially interrupted on unit %u, new duration: %u ms",aur->GetId(), GetGUIDLow(), aur->GetAuraDuration());
}
}
@@ -4491,7 +4151,7 @@ void Unit::_RemoveAllAuraMods()
{
for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end(); ++i)
{
- (*i).second->ApplyModifier(false);
+ (*i).second->ApplyAllModifiers(false);
}
}
@@ -4499,15 +4159,94 @@ void Unit::_ApplyAllAuraMods()
{
for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end(); ++i)
{
- (*i).second->ApplyModifier(true);
+ (*i).second->ApplyAllModifiers(true);
+ }
+}
+
+bool Unit::HasAuraTypeWithMiscvalue(AuraType auratype, uint32 miscvalue) const
+{
+ AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
+ for(AuraEffectList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
+ if (miscvalue == (*i)->GetMiscValue())
+ return true;
+ return false;
+}
+
+bool Unit::HasAuraType(AuraType auraType) const
+{
+ return (!m_modAuras[auraType].empty());
+}
+
+bool Unit::HasAura(uint32 spellId, uint64 caster) const
+{
+ //Special case for non existing spell
+ if (spellId==61988)
+ return HasAura(61987, caster) || HasAura(25771, caster);
+
+ if (Aura * aur = GetAura(spellId, caster))
+ return true;
+ return false;
+}
+
+bool Unit::HasAura(Aura * aur) const
+{
+ // no need to find aura
+ if (!aur || aur->IsRemoved())
+ return false;
+ for(AuraMap::const_iterator iter = m_Auras.lower_bound(aur->GetId()); iter != m_Auras.upper_bound(aur->GetId());)
+ {
+ if (aur == iter->second)
+ return true;
+ else
+ ++iter;
}
+ return false;
}
-Aura* Unit::GetAura(uint32 spellId, uint32 effindex)
+bool Unit::HasAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster) const
{
- AuraMap::iterator iter = m_Auras.find(spellEffectPair(spellId, effindex));
- if (iter != m_Auras.end())
- return iter->second;
+ if (Aura * aur = GetAura(spellId, caster))
+ return bool(aur->HasEffect(effIndex));
+ return false;
+}
+
+Aura * Unit::GetAura(uint32 spellId, uint64 caster) const
+{
+ if (!caster)
+ {
+ AuraMap::const_iterator itr = m_Auras.find(spellId);
+ return itr != m_Auras.end() ? itr->second : NULL;
+ }
+ else
+ {
+ AuraMap const& auras = GetAuras();
+ for(AuraMap::const_iterator itr = auras.lower_bound(spellId); itr != auras.upper_bound(spellId); ++itr)
+ if(itr->second->GetCasterGUID()==caster)
+ return itr->second;
+ return NULL;
+ }
+}
+
+AuraEffect * Unit::GetAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster) const
+{
+ if (Aura * aur = GetAura(spellId, caster))
+ return aur->GetPartAura(effIndex);
+ return false;
+}
+
+AuraEffect* Unit::GetAura(AuraType type, uint32 family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, uint64 casterGUID)
+{
+ AuraEffectList const& auras = GetAurasByType(type);
+ for(AuraEffectList::const_iterator i = auras.begin();i != auras.end(); ++i)
+ {
+ SpellEntry const *spell = (*i)->GetSpellProto();
+ if (spell->SpellFamilyName == family && spell->SpellFamilyFlags.HasFlag(familyFlag1, familyFlag2, familyFlag3))
+ {
+ if (casterGUID && (*i)->GetCasterGUID()!=casterGUID)
+ continue;
+ return (*i);
+ }
+ }
return NULL;
}
@@ -4522,7 +4261,7 @@ void Unit::RemoveDynObject(uint32 spellid)
return;
for (DynObjectGUIDs::iterator i = m_dynObjGUIDs.begin(); i != m_dynObjGUIDs.end();)
{
- DynamicObject* dynObj = ObjectAccessor::GetDynamicObject(*this, *i);
+ DynamicObject* dynObj = GetMap()->GetDynamicObject(*i);
if(!dynObj) // may happen if a dynobj is removed when grid unload
{
i = m_dynObjGUIDs.erase(i);
@@ -4541,7 +4280,7 @@ void Unit::RemoveAllDynObjects()
{
while(!m_dynObjGUIDs.empty())
{
- DynamicObject* dynObj = ObjectAccessor::GetDynamicObject(*this,*m_dynObjGUIDs.begin());
+ DynamicObject* dynObj = GetMap()->GetDynamicObject(*m_dynObjGUIDs.begin());
if(dynObj)
dynObj->Delete();
m_dynObjGUIDs.erase(m_dynObjGUIDs.begin());
@@ -4552,7 +4291,7 @@ DynamicObject * Unit::GetDynObject(uint32 spellId, uint32 effIndex)
{
for (DynObjectGUIDs::iterator i = m_dynObjGUIDs.begin(); i != m_dynObjGUIDs.end();)
{
- DynamicObject* dynObj = ObjectAccessor::GetDynamicObject(*this, *i);
+ DynamicObject* dynObj = GetMap()->GetDynamicObject(*i);
if(!dynObj)
{
i = m_dynObjGUIDs.erase(i);
@@ -4570,7 +4309,7 @@ DynamicObject * Unit::GetDynObject(uint32 spellId)
{
for (DynObjectGUIDs::iterator i = m_dynObjGUIDs.begin(); i != m_dynObjGUIDs.end();)
{
- DynamicObject* dynObj = ObjectAccessor::GetDynamicObject(*this, *i);
+ DynamicObject* dynObj = GetMap()->GetDynamicObject(*i);
if(!dynObj)
{
i = m_dynObjGUIDs.erase(i);
@@ -4584,27 +4323,54 @@ DynamicObject * Unit::GetDynObject(uint32 spellId)
return NULL;
}
+GameObject* Unit::GetGameObject(uint32 spellId) const
+{
+ for (GameObjectList::const_iterator i = m_gameObj.begin(); i != m_gameObj.end();)
+ if ((*i)->GetSpellId() == spellId)
+ return *i;
+
+ return NULL;
+}
+
void Unit::AddGameObject(GameObject* gameObj)
{
assert(gameObj && gameObj->GetOwnerGUID()==0);
m_gameObj.push_back(gameObj);
gameObj->SetOwnerGUID(GetGUID());
+
+ if ( GetTypeId()==TYPEID_PLAYER && gameObj->GetSpellId() )
+ {
+ SpellEntry const* createBySpell = sSpellStore.LookupEntry(gameObj->GetSpellId());
+ // Need disable spell use for owner
+ if (createBySpell && createBySpell->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE)
+ // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)
+ ((Player*)this)->AddSpellAndCategoryCooldowns(createBySpell,0,NULL,true);
+ }
}
void Unit::RemoveGameObject(GameObject* gameObj, bool del)
{
assert(gameObj && gameObj->GetOwnerGUID()==GetGUID());
+ gameObj->SetOwnerGUID(0);
+
// GO created by some spell
- if ( GetTypeId()==TYPEID_PLAYER && gameObj->GetSpellId() )
+ if (uint32 spellid = gameObj->GetSpellId())
{
- SpellEntry const* createBySpell = sSpellStore.LookupEntry(gameObj->GetSpellId());
- // Need activate spell use for owner
- if (createBySpell && createBySpell->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE)
- ((Player*)this)->SendCooldownEvent(createBySpell);
+ RemoveAurasDueToSpell(spellid);
+
+ if (GetTypeId()==TYPEID_PLAYER)
+ {
+ SpellEntry const* createBySpell = sSpellStore.LookupEntry(spellid );
+ // Need activate spell use for owner
+ if (createBySpell && createBySpell->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE)
+ // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)
+ ((Player*)this)->SendCooldownEvent(createBySpell);
+ }
}
- gameObj->SetOwnerGUID(0);
+
m_gameObj.remove(gameObj);
+
if(del)
{
gameObj->SetRespawnTime(0);
@@ -4616,7 +4382,7 @@ void Unit::RemoveGameObject(uint32 spellid, bool del)
{
if(m_gameObj.empty())
return;
- std::list<GameObject*>::iterator i, next;
+ GameObjectList::iterator i, next;
for (i = m_gameObj.begin(); i != m_gameObj.end(); i = next)
{
next = i;
@@ -4639,7 +4405,7 @@ void Unit::RemoveGameObject(uint32 spellid, bool del)
void Unit::RemoveAllGameObjects()
{
// remove references to unit
- for(std::list<GameObject*>::iterator i = m_gameObj.begin(); i != m_gameObj.end();)
+ for(GameObjectList::iterator i = m_gameObj.begin(); i != m_gameObj.end();)
{
(*i)->SetOwnerGUID(0);
(*i)->SetRespawnTime(0);
@@ -4655,6 +4421,7 @@ void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
data.append(log->attacker->GetPackGUID());
data << uint32(log->SpellID);
data << uint32(log->damage); //damage amount
+ data << uint32(int32 (log->target->GetHealth()-log->damage ) >0 ? 0 : log->damage - log->target->GetHealth());
data << uint8 (log->schoolMask); //damage school
data << uint32(log->absorb); //AbsorbedDamage
data << uint32(log->resist); //resist
@@ -4673,7 +4440,9 @@ void Unit::SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage,
data.append(target->GetPackGUID());
data.append(GetPackGUID());
data << uint32(SpellID);
- data << uint32(Damage-AbsorbedDamage-Resist-Blocked);
+ int32 damageDone = Damage-AbsorbedDamage-Resist-Blocked;
+ data << uint32(damageDone);
+ data << uint32(int32 (target->GetHealth()-damageDone ) >0 ? 0 : damageDone - target->GetHealth());// wotlk
data << uint8(damageSchoolMask); // spell school
data << uint32(AbsorbedDamage); // AbsorbedDamage
data << uint32(Resist); // resist
@@ -4712,25 +4481,65 @@ void Unit::SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
void Unit::SendAttackStateUpdate(CalcDamageInfo *damageInfo)
{
- WorldPacket data(SMSG_ATTACKERSTATEUPDATE, (16+84)); // we guess size
+ uint32 count = 1;
+ WorldPacket data(SMSG_ATTACKERSTATEUPDATE, (16+45)); // we guess size
data << (uint32)damageInfo->HitInfo;
data.append(GetPackGUID());
data.append(damageInfo->target->GetPackGUID());
data << (uint32)(damageInfo->damage); // Full damage
+ data << uint32(int32 (damageInfo->target->GetHealth()-damageInfo->damage ) >0 ? 0 : damageInfo->damage - damageInfo->target->GetHealth()); // Overkill
- data << (uint8)1; // Sub damage count
- //=== Sub damage description
- data << (uint32)(damageInfo->damageSchoolMask); // School of sub damage
- data << (float)damageInfo->damage; // sub damage
- data << (uint32)damageInfo->damage; // Sub Damage
- data << (uint32)damageInfo->absorb; // Absorb
- data << (uint32)damageInfo->resist; // Resist
- //=================================================
- data << (uint32)damageInfo->TargetState;
+ data << (uint8)count; // Sub damage count
+
+ for(int i = 0; i < count; ++i)
+ {
+ data << (uint32)(damageInfo->damageSchoolMask); // School of sub damage
+ data << (float)damageInfo->damage; // sub damage
+ data << (uint32)damageInfo->damage; // Sub Damage
+ }
+
+ if(damageInfo->HitInfo & (HITINFO_ABSORB | HITINFO_ABSORB2))
+ {
+ for(int i = 0; i < count; ++i)
+ data << (uint32)damageInfo->absorb; // Absorb
+ }
+
+ if(damageInfo->HitInfo & (HITINFO_RESIST | HITINFO_RESIST2))
+ {
+ for(int i = 0; i < count; ++i)
+ data << (uint32)damageInfo->resist; // Resist
+ }
+
+ data << (uint8)damageInfo->TargetState;
data << (uint32)0;
data << (uint32)0;
- data << (uint32)damageInfo->blocked_amount;
- SendMessageToSet( &data, true );/**/
+
+ if(damageInfo->HitInfo & HITINFO_BLOCK)
+ data << (uint32)damageInfo->blocked_amount;
+
+ if(damageInfo->HitInfo & HITINFO_UNK3)
+ data << uint32(0);
+
+ if(damageInfo->HitInfo & HITINFO_UNK1)
+ {
+ data << uint32(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ for(uint8 i = 0; i < 5; ++i)
+ {
+ data << float(0);
+ data << float(0);
+ }
+ data << uint32(0);
+ }
+
+ SendMessageToSet( &data, true );
}
void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount)
@@ -4738,176 +4547,77 @@ void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType,
sLog.outDebug("WORLD: Sending SMSG_ATTACKERSTATEUPDATE");
WorldPacket data(SMSG_ATTACKERSTATEUPDATE, (16+45)); // we guess size
- data << (uint32)HitInfo;
+ data << uint32(HitInfo); // flags
data.append(GetPackGUID());
data.append(target->GetPackGUID());
- data << (uint32)(Damage-AbsorbDamage-Resist-BlockedAmount);
+ int32 damageDone = Damage-AbsorbDamage-Resist-BlockedAmount;
+ data << uint32(damageDone);// damage
+ data << uint32(int32 (target->GetHealth()-damageDone ) >0 ? 0 : damageDone - target->GetHealth()); // Overkill
data << (uint8)SwingType; // count?
// for(i = 0; i < SwingType; ++i)
data << (uint32)damageSchoolMask;
- data << (float)(Damage-AbsorbDamage-Resist-BlockedAmount);
- // still need to double check damage
- data << (uint32)(Damage-AbsorbDamage-Resist-BlockedAmount);
- data << (uint32)AbsorbDamage;
- data << (uint32)Resist;
+ data << (float)(damageDone);
+ data << (uint32)(damageDone);
// end loop
- data << (uint32)TargetState;
-
- if( AbsorbDamage == 0 ) //also 0x3E8 = 0x3E8, check when that happens
- data << (uint32)0;
- else
- data << (uint32)-1;
-
- data << (uint32)0;
- data << (uint32)BlockedAmount;
-
- SendMessageToSet( &data, true );
-}
-/*
-void Unit::ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 damage, SpellSchoolMask damageSchoolMask, SpellEntry const *procSpell, bool isTriggeredSpell, WeaponAttackType attType)
-{
- sLog.outDebug("ProcDamageAndSpell: attacker flags are 0x%x, victim flags 0x%x", procAttacker, procVictim);
- if(procSpell)
- sLog.outDebug("ProcDamageAndSpell: invoked due to spell id %u %s", procSpell->Id, (isTriggeredSpell?"(triggered)":""));
-
- // Assign melee/ranged proc flags for magic attacks, that are actually melee/ranged abilities
- // not assign for spell proc triggered spell to prevent infinity (or unexpected 2-3 times) melee damage spell proc call with melee damage effect
- // That is the question though if it's fully correct
- if(procSpell && !isTriggeredSpell)
+ if(HitInfo & (HITINFO_ABSORB | HITINFO_ABSORB2))
{
- if(procSpell->DmgClass == SPELL_DAMAGE_CLASS_MELEE)
- {
- if(procAttacker & PROC_FLAG_HIT_SPELL) procAttacker |= PROC_FLAG_HIT_MELEE;
- if(procAttacker & PROC_FLAG_CRIT_SPELL) procAttacker |= PROC_FLAG_CRIT_MELEE;
- if(procVictim & PROC_FLAG_STRUCK_SPELL) procVictim |= PROC_FLAG_STRUCK_MELEE;
- if(procVictim & PROC_FLAG_STRUCK_CRIT_SPELL) procVictim |= PROC_FLAG_STRUCK_CRIT_MELEE;
- attType = BASE_ATTACK; // Melee abilities are assumed to be dealt with mainhand weapon
- }
- else if (procSpell->DmgClass == SPELL_DAMAGE_CLASS_RANGED)
- {
- if(procAttacker & PROC_FLAG_HIT_SPELL) procAttacker |= PROC_FLAG_HIT_RANGED;
- if(procAttacker & PROC_FLAG_CRIT_SPELL) procAttacker |= PROC_FLAG_CRIT_RANGED;
- if(procVictim & PROC_FLAG_STRUCK_SPELL) procVictim |= PROC_FLAG_STRUCK_RANGED;
- if(procVictim & PROC_FLAG_STRUCK_CRIT_SPELL) procVictim |= PROC_FLAG_STRUCK_CRIT_RANGED;
- attType = RANGED_ATTACK;
- }
+ // for(i = 0; i < SwingType; ++i)
+ data << uint32(AbsorbDamage);
+ // end loop
}
- if(damage && (procVictim & (PROC_FLAG_STRUCK_MELEE|PROC_FLAG_STRUCK_RANGED|PROC_FLAG_STRUCK_SPELL)))
- procVictim |= (PROC_FLAG_TAKE_DAMAGE|PROC_FLAG_TOUCH);
- // Not much to do if no flags are set.
- if (procAttacker)
+ if(HitInfo & (HITINFO_RESIST | HITINFO_RESIST2))
{
- // processing auras that not generate casts at proc event before auras that generate casts to prevent proc aura added at prev. proc aura execute in set
- ProcDamageAndSpellFor(false,pVictim,procAttacker,attackerProcEffectAuraTypes,attType, procSpell, damage, damageSchoolMask);
- ProcDamageAndSpellFor(false,pVictim,procAttacker,attackerProcCastAuraTypes,attType, procSpell, damage, damageSchoolMask);
+ // for(i = 0; i < SwingType; ++i)
+ data << uint32(Resist);
+ // end loop
}
- // Now go on with a victim's events'n'auras
- // Not much to do if no flags are set or there is no victim
- if(pVictim && pVictim->isAlive() && procVictim)
+ data << (uint8)TargetState;
+ data << (uint32)0;
+ data << (uint32)0;
+
+ if(HitInfo & HITINFO_BLOCK)
{
- // processing auras that not generate casts at proc event before auras that generate casts to prevent proc aura added at prev. proc aura execute in set
- pVictim->ProcDamageAndSpellFor(true,this,procVictim,victimProcEffectAuraTypes,attType,procSpell, damage, damageSchoolMask);
- pVictim->ProcDamageAndSpellFor(true,this,procVictim,victimProcCastAuraTypes,attType,procSpell, damage, damageSchoolMask);
+ data << uint32(BlockedAmount);
}
-}
-void Unit::CastMeleeProcDamageAndSpell(Unit* pVictim, uint32 damage, SpellSchoolMask damageSchoolMask, WeaponAttackType attType, MeleeHitOutcome outcome, SpellEntry const *spellCasted, bool isTriggeredSpell)
-{
- if(!pVictim)
- return;
-
- uint32 procAttacker = PROC_FLAG_NONE;
- uint32 procVictim = PROC_FLAG_NONE;
-
- switch(outcome)
+ if(HitInfo & HITINFO_UNK3)
{
- case MELEE_HIT_EVADE:
- return;
- case MELEE_HIT_MISS:
- if(attType == BASE_ATTACK || attType == OFF_ATTACK)
- {
- procAttacker = PROC_FLAG_MISS;
- }
- break;
- case MELEE_HIT_BLOCK_CRIT:
- case MELEE_HIT_CRIT:
- if(spellCasted && attType == BASE_ATTACK)
- {
- procAttacker |= PROC_FLAG_CRIT_SPELL;
- procVictim |= PROC_FLAG_STRUCK_CRIT_SPELL;
- if ( outcome == MELEE_HIT_BLOCK_CRIT )
- {
- procVictim |= PROC_FLAG_BLOCK;
- procAttacker |= PROC_FLAG_TARGET_BLOCK;
- }
- }
- else if(attType == BASE_ATTACK || attType == OFF_ATTACK)
- {
- procAttacker = PROC_FLAG_HIT_MELEE | PROC_FLAG_CRIT_MELEE;
- procVictim = PROC_FLAG_STRUCK_MELEE | PROC_FLAG_STRUCK_CRIT_MELEE;
- }
- else
- {
- procAttacker = PROC_FLAG_HIT_RANGED | PROC_FLAG_CRIT_RANGED;
- procVictim = PROC_FLAG_STRUCK_RANGED | PROC_FLAG_STRUCK_CRIT_RANGED;
- }
- break;
- case MELEE_HIT_PARRY:
- procAttacker = PROC_FLAG_TARGET_DODGE_OR_PARRY;
- procVictim = PROC_FLAG_PARRY;
- break;
- case MELEE_HIT_BLOCK:
- procAttacker = PROC_FLAG_TARGET_BLOCK;
- procVictim = PROC_FLAG_BLOCK;
- break;
- case MELEE_HIT_DODGE:
- procAttacker = PROC_FLAG_TARGET_DODGE_OR_PARRY;
- procVictim = PROC_FLAG_DODGE;
- break;
- case MELEE_HIT_CRUSHING:
- if(attType == BASE_ATTACK || attType == OFF_ATTACK)
- {
- procAttacker = PROC_FLAG_HIT_MELEE | PROC_FLAG_CRIT_MELEE;
- procVictim = PROC_FLAG_STRUCK_MELEE | PROC_FLAG_STRUCK_CRIT_MELEE;
- }
- else
- {
- procAttacker = PROC_FLAG_HIT_RANGED | PROC_FLAG_CRIT_RANGED;
- procVictim = PROC_FLAG_STRUCK_RANGED | PROC_FLAG_STRUCK_CRIT_RANGED;
- }
- break;
- default:
- if(attType == BASE_ATTACK || attType == OFF_ATTACK)
- {
- procAttacker = PROC_FLAG_HIT_MELEE;
- procVictim = PROC_FLAG_STRUCK_MELEE;
- }
- else
- {
- procAttacker = PROC_FLAG_HIT_RANGED;
- procVictim = PROC_FLAG_STRUCK_RANGED;
- }
- break;
+ data << uint32(0);
}
- if(damage > 0)
- procVictim |= PROC_FLAG_TAKE_DAMAGE;
+ if(HitInfo & HITINFO_UNK1)
+ {
+ data << uint32(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ for(uint8 i = 0; i < 5; ++i)
+ {
+ data << float(0);
+ data << float(0);
+ }
+ data << uint32(0);
+ }
- if(procAttacker != PROC_FLAG_NONE || procVictim != PROC_FLAG_NONE)
- ProcDamageAndSpell(pVictim, procAttacker, procVictim, damage, damageSchoolMask, spellCasted, isTriggeredSpell, attType);
-}*/
+ SendMessageToSet( &data, true );
+}
-bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown)
+bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const * procSpell, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown)
{
SpellEntry const *hasteSpell = triggeredByAura->GetSpellProto();
- Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
- ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
+ Item* castItem = triggeredByAura->GetParentAura()->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
+ ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetParentAura()->GetCastItemGUID()) : NULL;
uint32 triggered_spell_id = 0;
Unit* target = pVictim;
@@ -4965,34 +4675,59 @@ bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return true;
}
-bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown)
+bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown)
{
SpellEntry const *dummySpell = triggeredByAura->GetSpellProto ();
- uint32 effIndex = triggeredByAura->GetEffIndex ();
+ uint32 effIndex = triggeredByAura->GetEffIndex();
+ int32 triggerAmount = triggeredByAura->GetAmount();
- Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
- ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
+ Item* castItem = triggeredByAura->GetParentAura()->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
+ ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetParentAura()->GetCastItemGUID()) : NULL;
uint32 triggered_spell_id = 0;
Unit* target = pVictim;
int32 basepoints0 = 0;
+ // Master of subtlety (checked here because ranks have different spellfamilynames)
+ if (dummySpell->Id == 31223 || dummySpell->Id == 31221 || dummySpell->Id == 31222)
+ {
+ if (procEx & AURA_REMOVE_PROC_EX_MASK)
+ triggered_spell_id = 31666;
+ else
+ {
+ triggered_spell_id = 31665;
+ basepoints0 = triggerAmount;
+ }
+ }
switch(dummySpell->SpellFamilyName)
{
case SPELLFAMILY_GENERIC:
{
switch (dummySpell->Id)
{
- // Eye of Eye
+ // Improved Divine Spirit
+ case 33174:
+ case 33182:
+ {
+ // Tricky thing here, we find current aura from spell by caster and change its modifier value
+ int32 spelldmg = CalculateSpellDamage(procSpell, 0, procSpell->EffectBasePoints[0],pVictim);
+ if (AuraEffect * Aur = pVictim->GetAuraEffect(procSpell->Id, effIndex+1, triggeredByAura->GetCasterGUID()))
+ {
+ // Remove aura mods
+ Aur->ApplyModifier(false);
+ Aur->SetAmount(Aur->GetAmount() + spelldmg * triggerAmount / 100);
+ // Apply extended aura mods
+ Aur->ApplyModifier(true);
+ return true;
+ }
+ return false;
+ }
+ // Eye for an Eye
case 9799:
case 25988:
{
- // prevent damage back from weapon special attacks
- if (!procSpell || procSpell->DmgClass != SPELL_DAMAGE_CLASS_MAGIC )
- return false;
-
// return damage % to attacker but < 50% own total health
- basepoints0 = triggeredByAura->GetModifier()->m_amount*int32(damage)/100;
+ basepoints0 = triggerAmount*int32(damage)/100;
if(basepoints0 > GetMaxHealth()/2)
basepoints0 = GetMaxHealth()/2;
@@ -5021,15 +4756,14 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
if (!procSpell || procSpell->Id == 24659)
return false;
// Need remove one 24659 aura
- RemoveSingleAuraFromStack(24659, 0);
- RemoveSingleAuraFromStack(24659, 1);
+ RemoveAuraFromStack(24659);
return true;
}
// Restless Strength
case 24661:
{
// Need remove one 24662 aura
- RemoveSingleAuraFromStack(24662, 0);
+ RemoveAuraFromStack(24662);
return true;
}
// Adaptive Warding (Frostfire Regalia set)
@@ -5040,12 +4774,12 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
// find Mage Armor
bool found = false;
- AuraList const& mRegenInterupt = GetAurasByType(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT);
- for(AuraList::const_iterator iter = mRegenInterupt.begin(); iter != mRegenInterupt.end(); ++iter)
+ AuraEffectList const& mRegenInterupt = GetAurasByType(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT);
+ for(AuraEffectList::const_iterator iter = mRegenInterupt.begin(); iter != mRegenInterupt.end(); ++iter)
{
if(SpellEntry const* iterSpellProto = (*iter)->GetSpellProto())
{
- if(iterSpellProto->SpellFamilyName==SPELLFAMILY_MAGE && (iterSpellProto->SpellFamilyFlags & 0x10000000))
+ if(iterSpellProto->SpellFamilyName==SPELLFAMILY_MAGE && (iterSpellProto->SpellFamilyFlags[0] & 0x10000000))
{
found=true;
break;
@@ -5103,15 +4837,26 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
if(!target)
return false;
- basepoints0 = int32(damage * 2.5f); // manaregen
triggered_spell_id = 34650;
break;
}
+ // Overkill
+ case 58426:
+ {
+ if (procEx & AURA_REMOVE_PROC_EX_MASK)
+ triggered_spell_id = 58428;
+ else
+ {
+ basepoints0 = -triggerAmount;
+ triggered_spell_id = 58427;
+ }
+ break;
+ }
// Mark of Malice
case 33493:
{
// Cast finish spell at last charge
- if (triggeredByAura->m_procCharges > 1)
+ if (triggeredByAura->GetParentAura()->GetAuraCharges() > 1)
return false;
target = this;
@@ -5314,6 +5059,57 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
}
return false;
}
+ // Living Seed
+ case 48504:
+ {
+ triggered_spell_id = 48503;
+ basepoints0 = triggerAmount;
+ target = this;
+ break;
+ }
+ // Kill command
+ case 58914:
+ {
+ // Remove aura stack from pet
+ RemoveAuraFromStack(58914);
+ Unit* owner = GetOwner();
+ if(!owner)
+ return true;
+ // reduce the owner's aura stack
+ owner->RemoveAuraFromStack(34027);
+ return true;
+ }
+ // Vampiric Touch (generic, used by some boss)
+ case 52723:
+ case 60501:
+ {
+ triggered_spell_id = 52724;
+ basepoints0 = damage / 2;
+ target = this;
+ break;
+ }
+ // Divine purpose
+ case 31871:
+ case 31872:
+ {
+ // Roll chane
+ if (!roll_chance_i(triggerAmount))
+ return false;
+
+ // Remove any stun effect on target
+ AuraMap& Auras = pVictim->GetAuras();
+ for(AuraMap::iterator iter = Auras.begin(); iter != Auras.end();)
+ {
+ SpellEntry const *spell = iter->second->GetSpellProto();
+ if( GetAllSpellMechanicMask(spell) & 1<<(MECHANIC_STUN))
+ {
+ pVictim->RemoveAura(iter);
+ }
+ else
+ ++iter;
+ }
+ return true;
+ }
}
break;
}
@@ -5326,7 +5122,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// mana reward
- basepoints0 = (triggeredByAura->GetModifier()->m_amount * GetMaxPower(POWER_MANA) / 100);
+ basepoints0 = (triggerAmount * GetMaxPower(POWER_MANA) / 100);
target = this;
triggered_spell_id = 29442;
break;
@@ -5338,7 +5134,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// mana cost save
- basepoints0 = procSpell->manaCost * triggeredByAura->GetModifier()->m_amount/100;
+ int32 cost = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100;
+ basepoints0 = cost * triggerAmount/100;
if( basepoints0 <=0 )
return false;
@@ -5346,8 +5143,53 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
triggered_spell_id = 29077;
break;
}
+ // Shattered Barrier
+ if (dummySpell->SpellIconID == 2945)
+ {
+ // only on dispel/remove aura by destroy
+ target = NULL;
+ triggered_spell_id = 55080;
+ CastSpell(target, triggered_spell_id, true);
+ return true;
+ }
+ // Hot Streak
+ if (dummySpell->SpellIconID == 2999)
+ {
+ if (effIndex!=0)
+ return false;
+ AuraEffect *counter = GetAuraEffect(triggeredByAura->GetId(), 1);
+ if (!counter)
+ return true;
+
+ // Count spell criticals in a row in second aura
+ if (procEx & PROC_EX_CRITICAL_HIT)
+ {
+ counter->SetAmount(counter->GetAmount()*2);
+ if (counter->GetAmount() < 100) // not enough
+ return true;
+ // Crititcal counted -> roll chance
+ if (roll_chance_i(triggerAmount))
+ CastSpell(this, 48108, true, castItem, triggeredByAura);
+ }
+ counter->SetAmount(25);
+ return true;
+ }
+ // Burnout
+ if (dummySpell->SpellIconID == 2998)
+ {
+ if(!procSpell)
+ return false;
+
+ int32 cost = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100;
+ basepoints0 = cost * triggerAmount/100;
+ if( basepoints0 <=0 )
+ return false;
+ triggered_spell_id = 44450;
+ target = this;
+ break;
+ }
// Incanter's Regalia set (add trigger chance to Mana Shield)
- if (dummySpell->SpellFamilyFlags & 0x0000000000008000LL)
+ if (dummySpell->SpellFamilyFlags[0] & 0x8000)
{
if(GetTypeId() != TYPEID_PLAYER)
return false;
@@ -5384,7 +5226,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case 11129:
{
//last charge and crit
- if (triggeredByAura->m_procCharges <= 1 && (procEx & PROC_EX_CRITICAL_HIT) )
+ if (triggeredByAura->GetParentAura()->GetAuraCharges() <= 1 && (procEx & PROC_EX_CRITICAL_HIT) )
{
RemoveAurasDueToSpell(28682); //-> remove Combustion auras
return true; // charge counting (will removed)
@@ -5399,7 +5241,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case SPELLFAMILY_WARRIOR:
{
// Retaliation
- if(dummySpell->SpellFamilyFlags==0x0000000800000000LL)
+ if(dummySpell->SpellFamilyFlags.IsEqual(0, 0x8, 0))
{
// check attack comes not from behind
if (!HasInArc(M_PI, pVictim))
@@ -5408,26 +5250,51 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
triggered_spell_id = 22858;
break;
}
- else if (dummySpell->SpellIconID == 1697) // Second Wind
+ // Glyph of Devastate
+ if(dummySpell->Id==58388)
+ {
+ // get highest rank of the Sunder Armor spell
+ if (GetTypeId()!=TYPEID_PLAYER)
+ return false;
+ const PlayerSpellMap& sp_list = ((Player*)this)->GetSpellMap();
+ for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
+ {
+ // only highest rank is shown in spell book, so simply check if shown in spell book
+ if(!itr->second->active || itr->second->disabled || itr->second->state == PLAYERSPELL_REMOVED)
+ continue;
+
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
+ if (!spellInfo)
+ continue;
+
+ if (spellInfo->SpellFamilyFlags.IsEqual(SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR)
+ && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR)
+ {
+ triggered_spell_id = spellInfo->Id;
+ break;
+ }
+ }
+ if (!triggered_spell_id)
+ return false;
+ for (int32 value = CalculateSpellDamage(dummySpell, 0 , dummySpell->EffectBasePoints[0], pVictim);value>0;value--)
+ CastSpell(target,triggered_spell_id,true);
+ return true;
+ }
+ // Second Wind
+ if (dummySpell->SpellIconID == 1697)
{
// only for spells and hit/crit (trigger start always) and not start from self casted spells (5530 Mace Stun Effect for example)
if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim)
return false;
// Need stun or root mechanic
- if (procSpell->Mechanic != MECHANIC_ROOT && procSpell->Mechanic != MECHANIC_STUN)
- {
- int32 i;
- for (i=0; i<3; i++)
- if (procSpell->EffectMechanic[i] == MECHANIC_ROOT || procSpell->EffectMechanic[i] == MECHANIC_STUN)
- break;
- if (i == 3)
- return false;
- }
+ if (!(GetAllSpellMechanicMask(procSpell) & ((1<<MECHANIC_ROOT)|(1<<MECHANIC_STUN))))
+ return false;
switch (dummySpell->Id)
{
case 29838: triggered_spell_id=29842; break;
case 29834: triggered_spell_id=29841; break;
+ case 42770: triggered_spell_id=42771; break;
default:
sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (SW)",dummySpell->Id);
return false;
@@ -5436,16 +5303,23 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
target = this;
break;
}
+ // Damage Shield
+ if (dummySpell->SpellIconID == 3214)
+ {
+ triggered_spell_id = 59653;
+ // % of amount blocked
+ basepoints0 = GetShieldBlockValue() * triggerAmount / 100;
+ break;
+ }
break;
}
case SPELLFAMILY_WARLOCK:
{
// Seed of Corruption
- if (dummySpell->SpellFamilyFlags & 0x0000001000000000LL)
+ if (dummySpell->SpellFamilyFlags[1] & 0x00000010)
{
- Modifier* mod = triggeredByAura->GetModifier();
// if damage is more than need or target die from damage deal finish spell
- if( mod->m_amount <= damage || GetHealth() <= damage )
+ if( triggeredByAura->GetAmount() <= damage || GetHealth() <= damage )
{
// remember guid before aura delete
uint64 casterGuid = triggeredByAura->GetCasterGUID();
@@ -5460,15 +5334,14 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
}
// Damage counting
- mod->m_amount-=damage;
+ triggeredByAura->SetAmount(triggeredByAura->GetAmount() - damage);
return true;
}
// Seed of Corruption (Mobs cast) - no die req
- if (dummySpell->SpellFamilyFlags == 0x00LL && dummySpell->SpellIconID == 1932)
+ if (dummySpell->SpellFamilyFlags.IsEqual(0,0,0) && dummySpell->SpellIconID == 1932)
{
- Modifier* mod = triggeredByAura->GetModifier();
// if damage is more than need deal finish spell
- if( mod->m_amount <= damage )
+ if( triggeredByAura->GetAmount() <= damage )
{
// remember guid before aura delete
uint64 casterGuid = triggeredByAura->GetCasterGUID();
@@ -5482,9 +5355,19 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return true; // no hidden cooldown
}
// Damage counting
- mod->m_amount-=damage;
+ triggeredByAura->SetAmount(triggeredByAura->GetAmount() - damage);
return true;
}
+ // Fel Synergy
+ if (dummySpell->SpellIconID == 3222)
+ {
+ target = GetGuardianPet();
+ if (!target)
+ return false;
+ triggered_spell_id = 54181;
+ basepoints0 = damage * 15 / 100;
+ break;
+ }
switch(dummySpell->Id)
{
// Nightfall
@@ -5500,12 +5383,45 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case 30295:
case 30296:
{
+ // Improved Soul Leech
+ AuraEffectList const& SoulLeechAuras = GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraEffectList::const_iterator i = SoulLeechAuras.begin();i != SoulLeechAuras.end(); ++i)
+ {
+ if ((*i)->GetId()==54117 || (*i)->GetId()==54118)
+ {
+ basepoints0 = int32((*i)->GetAmount());
+ if (target = GetGuardianPet())
+ {
+ // regen mana for pet
+ CastCustomSpell(target,54607,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
+ }
+ // regen mana for caster
+ CastCustomSpell(this,59117,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
+ break;
+ }
+ }
// health
- basepoints0 = int32(damage*triggeredByAura->GetModifier()->m_amount/100);
+ basepoints0 = int32(damage*triggerAmount/100);
target = this;
triggered_spell_id = 30294;
break;
}
+ // Improved Fear
+ case 53754:
+ {
+ if(!pVictim || !pVictim->isAlive())
+ return false;
+ pVictim->CastSpell(pVictim, 60946,true);
+ return true;
+ }
+ // Improved Fear (Rank 2)
+ case 53759:
+ {
+ if(!pVictim || !pVictim->isAlive())
+ return false;
+ pVictim->CastSpell(pVictim, 60947,true);
+ return true;
+ }
// Shadowflame (Voidheart Raiment set bonus)
case 37377:
{
@@ -5515,12 +5431,12 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
// Pet Healing (Corruptor Raiment or Rift Stalker Armor)
case 37381:
{
- target = GetPet();
+ target = GetGuardianPet();
if(!target)
return false;
// heal amount
- basepoints0 = damage * triggeredByAura->GetModifier()->m_amount/100;
+ basepoints0 = damage * triggerAmount/100;
triggered_spell_id = 37382;
break;
}
@@ -5536,7 +5452,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case SPELLFAMILY_PRIEST:
{
// Vampiric Touch
- if( dummySpell->SpellFamilyFlags & 0x0000040000000000LL )
+ if( dummySpell->SpellFamilyFlags[1] & 0x00000400 )
{
if(!pVictim || !pVictim->isAlive())
return false;
@@ -5546,10 +5462,17 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// energize amount
- basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100;
+ basepoints0 = triggerAmount*damage/100;
pVictim->CastCustomSpell(pVictim,34919,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
return true; // no hidden cooldown
}
+ // Divine Aegis
+ if (dummySpell->SpellIconID == 2820)
+ {
+ basepoints0 = damage * triggerAmount/100;
+ triggered_spell_id = 47753;
+ break;
+ }
switch(dummySpell->Id)
{
// Vampiric Embrace
@@ -5563,18 +5486,19 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// heal amount
- basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100;
- pVictim->CastCustomSpell(pVictim,15290,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
+ int32 team = triggerAmount*damage/500;
+ int32 self = triggerAmount*damage/100 - team;
+ pVictim->CastCustomSpell(pVictim,15290,&team,&self,NULL,true,castItem,triggeredByAura);
return true; // no hidden cooldown
}
// Priest Tier 6 Trinket (Ashtongue Talisman of Acumen)
case 40438:
{
// Shadow Word: Pain
- if( procSpell->SpellFamilyFlags & 0x0000000000008000LL )
+ if( procSpell->SpellFamilyFlags[0] & 0x8000 )
triggered_spell_id = 40441;
// Renew
- else if( procSpell->SpellFamilyFlags & 0x0000000000000010LL )
+ else if( procSpell->SpellFamilyFlags[0] & 0x10 )
triggered_spell_id = 40440;
else
return false;
@@ -5582,6 +5506,50 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
target = this;
break;
}
+ // Glyph of Power Word: Shield
+ case 55672:
+ {
+ basepoints0 = damage * triggerAmount/100;
+ triggered_spell_id = 56160;
+ break;
+ }
+ // Improved Shadowform
+ case 47570:
+ case 47569:
+ {
+ RemoveAurasByTypeWithDispel(SPELL_AURA_MOD_ROOT);
+ RemoveAurasByTypeWithDispel(SPELL_AURA_MOD_DECREASE_SPEED);
+ break;
+ }
+ // Psychic Horror
+ case 47571:
+ {
+ if(!pVictim || !pVictim->isAlive())
+ return false;
+ pVictim->CastSpell(pVictim, 59980,true);
+ return true;
+ }
+ // Psychic Horror (Rank 2)
+ case 47572:
+ {
+ if(!pVictim || !pVictim->isAlive())
+ return false;
+ pVictim->CastSpell(pVictim, 59981,true);
+ return true;
+ }
+ // Glyph of Dispel Magic
+ case 55677:
+ {
+ // Dispel Magic shares spellfamilyflag with abolish disease
+ if (procSpell->SpellIconID!=74)
+ return false;
+ if(!target->IsFriendlyTo(this))
+ return false;
+
+ basepoints0 = int32(target->GetMaxHealth() * triggerAmount / 100);
+ triggered_spell_id = 56131;
+ break;
+ }
// Oracle Healing Bonus ("Garments of the Oracle" set)
case 26169:
{
@@ -5598,12 +5566,12 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// heal amount
- basepoints0 = int32(damage * 2 / 100);
+ basepoints0 = damage * triggerAmount/100;
target = this;
triggered_spell_id = 39373;
break;
}
- // Vestments of Faith (Priest Tier 3) - 4 pieces bonus
+ // Greater Heal (Vestments of Faith (Priest Tier 3) - 4 pieces bonus)
case 28809:
{
triggered_spell_id = 28810;
@@ -5616,6 +5584,20 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
{
switch(dummySpell->Id)
{
+ // Leader of the Pack
+ case 24932:
+ {
+ if (triggerAmount <= 0)
+ return false;
+ basepoints0 = triggerAmount * GetMaxHealth() / 100;
+ target = this;
+ triggered_spell_id = 34299;
+ if (triggeredByAura->GetCaster() != this)
+ break;
+ int32 basepoints1 = triggerAmount * 2;
+ CastCustomSpell(this,60889,&basepoints1,0,0,true,0,triggeredByAura);
+ break;
+ }
// Healing Touch (Dreamwalker Raiment set)
case 28719:
{
@@ -5625,6 +5607,15 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
triggered_spell_id = 28742;
break;
}
+ // Glyph of Rejuvenation
+ case 54754:
+ {
+ if (pVictim->GetHealth() >= triggerAmount * pVictim->GetMaxHealth()/100)
+ return false;
+ basepoints0 = int32(triggerAmount * damage / 100);
+ triggered_spell_id = 54755;
+ break;
+ }
// Healing Touch Refund (Idol of Longevity trinket)
case 28847:
{
@@ -5646,19 +5637,19 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
float chance;
// Starfire
- if( procSpell->SpellFamilyFlags & 0x0000000000000004LL )
+ if( procSpell->SpellFamilyFlags[0] & 0x4 )
{
triggered_spell_id = 40445;
chance = 25.f;
}
// Rejuvenation
- else if( procSpell->SpellFamilyFlags & 0x0000000000000010LL )
+ else if( procSpell->SpellFamilyFlags[0] & 0x10 )
{
triggered_spell_id = 40446;
chance = 25.f;
}
// Mangle (cat/bear)
- else if( procSpell->SpellFamilyFlags & 0x0000044000000000LL )
+ else if( procSpell->SpellFamilyFlags[1] & 0x00000440)
{
triggered_spell_id = 40452;
chance = 40.f;
@@ -5680,6 +5671,39 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
break;
}
}
+ // Eclipse
+ if (dummySpell->SpellIconID == 2856)
+ {
+ if (!procSpell)
+ return false;
+ // Only 0 aura can proc
+ if (effIndex!=0)
+ return false;
+ // Wrath crit
+ if (procSpell->SpellFamilyFlags[0] & 0x1)
+ {
+ if (!roll_chance_i(60))
+ return false;
+ triggered_spell_id = 48518;
+ target = this;
+ break;
+ }
+ // Starfire crit
+ if (procSpell->SpellFamilyFlags[0] & 0x4)
+ {
+ triggered_spell_id = 48517;
+ target = this;
+ break;
+ }
+ return false;
+ }
+ // Living Seed
+ else if (dummySpell->SpellIconID == 2860)
+ {
+ triggered_spell_id = 48504;
+ basepoints0 = triggerAmount * damage / 100;
+ break;
+ }
break;
}
case SPELLFAMILY_ROGUE:
@@ -5697,19 +5721,32 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
break;
}
}
+ // Cut to the Chase
+ if( dummySpell->SpellIconID == 2909 )
+ {
+ // "refresh your Slice and Dice duration to its 5 combo point maximum"
+ // lookup Slice and Dice
+ if (AuraEffect * aur = GetAura(SPELL_AURA_MOD_HASTE, SPELLFAMILY_ROGUE,0x40000, 0, 0))
+ {
+ aur->GetParentAura()->SetAuraDuration(GetSpellMaxDuration(aur->GetSpellProto()));
+ return true;
+ }
+ return false;
+ }
+ // Deadly Brew
+ else if( dummySpell->SpellIconID == 2963 )
+ {
+ triggered_spell_id = 3409;
+ break;
+ }
// Quick Recovery
- if( dummySpell->SpellIconID == 2116 )
+ else if( dummySpell->SpellIconID == 2116 )
{
if(!procSpell)
return false;
- // only rogue's finishing moves (maybe need additional checks)
- if( procSpell->SpellFamilyName!=SPELLFAMILY_ROGUE ||
- (procSpell->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE) == 0)
- return false;
-
// energy cost save
- basepoints0 = procSpell->manaCost * triggeredByAura->GetModifier()->m_amount/100;
+ basepoints0 = procSpell->manaCost * triggerAmount/100;
if(basepoints0 <= 0)
return false;
@@ -5728,7 +5765,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// mana cost save
- basepoints0 = procSpell->manaCost * 40/100;
+ int32 mana = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100;
+ basepoints0 = mana * 40/100;
if(basepoints0 <= 0)
return false;
@@ -5736,75 +5774,142 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
triggered_spell_id = 34720;
break;
}
+ // Hunting Party
+ if ( dummySpell->SpellIconID == 3406 )
+ {
+ triggered_spell_id = 57669;
+ target = this;
+ break;
+ }
+ // Lock and Load
+ if ( dummySpell->SpellIconID == 3579 )
+ {
+ // Proc only from periodic (from trap activation proc another aura of this spell)
+ if (!(procFlag & PROC_FLAG_ON_DO_PERIODIC) || !roll_chance_i(triggerAmount))
+ return false;
+ triggered_spell_id = 56453;
+ target = this;
+ break;
+ }
+ // Rapid Recuperation
+ if ( dummySpell->SpellIconID == 3560 )
+ {
+ // This effect only from Rapid Killing (mana regen)
+ if (!(procSpell->SpellFamilyFlags[1] & 0x01000000))
+ return false;
+ triggered_spell_id = 56654;
+ target = this;
+ break;
+ }
break;
}
case SPELLFAMILY_PALADIN:
{
- // Seal of Righteousness - melee proc dummy
- if (dummySpell->SpellFamilyFlags&0x000000008000000LL && triggeredByAura->GetEffIndex()==0)
+ // Seal of Righteousness - melee proc dummy (addition ${$MWS*(0.022*$AP+0.044*$SPH)} damage)
+ if (dummySpell->SpellFamilyFlags[0]&0x8000000)
{
- if(GetTypeId() != TYPEID_PLAYER)
+ if (effIndex!=0)
return false;
-
- uint32 spellId;
- switch (triggeredByAura->GetId())
- {
- case 21084: spellId = 25742; break; // Rank 1
- case 20287: spellId = 25740; break; // Rank 2
- case 20288: spellId = 25739; break; // Rank 3
- case 20289: spellId = 25738; break; // Rank 4
- case 20290: spellId = 25737; break; // Rank 5
- case 20291: spellId = 25736; break; // Rank 6
- case 20292: spellId = 25735; break; // Rank 7
- case 20293: spellId = 25713; break; // Rank 8
- case 27155: spellId = 27156; break; // Rank 9
- default:
- sLog.outError("Unit::HandleDummyAuraProc: non handled possibly SoR (Id = %u)", triggeredByAura->GetId());
- return false;
- }
- Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
- float speed = (item ? item->GetProto()->Delay : BASE_ATTACK_TIME)/1000.0f;
-
- float damageBasePoints;
- if(item && item->GetProto()->InventoryType == INVTYPE_2HWEAPON)
- // two hand weapon
- damageBasePoints=1.20f*triggeredByAura->GetModifier()->m_amount * 1.2f * 1.03f * speed/100.0f + 1;
- else
- // one hand weapon/no weapon
- damageBasePoints=0.85f*ceil(triggeredByAura->GetModifier()->m_amount * 1.2f * 1.03f * speed/100.0f) - 1;
-
- int32 damagePoint = int32(damageBasePoints + 0.03f * (GetWeaponDamageRange(BASE_ATTACK,MINDAMAGE)+GetWeaponDamageRange(BASE_ATTACK,MAXDAMAGE))/2.0f) + 1;
-
- // apply damage bonuses manually
- if(damagePoint >= 0)
- damagePoint = SpellDamageBonus(pVictim, dummySpell, damagePoint, SPELL_DIRECT_DAMAGE);
-
- CastCustomSpell(pVictim,spellId,&damagePoint,NULL,NULL,true,NULL, triggeredByAura);
- return true; // no hidden cooldown
+ triggered_spell_id = 25742;
+ float ap = GetTotalAttackPowerValue(BASE_ATTACK);
+ int32 holy = SpellBaseDamageBonus(SPELL_SCHOOL_MASK_HOLY) +
+ SpellBaseDamageBonusForVictim(SPELL_SCHOOL_MASK_HOLY, pVictim);
+ basepoints0 = GetAttackTime(BASE_ATTACK) * int32(ap*0.022f + 0.044f * holy) / 1000;
+ break;
}
- // Seal of Blood do damage trigger
- if(dummySpell->SpellFamilyFlags & 0x0000040000000000LL)
+ // Light's Beacon - Beacon of Light
+ if ( dummySpell->Id == 53651 )
{
- switch(triggeredByAura->GetEffIndex())
+ if (Unit * caster = triggeredByAura->GetCaster())
{
- case 0:
- triggered_spell_id = 31893;
- break;
- case 1:
+ // do not proc when target of beacon of light is healed
+ if (caster == pVictim)
+ return false;
+ if (Aura * aur = caster->GetAura(53563))
{
- // damage
- damage += CalculateDamage(BASE_ATTACK, false) * 35 / 100; // add spell damage from prev effect (35%)
- basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100;
-
- target = this;
- triggered_spell_id = 32221;
- break;
+ if (Unit * paladin = aur->GetCaster())
+ {
+ if (paladin != this)
+ return false;
+ basepoints0 = damage;
+ triggered_spell_id = 53654;
+ target = caster;
+ break;
+ }
+ else
+ {
+ pVictim->RemoveAura(triggeredByAura->GetParentAura());
+ return false;
+ }
}
}
+ else return false;
+ }
+ // Judgements of the Wise
+ if (dummySpell->SpellIconID == 3017)
+ {
+ // hardcoded amount
+ basepoints0 = 15 * GetCreatePowers(POWER_MANA)/100;
+ target = this;
+ triggered_spell_id = 31930;
+ // replenishment
+ CastSpell(this,57669,true);
+ break;
+ }
+ // Sanctified Wrath
+ if (dummySpell->SpellIconID == 3029)
+ {
+ triggered_spell_id = 57318;
+ target = this;
+ basepoints0 = triggerAmount;
+ CastCustomSpell(target,triggered_spell_id,&basepoints0,&basepoints0,NULL,true,castItem,triggeredByAura);
+ return true;
+ }
+ // Sacred Shield
+ if (dummySpell->SpellFamilyFlags[1]&0x00080000)
+ {
+ triggered_spell_id = 58597;
+ target = this;
+ break;
+ }
+ // Righteous Vengeance
+ if (dummySpell->SpellIconID == 3025)
+ {
+ // 4 damage tick
+ basepoints0 = triggerAmount*damage/400;
+ triggered_spell_id = 61840;
+ break;
+ }
+ // Sheath of Light
+ if (dummySpell->SpellIconID == 3030)
+ {
+ // 4 healing tick
+ basepoints0 = triggerAmount*damage/400;
+ triggered_spell_id = 54203;
+ break;
}
-
switch(dummySpell->Id)
{
+ // Judgement of Light
+ case 20185:
+ {
+ // Get judgement caster
+ Unit *caster = triggeredByAura->GetCaster();
+ if (!caster)
+ return false;
+ float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
+ int32 holy = caster->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_HOLY) +
+ caster->SpellBaseDamageBonusForVictim(SPELL_SCHOOL_MASK_HOLY, this);
+ basepoints0 = int32(ap*0.10f + 0.10f*holy);
+ pVictim->CastCustomSpell(pVictim, 20267, &basepoints0, 0, 0, true, 0, triggeredByAura);
+ return true;
+ }
+ // Judgement of Wisdom
+ case 20186:
+ {
+ pVictim->CastSpell(pVictim, 20268, true, NULL, triggeredByAura);
+ return true;
+ }
// Holy Power (Redemption Armor set)
case 28789:
{
@@ -5836,7 +5941,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
}
break;
}
- //Seal of Vengeance
+ // Seal of Vengeance (damage calc on apply aura)
case 31801:
{
if(effIndex != 0) // effect 1,2 used by seal unleashing code
@@ -5845,7 +5950,16 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
triggered_spell_id = 31803;
break;
}
- // Spiritual Att.
+ // Seal of Corruption
+ case 53736:
+ {
+ if(effIndex != 0) // effect 1,2 used by seal unleashing code
+ return false;
+
+ triggered_spell_id = 53742;
+ break;
+ }
+ // Spiritual Attunement
case 31785:
case 33776:
{
@@ -5854,11 +5968,45 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// heal amount
- basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100;
+ basepoints0 = triggerAmount*damage/100;
target = this;
triggered_spell_id = 31786;
break;
}
+ // Seal of Blood do damage trigger
+ case 31892:
+ {
+ if (effIndex == 0) // 0 effect - is proc on enemy
+ triggered_spell_id = 31893;
+ else if (effIndex == 1) // 1 effect - is proc on self
+ {
+ // add spell damage from prev effect (27%)
+ damage += CalculateDamage(BASE_ATTACK, false) * 27 / 100;
+ basepoints0 = triggerAmount * damage / 100;
+ target = this;
+ triggered_spell_id = 32221;
+ }
+ else
+ return false;
+ break;
+ }
+ // Seal of the Martyr do damage trigger
+ case 53720:
+ {
+ if (effIndex == 0) // 0 effect - is proc on enemy
+ triggered_spell_id = 53719;
+ else if (effIndex == 1) // 1 effect - is proc on self
+ {
+ // add spell damage from prev effect (27%)
+ damage += CalculateDamage(BASE_ATTACK, false) * 27 / 100;
+ basepoints0 = triggerAmount * damage / 100;
+ target = this;
+ triggered_spell_id = 53718;
+ }
+ else
+ return false;
+ break;
+ }
// Paladin Tier 6 Trinket (Ashtongue Talisman of Zeal)
case 40470:
{
@@ -5868,13 +6016,13 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
float chance;
// Flash of light/Holy light
- if( procSpell->SpellFamilyFlags & 0x00000000C0000000LL)
+ if( procSpell->SpellFamilyFlags[0] & 0xC0000000)
{
triggered_spell_id = 40471;
chance = 15.f;
}
// Judgement
- else if( procSpell->SpellFamilyFlags & 0x0000000000800000LL )
+ else if( procSpell->SpellFamilyFlags[0] & 0x800000 )
{
triggered_spell_id = 40472;
chance = 50.f;
@@ -5887,6 +6035,33 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
break;
}
+ // Glyph of Divinity
+ case 54939:
+ {
+ // Lookup base amount mana restore
+ for (int i=0; i<3;i++)
+ if (procSpell->Effect[i] == SPELL_EFFECT_ENERGIZE)
+ {
+ int32 mana = procSpell->EffectBasePoints[i];
+ CastCustomSpell(this, 54986, 0, &mana, 0, true, castItem, triggeredByAura);
+ break;
+ }
+ return true;
+ }
+ // Glyph of Flash of Light
+ case 54936:
+ {
+ triggered_spell_id = 54957;
+ basepoints0 = triggerAmount*damage/100;
+ break;
+ }
+ // Glyph of Holy Light
+ case 54937:
+ {
+ triggered_spell_id = 54968;
+ basepoints0 = triggerAmount*damage/100;
+ break;
+ }
}
break;
}
@@ -5894,6 +6069,20 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
{
switch(dummySpell->Id)
{
+ // Improved fire nova totem
+ case 16544:
+ {
+ triggered_spell_id = 51880;
+ break;
+ }
+ // Tidal Force
+ case 55198:
+ {
+ // Remove aura stack from caster
+ RemoveAuraFromStack(55166);
+ // drop charges
+ return false;
+ }
// Totemic Power (The Earthshatterer set)
case 28823:
{
@@ -5945,14 +6134,19 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
if( cooldown && ((Player*)this)->HasSpellCooldown(dummySpell->Id))
return false;
+ // Now amount of extra power stored in 1 effect of Enchant spell
+ // Get it by item enchant id
uint32 spellId;
switch (castItem->GetEnchantmentId(EnchantmentSlot(TEMP_ENCHANTMENT_SLOT)))
{
- case 283: spellId = 33757; break; //1 Rank
- case 284: spellId = 33756; break; //2 Rank
- case 525: spellId = 33755; break; //3 Rank
- case 1669:spellId = 33754; break; //4 Rank
- case 2636:spellId = 33727; break; //5 Rank
+ case 283: spellId = 8232; break; // 1 Rank
+ case 284: spellId = 8235; break; // 2 Rank
+ case 525: spellId = 10486; break; // 3 Rank
+ case 1669:spellId = 16362; break; // 4 Rank
+ case 2636:spellId = 25505; break; // 5 Rank
+ case 3785:spellId = 58801; break; // 6 Rank
+ case 3786:spellId = 58803; break; // 7 Rank
+ case 3787:spellId = 58804; break; // 8 Rank
default:
{
sLog.outError("Unit::HandleDummyAuraProc: non handled item enchantment (rank?) %u for spell id: %u (Windfury)",
@@ -5968,7 +6162,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
}
- int32 extra_attack_power = CalculateSpellDamage(windfurySpellEntry,0,windfurySpellEntry->EffectBasePoints[0],pVictim);
+ int32 extra_attack_power = CalculateSpellDamage(windfurySpellEntry, 1, windfurySpellEntry->EffectBasePoints[1], pVictim);
// Off-Hand case
if ( castItem->GetSlot() == EQUIPMENT_SLOT_OFFHAND )
@@ -6002,17 +6196,17 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
float chance;
- if (procSpell->SpellFamilyFlags & 0x0000000000000001LL)
+ if (procSpell->SpellFamilyFlags[0] & 0x1)
{
triggered_spell_id = 40465; // Lightning Bolt
chance = 15.f;
}
- else if (procSpell->SpellFamilyFlags & 0x0000000000000080LL)
+ else if (procSpell->SpellFamilyFlags[0] & 0x80)
{
triggered_spell_id = 40465; // Lesser Healing Wave
chance = 10.f;
}
- else if (procSpell->SpellFamilyFlags & 0x0000001000000000LL)
+ else if (procSpell->SpellFamilyFlags[1] & 0x00000010)
{
triggered_spell_id = 40466; // Stormstrike
chance = 50.f;
@@ -6026,20 +6220,68 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
target = this;
break;
}
+ // Glyph of Healing Wave
+ case 55440:
+ {
+ // Not proc from self heals
+ if (this==pVictim)
+ return false;
+ basepoints0 = triggerAmount * damage / 100;
+ target = this;
+ triggered_spell_id = 55533;
+ break;
+ }
+ // Spirit Hunt
+ case 58877:
+ {
+ // Cast on owner
+ target = GetOwner();
+ if(!target)
+ return false;
+ basepoints0 = triggerAmount * damage / 100;
+ triggered_spell_id = 58879;
+ break;
+ }
+ }
+ // Ancestral Awakening
+ if (dummySpell->SpellIconID == 3065)
+ {
+ // TODO: frite dummy fot triggered spell
+ triggered_spell_id = 52759;
+ basepoints0 = triggerAmount * damage / 100;
+ target = this;
+ break;
}
-
// Earth Shield
- if(dummySpell->SpellFamilyFlags==0x40000000000LL)
+ if(dummySpell->SpellFamilyFlags[1] & 0x00000400)
{
- if(GetTypeId() != TYPEID_PLAYER)
- return false;
-
- // heal
- basepoints0 = triggeredByAura->GetModifier()->m_amount;
+ basepoints0 = triggerAmount;
target = this;
triggered_spell_id = 379;
break;
}
+ // Improved Water Shield
+ if (dummySpell->SpellIconID == 2287)
+ {
+ // Lesser Healing Wave need aditional 60% roll
+ if (procSpell->SpellFamilyFlags[0] & 0x80 && !roll_chance_i(60))
+ return false;
+ // lookup water shield
+ AuraEffectList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL);
+ for(AuraEffectList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr)
+ {
+ if( (*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN &&
+ (*itr)->GetSpellProto()->SpellFamilyFlags[1] & 0x00000020)
+ {
+ uint32 spell = (*itr)->GetSpellProto()->EffectTriggerSpell[(*itr)->GetEffIndex()];
+ CastSpell(this, spell, true, castItem, triggeredByAura);
+ (*itr)->GetParentAura()->DropAuraCharge();
+ return true;
+ }
+ }
+ return false;
+ break;
+ }
// Lightning Overload
if (dummySpell->SpellIconID == 2018) // only this spell have SpellFamily Shaman SpellIconID == 2018 and dummy aura
{
@@ -6067,6 +6309,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case 15208: spellId = 45294; break; // Rank 10
case 25448: spellId = 45295; break; // Rank 11
case 25449: spellId = 45296; break; // Rank 12
+ case 49237: spellId = 49239; break; // Rank 13
+ case 49238: spellId = 49240; break; // Rank 14
// Chain Lightning
case 421: spellId = 45297; break; // Rank 1
case 930: spellId = 45298; break; // Rank 2
@@ -6074,44 +6318,152 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case 10605: spellId = 45300; break; // Rank 4
case 25439: spellId = 45301; break; // Rank 5
case 25442: spellId = 45302; break; // Rank 6
+ case 49268: spellId = 49270; break; // Rank 7
+ case 49269: spellId = 49271; break; // Rank 8
default:
sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (LO)", procSpell->Id);
return false;
}
- // No thread generated mod
- SpellModifier *mod = new SpellModifier;
- mod->op = SPELLMOD_THREAT;
- mod->value = -100;
- mod->type = SPELLMOD_PCT;
- mod->spellId = dummySpell->Id;
- mod->effectId = 0;
- mod->lastAffected = NULL;
- mod->mask = 0x0000000000000003LL;
- mod->charges = 0;
- ((Player*)this)->AddSpellMod(mod, true);
-
- // Remove cooldown (Chain Lightning - have Category Recovery time)
- if (procSpell->SpellFamilyFlags & 0x0000000000000002LL)
- ((Player*)this)->RemoveSpellCooldown(spellId);
-
- // Hmmm.. in most case spells already set half basepoints but...
- // Lightning Bolt (2-10 rank) have full basepoint and half bonus from level
- // As on wiki:
- // BUG: Rank 2 to 10 (and maybe 11) of Lightning Bolt will proc another Bolt with FULL damage (not halved). This bug is known and will probably be fixed soon.
- // So - no add changes :)
- CastSpell(pVictim, spellId, true, castItem, triggeredByAura);
+ // Apply spellmod
+ CastSpell(this, 39805, true, castItem, triggeredByAura);
- ((Player*)this)->AddSpellMod(mod, false);
-
- if( cooldown && GetTypeId()==TYPEID_PLAYER )
- ((Player*)this)->AddSpellCooldown(dummySpell->Id,0,time(NULL) + cooldown);
+ CastSpell(pVictim, spellId, true, castItem, triggeredByAura);
return true;
}
+ // Static Shock
+ if(dummySpell->SpellIconID == 3059)
+ {
+ // lookup Lightning Shield
+ AuraEffectList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL);
+ for(AuraEffectList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr)
+ {
+ if( (*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN &&
+ (*itr)->GetSpellProto()->SpellFamilyFlags[0] & 0x400)
+ {
+ uint32 spell = 0;
+ switch ((*itr)->GetId())
+ {
+ case 324: spell = 26364; break;
+ case 325: spell = 26365; break;
+ case 905: spell = 26366; break;
+ case 945: spell = 26367; break;
+ case 8134: spell = 26369; break;
+ case 10431: spell = 26370; break;
+ case 10432: spell = 26363; break;
+ case 25469: spell = 26371; break;
+ case 25472: spell = 26372; break;
+ case 49280: spell = 49278; break;
+ case 49281: spell = 49279; break;
+ default:
+ return false;
+ }
+ CastSpell(this, spell, true, castItem, triggeredByAura);
+ (*itr)->GetParentAura()->DropAuraCharge();
+ return true;
+ }
+ }
+ return false;
+ break;
+ }
+ break;
+ }
+ case SPELLFAMILY_DEATHKNIGHT:
+ {
+ // Blood Aura
+ if (dummySpell->SpellIconID == 2636)
+ {
+ if (GetTypeId() != TYPEID_PLAYER || !((Player*)this)->isHonorOrXPTarget(pVictim))
+ return false;
+ basepoints0 = triggerAmount * damage / 100;
+ triggered_spell_id = 53168;
+ break;
+ }
+ // Butchery
+ if (dummySpell->SpellIconID == 2664)
+ {
+ basepoints0 = triggerAmount;
+ triggered_spell_id = 50163;
+ target = this;
+ break;
+ }
+ // Dancing Rune Weapon
+ if (dummySpell->Id == 49028)
+ {
+ // 1 dummy aura for dismiss rune blade
+ if (effIndex!=2)
+ return false;
+ // TODO: wite script for this "fights on its own, doing the same attacks"
+ // NOTE: Trigger here on every attack and spell cast
+ return false;
+ }
+ // Mark of Blood
+ if (dummySpell->Id == 49005)
+ {
+ // TODO: need more info (cooldowns/PPM)
+ triggered_spell_id = 50424;
+ break;
+ }
+ // Vendetta
+ if (dummySpell->SpellFamilyFlags[0] & 0x10000)
+ {
+ basepoints0 = triggerAmount * GetMaxHealth() / 100;
+ triggered_spell_id = 50181;
+ target = this;
+ break;
+ }
+ // Necrosis
+ if (dummySpell->SpellIconID == 2709)
+ {
+ basepoints0 = triggerAmount * damage / 100;
+ triggered_spell_id = 51460;
+ break;
+ }
+ // Runic Power Back on Snare/Root
+ if (dummySpell->Id == 61257)
+ {
+ // only for spells and hit/crit (trigger start always) and not start from self casted spells
+ if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim)
+ return false;
+ // Need snare or root mechanic
+ if (!(GetAllSpellMechanicMask(procSpell) & ((1<<MECHANIC_ROOT)|(1<<MECHANIC_SNARE))))
+ return false;
+ triggered_spell_id = 61258;
+ target = this;
+ break;
+ }
+ // Wandering Plague
+ if (dummySpell->SpellIconID == 1614)
+ {
+ if (!roll_chance_f(GetUnitCriticalChance(BASE_ATTACK, pVictim)))
+ return false;
+ basepoints0 = triggerAmount * damage / 100;
+ triggered_spell_id = 50526;
+ break;
+ }
+ // Death Strike healing effect
+ if (dummySpell->Id == 45469)
+ {
+ uint8 n=0;
+ Unit::AuraEffectList const& decSpeedList = pVictim->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
+ for(Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
+ {
+ if((*iter)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_DEATHKNIGHT
+ && (*iter)->GetCasterGUID() == GetGUID()
+ && (*iter)->GetSpellProto()->Dispel == DISPEL_DISEASE)
+ {
+ n++;
+ }
+ }
+ int32 heal=0.5f*n*damage+damage;
+ CastCustomSpell(this,45470,&heal,NULL,NULL,true);
+ return true;
+ }
break;
}
case SPELLFAMILY_POTION:
{
+ // alchemist's stone
if (dummySpell->Id == 17619)
{
if (procSpell->SpellFamilyName == SPELLFAMILY_POTION)
@@ -6126,13 +6478,35 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
{
triggered_spell_id = 21400;
}
- else continue;
+ else
+ continue;
+
basepoints0 = CalculateSpellDamage(procSpell,i,procSpell->EffectBasePoints[i],this) * 0.4f;
- CastCustomSpell(this,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
+ CastCustomSpell(this,triggered_spell_id,&basepoints0,NULL,NULL,true,NULL,triggeredByAura);
}
return true;
}
}
+ break;
+ }
+ case SPELLFAMILY_PET:
+ {
+ // improved cower
+ if (dummySpell->SpellIconID == 958 && procSpell->SpellIconID == 958)
+ {
+ triggered_spell_id = dummySpell->Id == 53180 ? 54200 : 54201;
+ target = this;
+ break;
+ }
+ // guard dog
+ if (dummySpell->SpellIconID == 201 && procSpell->SpellIconID == 201)
+ {
+ triggered_spell_id = 54445;
+ target = this;
+ pVictim->AddThreat(this,procSpell->EffectBasePoints[0]*triggerAmount/100);
+ break;
+ }
+ break;
}
default:
break;
@@ -6167,1172 +6541,632 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return true;
}
-/*
-bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags,WeaponAttackType attackType, uint32 cooldown)
+
+bool Unit::HandleObsModEnergyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown)
{
- SpellEntry const* auraSpellInfo = triggeredByAura->GetSpellProto();
+ SpellEntry const *dummySpell = triggeredByAura->GetSpellProto ();
+ uint32 effIndex = triggeredByAura->GetEffIndex();
+ int32 triggerAmount = triggeredByAura->GetAmount();
- Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
- ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
+ Item* castItem = triggeredByAura->GetParentAura()->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
+ ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetParentAura()->GetCastItemGUID()) : NULL;
- uint32 triggered_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()];
- Unit* target = !(procFlags & PROC_FLAG_HEAL) && IsPositiveSpell(triggered_spell_id) ? this : pVictim;
+ uint32 triggered_spell_id = 0;
+ Unit* target = pVictim;
int32 basepoints0 = 0;
- switch(auraSpellInfo->SpellFamilyName)
+ switch(dummySpell->SpellFamilyName)
{
- case SPELLFAMILY_GENERIC:
+ case SPELLFAMILY_HUNTER:
{
- switch(auraSpellInfo->Id)
+ // Aspect of the Viper
+ if ( dummySpell->SpellFamilyFlags[1] & 0x40000 )
{
- // Aegis of Preservation
- case 23780:
- //Aegis Heal (instead non-existed triggered spell)
- triggered_spell_id = 23781;
- target = this;
- break;
- // Elune's Touch (moonkin mana restore)
- case 24905:
- {
- // Elune's Touch (instead non-existed triggered spell)
- triggered_spell_id = 33926;
- basepoints0 = int32(0.3f * GetTotalAttackPowerValue(BASE_ATTACK));
- target = this;
- break;
- }
- // Enlightenment
- case 29601:
+ uint32 maxmana = GetMaxPower(POWER_MANA);
+ basepoints0 = maxmana* GetAttackTime(RANGED_ATTACK)/1000.0f/100.0f;
+
+ target = this;
+ triggered_spell_id = 34075;
+ break;
+ }
+ break;
+ }
+ }
+ // processed charge only counting case
+ if(!triggered_spell_id)
+ return true;
+
+ SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id);
+
+ if(!triggerEntry)
+ {
+ sLog.outError("Unit::HandleObsModEnergyAuraProc: Spell %u have not existed triggered spell %u",dummySpell->Id,triggered_spell_id);
+ return false;
+ }
+
+ // default case
+ if(!target || target!=this && !target->isAlive())
+ return false;
+
+ if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id))
+ return false;
+
+ if(basepoints0)
+ CastCustomSpell(target,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
+ else
+ CastSpell(target,triggered_spell_id,true,castItem,triggeredByAura);
+
+ if( cooldown && GetTypeId()==TYPEID_PLAYER )
+ ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown);
+
+ return true;
+}
+
+bool Unit::HandleModDamagePctTakenAuraProc(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown)
+{
+ SpellEntry const *dummySpell = triggeredByAura->GetSpellProto ();
+ uint32 effIndex = triggeredByAura->GetEffIndex();
+ int32 triggerAmount = triggeredByAura->GetAmount();
+
+ Item* castItem = triggeredByAura->GetParentAura()->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
+ ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetParentAura()->GetCastItemGUID()) : NULL;
+
+ uint32 triggered_spell_id = 0;
+ Unit* target = pVictim;
+ int32 basepoints0 = 0;
+
+ switch(dummySpell->SpellFamilyName)
+ {
+ case SPELLFAMILY_PALADIN:
+ {
+ // Blessing of Sanctuary
+ if ( dummySpell->SpellFamilyFlags[0] & 0x10000000 )
+ {
+ switch (getPowerType())
{
- // only for cast with mana price
- if(!procSpell || procSpell->powerType!=POWER_MANA || procSpell->manaCost==0 && procSpell->ManaCostPercentage==0 && procSpell->manaCostPerlevel==0)
+ case POWER_MANA: triggered_spell_id = 57319; break;
+ case POWER_RAGE: triggered_spell_id = 57320; break;
+ case POWER_RUNIC_POWER: triggered_spell_id = 57321; break;
+ default:
return false;
- break; // fall through to normal cast
}
- // Health Restore
- case 33510:
- {
- // at melee hit call std triggered spell
- if(procFlags & PROC_FLAG_HIT_MELEE)
- break; // fall through to normal cast
+ }
+ break;
+ }
+ }
+ // processed charge only counting case
+ if(!triggered_spell_id)
+ return true;
- // Mark of Conquest - else (at range hit) called custom case
- triggered_spell_id = 39557;
- target = this;
+ SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id);
+
+ if(!triggerEntry)
+ {
+ sLog.outError("Unit::HandleModDamagePctTakenAuraProc: Spell %u have not existed triggered spell %u",dummySpell->Id,triggered_spell_id);
+ return false;
+ }
+
+ // default case
+ if(!target || target!=this && !target->isAlive())
+ return false;
+
+ if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id))
+ return false;
+
+ if(basepoints0)
+ CastCustomSpell(target,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
+ else
+ CastSpell(target,triggered_spell_id,true,castItem,triggeredByAura);
+
+ if( cooldown && GetTypeId()==TYPEID_PLAYER )
+ ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown);
+
+ return true;
+}
+
+bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags, uint32 procEx, uint32 cooldown)
+{
+ // Get triggered aura spell info
+ SpellEntry const* auraSpellInfo = triggeredByAura->GetSpellProto();
+
+ // Basepoints of trigger aura
+ int32 triggerAmount = triggeredByAura->GetAmount();
+
+ // Set trigger spell id, target, custom basepoints
+ uint32 trigger_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()];
+ Unit* target = NULL;
+ int32 basepoints0 = 0;
+
+ if(triggeredByAura->GetAuraName() == SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE)
+ basepoints0 = triggerAmount;
+
+ Item* castItem = triggeredByAura->GetParentAura()->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
+ ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetParentAura()->GetCastItemGUID()) : NULL;
+
+ // Try handle unknown trigger spells
+ if (sSpellStore.LookupEntry(trigger_spell_id)==NULL)
+ {
+ switch (auraSpellInfo->SpellFamilyName)
+ {
+ case SPELLFAMILY_GENERIC:
+ //if (auraSpellInfo->Id==59532) // Abandon Passengers on Poly
+ //if (auraSpellInfo->Id==54775) // Abandon Vehicle on Poly
+ //if (auraSpellInfo->Id==34082) // Advantaged State (DND)
+ if (auraSpellInfo->Id == 23780) // Aegis of Preservation (Aegis of Preservation trinket)
+ trigger_spell_id = 23781;
+ //else if (auraSpellInfo->Id==43504) // Alterac Valley OnKill Proc Aura
+ //else if (auraSpellInfo->Id == 48876) // Beast's Mark
+ //{
+ // trigger_spell_id = 48877;
+ //}
+ //else if (auraSpellInfo->Id == 59237) // Beast's Mark
+ //{
+ // trigger_spell_id = 59233;
+ //}
+ //else if (auraSpellInfo->Id==46939) // Black Bow of the Betrayer
+ //{
+ // trigger_spell_id = 29471; // gain mana
+ // 27526; // drain mana if possible
+ //}
+ //else if (auraSpellInfo->Id==50844) // Blood Mirror
+ //else if (auraSpellInfo->Id==54476) // Blood Presence
+ //else if (auraSpellInfo->Id==50689) // Blood Presence (Rank 1)
+ //else if (auraSpellInfo->Id==37030) // Chaotic Temperament
+ //else if (auraSpellInfo->Id==52856) // Charge
+ else if (auraSpellInfo->Id==43820) // Charm of the Witch Doctor (Amani Charm of the Witch Doctor trinket)
+ {
+ // Pct value stored in dummy
+ basepoints0 = pVictim->GetCreateHealth() * auraSpellInfo->EffectBasePoints[1] / 100;
+ target = pVictim;
break;
}
- // Shaleskin
- case 36576:
- return true; // nothing to do
- // Forgotten Knowledge (Blade of Wizardry)
- case 38319:
- // only for harmful enemy targeted spell
- if(!pVictim || pVictim==this || !procSpell || IsPositiveSpell(procSpell->Id))
- return false;
- break; // fall through to normal cast
- // Aura of Wrath (Darkmoon Card: Wrath trinket bonus)
- case 39442:
- {
- // proc only at non-crit hits
- if(procFlags & (PROC_FLAG_CRIT_MELEE|PROC_FLAG_CRIT_RANGED|PROC_FLAG_CRIT_SPELL))
- return false;
- break; // fall through to normal cast
+ //else if (auraSpellInfo->Id==41248) // Consuming Strikes
+ // trigger_spell_id = 41249;
+ //else if (auraSpellInfo->Id==45205) // Copy Offhand Weapon
+ //else if (auraSpellInfo->Id==57594) // Copy Ranged Weapon
+ //else if (auraSpellInfo->Id==41054) // Copy Weapon
+ // trigger_spell_id = 41055;
+ //else if (auraSpellInfo->Id==45343) // Dark Flame Aura
+ //else if (auraSpellInfo->Id==47300) // Dark Flame Aura
+ else if (auraSpellInfo->Id==57345) // Darkmoon Card: Greatness
+ {
+ float stat = 0.0f;
+ // strength
+ if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 60229;stat = GetStat(STAT_STRENGTH); }
+ // agility
+ if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 60233;stat = GetStat(STAT_AGILITY); }
+ // intellect
+ if (GetStat(STAT_INTELLECT)> stat) { trigger_spell_id = 60234;stat = GetStat(STAT_INTELLECT);}
+ // spirit
+ if (GetStat(STAT_SPIRIT) > stat) { trigger_spell_id = 60235;stat = GetStat(STAT_SPIRIT); }
}
- // Augment Pain (Timbal's Focusing Crystal trinket bonus)
- case 45054:
+ //else if (auraSpellInfo->Id==31255) // Deadly Swiftness (Rank 1)
+ //else if (auraSpellInfo->Id==5301) // Defensive State (DND)
+ //else if (auraSpellInfo->Id==13358) // Defensive State (DND)
+ //else if (auraSpellInfo->Id==16092) // Defensive State (DND)
+ //else if (auraSpellInfo->Id==24949) // Defensive State 2 (DND)
+ //else if (auraSpellInfo->Id==40329) // Demo Shout Sensor
+ else if (auraSpellInfo->Id == 33896) // Desperate Defense (Stonescythe Whelp, Stonescythe Alpha, Stonescythe Ambusher)
+ trigger_spell_id = 33898;
+ //else if (auraSpellInfo->Id==18943) // Double Attack
+ //else if (auraSpellInfo->Id==19194) // Double Attack
+ //else if (auraSpellInfo->Id==19817) // Double Attack
+ //else if (auraSpellInfo->Id==19818) // Double Attack
+ //else if (auraSpellInfo->Id==22835) // Drunken Rage
+ // trigger_spell_id = 14822;
+ /*
+ else if (auraSpellInfo->SpellIconID==191) // Elemental Response
{
- if(!procSpell)
- return false;
-
- //only periodic damage can trigger spell
- bool found = false;
- for(int j = 0; j < 3; ++j)
+ switch (auraSpellInfo->Id && auraSpellInfo->AttributesEx==0)
{
- if( procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_DAMAGE ||
- procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_DAMAGE_PERCENT ||
- procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_LEECH )
- {
- found = true;
+ case 34191:
+ case 34329:
+ case 34524:
+ case 34582:
+ case 36733:
break;
- }
+ default:
+ sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Elemental Response",auraSpellInfo->Id);
+ return false;
}
- if(!found)
- return false;
-
- break; // fall through to normal cast
+ //This generic aura self-triggers a different spell for each school of magic that lands on the wearer:
+ switch (procSpell->School)
+ {
+ case SPELL_SCHOOL_FIRE: trigger_spell_id = 34192; break;
+ case SPELL_SCHOOL_FROST: trigger_spell_id = 34193; break;
+ case SPELL_SCHOOL_ARCANE:trigger_spell_id = 34194; break;
+ case SPELL_SCHOOL_NATURE:trigger_spell_id = 34195; break;
+ case SPELL_SCHOOL_SHADOW:trigger_spell_id = 34196; break;
+ case SPELL_SCHOOL_HOLY: trigger_spell_id = 34197; break;
+ case SPELL_SCHOOL_NORMAL:trigger_spell_id = 34198; break;
+ default:
+ sLog.outError("Unit::HandleProcTriggerSpell: Spell %u Elemental Response wrong school",auraSpellInfo->Id);
+ return false;
+ }
+ }
+ */
+ //else if (auraSpellInfo->Id==40364) // Entangling Roots Sensor
+ //else if (auraSpellInfo->Id==33207) // Gossip NPC Periodic - Fidget
+ //else if (auraSpellInfo->Id==50051) // Ethereal Pet Aura
+ //else if (auraSpellInfo->Id==35321) // Gushing Wound
+ //else if (auraSpellInfo->Id==38363) // Gushing Wound
+ //else if (auraSpellInfo->Id==39215) // Gushing Wound
+ //else if (auraSpellInfo->Id==44527) // Hate Monster (Spar Buddy) (30 sec)
+ //else if (auraSpellInfo->Id==44819) // Hate Monster (Spar Buddy) (>30% Health)
+ //else if (auraSpellInfo->Id==44526) // Hate Monster (Spar) (30 sec)
+ //else if (auraSpellInfo->Id==44820) // Hate Monster (Spar) (<30%)
+ //else if (auraSpellInfo->Id==49059) // Horde, Hate Monster (Spar Buddy) (>30% Health)
+ //else if (auraSpellInfo->Id==40250) // Improved Duration
+ //else if (auraSpellInfo->Id==59288) // Infra-Green Shield
+ //else if (auraSpellInfo->Id==54072) // Knockback Ball Passive
+ else if (auraSpellInfo->Id==27522 || auraSpellInfo->Id==40336)
+ // Mana Drain Trigger
+ {
+ // On successful melee or ranged attack gain $29471s1 mana and if possible drain $27526s1 mana from the target.
+ if (this && this->isAlive())
+ CastSpell(this, 29471, true, castItem, triggeredByAura);
+ if (pVictim && pVictim->isAlive())
+ CastSpell(pVictim, 27526, true, castItem, triggeredByAura);
+ return true;
}
- // Evasive Maneuvers (Commendation of Kael'thas)
- case 45057:
+ //else if (auraSpellInfo->Id==55580) // Mana Link
+ //else if (auraSpellInfo->Id==45903) // Offensive State
+ //else if (auraSpellInfo->Id==44326) // Pure Energy Passive
+ //else if (auraSpellInfo->Id==43453) // Rune Ward
+ //else if (auraSpellInfo->Id== 7137) // Shadow Charge (Rank 1)
+ //else if (auraSpellInfo->Id==36576) // Shaleskin (Shaleskin Flayer, Shaleskin Ripper) 30023 trigger
+ //else if (auraSpellInfo->Id==34783) // Spell Reflection
+ //else if (auraSpellInfo->Id==36096) // Spell Reflection
+ //else if (auraSpellInfo->Id==57587) // Steal Ranged ()
+ //else if (auraSpellInfo->Id==36207) // Steal Weapon
+ //else if (auraSpellInfo->Id== 7377) // Take Immune Periodic Damage <Not Working>
+ //else if (auraSpellInfo->Id==35205) // Vanish
+ //else if (auraSpellInfo->Id==42730) // Woe Strike
+ //else if (auraSpellInfo->Id==59735) // Woe Strike
+ //else if (auraSpellInfo->Id==46146) // [PH] Ahune Spanky Hands
+ break;
+ case SPELLFAMILY_MAGE:
+ if (auraSpellInfo->SpellIconID == 2127) // Blazing Speed
{
- // damage taken that reduces below 35% health
- // does NOT mean you must have been >= 35% before
- if (int32(GetHealth())-int32(damage) >= int32(GetMaxHealth()*0.35f))
- return false;
- break; // fall through to normal cast
+ switch (auraSpellInfo->Id)
+ {
+ case 31641: // Rank 1
+ case 31642: // Rank 2
+ trigger_spell_id = 31643;
+ break;
+ default:
+ sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Blazing Speed",auraSpellInfo->Id);
+ return false;
+ }
}
- }
-
- switch(triggered_spell_id)
+ break;
+ case SPELLFAMILY_WARRIOR:
+ if (auraSpellInfo->Id == 50421) // Scent of Blood
+ trigger_spell_id = 50422;
+ break;
+ case SPELLFAMILY_WARLOCK:
{
- // Setup
- case 15250:
+ // Pyroclasm
+ if (auraSpellInfo->SpellIconID == 1137)
{
- // applied only for main target
- if(!pVictim || pVictim != getVictim())
+ if(!pVictim || !pVictim->isAlive() || pVictim == this || procSpell == NULL)
+ return false;
+ // Calculate spell tick count for spells
+ uint32 tick = 1; // Default tick = 1
+
+ // Hellfire have 15 tick
+ if (procSpell->SpellFamilyFlags[0]&0x40)
+ tick = 15;
+ // Rain of Fire have 4 tick
+ else if (procSpell->SpellFamilyFlags[0]&0x20)
+ tick = 4;
+ else
return false;
- // continue normal case
- break;
- }
- // Shamanistic Rage triggered spell
- case 30824:
- basepoints0 = int32(GetTotalAttackPowerValue(BASE_ATTACK)*triggeredByAura->GetModifier()->m_amount/100);
- break;
- }
- break;
- }
- case SPELLFAMILY_MAGE:
- {
- switch(auraSpellInfo->SpellIconID)
- {
- // Blazing Speed
- case 2127:
- //Blazing Speed (instead non-existed triggered spell)
- triggered_spell_id = 31643;
- target = this;
- break;
- }
- switch(auraSpellInfo->Id)
- {
- // Persistent Shield (Scarab Brooch)
- case 26467:
- basepoints0 = int32(damage * 0.15f);
- break;
- }
- break;
- }
- case SPELLFAMILY_WARRIOR:
- {
- //Rampage
- if((auraSpellInfo->SpellFamilyFlags & 0x100000) && auraSpellInfo->SpellIconID==2006)
- {
- //all ranks have effect[0]==AURA (Proc Trigger Spell, non-existed)
- //and effect[1]==TriggerSpell
- if(auraSpellInfo->Effect[1]!=SPELL_EFFECT_TRIGGER_SPELL)
- {
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have wrong effect in RM",triggeredByAura->GetSpellProto()->Id);
- return false;
- }
- triggered_spell_id = auraSpellInfo->EffectTriggerSpell[1];
- break; // fall through to normal cast
- }
- break;
- }
- case SPELLFAMILY_WARLOCK:
- {
- // Pyroclasm
- if(auraSpellInfo->SpellFamilyFlags == 0x0000000000000000 && auraSpellInfo->SpellIconID==1137)
- {
- // last case for Hellfire that damage caster also but don't must stun caster
- if( pVictim == this )
- return false;
+ // Calculate chance = baseChance / tick
+ float chance = 0;
+ switch (auraSpellInfo->Id)
+ {
+ case 18096: chance = 13.0f / tick; break;
+ case 18073: chance = 26.0f / tick; break;
+ }
+ // Roll chance
+ if (!roll_chance_f(chance))
+ return false;
- // custom chance
- float chance = 0;
- switch (triggeredByAura->GetId())
- {
- case 18096: chance = 13.0f; break;
- case 18073: chance = 26.0f; break;
+ trigger_spell_id = 18093;
}
- if (!roll_chance_f(chance))
- return false;
-
- // Pyroclasm (instead non-existed triggered spell)
- triggered_spell_id = 18093;
- target = pVictim;
- break;
- }
- // Drain Soul
- if(auraSpellInfo->SpellFamilyFlags & 0x0000000000004000)
- {
- bool found = false;
- Unit::AuraList const& mAddFlatModifier = GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER);
- for(Unit::AuraList::const_iterator i = mAddFlatModifier.begin(); i != mAddFlatModifier.end(); ++i)
+ // Drain Soul
+ else if (auraSpellInfo->SpellFamilyFlags[0] & 0x4000)
{
- //Improved Drain Soul
- if ((*i)->GetModifier()->m_miscvalue == SPELLMOD_CHANCE_OF_SUCCESS && (*i)->GetSpellProto()->SpellIconID == 113)
+ Unit::AuraEffectList const& mAddFlatModifier = GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER);
+ for(Unit::AuraEffectList::const_iterator i = mAddFlatModifier.begin(); i != mAddFlatModifier.end(); ++i)
{
- int32 value2 = CalculateSpellDamage((*i)->GetSpellProto(),2,(*i)->GetSpellProto()->EffectBasePoints[2],this);
- basepoints0 = value2 * GetMaxPower(POWER_MANA) / 100;
- // Drain Soul
- CastCustomSpell(this, 18371, &basepoints0, NULL, NULL, true, castItem, triggeredByAura);
- break;
+ if ((*i)->GetMiscValue() == SPELLMOD_CHANCE_OF_SUCCESS && (*i)->GetSpellProto()->SpellIconID == 113)
+ {
+ int32 value2 = CalculateSpellDamage((*i)->GetSpellProto(),2,(*i)->GetSpellProto()->EffectBasePoints[2],this);
+ // Drain Soul
+ CastCustomSpell(this, 18371, &basepoints0, NULL, NULL, true, castItem, triggeredByAura);
+ break;
+ }
}
+ // Not remove charge (aura removed on death in any cases)
+ // Need for correct work Drain Soul SPELL_AURA_CHANNEL_DEATH_ITEM aura
+ return false;
}
- // Not remove charge (aura removed on death in any cases)
- // Need for correct work Drain Soul SPELL_AURA_CHANNEL_DEATH_ITEM aura
- return false;
- }
- break;
- }
- case SPELLFAMILY_PRIEST:
- {
- //Blessed Recovery
- if(auraSpellInfo->SpellFamilyFlags == 0x00000000LL && auraSpellInfo->SpellIconID==1875)
- {
- switch (triggeredByAura->GetSpellProto()->Id)
+ // Nether Protection
+ else if (auraSpellInfo->SpellIconID == 1985)
{
- case 27811: triggered_spell_id = 27813; break;
- case 27815: triggered_spell_id = 27817; break;
- case 27816: triggered_spell_id = 27818; break;
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in BR",triggeredByAura->GetSpellProto()->Id);
+ if (!procSpell)
return false;
+ switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell)))
+ {
+ case SPELL_SCHOOL_NORMAL:
+ case SPELL_SCHOOL_HOLY:
+ return false; // ignore
+ case SPELL_SCHOOL_FIRE: trigger_spell_id = 54371; break;
+ case SPELL_SCHOOL_NATURE: trigger_spell_id = 54375; break;
+ case SPELL_SCHOOL_FROST: trigger_spell_id = 54372; break;
+ case SPELL_SCHOOL_SHADOW: trigger_spell_id = 54374; break;
+ case SPELL_SCHOOL_ARCANE: trigger_spell_id = 54373; break;
+ default:
+ return false;
+ }
}
-
- int32 heal_amount = damage * triggeredByAura->GetModifier()->m_amount / 100;
- basepoints0 = heal_amount/3;
- target = this;
break;
}
- // Shadowguard
- if((auraSpellInfo->SpellFamilyFlags & 0x80000000LL) && auraSpellInfo->SpellVisual==7958)
- {
- switch(triggeredByAura->GetSpellProto()->Id)
- {
- case 18137:
- triggered_spell_id = 28377; break; // Rank 1
- case 19308:
- triggered_spell_id = 28378; break; // Rank 2
- case 19309:
- triggered_spell_id = 28379; break; // Rank 3
- case 19310:
- triggered_spell_id = 28380; break; // Rank 4
- case 19311:
- triggered_spell_id = 28381; break; // Rank 5
- case 19312:
- triggered_spell_id = 28382; break; // Rank 6
- case 25477:
- triggered_spell_id = 28385; break; // Rank 7
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in SG",triggeredByAura->GetSpellProto()->Id);
+ case SPELLFAMILY_PRIEST:
+ {
+ // Greater Heal Refund
+ if (auraSpellInfo->Id==37594)
+ trigger_spell_id = 37595;
+ // Blessed Recovery
+ else if (auraSpellInfo->SpellIconID == 1875)
+ {
+ switch (auraSpellInfo->Id)
+ {
+ case 27811: trigger_spell_id = 27813; break;
+ case 27815: trigger_spell_id = 27817; break;
+ case 27816: trigger_spell_id = 27818; break;
+ default:
+ sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in BR", auraSpellInfo->Id);
return false;
+ }
+ basepoints0 = damage * triggerAmount / 100 / 3;
+ target = this;
}
- target = pVictim;
break;
}
- break;
- }
- case SPELLFAMILY_DRUID:
- {
- switch(auraSpellInfo->Id)
+ case SPELLFAMILY_DRUID:
{
- // Leader of the Pack (triggering Improved Leader of the Pack heal)
- case 24932:
- {
- if (triggeredByAura->GetModifier()->m_amount == 0)
- return false;
- basepoints0 = triggeredByAura->GetModifier()->m_amount * GetMaxHealth() / 100;
- triggered_spell_id = 34299;
- break;
- };
- // Druid Forms Trinket (Druid Tier5 Trinket, triggers different spells per Form)
- case 37336:
+ // Druid Forms Trinket
+ if (auraSpellInfo->Id==37336)
{
switch(m_form)
{
+ case FORM_NONE: trigger_spell_id = 37344;break;
+ case FORM_CAT: trigger_spell_id = 37341;break;
case FORM_BEAR:
- case FORM_DIREBEAR:
- triggered_spell_id=37340; break;// Ursine Blessing
- case FORM_CAT:
- triggered_spell_id=37341; break;// Feline Blessing
- case FORM_TREE:
- triggered_spell_id=37342; break;// Slyvan Blessing
- case FORM_MOONKIN:
- triggered_spell_id=37343; break;// Lunar Blessing
- case FORM_NONE:
- triggered_spell_id=37344; break;// Cenarion Blessing (for caster form, except FORM_MOONKIN)
+ case FORM_DIREBEAR: trigger_spell_id = 37340;break;
+ case FORM_TREE: trigger_spell_id = 37342;break;
+ case FORM_MOONKIN: trigger_spell_id = 37343;break;
default:
return false;
}
-
- target = this;
- break;
}
+ //else if (auraSpellInfo->Id==40363)// Entangling Roots ()
+ // trigger_spell_id = ????;
+ break;
}
- break;
- }
- case SPELLFAMILY_ROGUE:
- {
- if(auraSpellInfo->SpellFamilyFlags == 0x0000000000000000LL)
+ case SPELLFAMILY_HUNTER:
+ break;
+ case SPELLFAMILY_PALADIN:
{
- switch(auraSpellInfo->SpellIconID)
+ /*
+ // Blessed Life
+ if (auraSpellInfo->SpellIconID == 2137)
{
- // Combat Potency
- case 2260:
+ switch (auraSpellInfo->Id)
{
- // skip non offhand attacks
- if(attackType!=OFF_ATTACK)
+ case 31828: // Rank 1
+ case 31829: // Rank 2
+ case 31830: // Rank 3
+ break;
+ default:
+ sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Blessed Life", auraSpellInfo->Id);
return false;
- break; // fall through to normal cast
}
}
- }
- break;
- }
- case SPELLFAMILY_PALADIN:
- {
- if(auraSpellInfo->SpellFamilyFlags == 0x00000000LL)
- {
- switch(auraSpellInfo->Id)
+ */
+ // Healing Discount
+ if (auraSpellInfo->Id==37705)
{
- // Lightning Capacitor
- case 37657:
- {
- // trinket ProcTriggerSpell but for safe checks for player
- if(!castItem || !pVictim || !pVictim->isAlive() || GetTypeId()!=TYPEID_PLAYER)
- return false;
-
- if(((Player*)this)->HasSpellCooldown(37657))
- return false;
-
- // stacking
- CastSpell(this, 37658, true, castItem, triggeredByAura);
- // 2.5s cooldown before it can stack again, current system allow 1 sec step in cooldown
- ((Player*)this)->AddSpellCooldown(37657,0,time(NULL)+(roll_chance_i(50) ? 2 : 3));
-
- // counting
- Aura * dummy = GetDummyAura(37658);
- if (!dummy)
- return false;
-
- // release at 3 aura in stack
- if(dummy->GetStackAmount() <= 2)
- return true; // main triggered spell casted anyway
-
- RemoveAurasDueToSpell(37658);
- CastSpell(pVictim, 37661, true, castItem, triggeredByAura);
- return true;
- }
- // Healing Discount
- case 37705:
- // Healing Trance (instead non-existed triggered spell)
- triggered_spell_id = 37706;
- target = this;
- break;
- // HoTs on Heals (Fel Reaver's Piston trinket)
- case 38299:
- {
- // at direct heal effect
- if(!procSpell || !IsSpellHaveEffect(procSpell,SPELL_EFFECT_HEAL))
- return false;
-
- // single proc at time
- AuraList const& scAuras = GetSingleCastAuras();
- for(AuraList::const_iterator itr = scAuras.begin(); itr != scAuras.end(); ++itr)
- if((*itr)->GetId()==triggered_spell_id)
- return false;
-
- // positive cast at victim instead self
- target = pVictim;
- break;
- }
+ trigger_spell_id = 37706;
+ target = this;
}
- switch(auraSpellInfo->SpellIconID)
+ // Soul Preserver
+ if (auraSpellInfo->Id==60510)
{
- case 241:
- {
- switch(auraSpellInfo->EffectTriggerSpell[0])
- {
- //Illumination
- case 18350:
- {
- if(!procSpell)
- return false;
-
- // procspell is triggered spell but we need mana cost of original casted spell
- uint32 originalSpellId = procSpell->Id;
-
- // Holy Shock
- if(procSpell->SpellFamilyName == SPELLFAMILY_PALADIN)
- {
- if(procSpell->SpellFamilyFlags & 0x0001000000000000LL)
- {
- switch(procSpell->Id)
- {
- case 25914: originalSpellId = 20473; break;
- case 25913: originalSpellId = 20929; break;
- case 25903: originalSpellId = 20930; break;
- case 27175: originalSpellId = 27174; break;
- case 33074: originalSpellId = 33072; break;
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in HShock",procSpell->Id);
- return false;
- }
- }
- }
-
- SpellEntry const *originalSpell = sSpellStore.LookupEntry(originalSpellId);
- if(!originalSpell)
- {
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u unknown but selected as original in Illu",originalSpellId);
- return false;
- }
-
- // percent stored in effect 1 (class scripts) base points
- int32 percent = auraSpellInfo->EffectBasePoints[1]+1;
-
- basepoints0 = originalSpell->manaCost*percent/100;
- triggered_spell_id = 20272;
- target = this;
- break;
- }
- }
- break;
- }
+ trigger_spell_id = 60515;
+ target = this;
}
- }
- if(auraSpellInfo->SpellFamilyFlags & 0x00080000)
- {
- switch(auraSpellInfo->SpellIconID)
+ // Illumination
+ else if (auraSpellInfo->SpellIconID==241)
{
- //Judgement of Wisdom (overwrite non existing triggered spell call in spell.dbc
- case 206:
+ if(!procSpell)
+ return false;
+ // procspell is triggered spell but we need mana cost of original casted spell
+ uint32 originalSpellId = procSpell->Id;
+ // Holy Shock heal
+ if(procSpell->SpellFamilyFlags[1] & 0x00010000)
{
- if(!pVictim || !pVictim->isAlive())
- return false;
-
- switch(triggeredByAura->GetSpellProto()->Id)
+ switch(procSpell->Id)
{
- case 20186:
- triggered_spell_id = 20268; // Rank 1
- break;
- case 20354:
- triggered_spell_id = 20352; // Rank 2
- break;
- case 20355:
- triggered_spell_id = 20353; // Rank 3
- break;
- case 27164:
- triggered_spell_id = 27165; // Rank 4
- break;
+ case 25914: originalSpellId = 20473; break;
+ case 25913: originalSpellId = 20929; break;
+ case 25903: originalSpellId = 20930; break;
+ case 27175: originalSpellId = 27174; break;
+ case 33074: originalSpellId = 33072; break;
+ case 48820: originalSpellId = 48824; break;
+ case 48821: originalSpellId = 48825; break;
default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in JoW",triggeredByAura->GetSpellProto()->Id);
- return false;
+ sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in HShock",procSpell->Id);
+ return false;
}
-
- pVictim->CastSpell(pVictim,triggered_spell_id,true,castItem,triggeredByAura,GetGUID());
- return true; // no hidden cooldown
}
- //Judgement of Light
- case 299:
+ SpellEntry const *originalSpell = sSpellStore.LookupEntry(originalSpellId);
+ if(!originalSpell)
{
- if(!pVictim || !pVictim->isAlive())
- return false;
-
- // overwrite non existing triggered spell call in spell.dbc
- switch(triggeredByAura->GetSpellProto()->Id)
- {
- case 20185:
- triggered_spell_id = 20267; // Rank 1
- break;
- case 20344:
- triggered_spell_id = 20341; // Rank 2
- break;
- case 20345:
- triggered_spell_id = 20342; // Rank 3
- break;
- case 20346:
- triggered_spell_id = 20343; // Rank 4
- break;
- case 27162:
- triggered_spell_id = 27163; // Rank 5
- break;
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in JoL",triggeredByAura->GetSpellProto()->Id);
- return false;
- }
- pVictim->CastSpell(pVictim,triggered_spell_id,true,castItem,triggeredByAura,GetGUID());
- return true; // no hidden cooldown
+ sLog.outError("Unit::HandleProcTriggerSpell: Spell %u unknown but selected as original in Illu",originalSpellId);
+ return false;
}
+ // percent stored in effect 1 (class scripts) base points
+ int32 cost = originalSpell->manaCost + originalSpell->ManaCostPercentage * GetCreateMana() / 100;
+ basepoints0 = cost*auraSpellInfo->CalculateSimpleValue(1)/100;
+ trigger_spell_id = 20272;
+ target = this;
}
- }
- // custom check for proc spell
- switch(auraSpellInfo->Id)
- {
- // Bonus Healing (item spell)
- case 40971:
+ // Lightning Capacitor
+ else if (auraSpellInfo->Id==37657)
{
if(!pVictim || !pVictim->isAlive())
return false;
+ // stacking
+ CastSpell(this, 37658, true, NULL, triggeredByAura);
- // bonus if health < 50%
- if(pVictim->GetHealth() >= pVictim->GetMaxHealth()*triggeredByAura->GetModifier()->m_amount/100)
+ AuraEffect * dummy = GetDummyAura(37658);
+ // release at 3 aura in stack (cont contain in basepoint of trigger aura)
+ if(!dummy || dummy->GetParentAura()->GetStackAmount() < triggerAmount)
return false;
- // cast at target positive spell
+ RemoveAurasDueToSpell(37658);
+ trigger_spell_id = 37661;
target = pVictim;
- break;
}
- }
- switch(triggered_spell_id)
- {
- // Seal of Command
- case 20424:
- // prevent chain of triggered spell from same triggered spell
- if(procSpell && procSpell->Id==20424)
+ // Thunder Capacitor
+ else if (auraSpellInfo->Id == 54841)
+ {
+ if(!pVictim || !pVictim->isAlive())
return false;
- break;
+ // stacking
+ CastSpell(this, 54842, true, NULL, triggeredByAura);
+
+ // counting
+ AuraEffect * dummy = GetDummyAura(54842);
+ // release at 3 aura in stack (cont contain in basepoint of trigger aura)
+ if(!dummy || dummy->GetParentAura()->GetStackAmount() < triggerAmount)
+ return false;
+
+ RemoveAurasDueToSpell(54842);
+ trigger_spell_id = 54843;
+ target = pVictim;
+ }
+ break;
}
- break;
- }
- case SPELLFAMILY_SHAMAN:
- {
- if(auraSpellInfo->SpellFamilyFlags == 0x0000000000000000)
+ case SPELLFAMILY_SHAMAN:
{
- switch(auraSpellInfo->SpellIconID)
+ // Lightning Shield (overwrite non existing triggered spell call in spell.dbc
+ if(auraSpellInfo->SpellFamilyFlags[0] & 0x400)
{
- case 19:
+ switch(auraSpellInfo->Id)
{
- switch(auraSpellInfo->Id)
- {
- case 23551: // Lightning Shield - Tier2: 8 pieces proc shield
- {
- // Lightning Shield (overwrite non existing triggered spell call in spell.dbc)
- triggered_spell_id = 23552;
- target = pVictim;
- break;
- }
- case 23552: // Lightning Shield - trigger shield damage
- {
- // Lightning Shield (overwrite non existing triggered spell call in spell.dbc)
- triggered_spell_id = 27635;
- target = pVictim;
- break;
- }
- }
- break;
- }
- // Mana Surge (Shaman T1 bonus)
- case 87:
- {
- if(!procSpell)
- return false;
-
- basepoints0 = procSpell->manaCost * 35/100;
- triggered_spell_id = 23571;
- target = this;
- break;
+ case 324: // Rank 1
+ trigger_spell_id = 26364; break;
+ case 325: // Rank 2
+ trigger_spell_id = 26365; break;
+ case 905: // Rank 3
+ trigger_spell_id = 26366; break;
+ case 945: // Rank 4
+ trigger_spell_id = 26367; break;
+ case 8134: // Rank 5
+ trigger_spell_id = 26369; break;
+ case 10431: // Rank 6
+ trigger_spell_id = 26370; break;
+ case 10432: // Rank 7
+ trigger_spell_id = 26363; break;
+ case 25469: // Rank 8
+ trigger_spell_id = 26371; break;
+ case 25472: // Rank 9
+ trigger_spell_id = 26372; break;
+ case 49280: // Rank 10
+ trigger_spell_id = 49278; break;
+ case 49281: // Rank 11
+ trigger_spell_id = 49279; break;
+ default:
+ sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in LShield", auraSpellInfo->Id);
+ return false;
}
- //Nature's Guardian
- case 2013:
- {
- if(GetTypeId()!=TYPEID_PLAYER)
- return false;
-
- // damage taken that reduces below 30% health
- // does NOT mean you must have been >= 30% before
- if (10*(int32(GetHealth())-int32(damage)) >= 3*GetMaxHealth())
- return false;
-
- triggered_spell_id = 31616;
+ }
+ // Lightning Shield (The Ten Storms set)
+ else if (auraSpellInfo->Id == 23551)
+ {
+ trigger_spell_id = 23552;
+ target = pVictim;
+ }
+ // Damage from Lightning Shield (The Ten Storms set)
+ else if (auraSpellInfo->Id == 23552)
+ trigger_spell_id = 27635;
+ // Mana Surge (The Earthfury set)
+ else if (auraSpellInfo->Id == 23572)
+ {
+ if(!procSpell)
+ return false;
+ basepoints0 = procSpell->manaCost * 35 / 100;
+ trigger_spell_id = 23571;
+ target = this;
+ }
+ // Nature's Guardian
+ else if (auraSpellInfo->SpellIconID == 2013)
+ {
+ // Check health condition - should drop to less 30% (damage deal after this!)
+ if (!(10*(int32(GetHealth() - damage)) < 3 * GetMaxHealth()))
+ return false;
- // need check cooldown now
- if( cooldown && ((Player*)this)->HasSpellCooldown(triggered_spell_id))
- return false;
+ if(pVictim && pVictim->isAlive())
+ pVictim->getThreatManager().modifyThreatPercent(this,-10);
- basepoints0 = triggeredByAura->GetModifier()->m_amount * GetMaxHealth() / 100;
- target = this;
- if(pVictim && pVictim->isAlive())
- pVictim->getThreatManager().modifyThreatPercent(this,-10);
- break;
- }
+ basepoints0 = triggerAmount * GetMaxHealth() / 100;
+ trigger_spell_id = 31616;
+ target = this;
}
- }
-
- // Water Shield (we can't set cooldown for main spell - it's player casted spell
- if((auraSpellInfo->SpellFamilyFlags & 0x0000002000000000LL) && auraSpellInfo->SpellVisual==7358)
- {
- target = this;
break;
}
-
- // Lightning Shield
- if((auraSpellInfo->SpellFamilyFlags & 0x00000400) && auraSpellInfo->SpellVisual==37)
- {
- // overwrite non existing triggered spell call in spell.dbc
- switch(triggeredByAura->GetSpellProto()->Id)
- {
- case 324:
- triggered_spell_id = 26364; break; // Rank 1
- case 325:
- triggered_spell_id = 26365; break; // Rank 2
- case 905:
- triggered_spell_id = 26366; break; // Rank 3
- case 945:
- triggered_spell_id = 26367; break; // Rank 4
- case 8134:
- triggered_spell_id = 26369; break; // Rank 5
- case 10431:
- triggered_spell_id = 26370; break; // Rank 6
- case 10432:
- triggered_spell_id = 26363; break; // Rank 7
- case 25469:
- triggered_spell_id = 26371; break; // Rank 8
- case 25472:
- triggered_spell_id = 26372; break; // Rank 9
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in LShield",triggeredByAura->GetSpellProto()->Id);
+ case SPELLFAMILY_DEATHKNIGHT:
+ {
+ // Acclimation
+ if (auraSpellInfo->SpellIconID == 1930)
+ {
+ if (!procSpell)
return false;
+ switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell)))
+ {
+ case SPELL_SCHOOL_NORMAL:
+ return false; // ignore
+ case SPELL_SCHOOL_HOLY: trigger_spell_id = 50490; break;
+ case SPELL_SCHOOL_FIRE: trigger_spell_id = 50362; break;
+ case SPELL_SCHOOL_NATURE: trigger_spell_id = 50488; break;
+ case SPELL_SCHOOL_FROST: trigger_spell_id = 50485; break;
+ case SPELL_SCHOOL_SHADOW: trigger_spell_id = 50489; break;
+ case SPELL_SCHOOL_ARCANE: trigger_spell_id = 54373; break;
+ default:
+ return false;
+ }
+ }
+ // Blood Presence
+ else if (auraSpellInfo->Id == 48266)
+ {
+ if (GetTypeId() != TYPEID_PLAYER)
+ return false;
+ if (!((Player*)this)->isHonorOrXPTarget(pVictim))
+ return false;
+ trigger_spell_id = 50475;
+ basepoints0 = damage * triggerAmount / 100;
}
-
- target = pVictim;
break;
}
- break;
- }
- }
-
- // standard non-dummy case
- if(!triggered_spell_id)
- {
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",auraSpellInfo->Id,triggeredByAura->GetEffIndex());
- return false;
- }
-
- SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id);
-
- if(!triggerEntry)
- {
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have not existed EffectTriggered[%d]=%u, not handled custom case?",auraSpellInfo->Id,triggeredByAura->GetEffIndex(),triggered_spell_id);
- return false;
- }
-
- // not allow proc extra attack spell at extra attack
- if( m_extraAttacks && IsSpellHaveEffect(triggerEntry,SPELL_EFFECT_ADD_EXTRA_ATTACKS) )
- return false;
-
- if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id))
- return false;
-
- // default case
- if(!target || target!=this && !target->isAlive())
- return false;
-
- if(basepoints0)
- CastCustomSpell(target,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
- else
- CastSpell(target,triggered_spell_id,true,castItem,triggeredByAura);
-
- if( cooldown && GetTypeId()==TYPEID_PLAYER )
- ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown);
-
- return true;
-}
-*/
-
-bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags, uint32 procEx, uint32 cooldown)
-{
- // Get triggered aura spell info
- SpellEntry const* auraSpellInfo = triggeredByAura->GetSpellProto();
-
- // Basepoints of trigger aura
- int32 triggerAmount = triggeredByAura->GetModifier()->m_amount;
-
- // Set trigger spell id, target, custom basepoints
- uint32 trigger_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()];
- Unit* target = NULL;
- int32 basepoints0 = 0;
-
- Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
- ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
-
- // Try handle uncnown trigger spells
- if (sSpellStore.LookupEntry(trigger_spell_id)==NULL)
- switch (auraSpellInfo->SpellFamilyName)
- {
- //=====================================================================
- // Generic class
- // ====================================================================
- // .....
- //=====================================================================
- case SPELLFAMILY_GENERIC:
-// if (auraSpellInfo->Id==34082) // Advantaged State (DND)
-// trigger_spell_id = ???;
- if (auraSpellInfo->Id == 23780) // Aegis of Preservation (Aegis of Preservation trinket)
- trigger_spell_id = 23781;
-// else if (auraSpellInfo->Id==43504) // Alterac Valley OnKill Proc Aura
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==37030) // Chaotic Temperament
-// trigger_spell_id = ;
- else if (auraSpellInfo->Id==43820) // Charm of the Witch Doctor (Amani Charm of the Witch Doctor trinket)
- {
- // Pct value stored in dummy
- basepoints0 = pVictim->GetCreateHealth() * auraSpellInfo->EffectBasePoints[1] / 100;
- target = pVictim;
- break;
- }
-// else if (auraSpellInfo->Id==41248) // Consuming Strikes
-// trigger_spell_id = 41249;
-// else if (auraSpellInfo->Id==41054) // Copy Weapon
-// trigger_spell_id = 41055;
-// else if (auraSpellInfo->Id==31255) // Deadly Swiftness (Rank 1)
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==5301) // Defensive State (DND)
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==13358) // Defensive State (DND)
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==16092) // Defensive State (DND)
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==24949) // Defensive State 2 (DND)
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==40329) // Demo Shout Sensor
-// trigger_spell_id = ;
- // Desperate Defense (Stonescythe Whelp, Stonescythe Alpha, Stonescythe Ambusher)
- else if (auraSpellInfo->Id == 33896)
- trigger_spell_id = 33898;
-// else if (auraSpellInfo->Id==18943) // Double Attack
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==19194) // Double Attack
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==19817) // Double Attack
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==19818) // Double Attack
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==22835) // Drunken Rage
-// trigger_spell_id = 14822;
- /*
- else if (auraSpellInfo->SpellIconID==191) // Elemental Response
- {
- switch (auraSpellInfo->Id && auraSpellInfo->AttributesEx==0)
- {
- case 34191:
- case 34329:
- case 34524:
- case 34582:
- case 36733:break;
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Elemental Response",auraSpellInfo->Id);
- return false;
- }
- //This generic aura self-triggers a different spell for each school of magic that lands on the wearer:
- switch (procSpell->School)
- {
- case SPELL_SCHOOL_FIRE: trigger_spell_id = 34192;break;//Fire: 34192
- case SPELL_SCHOOL_FROST: trigger_spell_id = 34193;break;//Frost: 34193
- case SPELL_SCHOOL_ARCANE: trigger_spell_id = 34194;break;//Arcane: 34194
- case SPELL_SCHOOL_NATURE: trigger_spell_id = 34195;break;//Nature: 34195
- case SPELL_SCHOOL_SHADOW: trigger_spell_id = 34196;break;//Shadow: 34196
- case SPELL_SCHOOL_HOLY: trigger_spell_id = 34197;break;//Holy: 34197
- case SPELL_SCHOOL_NORMAL: trigger_spell_id = 34198;break;//Physical: 34198
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u Elemental Response wrong school",auraSpellInfo->Id);
- return false;
- }
- }*/
-// else if (auraSpellInfo->Id==6542) // Enraged Defense
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==40364) // Entangling Roots Sensor
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==33207) // Gossip NPC Periodic - Fidget
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==35321) // Gushing Wound
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==38363) // Gushing Wound
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==39215) // Gushing Wound
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==40250) // Improved Duration
-// trigger_spell_id = ;
- else if (auraSpellInfo->Id==27522) // Mana Drain Trigger
- {
- // On successful melee or ranged attack gain $29471s1 mana and if possible drain $27526s1 mana from the target.
- if (this && this->isAlive())
- CastSpell(this, 29471, true, castItem, triggeredByAura);
- if (pVictim && pVictim->isAlive())
- CastSpell(pVictim, 27526, true, castItem, triggeredByAura);
- return true;
- }
- else if (auraSpellInfo->Id==24905) // Moonkin Form (Passive)
- {
- // Elune's Touch (instead non-existed triggered spell) 30% from AP
- trigger_spell_id = 33926;
- basepoints0 = GetTotalAttackPowerValue(BASE_ATTACK) * 30 / 100;
- target = this;
- }
-// else if (auraSpellInfo->Id==43453) // Rune Ward
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==7137) // Shadow Charge (Rank 1)
-// trigger_spell_id = ;
- // Shaleskin (Shaleskin Flayer, Shaleskin Ripper) 30023 trigger
-// else if (auraSpellInfo->Id==36576)
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==34783) // Spell Reflection
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==36096) // Spell Reflection
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==36207) // Steal Weapon
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==35205) // Vanish
- break;
- //=====================================================================
- // Mage
- //=====================================================================
- // Blazing Speed (Rank 1,2) trigger = 18350
- //=====================================================================
- case SPELLFAMILY_MAGE:
- // Blazing Speed
- if (auraSpellInfo->SpellIconID == 2127)
- {
- switch (auraSpellInfo->Id)
- {
- case 31641: // Rank 1
- case 31642: // Rank 2
- trigger_spell_id = 31643;
- break;
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Blazing Speed",auraSpellInfo->Id);
- return false;
- }
- }
- break;
- //=====================================================================
- // Warrior
- //=====================================================================
- // Rampage (Rank 1-3) trigger = 18350
- //=====================================================================
- case SPELLFAMILY_WARRIOR:
- // Rampage
- if (auraSpellInfo->SpellIconID == 2006 && auraSpellInfo->SpellFamilyFlags==0x100000)
- {
- switch(auraSpellInfo->Id)
- {
- case 29801: trigger_spell_id = 30029; break; // Rank 1
- case 30030: trigger_spell_id = 30031; break; // Rank 2
- case 30033: trigger_spell_id = 30032; break; // Rank 3
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in Rampage",auraSpellInfo->Id);
- return false;
- }
- }
- break;
- //=====================================================================
- // Warlock
- //=====================================================================
- // Pyroclasm trigger = 18350
- // Drain Soul (Rank 1-5) trigger = 0
- //=====================================================================
- case SPELLFAMILY_WARLOCK:
- {
- // Pyroclasm
- if (auraSpellInfo->SpellIconID == 1137)
- {
- if(!pVictim || !pVictim->isAlive() || pVictim == this || procSpell == NULL)
- return false;
- // Calculate spell tick count for spells
- uint32 tick = 1; // Default tick = 1
-
- // Hellfire have 15 tick
- if (procSpell->SpellFamilyFlags&0x0000000000000040LL)
- tick = 15;
- // Rain of Fire have 4 tick
- else if (procSpell->SpellFamilyFlags&0x0000000000000020LL)
- tick = 4;
- else
- return false;
-
- // Calculate chance = baseChance / tick
- float chance = 0;
- switch (auraSpellInfo->Id)
- {
- case 18096: chance = 13.0f / tick; break;
- case 18073: chance = 26.0f / tick; break;
- }
- // Roll chance
- if (!roll_chance_f(chance))
- return false;
-
- trigger_spell_id = 18093;
- }
- // Drain Soul
- else if (auraSpellInfo->SpellFamilyFlags & 0x0000000000004000LL)
- {
- Unit::AuraList const& mAddFlatModifier = GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER);
- for(Unit::AuraList::const_iterator i = mAddFlatModifier.begin(); i != mAddFlatModifier.end(); ++i)
- {
- if ((*i)->GetModifier()->m_miscvalue == SPELLMOD_CHANCE_OF_SUCCESS && (*i)->GetSpellProto()->SpellIconID == 113)
- {
- int32 value2 = CalculateSpellDamage((*i)->GetSpellProto(),2,(*i)->GetSpellProto()->EffectBasePoints[2],this);
- basepoints0 = value2 * GetMaxPower(POWER_MANA) / 100;
- }
- }
- if ( basepoints0 == 0 )
- return false;
- trigger_spell_id = 18371;
- }
- break;
- }
- //=====================================================================
- // Priest
- //=====================================================================
- // Greater Heal Refund trigger = 18350
- // Blessed Recovery (Rank 1-3) trigger = 18350
- // Shadowguard (1-7) trigger = 28376
- //=====================================================================
- case SPELLFAMILY_PRIEST:
- {
- // Greater Heal Refund
- if (auraSpellInfo->Id==37594)
- trigger_spell_id = 37595;
- // Shadowguard
- else if(auraSpellInfo->SpellFamilyFlags==0x100080000000LL && auraSpellInfo->SpellVisual==7958)
- {
- switch(auraSpellInfo->Id)
- {
- case 18137: trigger_spell_id = 28377; break; // Rank 1
- case 19308: trigger_spell_id = 28378; break; // Rank 2
- case 19309: trigger_spell_id = 28379; break; // Rank 3
- case 19310: trigger_spell_id = 28380; break; // Rank 4
- case 19311: trigger_spell_id = 28381; break; // Rank 5
- case 19312: trigger_spell_id = 28382; break; // Rank 6
- case 25477: trigger_spell_id = 28385; break; // Rank 7
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in SG", auraSpellInfo->Id);
- return false;
- }
- }
- // Blessed Recovery
- else if (auraSpellInfo->SpellIconID == 1875)
- {
- switch (auraSpellInfo->Id)
- {
- case 27811: trigger_spell_id = 27813; break;
- case 27815: trigger_spell_id = 27817; break;
- case 27816: trigger_spell_id = 27818; break;
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in BR", auraSpellInfo->Id);
- return false;
- }
- basepoints0 = damage * triggerAmount / 100 / 3;
- target = this;
- }
- break;
- }
- //=====================================================================
- // Druid
- // ====================================================================
- // Druid Forms Trinket trigger = 18350
- // Entangling Roots trigger = 30023
- // Leader of the Pack trigger = 18350
- //=====================================================================
- case SPELLFAMILY_DRUID:
- {
- // Druid Forms Trinket
- if (auraSpellInfo->Id==37336)
- {
- switch(m_form)
- {
- case 0: trigger_spell_id = 37344;break;
- case FORM_CAT: trigger_spell_id = 37341;break;
- case FORM_BEAR:
- case FORM_DIREBEAR: trigger_spell_id = 37340;break;
- case FORM_TREE: trigger_spell_id = 37342;break;
- case FORM_MOONKIN: trigger_spell_id = 37343;break;
- default:
- return false;
- }
- }
-// else if (auraSpellInfo->Id==40363)// Entangling Roots ()
-// trigger_spell_id = ????;
- // Leader of the Pack
- else if (auraSpellInfo->Id == 24932)
- {
- if (triggerAmount == 0)
- return false;
- basepoints0 = triggerAmount * GetMaxHealth() / 100;
- trigger_spell_id = 34299;
- }
- break;
- }
- //=====================================================================
- // Hunter
- // ====================================================================
- // ......
- //=====================================================================
- case SPELLFAMILY_HUNTER:
- break;
- //=====================================================================
- // Paladin
- // ====================================================================
- // Blessed Life trigger = 31934
- // Healing Discount trigger = 18350
- // Illumination (Rank 1-5) trigger = 18350
- // Judgement of Light (Rank 1-5) trigger = 5373
- // Judgement of Wisdom (Rank 1-4) trigger = 1826
- // Lightning Capacitor trigger = 18350
- //=====================================================================
- case SPELLFAMILY_PALADIN:
- {
- /* // Blessed Life
- if (auraSpellInfo->SpellIconID == 2137)
- {
- switch (auraSpellInfo->Id)
- {
- case 31828: // Rank 1
- case 31829: // Rank 2
- case 31830: // Rank 3
+ default:
break;
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Blessed Life", auraSpellInfo->Id);
- return false;
- }
- }*/
- // Healing Discount
- if (auraSpellInfo->Id==37705)
- {
- trigger_spell_id = 37706;
- target = this;
- }
- // Judgement of Light and Judgement of Wisdom
- else if (auraSpellInfo->SpellFamilyFlags & 0x0000000000080000LL)
- {
- switch (auraSpellInfo->Id)
- {
- // Judgement of Light
- case 20185: trigger_spell_id = 20267;break; // Rank 1
- case 20344: trigger_spell_id = 20341;break; // Rank 2
- case 20345: trigger_spell_id = 20342;break; // Rank 3
- case 20346: trigger_spell_id = 20343;break; // Rank 4
- case 27162: trigger_spell_id = 27163;break; // Rank 5
- // Judgement of Wisdom
- case 20186: trigger_spell_id = 20268;break; // Rank 1
- case 20354: trigger_spell_id = 20352;break; // Rank 2
- case 20355: trigger_spell_id = 20353;break; // Rank 3
- case 27164: trigger_spell_id = 27165;break; // Rank 4
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Judgement of Light/Wisdom", auraSpellInfo->Id);
- return false;
- }
- pVictim->CastSpell(pVictim, trigger_spell_id, true, castItem, triggeredByAura);
- return true; // no hidden cooldown
- }
- // Illumination
- else if (auraSpellInfo->SpellIconID==241)
- {
- if(!procSpell)
- return false;
- // procspell is triggered spell but we need mana cost of original casted spell
- uint32 originalSpellId = procSpell->Id;
- // Holy Shock
- if(procSpell->SpellFamilyFlags & 0x00200000)
- {
- switch(procSpell->Id)
- {
- case 25914: originalSpellId = 20473; break;
- case 25913: originalSpellId = 20929; break;
- case 25903: originalSpellId = 20930; break;
- case 27175: originalSpellId = 27174; break;
- case 33074: originalSpellId = 33072; break;
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in HShock",procSpell->Id);
- return false;
- }
- }
- SpellEntry const *originalSpell = sSpellStore.LookupEntry(originalSpellId);
- if(!originalSpell)
- {
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u unknown but selected as original in Illu",originalSpellId);
- return false;
- }
- // percent stored in effect 1 (class scripts) base points
- basepoints0 = originalSpell->manaCost*(auraSpellInfo->EffectBasePoints[1]+1)/100;
- trigger_spell_id = 20272;
- target = this;
- }
- // Lightning Capacitor
- else if (auraSpellInfo->Id==37657)
- {
- if(!pVictim || !pVictim->isAlive())
- return false;
- // stacking
- CastSpell(this, 37658, true, NULL, triggeredByAura);
- // counting
- Aura * dummy = GetDummyAura(37658);
- if (!dummy)
- return false;
- // release at 3 aura in stack (cont contain in basepoint of trigger aura)
- if(dummy->GetStackAmount() <= 2)
- return false;
-
- RemoveAurasDueToSpell(37658);
- trigger_spell_id = 37661;
- target = pVictim;
- }
- break;
- }
- //=====================================================================
- // Shaman
- //====================================================================
- // Lightning Shield trigger = 18350
- // Mana Surge trigger = 18350
- // Nature's Guardian (Rank 1-5) trigger = 18350
- //=====================================================================
- case SPELLFAMILY_SHAMAN:
- {
- //Lightning Shield (overwrite non existing triggered spell call in spell.dbc
- if(auraSpellInfo->SpellFamilyFlags==0x00000400 && auraSpellInfo->SpellVisual==37)
- {
- switch(auraSpellInfo->Id)
- {
- case 324: trigger_spell_id = 26364; break; // Rank 1
- case 325: trigger_spell_id = 26365; break; // Rank 2
- case 905: trigger_spell_id = 26366; break; // Rank 3
- case 945: trigger_spell_id = 26367; break; // Rank 4
- case 8134: trigger_spell_id = 26369; break; // Rank 5
- case 10431: trigger_spell_id = 26370; break; // Rank 6
- case 10432: trigger_spell_id = 26363; break; // Rank 7
- case 25469: trigger_spell_id = 26371; break; // Rank 8
- case 25472: trigger_spell_id = 26372; break; // Rank 9
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in LShield", auraSpellInfo->Id);
- return false;
- }
- }
- // Lightning Shield (The Ten Storms set)
- else if (auraSpellInfo->Id == 23551)
- {
- trigger_spell_id = 23552;
- target = pVictim;
- }
- // Damage from Lightning Shield (The Ten Storms set)
- else if (auraSpellInfo->Id == 23552)
- trigger_spell_id = 27635;
- // Mana Surge (The Earthfury set)
- else if (auraSpellInfo->Id == 23572)
- {
- if(!procSpell)
- return false;
- basepoints0 = procSpell->manaCost * 35 / 100;
- trigger_spell_id = 23571;
- target = this;
- }
- else if (auraSpellInfo->SpellIconID == 2013) //Nature's Guardian
- {
- // Check health condition - should drop to less 30% (damage deal after this!)
- if (!(10*(int32(GetHealth() - damage)) < 3 * GetMaxHealth()))
- return false;
-
- if(pVictim && pVictim->isAlive())
- pVictim->getThreatManager().modifyThreatPercent(this,-10);
-
- basepoints0 = triggerAmount * GetMaxHealth() / 100;
- trigger_spell_id = 31616;
- target = this;
- }
- break;
- }
- // default
- default:
- break;
+ }
}
// All ok. Check current trigger spell
@@ -7406,6 +7240,15 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
return false;
break;
}
+ // Rapid Recuperation
+ case 53228:
+ case 53232:
+ {
+ // This effect only from Rapid Fire (ability cast)
+ if (!(procSpell->SpellFamilyFlags[0] & 0x20))
+ return false;
+ break;
+ }
}
// Costum basepoints/target for exist spell
@@ -7435,11 +7278,16 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
// Need add combopoint AFTER finish movie (or they dropped in finish phase)
break;
}
+ // Bloodthirst (($m/100)% of max health)
+ case 23880:
+ {
+ basepoints0 = int32(GetMaxHealth() * triggerAmount / 100);
+ break;
+ }
// Shamanistic Rage triggered spell
case 30824:
{
basepoints0 = int32(GetTotalAttackPowerValue(BASE_ATTACK) * triggerAmount / 100);
- trigger_spell_id = 30824;
break;
}
// Enlightenment (trigger only from mana cost spells)
@@ -7449,6 +7297,59 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
return false;
break;
}
+ // Brain Freeze
+ case 57761:
+ {
+ if(!procSpell)
+ return false;
+ // For trigger from Blizzard need exist Improved Blizzard
+ if (procSpell->SpellFamilyName==SPELLFAMILY_MAGE && procSpell->SpellFamilyFlags[0] & 0x80)
+ {
+ bool found = false;
+ AuraEffectList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ for(AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
+ {
+ int32 script = (*i)->GetMiscValue();
+ if(script==836 || script==988 || script==989)
+ {
+ found=true;
+ break;
+ }
+ }
+ if(!found)
+ return false;
+ }
+ break;
+ }
+ // Astral Shift
+ case 52179:
+ {
+ if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim)
+ return false;
+
+ // Need stun, fear or silence mechanic
+ if (!(GetAllSpellMechanicMask(procSpell) & ((1<<MECHANIC_SILENCE)|(1<<MECHANIC_STUN)|(1<<MECHANIC_FEAR))))
+ return false;
+ break;
+ }
+ // Burning Determination
+ case 54748:
+ {
+ if(!procSpell)
+ return false;
+ // Need Interrupt or Silenced mechanic
+ if (!(GetAllSpellMechanicMask(procSpell) & ((1<<MECHANIC_INTERRUPT)|(1<<MECHANIC_SILENCE))))
+ return false;
+ break;
+ }
+ // Lock and Load
+ case 56453:
+ {
+ // Proc only from trap activation (from periodic proc another aura of this spell)
+ if (!(procFlags & PROC_FLAG_ON_TRAP_ACTIVATION) || !roll_chance_i(triggerAmount))
+ return false;
+ break;
+ }
}
if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(trigger_spell_id))
@@ -7475,15 +7376,15 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
return true;
}
-bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown)
+bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, AuraEffect *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown)
{
- int32 scriptId = triggeredByAura->GetModifier()->m_miscvalue;
+ int32 scriptId = triggeredByAura->GetMiscValue();
if(!pVictim || !pVictim->isAlive())
return false;
- Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
- ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
+ Item* castItem = triggeredByAura->GetParentAura()->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
+ ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetParentAura()->GetCastItemGUID()) : NULL;
uint32 triggered_spell_id = 0;
@@ -7491,21 +7392,21 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAur
{
case 836: // Improved Blizzard (Rank 1)
{
- if (!procSpell || procSpell->SpellVisual!=9487)
+ if (!procSpell || procSpell->SpellVisual[0]!=9487)
return false;
triggered_spell_id = 12484;
break;
}
case 988: // Improved Blizzard (Rank 2)
{
- if (!procSpell || procSpell->SpellVisual!=9487)
+ if (!procSpell || procSpell->SpellVisual[0]!=9487)
return false;
triggered_spell_id = 12485;
break;
}
case 989: // Improved Blizzard (Rank 3)
{
- if (!procSpell || procSpell->SpellVisual!=9487)
+ if (!procSpell || procSpell->SpellVisual[0]!=9487)
return false;
triggered_spell_id = 12486;
break;
@@ -7542,6 +7443,29 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAur
case 5497: // Improved Mana Gems (Serpent-Coil Braid)
triggered_spell_id = 37445; // Mana Surge
break;
+ case 8152: // Serendipity
+ {
+ // if heal your target over maximum health
+ if (pVictim->GetHealth() + damage < pVictim->GetMaxHealth())
+ return false;
+ int32 cost = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100;
+ int32 basepoints0 = cost * triggeredByAura->GetAmount()/100;
+ CastCustomSpell(this, 47762, &basepoints0, 0, 0, true, 0, triggeredByAura);
+ return true;
+ }
+ // Rapture
+ case 7556: // Rank 1
+ case 7555: // Rank 2
+ case 7554: // Rank 3
+ case 7553: // Rank 4
+ case 7552: // Rank 5
+ {
+ int32 basepoints0 = ((getLevel() * (-0.2) + 18) / 1000000) * damage * GetMaxPower(POWER_MANA);
+ if(basepoints0 > (GetMaxPower(POWER_MANA) / 100) * (triggeredByAura->GetAmount() / 10))
+ basepoints0 = (GetMaxPower(POWER_MANA) / 100) * (triggeredByAura->GetAmount() / 10);
+ CastCustomSpell(this, 47755, &basepoints0, 0, 0, true, 0, triggeredByAura);
+ return true;
+ }
}
// not processed
@@ -7633,6 +7557,8 @@ FactionTemplateEntry const* Unit::getFactionTemplateEntry() const
bool Unit::IsHostileTo(Unit const* unit) const
{
+ if(!unit)
+ return false;
// always non-hostile to self
if(unit==this)
return false;
@@ -7683,11 +7609,11 @@ bool Unit::IsHostileTo(Unit const* unit) const
return false;
// Sanctuary
- if(pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY) && pTester->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY))
+ if(pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY) && pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY))
return false;
// PvP FFA state
- if(pTester->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP) && pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP))
+ if(pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP) && pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
return true;
//= PvP states
@@ -7712,28 +7638,31 @@ bool Unit::IsHostileTo(Unit const* unit) const
if(tester->GetTypeId()==TYPEID_PLAYER)
{
// forced reaction
- ForcedReactions::const_iterator forceItr = ((Player*)tester)->m_forcedReactions.find(target_faction->faction);
- if(forceItr!=((Player*)tester)->m_forcedReactions.end())
- return forceItr->second <= REP_HOSTILE;
-
- // if faction have reputation then hostile state for tester at 100% dependent from at_war state
- if(FactionEntry const* raw_target_faction = sFactionStore.LookupEntry(target_faction->faction))
- if(raw_target_faction->reputationListID >=0)
- if(FactionState const* factionState = ((Player*)tester)->GetFactionState(raw_target_faction))
+ if(target_faction->faction)
+ {
+ if(ReputationRank const* force =((Player*)tester)->GetReputationMgr().GetForcedRankIfAny(target_faction))
+ return *force <= REP_HOSTILE;
+
+ // if faction have reputation then hostile state for tester at 100% dependent from at_war state
+ if(FactionEntry const* raw_target_faction = sFactionStore.LookupEntry(target_faction->faction))
+ if(FactionState const* factionState = ((Player*)tester)->GetReputationMgr().GetState(raw_target_faction))
return (factionState->Flags & FACTION_FLAG_AT_WAR);
+ }
}
// CvP forced reaction and reputation case
else if(target->GetTypeId()==TYPEID_PLAYER)
{
// forced reaction
- ForcedReactions::const_iterator forceItr = ((Player const*)target)->m_forcedReactions.find(tester_faction->faction);
- if(forceItr!=((Player const*)target)->m_forcedReactions.end())
- return forceItr->second <= REP_HOSTILE;
+ if(tester_faction->faction)
+ {
+ if(ReputationRank const* force = ((Player*)target)->GetReputationMgr().GetForcedRankIfAny(tester_faction))
+ return *force <= REP_HOSTILE;
- // apply reputation state
- FactionEntry const* raw_tester_faction = sFactionStore.LookupEntry(tester_faction->faction);
- if(raw_tester_faction && raw_tester_faction->reputationListID >=0 )
- return ((Player const*)target)->GetReputationRank(raw_tester_faction) <= REP_HOSTILE;
+ // apply reputation state
+ FactionEntry const* raw_tester_faction = sFactionStore.LookupEntry(tester_faction->faction);
+ if(raw_tester_faction && raw_tester_faction->reputationListID >=0 )
+ return ((Player const*)target)->GetReputationMgr().GetRank(raw_tester_faction) <= REP_HOSTILE;
+ }
}
// common faction based case (CvC,PvC,CvP)
@@ -7792,11 +7721,11 @@ bool Unit::IsFriendlyTo(Unit const* unit) const
return true;
// Sanctuary
- if(pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY) && pTester->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY))
+ if(pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY) && pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY))
return true;
// PvP FFA state
- if(pTester->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP) && pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP))
+ if(pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP) && pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
return false;
//= PvP states
@@ -7821,28 +7750,31 @@ bool Unit::IsFriendlyTo(Unit const* unit) const
if(tester->GetTypeId()==TYPEID_PLAYER)
{
// forced reaction
- ForcedReactions::const_iterator forceItr = ((Player const*)tester)->m_forcedReactions.find(target_faction->faction);
- if(forceItr!=((Player const*)tester)->m_forcedReactions.end())
- return forceItr->second >= REP_FRIENDLY;
+ if(target_faction->faction)
+ {
+ if(ReputationRank const* force =((Player*)tester)->GetReputationMgr().GetForcedRankIfAny(target_faction))
+ return *force >= REP_FRIENDLY;
- // if faction have reputation then friendly state for tester at 100% dependent from at_war state
- if(FactionEntry const* raw_target_faction = sFactionStore.LookupEntry(target_faction->faction))
- if(raw_target_faction->reputationListID >=0)
- if(FactionState const* FactionState = ((Player*)tester)->GetFactionState(raw_target_faction))
- return !(FactionState->Flags & FACTION_FLAG_AT_WAR);
+ // if faction have reputation then friendly state for tester at 100% dependent from at_war state
+ if(FactionEntry const* raw_target_faction = sFactionStore.LookupEntry(target_faction->faction))
+ if(FactionState const* factionState = ((Player*)tester)->GetReputationMgr().GetState(raw_target_faction))
+ return !(factionState->Flags & FACTION_FLAG_AT_WAR);
+ }
}
// CvP forced reaction and reputation case
else if(target->GetTypeId()==TYPEID_PLAYER)
{
// forced reaction
- ForcedReactions::const_iterator forceItr = ((Player const*)target)->m_forcedReactions.find(tester_faction->faction);
- if(forceItr!=((Player const*)target)->m_forcedReactions.end())
- return forceItr->second >= REP_FRIENDLY;
+ if(tester_faction->faction)
+ {
+ if(ReputationRank const* force =((Player*)target)->GetReputationMgr().GetForcedRankIfAny(tester_faction))
+ return *force >= REP_FRIENDLY;
- // apply reputation state
- if(FactionEntry const* raw_tester_faction = sFactionStore.LookupEntry(tester_faction->faction))
- if(raw_tester_faction->reputationListID >=0 )
- return ((Player const*)target)->GetReputationRank(raw_tester_faction) >= REP_FRIENDLY;
+ // apply reputation state
+ if(FactionEntry const* raw_tester_faction = sFactionStore.LookupEntry(tester_faction->faction))
+ if(raw_tester_faction->reputationListID >=0 )
+ return ((Player const*)target)->GetReputationMgr().GetRank(raw_tester_faction) >= REP_FRIENDLY;
+ }
}
// common faction based case (CvC,PvC,CvP)
@@ -7852,7 +7784,7 @@ bool Unit::IsFriendlyTo(Unit const* unit) const
bool Unit::IsHostileToPlayers() const
{
FactionTemplateEntry const* my_faction = getFactionTemplateEntry();
- if(!my_faction)
+ if(!my_faction || !my_faction->faction)
return false;
FactionEntry const* raw_faction = sFactionStore.LookupEntry(my_faction->faction);
@@ -7865,7 +7797,7 @@ bool Unit::IsHostileToPlayers() const
bool Unit::IsNeutralToAll() const
{
FactionTemplateEntry const* my_faction = getFactionTemplateEntry();
- if(!my_faction)
+ if(!my_faction || !my_faction->faction)
return true;
FactionEntry const* raw_faction = sFactionStore.LookupEntry(my_faction->faction);
@@ -7902,7 +7834,7 @@ bool Unit::Attack(Unit *victim, bool meleeAttack)
// remove SPELL_AURA_MOD_UNATTACKABLE at attack (in case non-interruptible spells stun aura applied also that not let attack)
if(HasAuraType(SPELL_AURA_MOD_UNATTACKABLE))
- RemoveSpellsCausingAura(SPELL_AURA_MOD_UNATTACKABLE);
+ RemoveAurasByType(SPELL_AURA_MOD_UNATTACKABLE);
if (m_attacking)
{
@@ -7917,34 +7849,43 @@ bool Unit::Attack(Unit *victim, bool meleeAttack)
}
return false;
}
- AttackStop();
+
+ //switch target
+ InterruptSpell(CURRENT_MELEE_SPELL);
+ if(!meleeAttack)
+ clearUnitState(UNIT_STAT_MELEE_ATTACKING);
}
+ if(m_attacking)
+ m_attacking->_removeAttacker(this);
+
+ m_attacking = victim;
+ m_attacking->_addAttacker(this);
+
//Set our target
SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID());
if(meleeAttack)
addUnitState(UNIT_STAT_MELEE_ATTACKING);
- m_attacking = victim;
- m_attacking->_addAttacker(this);
- //if(m_attacking->GetTypeId()==TYPEID_UNIT && ((Creature*)m_attacking)->IsAIEnabled)
- // ((Creature*)m_attacking)->AI()->AttackedBy(this);
+ // set position before any AI calls/assistance
+ //if(GetTypeId()==TYPEID_UNIT)
+ // ((Creature*)this)->SetCombatStartPosition(GetPositionX(), GetPositionY(), GetPositionZ());
- if(GetTypeId()==TYPEID_UNIT)
+ if(GetTypeId()==TYPEID_UNIT && !IsControlledByPlayer())
{
+ // should not let player enter combat by right clicking target
+ SetInCombatWith(victim);
+ if(victim->GetTypeId() == TYPEID_PLAYER)
+ victim->SetInCombatWith(this);
+ AddThreat(victim, 0.0f);
+
WorldPacket data(SMSG_AI_REACTION, 12);
data << uint64(GetGUID());
data << uint32(AI_REACTION_AGGRO); // Aggro sound
((WorldObject*)this)->SendMessageToSet(&data, true);
((Creature*)this)->CallAssistance();
-
- // should not let player enter combat by right clicking target
- SetInCombatWith(victim);
- if(victim->GetTypeId() == TYPEID_PLAYER)
- victim->SetInCombatWith(this);
- AddThreat(victim, 0.0f);
}
// delay offhand weapon attack to next attack time
@@ -7985,9 +7926,9 @@ bool Unit::AttackStop()
return true;
}
-void Unit::CombatStop(bool cast)
+void Unit::CombatStop(bool includingCast)
{
- if(cast && IsNonMeleeSpellCasted(false))
+ if (includingCast && IsNonMeleeSpellCasted(false))
InterruptNonMeleeSpells(false);
AttackStop();
@@ -7997,20 +7938,12 @@ void Unit::CombatStop(bool cast)
ClearInCombat();
}
-void Unit::CombatStopWithPets(bool cast)
+void Unit::CombatStopWithPets(bool includingCast)
{
- CombatStop(cast);
- if(Pet* pet = GetPet())
- pet->CombatStop(cast);
- if(Unit* charm = GetCharm())
- charm->CombatStop(cast);
- if(GetTypeId()==TYPEID_PLAYER)
- {
- GuardianPetList const& guardians = ((Player*)this)->GetGuardians();
- for(GuardianPetList::const_iterator itr = guardians.begin(); itr != guardians.end(); ++itr)
- if(Unit* guardian = Unit::GetUnit(*this,*itr))
- guardian->CombatStop(cast);
- }
+ CombatStop(includingCast);
+
+ for(ControlList::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
+ (*itr)->CombatStop(includingCast);
}
bool Unit::isAttackingPlayer() const
@@ -8018,23 +7951,15 @@ bool Unit::isAttackingPlayer() const
if(hasUnitState(UNIT_STAT_ATTACK_PLAYER))
return true;
- Pet* pet = GetPet();
- if(pet && pet->isAttackingPlayer())
- return true;
-
- Unit* charmed = GetCharm();
- if(charmed && charmed->isAttackingPlayer())
- return true;
+ for(ControlList::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
+ if((*itr)->isAttackingPlayer())
+ return true;
- for (int8 i = 0; i < MAX_TOTEM; i++)
- {
- if(m_TotemSlot[i])
- {
- Creature *totem = ObjectAccessor::GetCreature(*this, m_TotemSlot[i]);
- if(totem && totem->isAttackingPlayer())
- return true;
- }
- }
+ for(int8 i = 0; i < MAX_SUMMON_SLOT; ++i)
+ if(m_SummonSlot[i])
+ if(Creature *summon = GetMap()->GetCreature(m_SummonSlot[i]))
+ if(summon->isAttackingPlayer())
+ return true;
return false;
}
@@ -8086,7 +8011,7 @@ void Unit::ModifyAuraState(AuraState flag, bool apply)
{
// exceptions (applied at state but not removed at state change)
// Rampage
- if(spellProto->SpellIconID==2006 && spellProto->SpellFamilyName==SPELLFAMILY_WARRIOR && spellProto->SpellFamilyFlags==0x100000)
+ if(spellProto->SpellIconID==2006 && spellProto->SpellFamilyName==SPELLFAMILY_WARRIOR && spellProto->SpellFamilyFlags[0]==0x100000)
{
++itr;
continue;
@@ -8101,6 +8026,18 @@ void Unit::ModifyAuraState(AuraState flag, bool apply)
}
}
+bool Unit::HasAuraState(AuraState flag, SpellEntry const *spellProto, Unit * Caster) const
+{
+ if (Caster && spellProto)
+ {
+ AuraEffectList const& stateAuras = Caster->GetAurasByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
+ for(AuraEffectList::const_iterator j = stateAuras.begin();j != stateAuras.end(); ++j)
+ if((*j)->isAffectedOnSpell(spellProto))
+ return true;
+ }
+ return HasFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1));
+}
+
Unit *Unit::GetOwner() const
{
uint64 ownerid = GetOwnerGUID();
@@ -8125,15 +8062,16 @@ Player* Unit::GetCharmerOrOwnerPlayerOrPlayerItself() const
return GetTypeId()==TYPEID_PLAYER ? (Player*)this : NULL;
}
-Pet* Unit::GetPet() const
+Guardian* Unit::GetGuardianPet() const
{
if(uint64 pet_guid = GetPetGUID())
{
- if(Pet* pet = ObjectAccessor::GetPet(pet_guid))
- return pet;
+ if(Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, pet_guid))
+ if(pet->HasSummonMask(SUMMON_MASK_GUARDIAN))
+ return (Guardian*)pet;
- sLog.outError("Unit::GetPet: Pet %u not exist.",GUID_LOPART(pet_guid));
- const_cast<Unit*>(this)->SetPet(0);
+ sLog.outError("Unit::GetGuardianPet: Pet %u not exist.",GUID_LOPART(pet_guid));
+ const_cast<Unit*>(this)->SetPetGUID(0);
}
return NULL;
@@ -8147,28 +8085,307 @@ Unit* Unit::GetCharm() const
return pet;
sLog.outError("Unit::GetCharm: Charmed creature %u not exist.",GUID_LOPART(charm_guid));
- const_cast<Unit*>(this)->SetCharm(0);
+ const_cast<Unit*>(this)->SetUInt64Value(UNIT_FIELD_CHARM, 0);
}
return NULL;
}
-void Unit::SetPet(Pet* pet)
+void Unit::SetGuardian(Guardian* guardian, bool apply)
+{
+ sLog.outDebug("SetGuardian %u for %u, apply %u", guardian->GetEntry(), GetEntry(), apply);
+
+ if(apply)
+ {
+ if(!guardian->SetOwner(this, true))
+ return;
+
+ m_Controlled.insert(guardian);
+
+ if(guardian->isPet() || guardian->m_Properties && guardian->m_Properties->Category == SUMMON_CATEGORY_PET)
+ {
+ if(Guardian* oldPet = GetGuardianPet())
+ {
+ if(oldPet != guardian && (oldPet->isPet() || guardian->isPet() || oldPet->GetEntry() != guardian->GetEntry()))
+ {
+ // remove existing guardian pet
+ if(oldPet->isPet())
+ ((Pet*)oldPet)->Remove(PET_SAVE_AS_CURRENT);
+ else
+ oldPet->UnSummon();
+ SetPetGUID(guardian->GetGUID());
+ SetGuardianGUID(0);
+ }
+ }
+ else
+ {
+ SetPetGUID(guardian->GetGUID());
+ SetGuardianGUID(0);
+ }
+ }
+
+ if(AddUInt64Value(UNIT_FIELD_SUMMON, guardian->GetGUID()))
+ {
+ if(GetTypeId() == TYPEID_PLAYER && !GetCharmGUID())
+ {
+ if(guardian->isPet())
+ ((Player*)this)->PetSpellInitialize();
+ else
+ ((Player*)this)->CharmSpellInitialize();
+ }
+ }
+
+ // FIXME: hack, speed must be set only at follow
+ if(HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
+ guardian->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
+
+ if(GetTypeId() == TYPEID_PLAYER && guardian->HasSummonMask(SUMMON_MASK_PET))
+ for(int i = 0; i < MAX_MOVE_TYPE; ++i)
+ guardian->SetSpeed(UnitMoveType(i), m_speed_rate[i], true);
+ }
+ else
+ {
+ if(!guardian->SetOwner(this, false))
+ return;
+
+ m_Controlled.erase(guardian);
+
+ if(guardian->isPet() || guardian->m_Properties && guardian->m_Properties->Category == SUMMON_CATEGORY_PET)
+ {
+ if(GetPetGUID() == guardian->GetGUID())
+ SetPetGUID(0);
+ }
+
+ if(RemoveUInt64Value(UNIT_FIELD_SUMMON, guardian->GetGUID()))
+ {
+ //Check if there is another guardian
+ for(ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
+ {
+ if(GetCharmGUID() == (*itr)->GetGUID())
+ continue;
+
+ assert((*itr)->GetOwnerGUID() == GetGUID());
+ assert((*itr)->GetTypeId() == TYPEID_UNIT);
+ if(AddUInt64Value(UNIT_FIELD_SUMMON, (*itr)->GetGUID()))
+ {
+ //show another pet bar if there is no charm bar
+ if(GetTypeId() == TYPEID_PLAYER && !GetCharmGUID())
+ {
+ if(((Creature*)(*itr))->isPet())
+ ((Player*)this)->PetSpellInitialize();
+ else
+ ((Player*)this)->CharmSpellInitialize();
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+
+void Unit::SetCharm(Unit* charm, bool apply)
+{
+ if(apply)
+ {
+ if(GetTypeId() == TYPEID_PLAYER)
+ {
+ if(!AddUInt64Value(UNIT_FIELD_CHARM, charm->GetGUID()))
+ sLog.outCrash("Player %s is trying to charm unit %u, but it already has a charmed unit %u", GetName(), charm->GetEntry(), GetCharmGUID());
+
+ charm->m_ControlledByPlayer = true;
+ }
+ else
+ charm->m_ControlledByPlayer = false;
+
+ if(!charm->AddUInt64Value(UNIT_FIELD_CHARMEDBY, GetGUID()))
+ sLog.outCrash("Unit %u is being charmed, but it already has a charmer %u", charm->GetEntry(), charm->GetCharmerGUID());
+
+ m_Controlled.insert(charm);
+ }
+ else
+ {
+ if(GetTypeId() == TYPEID_PLAYER)
+ {
+ if(!RemoveUInt64Value(UNIT_FIELD_CHARM, charm->GetGUID()))
+ sLog.outCrash("Player %s is trying to uncharm unit %u, but it has another charmed unit %u", GetName(), charm->GetEntry(), GetCharmGUID());
+ }
+
+ if(charm->GetTypeId() == TYPEID_PLAYER || IS_PLAYER_GUID(charm->GetOwnerGUID()))
+ charm->m_ControlledByPlayer = true;
+ else
+ charm->m_ControlledByPlayer = false;
+
+ if(!charm->RemoveUInt64Value(UNIT_FIELD_CHARMEDBY, GetGUID()))
+ sLog.outCrash("Unit %u is being uncharmed, but it has another charmer %u", charm->GetEntry(), charm->GetCharmerGUID());
+
+ m_Controlled.erase(charm);
+ }
+}
+
+int32 Unit::DealHeal(Unit *pVictim, uint32 addhealth, SpellEntry const *spellProto, bool critical)
+{
+ int32 gain = pVictim->ModifyHealth(int32(addhealth));
+
+ if (GetTypeId()==TYPEID_PLAYER)
+ {
+ SendHealSpellLog(pVictim, spellProto->Id, addhealth, critical, gain);
+
+ if (BattleGround *bg = ((Player*)this)->GetBattleGround())
+ bg->UpdatePlayerScore((Player*)this, SCORE_HEALING_DONE, gain);
+
+ // use the actual gain, as the overheal shall not be counted, skip gain 0 (it ignored anyway in to criteria)
+ if (gain)
+ ((Player*)this)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, gain, 0, pVictim);
+
+ ((Player*)this)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED, addhealth);
+ }
+
+ if (pVictim->GetTypeId()==TYPEID_PLAYER)
+ {
+ ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED, gain);
+ ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED, addhealth);
+ }
+
+ return gain;
+}
+
+Unit* Unit::SelectMagnetTarget(Unit *victim, SpellEntry const *spellInfo)
{
- SetUInt64Value(UNIT_FIELD_SUMMON, pet ? pet->GetGUID() : 0);
+ if(!victim)
+ return NULL;
+
+ // Magic case
+ if(spellInfo && (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE || spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC))
+ {
+ //I am not sure if this should be redirected.
+ if(spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE)
+ return victim;
+
+ Unit::AuraEffectList const& magnetAuras = victim->GetAurasByType(SPELL_AURA_SPELL_MAGNET);
+ for(Unit::AuraEffectList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr)
+ if(Unit* magnet = (*itr)->GetCaster())
+ if(magnet->isAlive())
+ {
+ (*itr)->GetParentAura()->DropAuraCharge();
+ return magnet;
+ }
+ }
+ // Melee && ranged case
+ else
+ {
+ AuraEffectList const& hitTriggerAuras = victim->GetAurasByType(SPELL_AURA_ADD_CASTER_HIT_TRIGGER);
+ for(AuraEffectList::const_iterator i = hitTriggerAuras.begin(); i != hitTriggerAuras.end(); ++i)
+ if(Unit* magnet = (*i)->GetCaster())
+ if(magnet->isAlive() && magnet->IsWithinLOSInMap(this))
+ if(roll_chance_i((*i)->GetAmount()))
+ {
+ (*i)->GetParentAura()->DropAuraCharge();
+ return magnet;
+ }
+ }
- // FIXME: hack, speed must be set only at follow
- if(pet)
- for(int i = 0; i < MAX_MOVE_TYPE; ++i)
- pet->SetSpeed(UnitMoveType(i), m_speed_rate[i], true);
+ return victim;
}
-void Unit::SetCharm(Unit* pet)
+Unit* Unit::GetFirstControlled() const
{
+ //Sequence: charmed, pet, other guardians
+ Unit *unit = GetCharm();
+ if(!unit)
+ {
+ if(uint64 guid = GetUInt64Value(UNIT_FIELD_SUMMON))
+ unit = ObjectAccessor::GetUnit(*this, guid);
+ }
+ return unit;
+}
+
+void Unit::RemoveAllControlled()
+{
+ //possessed pet and vehicle
if(GetTypeId() == TYPEID_PLAYER)
- SetUInt64Value(UNIT_FIELD_CHARM, pet ? pet->GetGUID() : 0);
+ ((Player*)this)->StopCastingCharm();
+
+ while(!m_Controlled.empty())
+ {
+ Unit *target = *m_Controlled.begin();
+ m_Controlled.erase(m_Controlled.begin());
+ if(target->GetCharmerGUID() == GetGUID())
+ {
+ target->RemoveCharmAuras();
+ }
+ else if(target->GetOwnerGUID() == GetGUID()
+ && target->GetTypeId() == TYPEID_UNIT
+ && ((Creature*)target)->HasSummonMask(SUMMON_MASK_SUMMON))
+ {
+
+ if(!((TempSummon*)target)->isPet())
+ ((TempSummon*)target)->UnSummon();
+ }
+ else
+ {
+ sLog.outError("Unit %u is trying to release unit %u which is neither charmed nor owned by it", GetEntry(), target->GetEntry());
+ }
+ }
+ if(GetPetGUID() != GetUInt64Value(UNIT_FIELD_SUMMON))
+ sLog.outCrash("Unit %u is not able to release its summon %u", GetEntry(), GetPetGUID());
+ if(GetCharmGUID())
+ sLog.outCrash("Unit %u is not able to release its charm %u", GetEntry(), GetCharmGUID());
}
+Unit* Unit::GetNextRandomRaidMemberOrPet(float radius)
+{
+ Player* player = NULL;
+ if(GetTypeId() == TYPEID_PLAYER)
+ player = (Player*)this;
+ // Should we enable this also for charmed units?
+ else if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet())
+ player=(Player*)GetOwner();
+
+ if (!player)
+ return NULL;
+ Group *pGroup = player->GetGroup();
+ //When there is no group check pet presence
+ if (!pGroup)
+ {
+ // We are pet now, return owner
+ if(player!=this)
+ return IsWithinDistInMap(player, radius) ? player : NULL;
+ Unit * pet = GetGuardianPet();
+ //No pet, no group, nothing to return
+ if (!pet)
+ return NULL;
+ // We are owner now, return pet
+ return IsWithinDistInMap(pet, radius) ? pet : NULL;
+ }
+
+ std::vector<Unit*> nearMembers;
+ //reserve place for players and pets because resizing vector every unit push is unefficient (vector is reallocated then)
+ nearMembers.reserve(pGroup->GetMembersCount()*2);
+
+ for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+ {
+ Player* Target = itr->getSource();
+
+ // IsHostileTo check duel and controlled by enemy
+ if( Target && Target !=this && Target->isAlive() && IsWithinDistInMap(Target, radius) &&
+ !IsHostileTo(Target) )
+ nearMembers.push_back(Target);
+
+ // Push player's pet to vector
+ Unit * pet = Target->GetGuardianPet();
+ if (pet && pet !=this && pet->isAlive() && IsWithinDistInMap(pet, radius) &&
+ !IsHostileTo(pet) )
+ nearMembers.push_back(pet);
+ }
+
+ if (nearMembers.empty())
+ return NULL;
+
+ uint32 randTarget = urand(0,nearMembers.size()-1);
+ return nearMembers[randTarget];
+}
+
+//only called in Player::SetSeer
void Unit::AddPlayerToVision(Player* plr)
{
if(m_sharedVision.empty())
@@ -8177,9 +8394,9 @@ void Unit::AddPlayerToVision(Player* plr)
SetWorldObject(true);
}
m_sharedVision.push_back(plr);
- plr->SetFarsightTarget(this);
}
+//only called in Player::SetSeer
void Unit::RemovePlayerFromVision(Player* plr)
{
m_sharedVision.remove(plr);
@@ -8188,35 +8405,34 @@ void Unit::RemovePlayerFromVision(Player* plr)
setActive(false);
SetWorldObject(false);
}
- plr->ClearFarsight();
}
void Unit::RemoveBindSightAuras()
{
- RemoveSpellsCausingAura(SPELL_AURA_BIND_SIGHT);
+ RemoveAurasByType(SPELL_AURA_BIND_SIGHT);
}
void Unit::RemoveCharmAuras()
{
- RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM);
- RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS_PET);
- RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS);
+ RemoveAurasByType(SPELL_AURA_MOD_CHARM);
+ RemoveAurasByType(SPELL_AURA_MOD_POSSESS_PET);
+ RemoveAurasByType(SPELL_AURA_MOD_POSSESS);
}
void Unit::UnsummonAllTotems()
{
- for (int8 i = 0; i < MAX_TOTEM; ++i)
+ for (int8 i = 0; i < MAX_SUMMON_SLOT; ++i)
{
- if(!m_TotemSlot[i])
+ if(!m_SummonSlot[i])
continue;
- Creature *OldTotem = ObjectAccessor::GetCreature(*this, m_TotemSlot[i]);
- if (OldTotem && OldTotem->isTotem())
- ((Totem*)OldTotem)->UnSummon();
+ Creature *OldTotem = GetMap()->GetCreature(m_SummonSlot[i]);
+ if(OldTotem && OldTotem->isSummon())
+ ((TempSummon*)OldTotem)->UnSummon();
}
}
-void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, bool critical)
+void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, bool critical, int32 gain)
{
// we guess size
WorldPacket data(SMSG_SPELLHEALLOG, (8+8+4+4+1));
@@ -8224,6 +8440,7 @@ void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, bool c
data.append(GetPackGUID());
data << uint32(SpellID);
data << uint32(Damage);
+ data << uint32((int32)Damage > gain ? (int32)Damage - gain : 0); // overheal
data << uint8(critical ? 1 : 0);
data << uint8(0); // unused in client?
SendMessageToSet(&data, true);
@@ -8240,426 +8457,319 @@ void Unit::SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, Po
SendMessageToSet(&data, true);
}
-uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 pdamage, DamageEffectType damagetype)
+uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack)
{
if(!spellProto || !pVictim || damagetype==DIRECT_DAMAGE )
return pdamage;
- //if(spellProto->SchoolMask == SPELL_SCHOOL_MASK_NORMAL)
- // return pdamage;
- //damage = CalcArmorReducedDamage(pVictim, damage);
-
- int32 BonusDamage = 0;
- if( GetTypeId()==TYPEID_UNIT )
- {
- // Pets just add their bonus damage to their spell damage
- // note that their spell damage is just gain of their own auras
- if (((Creature*)this)->isPet())
- {
- BonusDamage = ((Pet*)this)->GetBonusDamage();
- }
- // For totems get damage bonus from owner (statue isn't totem in fact)
- else if (((Creature*)this)->isTotem() && ((Totem*)this)->GetTotemType()!=TOTEM_STATUE)
- {
- if(Unit* owner = GetOwner())
- return owner->SpellDamageBonus(pVictim, spellProto, pdamage, damagetype);
- }
- }
-
- // Damage Done
- uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
-
- // Taken/Done fixed damage bonus auras
- int32 DoneAdvertisedBenefit = SpellBaseDamageBonus(GetSpellSchoolMask(spellProto))+BonusDamage;
- int32 TakenAdvertisedBenefit = SpellBaseDamageBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
-
- // Damage over Time spells bonus calculation
- float DotFactor = 1.0f;
- if(damagetype == DOT)
+ // For totems get damage bonus from owner (statue isn't totem in fact)
+ if( GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem())
{
- int32 DotDuration = GetSpellDuration(spellProto);
- // 200% limit
- if(DotDuration > 0)
- {
- if(DotDuration > 30000) DotDuration = 30000;
- if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
- int x = 0;
- for(int j = 0; j < 3; j++)
- {
- if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
- spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||
- spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
- {
- x = j;
- break;
- }
- }
- int DotTicks = 6;
- if(spellProto->EffectAmplitude[x] != 0)
- DotTicks = DotDuration / spellProto->EffectAmplitude[x];
- if(DotTicks)
- {
- DoneAdvertisedBenefit /= DotTicks;
- TakenAdvertisedBenefit /= DotTicks;
- }
- }
+ if(Unit* owner = GetOwner())
+ return owner->SpellDamageBonus(pVictim, spellProto, pdamage, damagetype);
}
// Taken/Done total percent damage auras
float DoneTotalMod = 1.0f;
float TakenTotalMod = 1.0f;
+ int32 DoneTotal = 0;
+ int32 TakenTotal = 0;
// ..done
- AuraList const& mModDamagePercentDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
- for(AuraList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
+ // Pet damage
+ if( GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet() )
+ DoneTotalMod *= ((Creature*)this)->GetSpellDamageMod(((Creature*)this)->GetCreatureInfo()->rank);
+
+ AuraEffectList const& mModDamagePercentDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ for(AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
{
- if( ((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto)) &&
+ if( ((*i)->GetMiscValue() & GetSpellSchoolMask(spellProto)) &&
(*i)->GetSpellProto()->EquippedItemClass == -1 &&
// -1 == any item class (not wand then)
(*i)->GetSpellProto()->EquippedItemInventoryTypeMask == 0 )
// 0 == any inventory type (not wand then)
{
- DoneTotalMod *= ((*i)->GetModifierValue() +100.0f)/100.0f;
+ DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
}
}
uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
- AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);
- for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i)
- if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- DoneTotalMod *= ((*i)->GetModifierValue() +100.0f)/100.0f;
-
- // ..taken
- AuraList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
- for(AuraList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i)
- if( (*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto) )
- TakenTotalMod *= ((*i)->GetModifierValue() +100.0f)/100.0f;
-
- // .. taken pct: scripted (increases damage of * against targets *)
- AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
- {
- switch((*i)->GetModifier()->m_miscvalue)
- {
- //Molten Fury
- case 4920: case 4919:
- if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_20_PERCENT))
- TakenTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f; break;
- }
- }
-
- bool hasmangle=false;
- // .. taken pct: dummy auras
- AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
- for(AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
- {
- switch((*i)->GetSpellProto()->SpellIconID)
+ // Add flat bonus from spell damage versus
+ DoneTotal += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS, creatureTypeMask);
+ AuraEffectList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);
+ for(AuraEffectList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i)
+ if(creatureTypeMask & uint32((*i)->GetMiscValue()))
+ DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
+
+ // done scripted mod (take it from owner)
+ Unit *owner = GetOwner();
+ if (!owner) owner = this;
+ AuraEffectList const& mOverrideClassScript= owner->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ for(AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
+ {
+ if (!(*i)->isAffectedOnSpell(spellProto))
+ continue;
+ switch((*i)->GetMiscValue())
{
- //Cheat Death
- case 2109:
- if( ((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto)) )
- {
- if(pVictim->GetTypeId() != TYPEID_PLAYER)
- continue;
- float mod = -((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL)*2*4;
- if (mod < (*i)->GetModifier()->m_amount)
- mod = (*i)->GetModifier()->m_amount;
- TakenTotalMod *= (mod+100.0f)/100.0f;
- }
+ case 4920: // Molten Fury
+ case 4919:
+ case 6917: // Death's Embrace
+ case 6926:
+ case 6928:
+ {
+ if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
+ DoneTotalMod *= (100.0f+(*i)->GetAmount())/100.0f;
break;
- //This is changed in WLK, using aura 255
- //Mangle
- case 2312:
- case 44955:
- // don't apply mod twice
- if (hasmangle)
- break;
- hasmangle=true;
- for(int j=0;j<3;j++)
- {
- if(GetEffectMechanic(spellProto, j)==MECHANIC_BLEED)
+ }
+ // Soul Siphon
+ case 4992:
+ case 4993:
+ {
+ // effect 1 m_amount
+ int32 maxPercent = (*i)->GetAmount();
+ // effect 0 m_amount
+ int32 stepPercent = CalculateSpellDamage((*i)->GetSpellProto(), 0, (*i)->GetSpellProto()->EffectBasePoints[0], this);
+ // count affliction effects and calc additional damage in percentage
+ int32 modPercent = 0;
+ AuraMap const& victimAuras = pVictim->GetAuras();
+ for (AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr)
+ {
+ SpellEntry const* m_spell = itr->second->GetSpellProto();
+ if (m_spell->SpellFamilyName != SPELLFAMILY_WARLOCK || !(m_spell->SpellFamilyFlags[1] & 0x0004071B || m_spell->SpellFamilyFlags[0] & 0x8044C402))
+ continue;
+ modPercent += stepPercent * itr->second->GetStackAmount();
+ if (modPercent >= maxPercent)
{
- TakenTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f;
+ modPercent = maxPercent;
break;
}
}
+ DoneTotalMod *= (modPercent+100.0f)/100.0f;
break;
- }
- }
-
- // Distribute Damage over multiple effects, reduce by AoE
- CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
-
- // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
- for(int j = 0; j < 3; ++j)
- {
- if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
- spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH )
- {
- CastingTime /= 2;
- break;
- }
- }
-
- switch(spellProto->SpellFamilyName)
- {
- case SPELLFAMILY_GENERIC:
- // Siphon Essence - 0%
- if(spellProto->AttributesEx == 268435456 && spellProto->SpellIconID == 2027)
- {
- CastingTime = 0;
- }
- // Goblin Rocket Launcher - 0%
- else if (spellProto->SpellIconID == 184 && spellProto->Attributes == 4259840)
- {
- CastingTime = 0;
- }
- // Darkmoon Card: Vengeance - 0.1%
- else if (spellProto->SpellVisual == 9850 && spellProto->SpellIconID == 2230)
- {
- CastingTime = 3.5;
- }
- case SPELLFAMILY_MAGE:
- // Ignite - do not modify, it is (8*Rank)% damage of procing Spell
- if(spellProto->Id==12654)
- {
- return pdamage;
- }
- // Ice Lance
- else if((spellProto->SpellFamilyFlags & 0x20000LL) && spellProto->SpellIconID == 186)
- {
- CastingTime /= 3; // applied 1/3 bonuses in case generic target
- if(pVictim->isFrozen()) // and compensate this for frozen target.
- TakenTotalMod *= 3.0f;
- }
- // Pyroblast - 115% of Fire Damage, DoT - 20% of Fire Damage
- else if((spellProto->SpellFamilyFlags & 0x400000LL) && spellProto->SpellIconID == 184 )
- {
- DotFactor = damagetype == DOT ? 0.2f : 1.0f;
- CastingTime = damagetype == DOT ? 3500 : 4025;
- }
- // Fireball - 100% of Fire Damage, DoT - 0% of Fire Damage
- else if((spellProto->SpellFamilyFlags & 0x1LL) && spellProto->SpellIconID == 185)
- {
- CastingTime = 3500;
- DotFactor = damagetype == DOT ? 0.0f : 1.0f;
- }
- // Molten armor
- else if (spellProto->SpellFamilyFlags & 0x0000000800000000LL)
- {
- CastingTime = 0;
- }
- // Arcane Missiles triggered spell
- else if ((spellProto->SpellFamilyFlags & 0x200000LL) && spellProto->SpellIconID == 225)
- {
- CastingTime = 1000;
- }
- // Blizzard triggered spell
- else if ((spellProto->SpellFamilyFlags & 0x80080LL) && spellProto->SpellIconID == 285)
- {
- CastingTime = 500;
- }
- break;
- case SPELLFAMILY_WARLOCK:
- // Life Tap
- if((spellProto->SpellFamilyFlags & 0x40000LL) && spellProto->SpellIconID == 208)
- {
- CastingTime = 2800; // 80% from +shadow damage
- DoneTotalMod = 1.0f;
- TakenTotalMod = 1.0f;
}
- // Dark Pact
- else if((spellProto->SpellFamilyFlags & 0x80000000LL) && spellProto->SpellIconID == 154 && GetPetGUID())
- {
- CastingTime = 3360; // 96% from +shadow damage
- DoneTotalMod = 1.0f;
- TakenTotalMod = 1.0f;
- }
- // Soul Fire - 115% of Fire Damage
- else if((spellProto->SpellFamilyFlags & 0x8000000000LL) && spellProto->SpellIconID == 184)
- {
- CastingTime = 4025;
- }
- // Curse of Agony - 120% of Shadow Damage
- else if((spellProto->SpellFamilyFlags & 0x0000000400LL) && spellProto->SpellIconID == 544)
- {
- DotFactor = 1.2f;
- }
- // Drain Mana - 0% of Shadow Damage
- else if((spellProto->SpellFamilyFlags & 0x10LL) && spellProto->SpellIconID == 548)
+ case 6916: // Death's Embrace
+ case 6925:
+ case 6927:
+ if (HasAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, spellProto, this))
+ DoneTotalMod *= (100.0f+(*i)->GetAmount())/100.0f;
+ break;
+ case 5481: // Starfire Bonus
{
- CastingTime = 0;
+ if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x200002, 0))
+ DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
+ break;
}
- // Drain Soul 214.3%
- else if ((spellProto->SpellFamilyFlags & 0x4000LL) && spellProto->SpellIconID == 113 )
+ case 4418: // Increased Shock Damage
+ case 4554: // Increased Lightning Damage
+ case 4555: // Improved Moonfire
+ case 5142: // Increased Lightning Damage
+ case 5147: // Improved Consecration / Libram of Resurgence
+ case 5148: // Idol of the Shooting Star
+ case 6008: // Increased Lightning Damage / Totem of Hex
{
- CastingTime = 7500;
+ DoneTotal+=(*i)->GetAmount();
+ break;
}
- // Hellfire
- else if ((spellProto->SpellFamilyFlags & 0x40LL) && spellProto->SpellIconID == 937)
+ // Tundra Stalker
+ // Merciless Combat
+ case 7277:
{
- CastingTime = damagetype == DOT ? 5000 : 500; // self damage seems to be so
+ // Merciless Combat
+ if ((*i)->GetSpellProto()->SpellIconID == 2656)
+ {
+ if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
+ DoneTotalMod *= (100.0f+(*i)->GetAmount())/100.0f;
+ }
+ else // Tundra Stalker
+ {
+ if (pVictim->GetAura(SPELL_AURA_DUMMY, SPELLFAMILY_DEATHKNIGHT,0, 0x04000000,0))
+ DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
+ break;
+ }
+ break;
}
- // Unstable Affliction - 180%
- else if (spellProto->Id == 31117 && spellProto->SpellIconID == 232)
+ case 7293: // Rage of Rivendare
{
- CastingTime = 6300;
+ if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, 0,0x02000000,0))
+ DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
+ break;
}
- // Corruption 93%
- else if ((spellProto->SpellFamilyFlags & 0x2LL) && spellProto->SpellIconID == 313)
+ // Twisted Faith
+ case 7377:
{
- DotFactor = 0.93f;
+ if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0,0, GetGUID()))
+ DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
+ break;
}
- break;
- case SPELLFAMILY_PALADIN:
- // Consecration - 95% of Holy Damage
- if((spellProto->SpellFamilyFlags & 0x20LL) && spellProto->SpellIconID == 51)
+ // Marked for Death
+ case 7598:
+ case 7599:
+ case 7600:
+ case 7601:
+ case 7602:
{
- DotFactor = 0.95f;
- CastingTime = 3500;
+ if (pVictim->GetAura(SPELL_AURA_MOD_STALKED, SPELLFAMILY_HUNTER, 0x400, 0))
+ DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
+ break;
}
- // Seal of Righteousness - 10.2%/9.8% ( based on weapon type ) of Holy Damage, multiplied by weapon speed
- else if((spellProto->SpellFamilyFlags & 0x8000000LL) && spellProto->SpellIconID == 25)
- {
- Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
- float wspeed = GetAttackTime(BASE_ATTACK)/1000.0f;
+ }
+ }
- if( item && item->GetProto()->InventoryType == INVTYPE_2HWEAPON)
- CastingTime = uint32(wspeed*3500*0.102f);
- else
- CastingTime = uint32(wspeed*3500*0.098f);
- }
- // Judgement of Righteousness - 73%
- else if ((spellProto->SpellFamilyFlags & 1024) && spellProto->SpellIconID == 25)
- {
- CastingTime = 2555;
- }
- // Seal of Vengeance - 17% per Fully Stacked Tick - 5 Applications
- else if ((spellProto->SpellFamilyFlags & 0x80000000000LL) && spellProto->SpellIconID == 2292)
- {
- DotFactor = 0.85f;
- CastingTime = 3500;
- }
- // Holy shield - 5% of Holy Damage
- else if ((spellProto->SpellFamilyFlags & 0x4000000000LL) && spellProto->SpellIconID == 453)
- {
- CastingTime = 175;
- }
- // Blessing of Sanctuary - 0%
- else if ((spellProto->SpellFamilyFlags & 0x10000000LL) && spellProto->SpellIconID == 29)
- {
- CastingTime = 0;
- }
- // Seal of Righteousness trigger - already computed for parent spell
- else if ( spellProto->SpellFamilyName==SPELLFAMILY_PALADIN && spellProto->SpellIconID==25 && spellProto->AttributesEx4 & 0x00800000LL )
- {
- return pdamage;
- }
- break;
- case SPELLFAMILY_SHAMAN:
- // totem attack
- if (spellProto->SpellFamilyFlags & 0x000040000000LL)
- {
- if (spellProto->SpellIconID == 33) // Fire Nova totem attack must be 21.4%(untested)
- CastingTime = 749; // ignore CastingTime and use as modifier
- else if (spellProto->SpellIconID == 680) // Searing Totem attack 8%
- CastingTime = 280; // ignore CastingTime and use as modifier
- else if (spellProto->SpellIconID == 37) // Magma totem attack must be 6.67%(untested)
- CastingTime = 234; // ignore CastingTimePenalty and use as modifier
- }
- // Lightning Shield (and proc shield from T2 8 pieces bonus ) 33% per charge
- else if( (spellProto->SpellFamilyFlags & 0x00000000400LL) || spellProto->Id == 23552)
- CastingTime = 1155; // ignore CastingTimePenalty and use as modifier
- break;
- case SPELLFAMILY_PRIEST:
- // Mana Burn - 0% of Shadow Damage
- if((spellProto->SpellFamilyFlags & 0x10LL) && spellProto->SpellIconID == 212)
- {
- CastingTime = 0;
- }
- // Mind Flay - 59% of Shadow Damage
- else if((spellProto->SpellFamilyFlags & 0x800000LL) && spellProto->SpellIconID == 548)
- {
- CastingTime = 2065;
- }
- // Holy Fire - 86.71%, DoT - 16.5%
- else if ((spellProto->SpellFamilyFlags & 0x100000LL) && spellProto->SpellIconID == 156)
- {
- DotFactor = damagetype == DOT ? 0.165f : 1.0f;
- CastingTime = damagetype == DOT ? 3500 : 3035;
- }
- // Shadowguard - 28% per charge
- else if ((spellProto->SpellFamilyFlags & 0x2000000LL) && spellProto->SpellIconID == 19)
- {
- CastingTime = 980;
- }
- // Touch of Weakeness - 10%
- else if ((spellProto->SpellFamilyFlags & 0x80000LL) && spellProto->SpellIconID == 1591)
- {
- CastingTime = 350;
- }
- // Reflective Shield (back damage) - 0% (other spells fit to check not have damage effects/auras)
- else if (spellProto->SpellFamilyFlags == 0 && spellProto->SpellIconID == 566)
- {
- CastingTime = 0;
- }
- // Holy Nova - 14%
- else if ((spellProto->SpellFamilyFlags & 0x400000LL) && spellProto->SpellIconID == 1874)
- {
- CastingTime = 500;
- }
- break;
- case SPELLFAMILY_DRUID:
- // Hurricane triggered spell
- if((spellProto->SpellFamilyFlags & 0x400000LL) && spellProto->SpellIconID == 220)
+ // Custom scripted damage
+ // Ice Lance
+ if (spellProto->SpellFamilyName == SPELLFAMILY_MAGE && spellProto->SpellIconID == 186)
+ {
+ if (pVictim->HasAuraState(AURA_STATE_FROZEN, spellProto, this))
+ DoneTotalMod *= 3.0f;
+ }
+
+ // Torment the weak
+ if (spellProto->SpellFamilyName== SPELLFAMILY_MAGE && (spellProto->SpellFamilyFlags[0]&0x20200021 || spellProto->SpellFamilyFlags[1]& 0x9000))
+ {
+ if(pVictim->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED))
+ {
+ AuraEffectList const& mDumyAuras = GetAurasByType(SPELL_AURA_DUMMY);
+ for(AuraEffectList::const_iterator i = mDumyAuras.begin(); i != mDumyAuras.end(); ++i)
{
- CastingTime = 500;
+ if ((*i)->GetSpellProto()->SpellIconID == 3263)
+ {
+ DoneTotalMod *=float((*i)->GetAmount() + 100.f) / 100.f;
+ break;
+ }
}
- break;
- case SPELLFAMILY_WARRIOR:
- case SPELLFAMILY_HUNTER:
- case SPELLFAMILY_ROGUE:
- CastingTime = 0;
- break;
- default:
- break;
+ }
}
- float LvlPenalty = CalculateLevelPenalty(spellProto);
-
- // Spellmod SpellDamage
- //float SpellModSpellDamage = 100.0f;
- float CoefficientPtc = DotFactor * 100.0f;
- if(spellProto->SchoolMask != SPELL_SCHOOL_MASK_NORMAL)
- CoefficientPtc *= ((float)CastingTime/3500.0f);
+ // ..taken
+ AuraEffectList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
+ for(AuraEffectList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i)
+ if( (*i)->GetMiscValue() & GetSpellSchoolMask(spellProto) )
+ TakenTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
- if(Player* modOwner = GetSpellModOwner())
- //modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,SpellModSpellDamage);
- modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,CoefficientPtc);
+ // .. taken pct: dummy auras
+ if (pVictim->GetTypeId() == TYPEID_PLAYER)
+ {
+ //Cheat Death
+ if (AuraEffect *dummy = pVictim->GetDummyAura(45182))
+ {
+ float mod = -((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL)*2*4;
+ if (mod < dummy->GetAmount())
+ mod = dummy->GetAmount();
+ TakenTotalMod *= (mod+100.0f)/100.0f;
+ }
+ }
- //SpellModSpellDamage /= 100.0f;
- CoefficientPtc /= 100.0f;
+ // From caster spells
+ AuraEffectList const& mOwnerTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER);
+ for(AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i)
+ if( (*i)->GetCasterGUID() == GetGUID() && (*i)->isAffectedOnSpell(spellProto))
+ TakenTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
- //float DoneActualBenefit = DoneAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty;
+ // Mod damage from spell mechanic
+ uint32 mechanicMask = GetAllSpellMechanicMask(spellProto);
+ if (mechanicMask)
+ {
+ AuraEffectList const& mDamageDoneMechanic = pVictim->GetAurasByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
+ for(AuraEffectList::const_iterator i = mDamageDoneMechanic.begin();i != mDamageDoneMechanic.end(); ++i)
+ if(mechanicMask & uint32(1<<((*i)->GetMiscValue())))
+ TakenTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
+ }
- float DoneActualBenefit = DoneAdvertisedBenefit * CoefficientPtc * LvlPenalty;
- float TakenActualBenefit = TakenAdvertisedBenefit * DotFactor * LvlPenalty;
- if(spellProto->SpellFamilyName && spellProto->SchoolMask != SPELL_SCHOOL_MASK_NORMAL)
- TakenActualBenefit *= ((float)CastingTime / 3500.0f);
+ // Taken/Done fixed damage bonus auras
+ int32 DoneAdvertisedBenefit = SpellBaseDamageBonus(GetSpellSchoolMask(spellProto));
+ int32 TakenAdvertisedBenefit = SpellBaseDamageBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
+ // Pets just add their bonus damage to their spell damage
+ // note that their spell damage is just gain of their own auras
+ if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->HasSummonMask(SUMMON_MASK_GUARDIAN))
+ DoneAdvertisedBenefit += ((Guardian*)this)->GetBonusDamage();
+
+ // Check for table values
+ float coeff;
+ SpellBonusEntry const* bonus = spellmgr.GetSpellBonusData(spellProto->Id);
+ if (bonus)
+ {
+ if (damagetype == DOT)
+ coeff = bonus->dot_damage;
+ else
+ coeff = bonus->direct_damage;
+ if (bonus->ap_bonus)
+ DoneTotal+=bonus->ap_bonus * GetTotalAttackPowerValue(BASE_ATTACK) * stack;
+ }
+ // Default calculation
+ if (DoneAdvertisedBenefit || TakenAdvertisedBenefit)
+ {
+ if(!bonus)
+ {
+ // Damage Done from spell damage bonus
+ int32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
+ // Damage over Time spells bonus calculation
+ float DotFactor = 1.0f;
+ if(damagetype == DOT)
+ {
+ int32 DotDuration = GetSpellDuration(spellProto);
+ // 200% limit
+ if(DotDuration > 0)
+ {
+ if(DotDuration > 30000) DotDuration = 30000;
+ if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
+ int x = 0;
+ for(int j = 0; j < 3; j++)
+ {
+ if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
+ spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||
+ spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
+ {
+ x = j;
+ break;
+ }
+ }
+ int32 DotTicks = 6;
+ if(spellProto->EffectAmplitude[x] != 0)
+ DotTicks = DotDuration / spellProto->EffectAmplitude[x];
+ if(DotTicks)
+ {
+ DoneAdvertisedBenefit /= DotTicks;
+ TakenAdvertisedBenefit /= DotTicks;
+ }
+ }
+ }
+ // Distribute Damage over multiple effects, reduce by AoE
+ CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
- float tmpDamage = (float(pdamage)+DoneActualBenefit)*DoneTotalMod;
+ // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
+ for(int j = 0; j < 3; ++j)
+ {
+ if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
+ spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH )
+ {
+ CastingTime /= 2;
+ break;
+ }
+ }
+ if(spellProto->SchoolMask != SPELL_SCHOOL_MASK_NORMAL)
+ coeff = (CastingTime / 3500.0f) * DotFactor;
+ else
+ coeff = DotFactor;
+ }
- // Add flat bonus from spell damage versus
- tmpDamage += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS, creatureTypeMask);
+ float coeff2 = CalculateLevelPenalty(spellProto) * stack;
+ if(spellProto->SpellFamilyName) //TODO: fix this
+ TakenTotal+= TakenAdvertisedBenefit * coeff * coeff2;
+ if(Player* modOwner = GetSpellModOwner())
+ {
+ coeff *= 100.0f;
+ modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_SPELL_BONUS_DAMAGE, coeff);
+ coeff /= 100.0f;
+ }
+ DoneTotal += DoneAdvertisedBenefit * coeff * coeff2;
+ }
- // apply spellmod to Done damage
+ float tmpDamage = (pdamage + DoneTotal) * DoneTotalMod;
+ // apply spellmod to Done damage (flat and pct)
if(Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage);
- tmpDamage = (tmpDamage+TakenActualBenefit)*TakenTotalMod;
-
- if( GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet() )
- tmpDamage *= ((Creature*)this)->GetSpellDamageMod(((Creature*)this)->GetCreatureInfo()->rank);
+ tmpDamage = (tmpDamage + TakenTotal) * TakenTotalMod;
return tmpDamage > 0 ? uint32(tmpDamage) : 0;
}
@@ -8669,39 +8779,36 @@ int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask)
int32 DoneAdvertisedBenefit = 0;
// ..done
- AuraList const& mDamageDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE);
- for(AuraList::const_iterator i = mDamageDone.begin();i != mDamageDone.end(); ++i)
- if(((*i)->GetModifier()->m_miscvalue & schoolMask) != 0 &&
+ AuraEffectList const& mDamageDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE);
+ for(AuraEffectList::const_iterator i = mDamageDone.begin();i != mDamageDone.end(); ++i)
+ if(((*i)->GetMiscValue() & schoolMask) != 0 &&
(*i)->GetSpellProto()->EquippedItemClass == -1 &&
// -1 == any item class (not wand then)
(*i)->GetSpellProto()->EquippedItemInventoryTypeMask == 0 )
// 0 == any inventory type (not wand then)
- DoneAdvertisedBenefit += (*i)->GetModifierValue();
+ DoneAdvertisedBenefit += (*i)->GetAmount();
if (GetTypeId() == TYPEID_PLAYER)
{
+ // Base value
+ DoneAdvertisedBenefit +=((Player*)this)->GetBaseSpellDamageBonus();
+
// Damage bonus from stats
- AuraList const& mDamageDoneOfStatPercent = GetAurasByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT);
- for(AuraList::const_iterator i = mDamageDoneOfStatPercent.begin();i != mDamageDoneOfStatPercent.end(); ++i)
+ AuraEffectList const& mDamageDoneOfStatPercent = GetAurasByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT);
+ for(AuraEffectList::const_iterator i = mDamageDoneOfStatPercent.begin();i != mDamageDoneOfStatPercent.end(); ++i)
{
- if((*i)->GetModifier()->m_miscvalue & schoolMask)
+ if((*i)->GetMiscValue() & schoolMask)
{
- SpellEntry const* iSpellProto = (*i)->GetSpellProto();
- uint8 eff = (*i)->GetEffIndex();
-
- // stat used dependent from next effect aura SPELL_AURA_MOD_SPELL_HEALING presence and misc value (stat index)
- Stats usedStat = STAT_INTELLECT;
- if(eff < 2 && iSpellProto->EffectApplyAuraName[eff+1]==SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT)
- usedStat = Stats(iSpellProto->EffectMiscValue[eff+1]);
-
- DoneAdvertisedBenefit += int32(GetStat(usedStat) * (*i)->GetModifierValue() / 100.0f);
+ // stat used stored in miscValueB for this aura
+ Stats usedStat = Stats((*i)->GetMiscBValue());
+ DoneAdvertisedBenefit += int32(GetStat(usedStat) * (*i)->GetAmount() / 100.0f);
}
}
// ... and attack power
- AuraList const& mDamageDonebyAP = GetAurasByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER);
- for(AuraList::const_iterator i =mDamageDonebyAP.begin();i != mDamageDonebyAP.end(); ++i)
- if ((*i)->GetModifier()->m_miscvalue & schoolMask)
- DoneAdvertisedBenefit += int32(GetTotalAttackPowerValue(BASE_ATTACK) * (*i)->GetModifierValue() / 100.0f);
+ AuraEffectList const& mDamageDonebyAP = GetAurasByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER);
+ for(AuraEffectList::const_iterator i =mDamageDonebyAP.begin();i != mDamageDonebyAP.end(); ++i)
+ if ((*i)->GetMiscValue() & schoolMask)
+ DoneAdvertisedBenefit += int32(GetTotalAttackPowerValue(BASE_ATTACK) * (*i)->GetAmount() / 100.0f);
}
return DoneAdvertisedBenefit;
@@ -8713,16 +8820,16 @@ int32 Unit::SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVic
int32 TakenAdvertisedBenefit = 0;
// ..done (for creature type by mask) in taken
- AuraList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);
- for(AuraList::const_iterator i = mDamageDoneCreature.begin();i != mDamageDoneCreature.end(); ++i)
- if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- TakenAdvertisedBenefit += (*i)->GetModifierValue();
+ AuraEffectList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);
+ for(AuraEffectList::const_iterator i = mDamageDoneCreature.begin();i != mDamageDoneCreature.end(); ++i)
+ if(creatureTypeMask & uint32((*i)->GetMiscValue()))
+ TakenAdvertisedBenefit += (*i)->GetAmount();
// ..taken
- AuraList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
- for(AuraList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i)
- if(((*i)->GetModifier()->m_miscvalue & schoolMask) != 0)
- TakenAdvertisedBenefit += (*i)->GetModifierValue();
+ AuraEffectList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
+ for(AuraEffectList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i)
+ if(((*i)->GetMiscValue() & schoolMask) != 0)
+ TakenAdvertisedBenefit += (*i)->GetAmount();
return TakenAdvertisedBenefit;
}
@@ -8751,30 +8858,86 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
crit_chance += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, schoolMask);
}
// taken
- if (pVictim && !IsPositiveSpell(spellProto->Id))
- {
- // Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE
- crit_chance += pVictim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE, schoolMask);
- // Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE
- crit_chance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE);
- // Modify by player victim resilience
- if (pVictim->GetTypeId() == TYPEID_PLAYER)
- crit_chance -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL);
+ if (pVictim)
+ {
+ if (!IsPositiveSpell(spellProto->Id))
+ {
+ // Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE
+ crit_chance += pVictim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE, schoolMask);
+ // Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE
+ crit_chance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE);
+ // Modify by player victim resilience
+ if (pVictim->GetTypeId() == TYPEID_PLAYER)
+ crit_chance -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL);
+ }
// scripted (increase crit chance ... against ... target by x%
- if(pVictim->isFrozen()) // Shatter
+ AuraEffectList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ for(AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
- AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
+ if (!((*i)->isAffectedOnSpell(spellProto)))
+ continue;
+ int32 modChance=0;
+ switch((*i)->GetMiscValue())
{
- switch((*i)->GetModifier()->m_miscvalue)
+ // Shatter
+ case 911: modChance+= 16.0f;
+ case 910: modChance+= 17.0f;
+ case 849: modChance+= 17.0f;
+ if (!pVictim->HasAuraState(AURA_STATE_FROZEN, spellProto, this))
+ break;
+ crit_chance+=modChance;
+ // Fingers of Frost
+ // TODO: Change this code to less hacky
+ if (Aura * aur = GetAura(44544))
+ aur->DropAuraCharge();
+ break;
+ case 7917: // Glyph of Shadowburn
+ if (pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
+ crit_chance+=(*i)->GetAmount();
+ break;
+ case 7997: // Renewed Hope
+ case 7998:
+ if (pVictim->HasAura(6788))
+ crit_chance+=(*i)->GetAmount();
+ break;
+ case 21: // Test of Faith
+ case 6935:
+ case 6918:
+ if (pVictim->GetHealth() < pVictim->GetMaxHealth()/2)
+ crit_chance+=(*i)->GetAmount();
+ break;
+ default:
+ break;
+ }
+ }
+ // Custom crit by class
+ switch(spellProto->SpellFamilyName)
+ {
+ case SPELLFAMILY_PALADIN:
+ // Sacred Shield
+ if (spellProto->SpellFamilyFlags[0] & 0x40000000)
{
- case 849: crit_chance+= 10.0f; break; //Shatter Rank 1
- case 910: crit_chance+= 20.0f; break; //Shatter Rank 2
- case 911: crit_chance+= 30.0f; break; //Shatter Rank 3
- case 912: crit_chance+= 40.0f; break; //Shatter Rank 4
- case 913: crit_chance+= 50.0f; break; //Shatter Rank 5
+ AuraEffect *aura = pVictim->GetDummyAura(58597);
+ if (aura && aura->GetCasterGUID() == GetGUID())
+ crit_chance+=aura->GetAmount();
+ break;
}
- }
+ break;
+ case SPELLFAMILY_SHAMAN:
+ // Lava Burst
+ if (spellProto->SpellFamilyFlags[1] & 0x00001000)
+ {
+ if (AuraEffect *flameShock = pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, 10000000, 0,0, GetGUID()))
+ {
+ // Consume shock aura if not have Glyph of Flame Shock
+ if (!GetAuraEffect(55447, 0))
+ pVictim->RemoveAurasDueToSpell(flameShock->GetId(), GetGUID());
+ return true;
+ }
+ break;
+ }
+ break;
+
}
}
break;
@@ -8785,7 +8948,6 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
if (pVictim)
{
crit_chance = GetUnitCriticalChance(attackType, pVictim);
- crit_chance+= (int32(GetMaxSkillValueForLevel(pVictim)) - int32(pVictim->GetDefenseSkillValue(this))) * 0.04f;
crit_chance+= GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, schoolMask);
}
break;
@@ -8804,7 +8966,7 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
return false;
}
-uint32 Unit::SpellCriticalBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim)
+uint32 Unit::SpellCriticalDamageBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim)
{
// Calculate critical bonus
int32 crit_bonus;
@@ -8836,233 +8998,312 @@ uint32 Unit::SpellCriticalBonus(SpellEntry const *spellProto, uint32 damage, Uni
return damage;
}
-uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, Unit *pVictim)
+uint32 Unit::SpellCriticalHealingBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim)
{
- // For totems get healing bonus from owner (statue isn't totem in fact)
- if( GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem() && ((Totem*)this)->GetTotemType()!=TOTEM_STATUE)
- if(Unit* owner = GetOwner())
- return owner->SpellHealingBonus(spellProto, healamount, damagetype, pVictim);
+ // Calculate critical bonus
+ int32 crit_bonus;
+ switch(spellProto->DmgClass)
+ {
+ case SPELL_DAMAGE_CLASS_MELEE: // for melee based spells is 100%
+ case SPELL_DAMAGE_CLASS_RANGED:
+ // TODO: write here full calculation for melee/ranged spells
+ crit_bonus = damage;
+ break;
+ default:
+ crit_bonus = damage / 2; // for spells is 50%
+ break;
+ }
- // Healing Done
- // These Spells are doing fixed amount of healing (TODO found less hack-like check)
- if (spellProto->Id == 15290 || spellProto->Id == 39373 ||
- spellProto->Id == 33778 || spellProto->Id == 379 ||
- spellProto->Id == 38395 || spellProto->Id == 40972 ||
- spellProto->Id == 22845 || spellProto->Id == 33504 ||
- spellProto->Id == 34299 || spellProto->Id == 27813 ||
- spellProto->Id == 27817 || spellProto->Id == 27818)
+ if(pVictim)
+ {
+ uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
+ crit_bonus = int32(crit_bonus * GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, creatureTypeMask));
+ }
+
+ if(crit_bonus > 0)
+ damage += crit_bonus;
+
+ damage = int32(float(damage) * GetTotalAuraMultiplier(SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT));
+
+ return damage;
+}
+
+uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack)
+{
+ // No heal amount for this class spells
+ if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE)
return healamount;
- int32 AdvertisedBenefit = SpellBaseHealingBonus(GetSpellSchoolMask(spellProto));
- uint32 CastingTime = GetSpellCastTime(spellProto);
+ // For totems get healing bonus from owner (statue isn't totem in fact)
+ if( GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem())
+ if(Unit* owner = GetOwner())
+ return owner->SpellHealingBonus(pVictim, spellProto, healamount, damagetype, stack);
- // Healing Taken
- AdvertisedBenefit += SpellBaseHealingBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
+ // Healing Done
+ // Taken/Done total percent damage auras
+ float DoneTotalMod = 1.0f;
+ float TakenTotalMod = 1.0f;
+ int32 DoneTotal = 0;
+ int32 TakenTotal = 0;
- // Blessing of Light dummy effects healing taken from Holy Light and Flash of Light
- if (spellProto->SpellFamilyName == SPELLFAMILY_PALADIN && (spellProto->SpellFamilyFlags & 0x00000000C0000000LL))
+ // Healing done percent
+ AuraEffectList const& mHealingDonePct = GetAurasByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT);
+ for(AuraEffectList::const_iterator i = mHealingDonePct.begin();i != mHealingDonePct.end(); ++i)
+ DoneTotalMod *= (100.0f + (*i)->GetAmount()) / 100.0f;
+
+ // done scripted mod (take it from owner)
+ Unit *owner = GetOwner();
+ if (!owner) owner = this;
+ AuraEffectList const& mOverrideClassScript= owner->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ for(AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
- AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
- for(AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
+ if (!(*i)->isAffectedOnSpell(spellProto))
+ continue;
+ switch((*i)->GetMiscValue())
{
- if((*i)->GetSpellProto()->SpellVisual == 9180)
+ case 4415: // Increased Rejuvenation Healing
+ case 4953:
+ case 3736: // Hateful Totem of the Third Wind / Increased Lesser Healing Wave / LK Arena (4/5/6) Totem of the Third Wind / Savage Totem of the Third Wind
+ DoneTotal+=(*i)->GetAmount();
+ break;
+ case 7997: // Renewed Hope
+ case 7998:
+ if (pVictim->HasAura(6788))
+ DoneTotalMod *=((*i)->GetAmount() + 100.0f)/100.0f;
+ break;
+ case 21: // Test of Faith
+ case 6935:
+ case 6918:
+ if (pVictim->GetHealth() < pVictim->GetMaxHealth()/2)
+ DoneTotalMod *=((*i)->GetAmount() + 100.0f)/100.0f;
+ break;
+ case 7798: // Glyph of Regrowth
{
- // Flash of Light
- if ((spellProto->SpellFamilyFlags & 0x0000000040000000LL) && (*i)->GetEffIndex() == 1)
- AdvertisedBenefit += (*i)->GetModifier()->m_amount;
- // Holy Light
- else if ((spellProto->SpellFamilyFlags & 0x0000000080000000LL) && (*i)->GetEffIndex() == 0)
- AdvertisedBenefit += (*i)->GetModifier()->m_amount;
+ if (pVictim->GetAura(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x40, 0))
+ DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
+ break;
}
- }
- }
-
- float ActualBenefit = 0.0f;
-
- if (AdvertisedBenefit != 0)
- {
- // Healing over Time spells
- float DotFactor = 1.0f;
- if(damagetype == DOT)
- {
- int32 DotDuration = GetSpellDuration(spellProto);
- if(DotDuration > 0)
+ case 8477: // Nourish Heal Boost
{
- // 200% limit
- if(DotDuration > 30000) DotDuration = 30000;
- if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
- int x = 0;
- for(int j = 0; j < 3; j++)
+ int32 stepPercent = (*i)->GetAmount();
+ int32 modPercent = 0;
+ AuraMap const& victimAuras = pVictim->GetAuras();
+ for (AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr)
{
- if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
- spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_HEAL ||
- spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
- {
- x = j;
- break;
- }
+ if (itr->second->GetCasterGUID()!=GetGUID())
+ continue;
+ SpellEntry const* m_spell = itr->second->GetSpellProto();
+ if ( m_spell->SpellFamilyName != SPELLFAMILY_DRUID ||
+ !(m_spell->SpellFamilyFlags[1] & 0x00000010 || m_spell->SpellFamilyFlags[0] & 0x50))
+ continue;
+ modPercent += stepPercent * itr->second->GetStackAmount();
}
- int DotTicks = 6;
- if(spellProto->EffectAmplitude[x] != 0)
- DotTicks = DotDuration / spellProto->EffectAmplitude[x];
- if(DotTicks)
- AdvertisedBenefit /= DotTicks;
+ DoneTotalMod *= (modPercent+100.0f)/100.0f;
+ break;
+ }
+ case 7871: // Glyph of Lesser Healing Wave
+ {
+ if (pVictim->GetAura(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 0 , 0x00000400, 0, GetGUID()))
+ DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
+ break;
}
+ default:
+ break;
}
+ }
- // distribute healing to all effects, reduce AoE damage
- CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
-
- // 0% bonus for damage and healing spells for leech spells from healing bonus
- for(int j = 0; j < 3; ++j)
+ // Taken/Done fixed damage bonus auras
+ int32 DoneAdvertisedBenefit = SpellBaseHealingBonus(GetSpellSchoolMask(spellProto));
+ int32 TakenAdvertisedBenefit = SpellBaseHealingBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
+
+ // Check for table values
+ SpellBonusEntry const* bonus = spellmgr.GetSpellBonusData(spellProto->Id);
+ float coeff;
+ float factorMod = 1.0f;
+ bool scripted = false;
+ if (bonus)
+ {
+ if (damagetype == DOT)
+ coeff = bonus->dot_damage;
+ else
+ coeff = bonus->direct_damage;
+ if (bonus->ap_bonus)
+ DoneTotal+=bonus->ap_bonus * GetTotalAttackPowerValue(BASE_ATTACK) * stack;
+ }
+ else // scripted bonus
+ {
+ // Gift of the Naaru
+ if (spellProto->Id==59547)
{
- if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
- spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH )
+ scripted = true;
+ uint32 apBonus = GetTotalAttackPowerValue(BASE_ATTACK);
+ if (apBonus > DoneAdvertisedBenefit)
{
- CastingTime = 0;
- break;
+ DoneTotal+=apBonus * stack;
+ coeff = 0.0f;
}
+ else
+ coeff = 1.0f;
+ }
+ // Earthliving - 0.45% of normal hot coeff
+ else if (spellProto->SpellFamilyName==SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags[1] & 0x80000)
+ {
+ factorMod *= 0.45f;
}
+ }
- // Exception
- switch (spellProto->SpellFamilyName)
+ // Default calculation
+ if (DoneAdvertisedBenefit || TakenAdvertisedBenefit)
+ {
+ if(!bonus && !scripted)
{
- case SPELLFAMILY_SHAMAN:
- // Healing stream from totem (add 6% per tick from hill bonus owner)
- if (spellProto->SpellFamilyFlags & 0x000000002000LL)
- CastingTime = 210;
- // Earth Shield 30% per charge
- else if (spellProto->SpellFamilyFlags & 0x40000000000LL)
- CastingTime = 1050;
- break;
- case SPELLFAMILY_DRUID:
- // Lifebloom
- if (spellProto->SpellFamilyFlags & 0x1000000000LL)
- {
- CastingTime = damagetype == DOT ? 3500 : 1200;
- DotFactor = damagetype == DOT ? 0.519f : 1.0f;
- }
- // Tranquility triggered spell
- else if (spellProto->SpellFamilyFlags & 0x80LL)
- CastingTime = 667;
- // Rejuvenation
- else if (spellProto->SpellFamilyFlags & 0x10LL)
- DotFactor = 0.845f;
- // Regrowth
- else if (spellProto->SpellFamilyFlags & 0x40LL)
+ // Damage Done from spell damage bonus
+ int32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
+ // Damage over Time spells bonus calculation
+ float DotFactor = 1.0f;
+ if(damagetype == DOT)
+ {
+ int32 DotDuration = GetSpellDuration(spellProto);
+ // 200% limit
+ if(DotDuration > 0)
{
- DotFactor = damagetype == DOT ? 0.705f : 1.0f;
- CastingTime = damagetype == DOT ? 3500 : 1010;
+ if(DotDuration > 30000) DotDuration = 30000;
+ if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
+ int x = 0;
+ for(int j = 0; j < 3; j++)
+ {
+ if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
+ spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||
+ spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
+ {
+ x = j;
+ break;
+ }
+ }
+ int32 DotTicks = 6;
+ if(spellProto->EffectAmplitude[x] != 0)
+ DotTicks = DotDuration / spellProto->EffectAmplitude[x];
+ if(DotTicks)
+ {
+ DoneAdvertisedBenefit = DoneAdvertisedBenefit * int32(stack) / DotTicks;
+ TakenAdvertisedBenefit = TakenAdvertisedBenefit * int32(stack) / DotTicks;
+ }
}
- // Improved Leader of the Pack
- else if (spellProto->AttributesEx2 == 536870912 && spellProto->SpellIconID == 312
- && spellProto->AttributesEx3 == 33554432)
+ }
+ // Distribute Damage over multiple effects, reduce by AoE
+ CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
+ // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
+ for(int j = 0; j < 3; ++j)
+ {
+ if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
+ spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH )
{
- CastingTime = 0;
+ CastingTime /= 2;
+ break;
}
- break;
- case SPELLFAMILY_PRIEST:
- // Holy Nova - 14%
- if ((spellProto->SpellFamilyFlags & 0x8000000LL) && spellProto->SpellIconID == 1874)
- CastingTime = 500;
- break;
- case SPELLFAMILY_PALADIN:
- // Seal and Judgement of Light
- if ( spellProto->SpellFamilyFlags & 0x100040000LL )
- CastingTime = 0;
- break;
- case SPELLFAMILY_WARRIOR:
- case SPELLFAMILY_ROGUE:
- case SPELLFAMILY_HUNTER:
- CastingTime = 0;
- break;
+ }
+ // As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells)
+ coeff = (CastingTime / 3500.0f) * DotFactor * 1.88f;
}
- float LvlPenalty = CalculateLevelPenalty(spellProto);
-
- // Spellmod SpellDamage
- //float SpellModSpellDamage = 100.0f;
- float CoefficientPtc = ((float)CastingTime/3500.0f)*DotFactor*100.0f;
-
+ factorMod *= CalculateLevelPenalty(spellProto)* stack;
+ TakenTotal += TakenAdvertisedBenefit * coeff * factorMod;
if(Player* modOwner = GetSpellModOwner())
- //modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,SpellModSpellDamage);
- modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,CoefficientPtc);
-
- //SpellModSpellDamage /= 100.0f;
- CoefficientPtc /= 100.0f;
-
- //ActualBenefit = (float)AdvertisedBenefit * ((float)CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty;
- ActualBenefit = (float)AdvertisedBenefit * CoefficientPtc * LvlPenalty;
+ {
+ coeff *= 100.0f;
+ modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_SPELL_BONUS_DAMAGE, coeff);
+ coeff /= 100.0f;
+ }
+ DoneTotal += DoneAdvertisedBenefit * coeff * factorMod;
}
// use float as more appropriate for negative values and percent applying
- float heal = healamount + ActualBenefit;
-
- // TODO: check for ALL/SPELLS type
- // Healing done percent
- AuraList const& mHealingDonePct = GetAurasByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT);
- for(AuraList::const_iterator i = mHealingDonePct.begin();i != mHealingDonePct.end(); ++i)
- heal *= (100.0f + (*i)->GetModifierValue()) / 100.0f;
-
+ float heal = (healamount + DoneTotal)*DoneTotalMod;
// apply spellmod to Done amount
if(Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, heal);
+ // Nourish cast
+ if (spellProto->SpellFamilyName == SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags[1] & 0x2000000)
+ {
+ // Rejuvenation, Regrowth, Lifebloom, or Wild Growth
+ if (pVictim->GetAura(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x50, 0x4000010, 0))
+ //increase healing by 20%
+ TakenTotalMod *= 1.2f;
+ }
+
+ // Taken mods
// Healing Wave cast
- if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags & 0x0000000000000040LL)
+ if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags[0] & 0x40)
{
- // Search for Healing Way on Victim (stack up to 3 time)
- int32 pctMod = 0;
- Unit::AuraList const& auraDummy = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr!=auraDummy.end(); ++itr)
+ // Search for Healing Way on Victim
+ Unit::AuraEffectList const& auraDummy = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraEffectList::const_iterator itr = auraDummy.begin(); itr!=auraDummy.end(); ++itr)
if((*itr)->GetId() == 29203)
- pctMod += (*itr)->GetModifier()->m_amount;
- // Apply bonus
- if (pctMod)
- heal = heal * (100 + pctMod) / 100;
+ TakenTotalMod *= ((*itr)->GetAmount()+100.0f) / 100.0f;
}
// Healing taken percent
float minval = pVictim->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HEALING_PCT);
if(minval)
- heal *= (100.0f + minval) / 100.0f;
+ TakenTotalMod *= (100.0f + minval) / 100.0f;
float maxval = pVictim->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HEALING_PCT);
if(maxval)
- heal *= (100.0f + maxval) / 100.0f;
+ TakenTotalMod *= (100.0f + maxval) / 100.0f;
+
+ if(damagetype==DOT)
+ {
+ // Healing over time taken percent
+ float minval_hot = pVictim->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HOT_PCT);
+ if(minval_hot)
+ TakenTotalMod *= (100.0f + minval_hot) / 100.0f;
+
+ float maxval_hot = pVictim->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HOT_PCT);
+ if(maxval_hot)
+ TakenTotalMod *= (100.0f + maxval_hot) / 100.0f;
+ }
- if (heal < 0) heal = 0;
+ AuraEffectList const& mHealingGet= pVictim->GetAurasByType(SPELL_AURA_MOD_HEALING_RECEIVED);
+ for(AuraEffectList::const_iterator i = mHealingGet.begin(); i != mHealingGet.end(); ++i)
+ if (GetGUID()==(*i)->GetCasterGUID() && (*i)->isAffectedOnSpell(spellProto) )
+ TakenTotalMod *= ((*i)->GetAmount() + 100.0f) / 100.0f;
- return uint32(heal);
+ heal = (heal + TakenTotal) * TakenTotalMod;
+
+ return heal < 0 ? 0 : uint32(heal);
}
int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask)
{
int32 AdvertisedBenefit = 0;
- AuraList const& mHealingDone = GetAurasByType(SPELL_AURA_MOD_HEALING_DONE);
- for(AuraList::const_iterator i = mHealingDone.begin();i != mHealingDone.end(); ++i)
- if(((*i)->GetModifier()->m_miscvalue & schoolMask) != 0)
- AdvertisedBenefit += (*i)->GetModifierValue();
+ AuraEffectList const& mHealingDone = GetAurasByType(SPELL_AURA_MOD_HEALING_DONE);
+ for(AuraEffectList::const_iterator i = mHealingDone.begin();i != mHealingDone.end(); ++i)
+ if(((*i)->GetMiscValue() & schoolMask) != 0)
+ AdvertisedBenefit += (*i)->GetAmount();
// Healing bonus of spirit, intellect and strength
if (GetTypeId() == TYPEID_PLAYER)
{
+ // Base value
+ AdvertisedBenefit +=((Player*)this)->GetBaseSpellHealingBonus();
+
// Healing bonus from stats
- AuraList const& mHealingDoneOfStatPercent = GetAurasByType(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT);
- for(AuraList::const_iterator i = mHealingDoneOfStatPercent.begin();i != mHealingDoneOfStatPercent.end(); ++i)
+ AuraEffectList const& mHealingDoneOfStatPercent = GetAurasByType(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT);
+ for(AuraEffectList::const_iterator i = mHealingDoneOfStatPercent.begin();i != mHealingDoneOfStatPercent.end(); ++i)
{
// stat used dependent from misc value (stat index)
Stats usedStat = Stats((*i)->GetSpellProto()->EffectMiscValue[(*i)->GetEffIndex()]);
- AdvertisedBenefit += int32(GetStat(usedStat) * (*i)->GetModifierValue() / 100.0f);
+ AdvertisedBenefit += int32(GetStat(usedStat) * (*i)->GetAmount() / 100.0f);
}
// ... and attack power
- AuraList const& mHealingDonebyAP = GetAurasByType(SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER);
- for(AuraList::const_iterator i = mHealingDonebyAP.begin();i != mHealingDonebyAP.end(); ++i)
- if ((*i)->GetModifier()->m_miscvalue & schoolMask)
- AdvertisedBenefit += int32(GetTotalAttackPowerValue(BASE_ATTACK) * (*i)->GetModifierValue() / 100.0f);
+ AuraEffectList const& mHealingDonebyAP = GetAurasByType(SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER);
+ for(AuraEffectList::const_iterator i = mHealingDonebyAP.begin();i != mHealingDonebyAP.end(); ++i)
+ if ((*i)->GetMiscValue() & schoolMask)
+ AdvertisedBenefit += int32(GetTotalAttackPowerValue(BASE_ATTACK) * (*i)->GetAmount() / 100.0f);
}
return AdvertisedBenefit;
}
@@ -9070,14 +9311,14 @@ int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask)
int32 Unit::SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim)
{
int32 AdvertisedBenefit = 0;
- AuraList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_HEALING);
- for(AuraList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i)
- if(((*i)->GetModifier()->m_miscvalue & schoolMask) != 0)
- AdvertisedBenefit += (*i)->GetModifierValue();
+ AuraEffectList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_HEALING);
+ for(AuraEffectList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i)
+ if(((*i)->GetMiscValue() & schoolMask) != 0)
+ AdvertisedBenefit += (*i)->GetAmount();
return AdvertisedBenefit;
}
-bool Unit::IsImmunedToDamage(SpellSchoolMask shoolMask, bool useCharges)
+bool Unit::IsImmunedToDamage(SpellSchoolMask shoolMask)
{
//If m_immuneToSchool type contain this school type, IMMUNE damage.
SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
@@ -9094,60 +9335,110 @@ bool Unit::IsImmunedToDamage(SpellSchoolMask shoolMask, bool useCharges)
return false;
}
-bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges)
+bool Unit::IsImmunedToDamage(SpellEntry const* spellInfo)
+{
+ if(spellInfo->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)
+ return false;
+
+ uint32 shoolMask = GetSpellSchoolMask(spellInfo);
+ if(!(spellInfo->AttributesEx &
+ (SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE | SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)) // can remove immune (by dispell or immune it)
+ && spellInfo->Id != 42292)
+ {
+ //If m_immuneToSchool type contain this school type, IMMUNE damage.
+ SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
+ for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
+ if(itr->type & shoolMask &&!IsDispelableBySpell(spellInfo, itr->spellId))
+ return true;
+ }
+
+ //If m_immuneToDamage type contain magic, IMMUNE damage.
+ SpellImmuneList const& damageList = m_spellImmune[IMMUNITY_DAMAGE];
+ for (SpellImmuneList::const_iterator itr = damageList.begin(); itr != damageList.end(); ++itr)
+ if(itr->type & shoolMask)
+ return true;
+
+ return false;
+}
+
+bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo)
{
if (!spellInfo)
return false;
+ // Single spell immunity.
+ SpellImmuneList const& idList = m_spellImmune[IMMUNITY_ID];
+ for(SpellImmuneList::const_iterator itr = idList.begin(); itr != idList.end(); ++itr)
+ if(itr->type == spellInfo->Id)
+ return true;
+
+ if(spellInfo->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)
+ return false;
+
SpellImmuneList const& dispelList = m_spellImmune[IMMUNITY_DISPEL];
for(SpellImmuneList::const_iterator itr = dispelList.begin(); itr != dispelList.end(); ++itr)
if(itr->type == spellInfo->Dispel)
return true;
- if( !(spellInfo->AttributesEx & SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE) && // unaffected by school immunity
- !(spellInfo->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) // can remove immune (by dispell or immune it)
- && (spellInfo->Id != 42292))
+ if(!(spellInfo->AttributesEx &
+ (SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE | SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)) // can remove immune (by dispell or immune it)
+ && spellInfo->Id != 42292)
{
SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
for(SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
if( !(IsPositiveSpell(itr->spellId) && IsPositiveSpell(spellInfo->Id)) &&
- (itr->type & GetSpellSchoolMask(spellInfo)) )
+ (itr->type & GetSpellSchoolMask(spellInfo)) && !IsDispelableBySpell(spellInfo, itr->spellId))
return true;
}
- SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
- for(SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
- {
- if(itr->type == spellInfo->Mechanic)
- {
- return true;
- }
- }
-
- SpellImmuneList const& idList = m_spellImmune[IMMUNITY_ID];
- for(SpellImmuneList::const_iterator itr = idList.begin(); itr != idList.end(); ++itr)
+ if (spellInfo->Mechanic)
{
- if(itr->type == spellInfo->Id)
+ SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
+ for(SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
{
- return true;
+ if(itr->type == spellInfo->Mechanic)
+ {
+ return true;
+ }
}
}
return false;
}
-bool Unit::IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const
+bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const
{
+ if (!spellInfo)
+ return false;
//If m_immuneToEffect type contain this effect type, IMMUNE effect.
+ uint32 effect = spellInfo->Effect[index];
SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT];
for (SpellImmuneList::const_iterator itr = effectList.begin(); itr != effectList.end(); ++itr)
if(itr->type == effect)
return true;
- SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
- for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
- if(itr->type == mechanic)
- return true;
+ if(uint32 mechanic = spellInfo->EffectMechanic[index])
+ {
+ SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
+ for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
+ if(itr->type == spellInfo->EffectMechanic[index])
+ return true;
+ }
+
+ if(uint32 aura = spellInfo->EffectApplyAuraName[index])
+ {
+ SpellImmuneList const& list = m_spellImmune[IMMUNITY_STATE];
+ for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr)
+ if(itr->type == aura)
+ return true;
+ // Check for immune to application of harmful magical effects
+ AuraEffectList const& immuneAuraApply = GetAurasByType(SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL);
+ for(AuraEffectList::const_iterator iter = immuneAuraApply.begin(); iter != immuneAuraApply.end(); ++iter)
+ if (spellInfo->Dispel == DISPEL_MAGIC && // Magic debuff
+ ((*iter)->GetMiscValue() & GetSpellSchoolMask(spellInfo)) && // Check school
+ !IsPositiveEffect(spellInfo->Id, index)) // Harmful
+ return true;
+ }
return false;
}
@@ -9182,10 +9473,10 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
int32 TakenFlatBenefit = 0;
// ..done (for creature type by mask) in taken
- AuraList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);
- for(AuraList::const_iterator i = mDamageDoneCreature.begin();i != mDamageDoneCreature.end(); ++i)
- if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- DoneFlatBenefit += (*i)->GetModifierValue();
+ AuraEffectList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);
+ for(AuraEffectList::const_iterator i = mDamageDoneCreature.begin();i != mDamageDoneCreature.end(); ++i)
+ if(creatureTypeMask & uint32((*i)->GetMiscValue()))
+ DoneFlatBenefit += (*i)->GetAmount();
// ..done
// SPELL_AURA_MOD_DAMAGE_DONE included in weapon damage
@@ -9197,20 +9488,20 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
APbonus += pVictim->GetTotalAuraModifier(SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS);
// ..done (base at attack power and creature type)
- AuraList const& mCreatureAttackPower = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS);
- for(AuraList::const_iterator i = mCreatureAttackPower.begin();i != mCreatureAttackPower.end(); ++i)
- if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- APbonus += (*i)->GetModifierValue();
+ AuraEffectList const& mCreatureAttackPower = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS);
+ for(AuraEffectList::const_iterator i = mCreatureAttackPower.begin();i != mCreatureAttackPower.end(); ++i)
+ if(creatureTypeMask & uint32((*i)->GetMiscValue()))
+ APbonus += (*i)->GetAmount();
}
else
{
APbonus += pVictim->GetTotalAuraModifier(SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS);
// ..done (base at attack power and creature type)
- AuraList const& mCreatureAttackPower = GetAurasByType(SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS);
- for(AuraList::const_iterator i = mCreatureAttackPower.begin();i != mCreatureAttackPower.end(); ++i)
- if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- APbonus += (*i)->GetModifierValue();
+ AuraEffectList const& mCreatureAttackPower = GetAurasByType(SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS);
+ for(AuraEffectList::const_iterator i = mCreatureAttackPower.begin();i != mCreatureAttackPower.end(); ++i)
+ if(creatureTypeMask & uint32((*i)->GetMiscValue()))
+ APbonus += (*i)->GetAmount();
}
if (APbonus!=0) // Can be negative
@@ -9232,10 +9523,10 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
}
// ..taken
- AuraList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
- for(AuraList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i)
- if((*i)->GetModifier()->m_miscvalue & GetMeleeDamageSchoolMask())
- TakenFlatBenefit += (*i)->GetModifierValue();
+ AuraEffectList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
+ for(AuraEffectList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i)
+ if((*i)->GetMiscValue() & GetMeleeDamageSchoolMask())
+ TakenFlatBenefit += (*i)->GetAmount();
if(attType!=RANGED_ATTACK)
TakenFlatBenefit += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN);
@@ -9243,39 +9534,39 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
TakenFlatBenefit += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN);
// Done/Taken total percent damage auras
- float DoneTotalMod = 1;
- float TakenTotalMod = 1;
+ float DoneTotalMod = 1.0f;
+ float TakenTotalMod = 1.0f;
// ..done
// SPELL_AURA_MOD_DAMAGE_PERCENT_DONE included in weapon damage
// SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT included in weapon damage
- AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);
- for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i)
- if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- DoneTotalMod *= ((*i)->GetModifierValue()+100.0f)/100.0f;
+ AuraEffectList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);
+ for(AuraEffectList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i)
+ if(creatureTypeMask & uint32((*i)->GetMiscValue()))
+ DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
// ..taken
- AuraList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
- for(AuraList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i)
- if((*i)->GetModifier()->m_miscvalue & GetMeleeDamageSchoolMask())
- TakenTotalMod *= ((*i)->GetModifierValue()+100.0f)/100.0f;
+ AuraEffectList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
+ for(AuraEffectList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i)
+ if((*i)->GetMiscValue() & GetMeleeDamageSchoolMask())
+ TakenTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
// .. taken pct: dummy auras
- AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
- for(AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
+ AuraEffectList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
+ for(AuraEffectList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
{
switch((*i)->GetSpellProto()->SpellIconID)
{
//Cheat Death
case 2109:
- if((*i)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL)
+ if((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
{
if(pVictim->GetTypeId() != TYPEID_PLAYER)
continue;
float mod = ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE)*(-8.0f);
- if (mod < (*i)->GetModifier()->m_amount)
- mod = (*i)->GetModifier()->m_amount;
+ if (mod < (*i)->GetAmount())
+ mod = (*i)->GetAmount();
TakenTotalMod *= (mod+100.0f)/100.0f;
}
break;
@@ -9284,22 +9575,22 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
if(spellProto==NULL)
break;
// Should increase Shred (initial Damage of Lacerate and Rake handled in Spell::EffectSchoolDMG)
- if(spellProto->SpellFamilyName==SPELLFAMILY_DRUID && (spellProto->SpellFamilyFlags==0x00008000LL))
- TakenTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f;
+ if(spellProto->SpellFamilyName==SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags.IsEqual (0x00008000,0,0))
+ TakenTotalMod *= (100.0f+(*i)->GetAmount())/100.0f;
break;
}
}
// .. taken pct: class scripts
- AuraList const& mclassScritAuras = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(AuraList::const_iterator i = mclassScritAuras.begin(); i != mclassScritAuras.end(); ++i)
+ AuraEffectList const& mclassScritAuras = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ for(AuraEffectList::const_iterator i = mclassScritAuras.begin(); i != mclassScritAuras.end(); ++i)
{
switch((*i)->GetMiscValue())
{
case 6427: case 6428: // Dirty Deeds
- if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT))
+ if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
{
- Aura* eff0 = GetAura((*i)->GetId(),0);
+ AuraEffect* eff0 = GetAuraEffect((*i)->GetId(),0,GetGUID());
if(!eff0 || (*i)->GetEffIndex()!=1)
{
sLog.outError("Spell structure of DD (%u) changed.",(*i)->GetId());
@@ -9307,7 +9598,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
}
// effect 0 have expected value but in negative state
- TakenTotalMod *= (-eff0->GetModifier()->m_amount+100.0f)/100.0f;
+ TakenTotalMod *= (-eff0->GetAmount()+100.0f)/100.0f;
}
break;
}
@@ -9315,15 +9606,15 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
if(attType != RANGED_ATTACK)
{
- AuraList const& mModMeleeDamageTakenPercent = pVictim->GetAurasByType(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT);
- for(AuraList::const_iterator i = mModMeleeDamageTakenPercent.begin(); i != mModMeleeDamageTakenPercent.end(); ++i)
- TakenTotalMod *= ((*i)->GetModifierValue()+100.0f)/100.0f;
+ AuraEffectList const& mModMeleeDamageTakenPercent = pVictim->GetAurasByType(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT);
+ for(AuraEffectList::const_iterator i = mModMeleeDamageTakenPercent.begin(); i != mModMeleeDamageTakenPercent.end(); ++i)
+ TakenTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
}
else
{
- AuraList const& mModRangedDamageTakenPercent = pVictim->GetAurasByType(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT);
- for(AuraList::const_iterator i = mModRangedDamageTakenPercent.begin(); i != mModRangedDamageTakenPercent.end(); ++i)
- TakenTotalMod *= ((*i)->GetModifierValue()+100.0f)/100.0f;
+ AuraEffectList const& mModRangedDamageTakenPercent = pVictim->GetAurasByType(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT);
+ for(AuraEffectList::const_iterator i = mModRangedDamageTakenPercent.begin(); i != mModRangedDamageTakenPercent.end(); ++i)
+ TakenTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
}
float tmpDamage = float(int32(*pdamage) + DoneFlatBenefit) * DoneTotalMod;
@@ -9378,7 +9669,23 @@ void Unit::ApplySpellDispelImmunity(const SpellEntry * spellProto, DispelType ty
ApplySpellImmune(spellProto->Id,IMMUNITY_DISPEL, type, apply);
if (apply && spellProto->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
- RemoveAurasWithDispelType(type);
+ {
+ // Create dispel mask by dispel type
+ uint32 dispelMask = GetDispellMask(type);
+ // Dispel all existing auras vs current dispel type
+ AuraMap& auras = GetAuras();
+ for(AuraMap::iterator itr = auras.begin(); itr != auras.end(); )
+ {
+ SpellEntry const* spell = itr->second->GetSpellProto();
+ if( (1<<spell->Dispel) & dispelMask )
+ {
+ // Dispel aura
+ RemoveAura(itr);
+ }
+ else
+ ++itr;
+ }
+ }
}
float Unit::GetWeaponProcChance() const
@@ -9392,42 +9699,31 @@ float Unit::GetWeaponProcChance() const
return 0;
}
-float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM) const
+float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM, const SpellEntry * spellProto) const
{
// proc per minute chance calculation
if (PPM <= 0) return 0.0f;
+ // Apply chance modifer aura
+ if (spellProto)
+ if(Player* modOwner = GetSpellModOwner())
+ modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_PROC_PER_MINUTE,PPM);
+
uint32 result = uint32((WeaponSpeed * PPM) / 600.0f); // result is chance in percents (probability = Speed_in_sec * (PPM / 60))
return result;
}
void Unit::Mount(uint32 mount)
{
- if(!mount)
- return;
-
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNT);
- SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, mount);
+ if(mount)
+ SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, mount);
SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT );
// unsummon pet
if(GetTypeId() == TYPEID_PLAYER)
- {
- Pet* pet = GetPet();
- if(pet)
- {
- if(pet->isControlled())
- {
- ((Player*)this)->SetTemporaryUnsummonedPetNumber(pet->GetCharmInfo()->GetPetNumber());
- ((Player*)this)->SetOldPetSpell(pet->GetUInt32Value(UNIT_CREATED_BY_SPELL));
- }
-
- ((Player*)this)->RemovePet(NULL,PET_SAVE_NOT_IN_SLOT);
- }
- else
- ((Player*)this)->SetTemporaryUnsummonedPetNumber(0);
- }
+ ((Player*)this)->UnsummonPetTemporaryIfAny();
}
void Unit::Unmount()
@@ -9443,14 +9739,8 @@ void Unit::Unmount()
// only resummon old pet if the player is already added to a map
// this prevents adding a pet to a not created map which would otherwise cause a crash
// (it could probably happen when logging in after a previous crash)
- if(GetTypeId() == TYPEID_PLAYER && IsInWorld() && ((Player*)this)->GetTemporaryUnsummonedPetNumber() && isAlive())
- {
- Pet* NewPet = new Pet;
- if(!NewPet->LoadPetFromDB(this, 0, ((Player*)this)->GetTemporaryUnsummonedPetNumber(), true))
- delete NewPet;
-
- ((Player*)this)->SetTemporaryUnsummonedPetNumber(0);
- }
+ if(GetTypeId() == TYPEID_PLAYER)
+ ((Player*)this)->ResummonPetTemporaryUnSummonedIfAny();
}
void Unit::SetInCombatWith(Unit* enemy)
@@ -9458,7 +9748,7 @@ void Unit::SetInCombatWith(Unit* enemy)
Unit* eOwner = enemy->GetCharmerOrOwnerOrSelf();
if(eOwner->IsPvP())
{
- SetInCombatState(true);
+ SetInCombatState(true,enemy);
return;
}
@@ -9468,27 +9758,22 @@ void Unit::SetInCombatWith(Unit* enemy)
Unit const* myOwner = GetCharmerOrOwnerOrSelf();
if(((Player const*)eOwner)->duel->opponent == myOwner)
{
- SetInCombatState(true);
+ SetInCombatState(true,enemy);
return;
}
}
- SetInCombatState(false);
+ SetInCombatState(false,enemy);
}
void Unit::CombatStart(Unit* target)
{
if(!target->IsStandState()/* && !target->hasUnitState(UNIT_STAT_STUNNED)*/)
- target->SetStandState(PLAYER_STATE_NONE);
+ target->SetStandState(UNIT_STAND_STATE_STAND);
if(!target->isInCombat() && target->GetTypeId() != TYPEID_PLAYER
&& !((Creature*)target)->HasReactState(REACT_PASSIVE) && ((Creature*)target)->IsAIEnabled)
{
((Creature*)target)->AI()->AttackStart(this);
- if(((Creature*)target)->GetFormation())
- {
- ((Creature*)target)->GetFormation()->MemberAttackStart((Creature*)target, this);
- sLog.outDebug("Unit::CombatStart() calls CreatureGroups::MemberHasAttacked(this);");
- }
}
SetInCombatWith(target);
@@ -9506,10 +9791,9 @@ void Unit::CombatStart(Unit* target)
me->UpdatePvP(true);
me->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
}
-
}
-void Unit::SetInCombatState(bool PvP)
+void Unit::SetInCombatState(bool PvP, Unit* enemy)
{
// only alive units can be in combat
if(!isAlive())
@@ -9523,8 +9807,18 @@ void Unit::SetInCombatState(bool PvP)
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
- if(GetTypeId() != TYPEID_PLAYER && GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_IDLE) != IDLE_MOTION_TYPE)
- ((Creature*)this)->SetHomePosition(GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
+ if(GetTypeId() != TYPEID_PLAYER)
+ {
+ if(GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_IDLE) != IDLE_MOTION_TYPE)
+ ((Creature*)this)->SetHomePosition(GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
+ if(enemy)
+ {
+ if(!((Creature*)this)->HasReactState(REACT_PASSIVE) && ((Creature*)this)->IsAIEnabled)
+ ((Creature*)this)->AI()->EnterCombat(enemy);
+ if(((Creature*)this)->GetFormation())
+ ((Creature*)this)->GetFormation()->MemberAttackStart((Creature*)this, enemy);
+ }
+ }
if(GetTypeId() != TYPEID_PLAYER && ((Creature*)this)->isPet())
{
@@ -9546,6 +9840,8 @@ void Unit::ClearInCombat()
// Player's state will be cleared in Player::UpdateContestedPvP
if(GetTypeId()!=TYPEID_PLAYER)
clearUnitState(UNIT_STAT_ATTACK_PLAYER);
+ else
+ ((Player*)this)->UpdatePotionCooldown();
if(GetTypeId() != TYPEID_PLAYER && ((Creature*)this)->isPet())
{
@@ -9603,7 +9899,7 @@ bool Unit::isAttackableByAOE() const
if(GetTypeId()==TYPEID_PLAYER && ((Player *)this)->isGameMaster())
return false;
- return !isInFlight();
+ return !hasUnitState(UNIT_STAT_UNATTACKABLE);
}
int32 Unit::ModifyHealth(int32 dVal)
@@ -9638,6 +9934,35 @@ int32 Unit::ModifyHealth(int32 dVal)
return gain;
}
+int32 Unit::GetHealthGain(int32 dVal)
+{
+ int32 gain = 0;
+
+ if(dVal==0)
+ return 0;
+
+ int32 curHealth = (int32)GetHealth();
+
+ int32 val = dVal + curHealth;
+ if(val <= 0)
+ {
+ return -curHealth;
+ }
+
+ int32 maxHealth = (int32)GetMaxHealth();
+
+ if(val < maxHealth)
+ {
+ gain = dVal;
+ }
+ else if(curHealth != maxHealth)
+ {
+ gain = maxHealth - curHealth;
+ }
+
+ return gain;
+}
+
int32 Unit::ModifyPower(Powers power, int32 dVal)
{
int32 gain = 0;
@@ -9687,8 +10012,8 @@ bool Unit::canDetectInvisibilityOf(Unit const* u) const
{
if(m_invisibilityMask & u->m_invisibilityMask) // same group
return true;
- AuraList const& auras = u->GetAurasByType(SPELL_AURA_MOD_STALKED); // Hunter mark
- for(AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
+ AuraEffectList const& auras = u->GetAurasByType(SPELL_AURA_MOD_STALKED); // Hunter mark
+ for(AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
if((*iter)->GetCasterGUID()==GetGUID())
return true;
@@ -9701,10 +10026,10 @@ bool Unit::canDetectInvisibilityOf(Unit const* u) const
// find invisibility level
uint32 invLevel = 0;
- Unit::AuraList const& iAuras = u->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY);
- for(Unit::AuraList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr)
- if(((*itr)->GetModifier()->m_miscvalue)==i && invLevel < (*itr)->GetModifier()->m_amount)
- invLevel = (*itr)->GetModifier()->m_amount;
+ Unit::AuraEffectList const& iAuras = u->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY);
+ for(Unit::AuraEffectList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr)
+ if(((*itr)->GetMiscValue())==i && invLevel < (*itr)->GetAmount())
+ invLevel = (*itr)->GetAmount();
// find invisibility detect level
uint32 detectLevel = 0;
@@ -9714,10 +10039,10 @@ bool Unit::canDetectInvisibilityOf(Unit const* u) const
}
else
{
- Unit::AuraList const& dAuras = GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION);
- for(Unit::AuraList::const_iterator itr = dAuras.begin(); itr != dAuras.end(); ++itr)
- if(((*itr)->GetModifier()->m_miscvalue)==i && detectLevel < (*itr)->GetModifier()->m_amount)
- detectLevel = (*itr)->GetModifier()->m_amount;
+ Unit::AuraEffectList const& dAuras = GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION);
+ for(Unit::AuraEffectList::const_iterator itr = dAuras.begin(); itr != dAuras.end(); ++itr)
+ if(((*itr)->GetMiscValue())==i && detectLevel < (*itr)->GetAmount())
+ detectLevel = (*itr)->GetAmount();
}
if(invLevel <= detectLevel)
@@ -9739,8 +10064,8 @@ bool Unit::canDetectStealthOf(Unit const* target, float distance) const
if(HasAuraType(SPELL_AURA_DETECT_STEALTH))
return true;
- AuraList const& auras = target->GetAurasByType(SPELL_AURA_MOD_STALKED); // Hunter mark
- for(AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
+ AuraEffectList const& auras = target->GetAurasByType(SPELL_AURA_MOD_STALKED); // Hunter mark
+ for(AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
if((*iter)->GetCasterGUID()==GetGUID())
return true;
@@ -9762,7 +10087,7 @@ void Unit::DestroyForNearbyPlayers()
std::list<Unit*> targets;
Trinity::AnyUnitInObjectRangeCheck check(this, World::GetMaxVisibleDistance());
- Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(targets, check);
+ Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(this, targets, check);
VisitNearbyWorldObject(World::GetMaxVisibleDistance(), searcher);
for(std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter)
if(*iter != this && (*iter)->GetTypeId() == TYPEID_PLAYER
@@ -9886,38 +10211,37 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
propagateSpeedChange();
- // Send speed change packet only for player
- if (GetTypeId()!=TYPEID_PLAYER)
- return;
-
WorldPacket data;
if(!forced)
{
switch(mtype)
{
case MOVE_WALK:
- data.Initialize(MSG_MOVE_SET_WALK_SPEED, 8+4+1+4+4+4+4+4+4+4);
+ data.Initialize(MSG_MOVE_SET_WALK_SPEED, 8+4+2+4+4+4+4+4+4+4);
break;
case MOVE_RUN:
- data.Initialize(MSG_MOVE_SET_RUN_SPEED, 8+4+1+4+4+4+4+4+4+4);
+ data.Initialize(MSG_MOVE_SET_RUN_SPEED, 8+4+2+4+4+4+4+4+4+4);
break;
case MOVE_RUN_BACK:
- data.Initialize(MSG_MOVE_SET_RUN_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4);
+ data.Initialize(MSG_MOVE_SET_RUN_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4);
break;
case MOVE_SWIM:
- data.Initialize(MSG_MOVE_SET_SWIM_SPEED, 8+4+1+4+4+4+4+4+4+4);
+ data.Initialize(MSG_MOVE_SET_SWIM_SPEED, 8+4+2+4+4+4+4+4+4+4);
break;
case MOVE_SWIM_BACK:
- data.Initialize(MSG_MOVE_SET_SWIM_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4);
+ data.Initialize(MSG_MOVE_SET_SWIM_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4);
break;
case MOVE_TURN_RATE:
- data.Initialize(MSG_MOVE_SET_TURN_RATE, 8+4+1+4+4+4+4+4+4+4);
+ data.Initialize(MSG_MOVE_SET_TURN_RATE, 8+4+2+4+4+4+4+4+4+4);
break;
case MOVE_FLIGHT:
- data.Initialize(MSG_MOVE_SET_FLIGHT_SPEED, 8+4+1+4+4+4+4+4+4+4);
+ data.Initialize(MSG_MOVE_SET_FLIGHT_SPEED, 8+4+2+4+4+4+4+4+4+4);
break;
case MOVE_FLIGHT_BACK:
- data.Initialize(MSG_MOVE_SET_FLIGHT_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4);
+ data.Initialize(MSG_MOVE_SET_FLIGHT_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4);
+ break;
+ case MOVE_PITCH_RATE:
+ data.Initialize(MSG_MOVE_SET_PITCH_RATE, 8+4+2+4+4+4+4+4+4+4);
break;
default:
sLog.outError("Unit::SetSpeed: Unsupported move type (%d), data not sent to client.",mtype);
@@ -9925,22 +10249,30 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
}
data.append(GetPackGUID());
- data << uint32(0); //movement flags
- data << uint8(0); //unk
+ data << uint32(0); // movement flags
+ data << uint16(0); // unk flags
data << uint32(getMSTime());
data << float(GetPositionX());
data << float(GetPositionY());
data << float(GetPositionZ());
data << float(GetOrientation());
- data << uint32(0); //flag unk
+ data << uint32(0); // fall time
data << float(GetSpeed(mtype));
SendMessageToSet( &data, true );
}
else
{
- // register forced speed changes for WorldSession::HandleForceSpeedChangeAck
- // and do it only for real sent packets and use run for run/mounted as client expected
- ++((Player*)this)->m_forced_speed_changes[mtype];
+ if(GetTypeId() == TYPEID_PLAYER)
+ {
+ // register forced speed changes for WorldSession::HandleForceSpeedChangeAck
+ // and do it only for real sent packets and use run for run/mounted as client expected
+ ++((Player*)this)->m_forced_speed_changes[mtype];
+
+ if(!isInCombat())
+ if(Pet* pet = ((Player*)this)->GetPet())
+ pet->SetSpeed(mtype, m_speed_rate[mtype], forced);
+ }
+
switch(mtype)
{
case MOVE_WALK:
@@ -9967,6 +10299,9 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
case MOVE_FLIGHT_BACK:
data.Initialize(SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE, 16);
break;
+ case MOVE_PITCH_RATE:
+ data.Initialize(SMSG_FORCE_PITCH_RATE_CHANGE, 16);
+ break;
default:
sLog.outError("Unit::SetSpeed: Unsupported move type (%d), data not sent to client.",mtype);
return;
@@ -9978,9 +10313,6 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
data << float(GetSpeed(mtype));
SendMessageToSet( &data, true );
}
- if(GetPetGUID() && !isInCombat())
- if(Pet* pet = GetPet())
- pet->SetSpeed(mtype, m_speed_rate[mtype], forced);
}
void Unit::SetHover(bool on)
@@ -10006,8 +10338,11 @@ void Unit::setDeathState(DeathState s)
if (s == JUST_DIED)
{
- RemoveAllAurasOnDeath();
UnsummonAllTotems();
+ RemoveAllControlled();
+ RemoveAllAurasOnDeath();
+ ExitVehicle();
+ //This is needed to clear visible auras after unit dies
ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false);
ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, false);
@@ -10051,6 +10386,10 @@ bool Unit::CanHaveThreatList() const
if( ((Creature*)this)->isTotem() )
return false;
+ // vehicles can not have threat list
+ if( ((Creature*)this)->isVehicle() )
+ return false;
+
// pets can not have a threat list, unless they are controlled by a creature
if( ((Creature*)this)->isPet() && IS_PLAYER_GUID(((Pet*)this)->GetOwnerGUID()) )
return false;
@@ -10156,17 +10495,41 @@ Unit* Creature::SelectVictim()
//otherwise enterevademode every update
Unit* target = NULL;
-
- if(!m_ThreatManager.isThreatListEmpty())
+ // First checking if we have some taunt on us
+ const AuraEffectList& tauntAuras = GetAurasByType(SPELL_AURA_MOD_TAUNT);
+ if ( !tauntAuras.empty() )
{
- if(!HasAuraType(SPELL_AURA_MOD_TAUNT))
+ Unit* caster;
+
+ // The last taunt aura caster is alive an we are happy to attack him
+ if ( (caster = tauntAuras.back()->GetCaster()) && caster->isAlive() )
+ return getVictim();
+ else if (tauntAuras.size() > 1)
{
- target = m_ThreatManager.getHostilTarget();
+ // We do not have last taunt aura caster but we have more taunt auras,
+ // so find first available target
+
+ // Auras are pushed_back, last caster will be on the end
+ AuraEffectList::const_iterator aura = --tauntAuras.end();
+ do
+ {
+ --aura;
+ if ( (caster = (*aura)->GetCaster()) &&
+ caster->IsInMap(this) && canAttack(caster) && caster->isInAccessiblePlaceFor((Creature*)this) )
+ {
+ target = caster;
+ break;
+ }
+ }while (aura != tauntAuras.begin());
}
else
target = getVictim();
}
+ if ( !target && !m_ThreatManager.isThreatListEmpty() )
+ // No taunt aura or taunt aura caster is dead standart target selection
+ target = m_ThreatManager.getHostilTarget();
+
if(target)
{
if(!hasUnitState(UNIT_STAT_STUNNED))
@@ -10199,9 +10562,9 @@ Unit* Creature::SelectVictim()
if(m_invisibilityMask)
{
- Unit::AuraList const& iAuras = GetAurasByType(SPELL_AURA_MOD_INVISIBILITY);
- for(Unit::AuraList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr)
- if((*itr)->IsPermanent())
+ Unit::AuraEffectList const& iAuras = GetAurasByType(SPELL_AURA_MOD_INVISIBILITY);
+ for(Unit::AuraEffectList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr)
+ if((*itr)->GetParentAura()->IsPermanent())
{
AI()->EnterEvadeMode();
break;
@@ -10238,8 +10601,11 @@ int32 Unit::CalculateSpellDamage(SpellEntry const* spellProto, uint8 effect_inde
int32 randomPoints = int32(spellProto->EffectDieSides[effect_index] + level * randomPointsPerLevel);
float comboDamage = spellProto->EffectPointsPerComboPoint[effect_index];
- // prevent random generator from getting confused by spells casted with Unit::CastCustomSpell
- int32 randvalue = spellProto->EffectBaseDice[effect_index] >= randomPoints ? spellProto->EffectBaseDice[effect_index]:irand(spellProto->EffectBaseDice[effect_index], randomPoints);
+ // range can have possitive and negative values, so order its for irand
+ int32 randvalue = int32(spellProto->EffectBaseDice[effect_index]) >= randomPoints
+ ? irand(randomPoints, int32(spellProto->EffectBaseDice[effect_index]))
+ : irand(int32(spellProto->EffectBaseDice[effect_index]), randomPoints);
+
int32 value = basePoints + randvalue;
//random damage
if(comboDamage != 0 && unitPlayer /*&& target && (target->GetGUID() == unitPlayer->GetComboTarget())*/)
@@ -10272,7 +10638,7 @@ int32 Unit::CalculateSpellDamage(SpellEntry const* spellProto, uint8 effect_inde
return value;
}
-int32 Unit::CalculateSpellDuration(SpellEntry const* spellProto, uint8 effect_index, Unit const* target)
+int32 Unit::CalcSpellDuration(SpellEntry const* spellProto)
{
Player* unitPlayer = (GetTypeId() == TYPEID_PLAYER) ? (Player*)this : NULL;
@@ -10288,14 +10654,24 @@ int32 Unit::CalculateSpellDuration(SpellEntry const* spellProto, uint8 effect_in
else
duration = minduration;
- if (duration > 0)
+ return duration;
+}
+
+int32 Unit::ModSpellDuration(SpellEntry const* spellProto, Unit const* target, int32 duration, bool positive)
+{
+ //don't mod permament auras duration
+ if (duration<0)
+ return duration;
+
+ //cut duration only of negative effects
+ if (!positive)
{
- int32 mechanic = GetEffectMechanic(spellProto, effect_index);
+ int32 mechanic = spellProto->Mechanic;
+
// Find total mod value (negative bonus)
int32 durationMod_always = target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD, mechanic);
// Find max mod (negative bonus)
int32 durationMod_not_stack = target->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK, mechanic);
-
int32 durationMod = 0;
// Select strongest negative mod
if (durationMod_always > durationMod_not_stack)
@@ -10304,12 +10680,41 @@ int32 Unit::CalculateSpellDuration(SpellEntry const* spellProto, uint8 effect_in
durationMod = durationMod_always;
if (durationMod != 0)
- duration = int32(int64(duration) * (100+durationMod) /100);
+ duration = int32( float (duration) * float(100.0f+durationMod) /100.0f);
- if (duration < 0) duration = 0;
+ // there are only negative mods currently
+ durationMod_always =target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL, spellProto->Dispel);
+ durationMod_not_stack=target->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK, spellProto->Dispel);
+
+ durationMod=0;
+ if (durationMod_always > durationMod_not_stack)
+ durationMod += durationMod_not_stack;
+ else
+ durationMod += durationMod_always;
+
+ if (durationMod != 0)
+ duration = int32( float (duration) * float(100.0f+durationMod) /100.0f);
}
+ //else positive mods here, there are no currently
+ //when there will be, change GetTotalAuraModifierByMiscValue to GetTotalPositiveAuraModifierByMiscValue
+ return duration>0 ? duration : 0;
+}
- return duration;
+void Unit::ModSpellCastTime(SpellEntry const* spellProto, int32 & castTime, Spell const * spell)
+{
+ if (!spellProto || castTime<0)
+ return;
+ //called from caster
+ if(Player* modOwner = GetSpellModOwner())
+ modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CASTING_TIME, castTime, spell);
+
+ if( !(spellProto->Attributes & (SPELL_ATTR_UNK4|SPELL_ATTR_UNK5)) && spellProto->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && spellProto->SpellFamilyName)
+ castTime = int32( float(castTime) * GetFloatValue(UNIT_MOD_CAST_SPEED));
+ else
+ {
+ if (spellProto->Attributes & SPELL_ATTR_RANGED && !(spellProto->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG))
+ castTime = int32 (float(castTime) * m_modAttackSpeedPct[RANGED_ATTACK]);
+ }
}
DiminishingLevels Unit::GetDiminishing(DiminishingGroup group)
@@ -10343,21 +10748,15 @@ DiminishingLevels Unit::GetDiminishing(DiminishingGroup group)
void Unit::IncrDiminishing(DiminishingGroup group)
{
// Checking for existing in the table
- bool IsExist = false;
for(Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i)
{
if(i->DRGroup != group)
continue;
-
- IsExist = true;
if(i->hitCount < DIMINISHING_LEVEL_IMMUNE)
i->hitCount += 1;
-
- break;
+ return;
}
-
- if(!IsExist)
- m_Diminishing.push_back(DiminishingReturn(group,getMSTime(),DIMINISHING_LEVEL_2));
+ m_Diminishing.push_back(DiminishingReturn(group,getMSTime(),DIMINISHING_LEVEL_2));
}
void Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster,DiminishingLevels Level)
@@ -10406,17 +10805,50 @@ void Unit::ApplyDiminishingAura( DiminishingGroup group, bool apply )
if(i->DRGroup != group)
continue;
- i->hitTime = getMSTime();
-
if(apply)
i->stack += 1;
else if(i->stack)
+ {
i->stack -= 1;
-
+ // Remember time after last aura from group removed
+ if (i->stack == 0)
+ i->hitTime = getMSTime();
+ }
break;
}
}
+uint32 Unit::GetSpellMaxRangeForTarget(Unit* target,const SpellRangeEntry * rangeEntry)
+{
+ if (!rangeEntry)
+ return 0;
+ if (rangeEntry->maxRangeHostile == rangeEntry->maxRangeFriend)
+ return rangeEntry->maxRangeFriend;
+ if (IsHostileTo(target))
+ return rangeEntry->maxRangeHostile;
+ return rangeEntry->maxRangeFriend;
+};
+uint32 Unit::GetSpellMinRangeForTarget(Unit* target,const SpellRangeEntry * rangeEntry)
+{
+ if (!rangeEntry)
+ return 0;
+ if (rangeEntry->minRangeHostile == rangeEntry->minRangeFriend)
+ return rangeEntry->minRangeFriend;
+ if (IsHostileTo(target))
+ return rangeEntry->minRangeHostile;
+ return rangeEntry->minRangeFriend;
+};
+uint32 Unit::GetSpellRadiusForTarget(Unit* target,const SpellRadiusEntry * radiusEntry)
+{
+ if (!radiusEntry)
+ return 0;
+ if (radiusEntry->radiusHostile == radiusEntry->radiusFriend)
+ return radiusEntry->radiusFriend;
+ if (IsHostileTo(target))
+ return radiusEntry->radiusHostile;
+ return radiusEntry->radiusFriend;
+};
+
Unit* Unit::GetUnit(WorldObject& object, uint64 guid)
{
return ObjectAccessor::GetUnit(object,guid);
@@ -10429,19 +10861,19 @@ Player* Unit::GetPlayer(uint64 guid)
Creature* Unit::GetCreature(WorldObject& object, uint64 guid)
{
- return ObjectAccessor::GetCreature(object, guid);
+ return object.GetMap()->GetCreature(guid);
}
bool Unit::isVisibleForInState( Player const* u, bool inVisibleList ) const
{
- return isVisibleForOrDetect(u, false, inVisibleList, false);
+ return u->canSeeOrDetect(this, false, inVisibleList, false);
}
uint32 Unit::GetCreatureType() const
{
if(GetTypeId() == TYPEID_PLAYER)
{
- SpellShapeshiftEntry const* ssEntry = sSpellShapeshiftStore.LookupEntry(((Player*)this)->m_form);
+ SpellShapeshiftEntry const* ssEntry = sSpellShapeshiftStore.LookupEntry(m_form);
if(ssEntry && ssEntry->creatureType > 0)
return ssEntry->creatureType;
else
@@ -10504,7 +10936,9 @@ bool Unit::HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, f
case UNIT_MOD_RAGE:
case UNIT_MOD_FOCUS:
case UNIT_MOD_ENERGY:
- case UNIT_MOD_HAPPINESS: UpdateMaxPower(GetPowerTypeByAuraGroup(unitMod)); break;
+ case UNIT_MOD_HAPPINESS:
+ case UNIT_MOD_RUNE:
+ case UNIT_MOD_RUNIC_POWER: UpdateMaxPower(GetPowerTypeByAuraGroup(unitMod)); break;
case UNIT_MOD_RESISTANCE_HOLY:
case UNIT_MOD_RESISTANCE_FIRE:
@@ -10531,7 +10965,7 @@ float Unit::GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) co
{
if( unitMod >= UNIT_MOD_END || modifierType >= MODIFIER_TYPE_END)
{
- sLog.outError("ERROR: trial to access non existed modifier value from UnitMods!");
+ sLog.outError("trial to access non existed modifier value from UnitMods!");
return 0.0f;
}
@@ -10561,7 +10995,7 @@ float Unit::GetTotalAuraModValue(UnitMods unitMod) const
{
if(unitMod >= UNIT_MOD_END)
{
- sLog.outError("ERROR: trial to access non existed UnitMods in GetTotalAuraModValue()!");
+ sLog.outError("trial to access non existed UnitMods in GetTotalAuraModValue()!");
return 0.0f;
}
@@ -10617,32 +11051,36 @@ Stats Unit::GetStatByAuraGroup(UnitMods unitMod) const
Powers Unit::GetPowerTypeByAuraGroup(UnitMods unitMod) const
{
- Powers power = POWER_MANA;
-
switch(unitMod)
{
- case UNIT_MOD_MANA: power = POWER_MANA; break;
- case UNIT_MOD_RAGE: power = POWER_RAGE; break;
- case UNIT_MOD_FOCUS: power = POWER_FOCUS; break;
- case UNIT_MOD_ENERGY: power = POWER_ENERGY; break;
- case UNIT_MOD_HAPPINESS: power = POWER_HAPPINESS; break;
-
- default:
- break;
+ case UNIT_MOD_MANA: return POWER_MANA;
+ case UNIT_MOD_RAGE: return POWER_RAGE;
+ case UNIT_MOD_FOCUS: return POWER_FOCUS;
+ case UNIT_MOD_ENERGY: return POWER_ENERGY;
+ case UNIT_MOD_HAPPINESS: return POWER_HAPPINESS;
+ case UNIT_MOD_RUNE: return POWER_RUNE;
+ case UNIT_MOD_RUNIC_POWER:return POWER_RUNIC_POWER;
}
- return power;
+ return POWER_MANA;
}
float Unit::GetTotalAttackPowerValue(WeaponAttackType attType) const
{
- UnitMods unitMod = (attType == RANGED_ATTACK) ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER;
-
- float val = GetTotalAuraModValue(unitMod);
- if(val < 0.0f)
- val = 0.0f;
-
- return val;
+ if (attType == RANGED_ATTACK)
+ {
+ int32 ap = GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER) + GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MODS);
+ if (ap < 0)
+ return 0.0f;
+ return ap * (1.0f + GetFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER));
+ }
+ else
+ {
+ int32 ap = GetInt32Value(UNIT_FIELD_ATTACK_POWER) + GetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS);
+ if (ap < 0)
+ return 0.0f;
+ return ap * (1.0f + GetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER));
+ }
}
float Unit::GetWeaponDamageRange(WeaponAttackType attType ,WeaponDamageRange type) const
@@ -10730,6 +11168,12 @@ void Unit::SetPower(Powers power, uint32 val)
SetStatInt32Value(UNIT_FIELD_POWER1 + power, val);
+ WorldPacket data(SMSG_POWER_UPDATE);
+ data.append(GetPackGUID());
+ data << uint8(power);
+ data << uint32(val);
+ SendMessageToSet(&data, GetTypeId() == TYPEID_PLAYER ? true : false);
+
// group update
if(GetTypeId() == TYPEID_PLAYER)
{
@@ -10824,15 +11268,6 @@ void Unit::ApplyMaxPowerMod(Powers power, uint32 val, bool apply)
}
}
-void Unit::ApplyAuraProcTriggerDamage( Aura* aura, bool apply )
-{
- AuraList& tAuraProcTriggerDamage = m_modAuras[SPELL_AURA_PROC_TRIGGER_DAMAGE];
- if(apply)
- tAuraProcTriggerDamage.push_back(aura);
- else
- tAuraProcTriggerDamage.remove(aura);
-}
-
uint32 Unit::GetCreatePowers( Powers power ) const
{
// POWER_FOCUS and POWER_HAPPINESS only have hunter pet
@@ -10843,6 +11278,7 @@ uint32 Unit::GetCreatePowers( Powers power ) const
case POWER_FOCUS: return (GetTypeId()==TYPEID_PLAYER || !((Creature const*)this)->isPet() || ((Pet const*)this)->getPetType()!=HUNTER_PET ? 0 : 100);
case POWER_ENERGY: return 100;
case POWER_HAPPINESS: return (GetTypeId()==TYPEID_PLAYER || !((Creature const*)this)->isPet() || ((Pet const*)this)->getPetType()!=HUNTER_PET ? 0 : 1050000);
+ case POWER_RUNIC_POWER: return 1000;
}
return 0;
@@ -10862,22 +11298,32 @@ void Unit::AddToWorld()
void Unit::RemoveFromWorld()
{
// cleanup
+ assert(GetGUID());
+
if(IsInWorld())
{
+ UnsummonAllTotems();
+ RemoveAllControlled();
RemoveCharmAuras();
RemoveBindSightAuras();
RemoveNotOwnSingleTargetAuras();
+ ExitVehicle();
+
+ if(GetCharmerGUID())
+ sLog.outCrash("Unit %u has charmer guid when removed from world", GetEntry());
+
WorldObject::RemoveFromWorld();
}
}
void Unit::CleanupsBeforeDelete()
{
- assert(m_uint32Values);
+ assert(GetGUID());
//A unit may be in removelist and not in world, but it is still in grid
//and may have some references during delete
RemoveAllAuras();
+ _DeleteAuras();
InterruptNonMeleeSpells(true);
m_Events.KillAllEvents(false); // non-delatable (currently casted spells) will not deleted now but it will deleted at call in Map::RemoveAllObjectsInRemoveList
CombatStop();
@@ -10988,7 +11434,7 @@ void CharmInfo::InitEmptyActionBar(bool withAttack)
for(uint32 x = 0; x < 10; ++x)
{
- PetActionBar[x].Type = ACT_CAST;
+ PetActionBar[x].Type = ACT_PASSIVE;
PetActionBar[x].SpellOrAction = 0;
}
if (withAttack)
@@ -11010,7 +11456,7 @@ void CharmInfo::InitPossessCreateSpells()
if(IsPassiveSpell(spellid))
m_unit->CastSpell(m_unit, spellid, true);
else
- AddSpellToAB(0, spellid, ACT_CAST);
+ AddSpellToAB(0, spellid, ACT_DISABLED);
}
}
}
@@ -11025,7 +11471,7 @@ void CharmInfo::InitCharmCreateSpells()
InitPetActionBar();
- for(uint32 x = 0; x < CREATURE_MAX_SPELLS; ++x)
+ for(uint32 x = 0; x < MAX_SPELL_CHARM; ++x)
{
uint32 spellId = ((Creature*)m_unit)->m_spells[x];
m_charmspells[x].spellId = spellId;
@@ -11054,7 +11500,7 @@ void CharmInfo::InitCharmCreateSpells()
if(onlyselfcast || !IsPositiveSpell(spellId)) //only self cast and spells versus enemies are autocastable
newstate = ACT_DISABLED;
else
- newstate = ACT_CAST;
+ newstate = ACT_PASSIVE;
AddSpellToAB(0, spellId, newstate);
}
@@ -11065,7 +11511,7 @@ bool CharmInfo::AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate)
{
for(uint8 i = 0; i < 10; i++)
{
- if((PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_CAST) && PetActionBar[i].SpellOrAction == oldid)
+ if((PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_PASSIVE) && PetActionBar[i].SpellOrAction == oldid)
{
PetActionBar[i].SpellOrAction = newid;
if(!oldid)
@@ -11087,7 +11533,7 @@ void CharmInfo::ToggleCreatureAutocast(uint32 spellid, bool apply)
if(IsPassiveSpell(spellid))
return;
- for(uint32 x = 0; x < CREATURE_MAX_SPELLS; ++x)
+ for(uint32 x = 0; x < MAX_SPELL_CHARM; ++x)
{
if(spellid == m_charmspells[x].spellId)
{
@@ -11107,209 +11553,29 @@ void CharmInfo::SetPetNumber(uint32 petnumber, bool statwindow)
bool Unit::isFrozen() const
{
- AuraList const& mRoot = GetAurasByType(SPELL_AURA_MOD_ROOT);
- for(AuraList::const_iterator i = mRoot.begin(); i != mRoot.end(); ++i)
- if( GetSpellSchoolMask((*i)->GetSpellProto()) & SPELL_SCHOOL_MASK_FROST)
- return true;
- return false;
+ return HasAuraState(AURA_STATE_FROZEN);
}
-/*
struct ProcTriggeredData
{
- ProcTriggeredData(Aura* _triggeredByAura, uint32 _cooldown)
- : triggeredByAura(_triggeredByAura),
- triggeredByAura_SpellPair(Unit::spellEffectPair(triggeredByAura->GetId(),triggeredByAura->GetEffIndex())),
- cooldown(_cooldown)
- {}
-
- Aura* triggeredByAura; // triggred aura, can be invalidate at triggered aura proccessing
- Unit::spellEffectPair triggeredByAura_SpellPair; // spell pair, used for re-find aura (by pointer comparison in range)
- uint32 cooldown; // possible hidden cooldown
-};
-
-typedef std::list< ProcTriggeredData > ProcTriggeredList;
-
-void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, AuraTypeSet const& procAuraTypes, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage, SpellSchoolMask damageSchoolMask )
-{
- for(AuraTypeSet::const_iterator aur = procAuraTypes.begin(); aur != procAuraTypes.end(); ++aur)
+ ProcTriggeredData(Aura* _aura)
+ : aura(_aura)
{
- // List of spells (effects) that proceed. Spell prototype and aura-specific value (damage for TRIGGER_DAMAGE)
- ProcTriggeredList procTriggered;
-
- AuraList const& auras = GetAurasByType(*aur);
- for(AuraList::const_iterator i = auras.begin(), next; i != auras.end(); i = next)
- {
- next = i; ++next;
-
- Aura* i_aura = *i;
-
- uint32 cooldown; // returned at next line
- if(!IsTriggeredAtSpellProcEvent(i_aura->GetSpellProto(), procSpell, procFlag,attType,isVictim,cooldown))
- continue;
-
- procTriggered.push_back( ProcTriggeredData(i_aura, cooldown) );
- }
-
- // Handle effects proceed this time
- for(ProcTriggeredList::iterator i = procTriggered.begin(); i != procTriggered.end(); ++i)
- {
- // Some auras can be deleted in function called in this loop (except first, ofc)
- // Until storing auras in std::multimap to hard check deleting by another way
- if(i != procTriggered.begin())
- {
- bool found = false;
- AuraMap::const_iterator lower = GetAuras().lower_bound(i->triggeredByAura_SpellPair);
- AuraMap::const_iterator upper = GetAuras().upper_bound(i->triggeredByAura_SpellPair);
- for(AuraMap::const_iterator itr = lower; itr!= upper; ++itr)
- {
- if(itr->second==i->triggeredByAura)
- {
- found = true;
- break;
- }
- }
-
- if(!found)
- {
- sLog.outError("Spell aura %u (id:%u effect:%u) has been deleted before call spell proc event handler",*aur,i->triggeredByAura_SpellPair.first,i->triggeredByAura_SpellPair.second);
- sLog.outError("It can be deleted one from early processed auras:");
- for(ProcTriggeredList::iterator i2 = procTriggered.begin(); i != i2; ++i2)
- sLog.outError(" Spell aura %u (id:%u effect:%u)",*aur,i2->triggeredByAura_SpellPair.first,i2->triggeredByAura_SpellPair.second);
- sLog.outError(" <end of list>");
- continue;
- }
- }
-
- /// this is aura triggering code call
- Aura* triggeredByAura = i->triggeredByAura;
-
- /// save charges existence before processing to prevent crash at access to deleted triggered aura after
- /// used in speedup code check before check aura existance.
- bool triggeredByAuraWithCharges = triggeredByAura->m_procCharges > 0;
-
- /// success in event proccesing
- /// used in speedup code check before check aura existance.
- bool casted = false;
-
- /// process triggered code
- switch(*aur)
- {
- case SPELL_AURA_PROC_TRIGGER_SPELL:
- {
- sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s proc aura of spell %u)",
- (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
- casted = HandleProcTriggerSpell(pTarget, damage, triggeredByAura, procSpell, procFlag, attType, i->cooldown);
- break;
- }
- case SPELL_AURA_PROC_TRIGGER_DAMAGE:
- {
- uint32 triggered_damage = triggeredByAura->GetModifier()->m_amount;
- sLog.outDebug("ProcDamageAndSpell: doing %u damage (triggered by %s aura of spell %u)",
- triggered_damage, (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
- SpellNonMeleeDamageLog(pTarget, triggeredByAura->GetId(), triggered_damage, true, true);
- casted = true;
- break;
- }
- case SPELL_AURA_DUMMY:
- {
- uint32 effect = triggeredByAura->GetEffIndex();
- sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s dummy aura of spell %u)",
- (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
- casted = HandleDummyAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag,i->cooldown);
- break;
- }
- case SPELL_AURA_PRAYER_OF_MENDING:
- {
- sLog.outDebug("ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
- (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
-
- casted = HandleMeandingAuraProc(triggeredByAura);
- break;
- }
- case SPELL_AURA_MOD_HASTE:
- {
- sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s haste aura of spell %u)",
- (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
- casted = HandleHasteAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag,i->cooldown);
- break;
- }
- case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
- {
- // nothing do, just charges counter
- // but count only in case appropriate school damage
- casted = triggeredByAura->GetModifier()->m_miscvalue & damageSchoolMask;
- break;
- }
- case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
- {
- sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s class script aura of spell %u)",
- (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
- casted = HandleOverrideClassScriptAuraProc(pTarget, triggeredByAura, procSpell,i->cooldown);
- break;
- }
- default:
- {
- // nothing do, just charges counter
- casted = true;
- break;
- }
- }
-
- /// Update charge (aura can be removed by triggers)
- if(casted && triggeredByAuraWithCharges)
- {
- /// need re-found aura (can be dropped by triggers)
- AuraMap::const_iterator lower = GetAuras().lower_bound(i->triggeredByAura_SpellPair);
- AuraMap::const_iterator upper = GetAuras().upper_bound(i->triggeredByAura_SpellPair);
- for(AuraMap::const_iterator itr = lower; itr!= upper; ++itr)
- {
- if(itr->second == triggeredByAura) // pointer still valid
- {
- if(triggeredByAura->m_procCharges > 0)
- triggeredByAura->m_procCharges -= 1;
-
- triggeredByAura->UpdateAuraCharges();
- break;
- }
- }
- }
- }
-
- /// Safely remove auras with zero charges
- for(AuraList::const_iterator i = auras.begin(), next; i != auras.end(); i = next)
- {
- next = i; ++next;
- if((*i)->m_procCharges == 0)
- {
- RemoveAurasDueToSpell((*i)->GetId());
- next = auras.begin();
- }
- }
+ effMask = 0;
+ spellProcEvent = NULL;
}
-}
-*/
-struct ProcTriggeredData
-{
- ProcTriggeredData(SpellProcEventEntry const * _spellProcEvent, Aura* _triggeredByAura)
- : spellProcEvent(_spellProcEvent), triggeredByAura(_triggeredByAura),
- triggeredByAura_SpellPair(Unit::spellEffectPair(triggeredByAura->GetId(),triggeredByAura->GetEffIndex()))
- {}
SpellProcEventEntry const *spellProcEvent;
- Aura* triggeredByAura;
- Unit::spellEffectPair triggeredByAura_SpellPair;
+ Aura * aura;
+ uint32 effMask;
};
typedef std::list< ProcTriggeredData > ProcTriggeredList;
-typedef std::list< uint32> RemoveSpellList;
// List of auras that CAN be trigger but may not exist in spell_proc_event
// in most case need for drop charges
// in some types of aura need do additional check
// for example SPELL_AURA_MECHANIC_IMMUNITY - need check for mechanic
-static bool isTriggerAura[TOTAL_AURAS];
-static bool isNonTriggerAura[TOTAL_AURAS];
-void InitTriggerAuraData()
+bool InitTriggerAuraData()
{
for (int i=0;i<TOTAL_AURAS;i++)
{
@@ -11323,12 +11589,13 @@ void InitTriggerAuraData()
isTriggerAura[SPELL_AURA_MOD_DAMAGE_DONE] = true;
isTriggerAura[SPELL_AURA_MOD_DAMAGE_TAKEN] = true;
isTriggerAura[SPELL_AURA_MOD_RESISTANCE] = true;
+ isTriggerAura[SPELL_AURA_MOD_STEALTH] = true; // Aura not have charges but need remove him on trigger
isTriggerAura[SPELL_AURA_MOD_ROOT] = true;
isTriggerAura[SPELL_AURA_REFLECT_SPELLS] = true;
isTriggerAura[SPELL_AURA_DAMAGE_IMMUNITY] = true;
isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL] = true;
isTriggerAura[SPELL_AURA_PROC_TRIGGER_DAMAGE] = true;
- isTriggerAura[SPELL_AURA_MOD_CASTING_SPEED] = true;
+ isTriggerAura[SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK] = true;
isTriggerAura[SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT] = true;
isTriggerAura[SPELL_AURA_MOD_POWER_COST_SCHOOL] = true;
isTriggerAura[SPELL_AURA_REFLECT_SPELLS_SCHOOL] = true;
@@ -11342,10 +11609,16 @@ void InitTriggerAuraData()
isTriggerAura[SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS] = true;
isTriggerAura[SPELL_AURA_MOD_HASTE] = true;
isTriggerAura[SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE]=true;
- isTriggerAura[SPELL_AURA_PRAYER_OF_MENDING] = true;
+ isTriggerAura[SPELL_AURA_RAID_PROC_FROM_CHARGE] = true;
+ isTriggerAura[SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE] = true;
+ isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE] = true;
+ isTriggerAura[SPELL_AURA_MOD_DAMAGE_FROM_CASTER] = true;
+ isTriggerAura[SPELL_AURA_ABILITY_IGNORE_AURASTATE] = true;
isNonTriggerAura[SPELL_AURA_MOD_POWER_REGEN]=true;
- isNonTriggerAura[SPELL_AURA_RESIST_PUSHBACK]=true;
+ isNonTriggerAura[SPELL_AURA_REDUCE_PUSHBACK]=true;
+
+ return true;
}
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition)
@@ -11388,15 +11661,6 @@ uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missC
void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage )
{
- ++m_procDeep;
- if (m_procDeep > 5)
- {
- sLog.outError("Prevent possible stack owerflow in Unit::ProcDamageAndSpellFor");
- if (procSpell)
- sLog.outError(" Spell %u", procSpell->Id);
- --m_procDeep;
- return;
- }
// For melee/ranged based attack need update skills and set some Aura states
if (procFlag & MELEE_BASED_TRIGGER_MASK)
{
@@ -11407,7 +11671,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
if (procExtra&(PROC_EX_NORMAL_HIT|PROC_EX_MISS|PROC_EX_RESIST))
{
if (pTarget->GetTypeId() != TYPEID_PLAYER && pTarget->GetCreatureType() != CREATURE_TYPE_CRITTER)
- ((Player*)this)->UpdateCombatSkills(pTarget, attType, MELEE_HIT_MISS, isVictim);
+ ((Player*)this)->UpdateCombatSkills(pTarget, attType, isVictim);
}
// Update defence if player is victim and parry/dodge/block
if (isVictim && procExtra&(PROC_EX_DODGE|PROC_EX_PARRY|PROC_EX_BLOCK))
@@ -11459,199 +11723,201 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
((Player*)this)->AddComboPoints(pTarget, 1);
StartReactiveTimer( REACTIVE_OVERPOWER );
}
- // Enable AURA_STATE_CRIT on crit
- if (procExtra & PROC_EX_CRITICAL_HIT)
- {
- ModifyAuraState(AURA_STATE_CRIT, true);
- StartReactiveTimer( REACTIVE_CRIT );
- if(getClass()==CLASS_HUNTER)
- {
- ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, true);
- StartReactiveTimer( REACTIVE_HUNTER_CRIT );
- }
- }
}
}
}
- RemoveSpellList removedSpells;
ProcTriggeredList procTriggered;
// Fill procTriggered list
for(AuraMap::const_iterator itr = GetAuras().begin(); itr!= GetAuras().end(); ++itr)
{
- SpellProcEventEntry const* spellProcEvent = NULL;
- if(!IsTriggeredAtSpellProcEvent(itr->second, procSpell, procFlag, procExtra, attType, isVictim, (damage > 0), spellProcEvent))
- continue;
+ ProcTriggeredData triggerData(itr->second);
- procTriggered.push_back( ProcTriggeredData(spellProcEvent, itr->second) );
- }
- // Handle effects proceed this time
- for(ProcTriggeredList::iterator i = procTriggered.begin(); i != procTriggered.end(); ++i)
- {
- // Some auras can be deleted in function called in this loop (except first, ofc)
- // Until storing auars in std::multimap to hard check deleting by another way
- if(i != procTriggered.begin())
+ if(!IsTriggeredAtSpellProcEvent(pTarget, triggerData.aura, procSpell, procFlag, procExtra, attType, isVictim, (damage > 0), triggerData.spellProcEvent))
+ continue;
+ for (uint8 i=0; i<MAX_SPELL_EFFECTS;++i)
{
- bool found = false;
- AuraMap::const_iterator lower = GetAuras().lower_bound(i->triggeredByAura_SpellPair);
- AuraMap::const_iterator upper = GetAuras().upper_bound(i->triggeredByAura_SpellPair);
- for(AuraMap::const_iterator itr = lower; itr!= upper; ++itr)
- {
- if(itr->second==i->triggeredByAura)
- {
- found = true;
- break;
- }
- }
- if(!found)
+ if (AuraEffect * aurEff = itr->second->GetPartAura(i))
{
-// sLog.outDebug("Spell aura %u (id:%u effect:%u) has been deleted before call spell proc event handler", i->triggeredByAura->GetModifier()->m_auraname, i->triggeredByAura_SpellPair.first, i->triggeredByAura_SpellPair.second);
-// sLog.outDebug("It can be deleted one from early proccesed auras:");
-// for(ProcTriggeredList::iterator i2 = procTriggered.begin(); i != i2; ++i2)
-// sLog.outDebug(" Spell aura %u (id:%u effect:%u)", i->triggeredByAura->GetModifier()->m_auraname,i2->triggeredByAura_SpellPair.first,i2->triggeredByAura_SpellPair.second);
-// sLog.outDebug(" <end of list>");
- continue;
+ // Skip this auras
+ if (isNonTriggerAura[aurEff->GetAuraName()])
+ continue;
+ // If not trigger by default and spellProcEvent==NULL - skip
+ if (!isTriggerAura[aurEff->GetAuraName()] && triggerData.spellProcEvent==NULL)
+ continue;
+ triggerData.effMask |= 1<<i;
}
}
+ if (triggerData.effMask)
+ procTriggered.push_front(triggerData);
+ }
+
+ // Nothing found
+ if (procTriggered.empty())
+ return;
+ // Handle effects proceed this time
+ for(ProcTriggeredList::iterator i = procTriggered.begin(); i != procTriggered.end(); ++i)
+ {
+ // look for aura in auras list, it may be removed while proc event processing
+ if (!HasAura(i->aura))
+ continue;
+
+ bool useCharges= i->aura->GetAuraCharges()>0;
+ bool takeCharges = false;
+ SpellEntry const *spellInfo = i->aura->GetSpellProto();
+ uint32 Id=i->aura->GetId();
- SpellProcEventEntry const *spellProcEvent = i->spellProcEvent;
- Aura *triggeredByAura = i->triggeredByAura;
- Modifier *auraModifier = triggeredByAura->GetModifier();
- SpellEntry const *spellInfo = triggeredByAura->GetSpellProto();
- uint32 effIndex = triggeredByAura->GetEffIndex();
- bool useCharges = triggeredByAura->m_procCharges > 0;
// For players set spell cooldown if need
uint32 cooldown = 0;
- if (GetTypeId() == TYPEID_PLAYER && spellProcEvent && spellProcEvent->cooldown)
- cooldown = spellProcEvent->cooldown;
+ if (GetTypeId() == TYPEID_PLAYER && i->spellProcEvent && i->spellProcEvent->cooldown)
+ cooldown = i->spellProcEvent->cooldown;
+
+ uint32 procDebug = 0;
- switch(auraModifier->m_auraname)
+ for (uint8 effIndex = 0; effIndex<MAX_SPELL_EFFECTS;++effIndex)
{
- case SPELL_AURA_PROC_TRIGGER_SPELL:
- {
- sLog.outDebug("ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
- // Don`t drop charge or add cooldown for not started trigger
- if (!HandleProcTriggerSpell(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
- continue;
- break;
- }
- case SPELL_AURA_PROC_TRIGGER_DAMAGE:
- {
- sLog.outDebug("ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", auraModifier->m_amount, spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
- SpellNonMeleeDamage damageInfo(this, pTarget, spellInfo->Id, spellInfo->SchoolMask);
- uint32 damage = SpellDamageBonus(pTarget, spellInfo, auraModifier->m_amount, SPELL_DIRECT_DAMAGE);
- CalculateSpellDamageTaken(&damageInfo, damage, spellInfo);
- SendSpellNonMeleeDamageLog(&damageInfo);
- DealSpellDamage(&damageInfo, true);
- break;
- }
- case SPELL_AURA_MANA_SHIELD:
- case SPELL_AURA_DUMMY:
- {
- sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
- if (!HandleDummyAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
- continue;
- break;
- }
- case SPELL_AURA_MOD_HASTE:
- {
- sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s haste aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
- if (!HandleHasteAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
- continue;
- break;
- }
- case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
- {
- sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
- if (!HandleOverrideClassScriptAuraProc(pTarget, triggeredByAura, procSpell, cooldown))
- continue;
- break;
- }
- case SPELL_AURA_PRAYER_OF_MENDING:
+ if (!(i->effMask & (1<<effIndex)))
+ continue;
+
+ AuraEffect *triggeredByAura = i->aura->GetPartAura(effIndex);
+ assert(triggeredByAura);
+
+ switch(triggeredByAura->GetAuraName())
{
- sLog.outDebug("ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
- (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
+ case SPELL_AURA_PROC_TRIGGER_SPELL:
+ {
+ sLog.outDebug("ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ // Don`t drop charge or add cooldown for not started trigger
+ if (!HandleProcTriggerSpell(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ continue;
+ break;
+ }
+ case SPELL_AURA_PROC_TRIGGER_DAMAGE:
+ {
+ sLog.outDebug("ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", triggeredByAura->GetAmount() , spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ SpellNonMeleeDamage damageInfo(this, pTarget, spellInfo->Id, spellInfo->SchoolMask);
+ uint32 damage = SpellDamageBonus(pTarget, spellInfo, triggeredByAura->GetAmount(), SPELL_DIRECT_DAMAGE);
+ CalculateSpellDamageTaken(&damageInfo, damage, spellInfo);
+ SendSpellNonMeleeDamageLog(&damageInfo);
+ DealSpellDamage(&damageInfo, true);
+ break;
+ }
+ case SPELL_AURA_MANA_SHIELD:
+ case SPELL_AURA_DUMMY:
+ {
+ sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ if (!HandleDummyAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ continue;
+ if (procDebug & 1)
+ sLog.outError("Dummy aura of spell %d procs twice from one effect!",spellInfo->Id);
+ procDebug |= 1;
+ break;
+ }
+ case SPELL_AURA_OBS_MOD_ENERGY:
+ sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ if (!HandleObsModEnergyAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ continue;
+ if (procDebug & 2)
+ sLog.outError("ObsModEnergy aura of spell %d procs twice from one effect!",spellInfo->Id);
+ procDebug |= 2;
+ break;
+ case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
+ sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ if (!HandleModDamagePctTakenAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ continue;
+ if (procDebug & 16)
+ sLog.outError("ModDamagePctTaken aura of spell %d procs twice from one effect!",spellInfo->Id);
+ procDebug |= 16;
+ break;
+ case SPELL_AURA_MOD_HASTE:
+ {
+ sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s haste aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ if (!HandleHasteAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ continue;
+ if (procDebug & 4)
+ sLog.outError("Haste aura of spell %d procs twice from one effect!",spellInfo->Id);
+ procDebug |= 4;
+ break;
+ }
+ case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
+ {
+ sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ if (!HandleOverrideClassScriptAuraProc(pTarget, damage, triggeredByAura, procSpell, cooldown))
+ continue;
+ if (procDebug & 8)
+ sLog.outError("OverrideClassScripts aura of spell %d procs twice from one effect!",spellInfo->Id);
+ procDebug |= 8;
+ break;
+ }
+ case SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE:
+ {
+ sLog.outDebug("ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
+ (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
- HandleMeandingAuraProc(triggeredByAura);
- break;
- }
- case SPELL_AURA_MOD_STUN:
- // Remove by default, but if charge exist drop it
- if (triggeredByAura->m_procCharges == 0)
- removedSpells.push_back(triggeredByAura->GetId());
- break;
- case SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS:
- case SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS:
- // Hunter's Mark (1-4 Rangs)
- if (spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && (spellInfo->SpellFamilyFlags&0x0000000000000400LL))
+ HandleAuraRaidProcFromChargeWithValue(triggeredByAura);
+ break;
+ }
+ case SPELL_AURA_RAID_PROC_FROM_CHARGE:
{
- uint32 basevalue = triggeredByAura->GetBasePoints();
- auraModifier->m_amount += basevalue/10;
- if (auraModifier->m_amount > basevalue*4)
- auraModifier->m_amount = basevalue*4;
+ sLog.outDebug("ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
+ (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
+
+ HandleAuraRaidProcFromCharge(triggeredByAura);
+ break;
}
- break;
- case SPELL_AURA_MOD_CASTING_SPEED:
- // Skip melee hits or instant cast spells
- if (procSpell == NULL || GetSpellCastTime(procSpell) == 0)
- continue;
- break;
- case SPELL_AURA_REFLECT_SPELLS_SCHOOL:
- // Skip Melee hits and spells ws wrong school
- if (procSpell == NULL || (auraModifier->m_miscvalue & procSpell->SchoolMask) == 0)
- continue;
- break;
- case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT:
- case SPELL_AURA_MOD_POWER_COST_SCHOOL:
- // Skip melee hits and spells ws wrong school or zero cost
- if (procSpell == NULL ||
- (procSpell->manaCost == 0 && procSpell->ManaCostPercentage == 0) || // Cost check
- (auraModifier->m_miscvalue & procSpell->SchoolMask) == 0) // School check
- continue;
- break;
- case SPELL_AURA_MECHANIC_IMMUNITY:
- // Compare mechanic
- if (procSpell==NULL || procSpell->Mechanic != auraModifier->m_miscvalue)
- continue;
- break;
- case SPELL_AURA_MOD_MECHANIC_RESISTANCE:
- // Compare mechanic
- if (procSpell==NULL || procSpell->Mechanic != auraModifier->m_miscvalue)
- continue;
- break;
- default:
- // nothing do, just charges counter
- break;
- }
- // Remove charge (aura can be removed by triggers)
- if(useCharges)
- {
- // need found aura on drop (can be dropped by triggers)
- AuraMap::const_iterator lower = GetAuras().lower_bound(i->triggeredByAura_SpellPair);
- AuraMap::const_iterator upper = GetAuras().upper_bound(i->triggeredByAura_SpellPair);
- for(AuraMap::const_iterator itr = lower; itr!= upper; ++itr)
- {
- if(itr->second == i->triggeredByAura)
+ case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE:
{
- triggeredByAura->m_procCharges -=1;
- triggeredByAura->UpdateAuraCharges();
- if (triggeredByAura->m_procCharges <= 0)
- removedSpells.push_back(triggeredByAura->GetId());
+ sLog.outDebug("ProcDamageAndSpell: casting spell %u (triggered with value by %s aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+
+ if (!HandleProcTriggerSpell(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ continue;
break;
}
+ case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK:
+ // Skip melee hits or instant cast spells
+ if (procSpell == NULL || GetSpellCastTime(procSpell) == 0)
+ continue;
+ break;
+ case SPELL_AURA_REFLECT_SPELLS_SCHOOL:
+ // Skip Melee hits and spells ws wrong school
+ if (procSpell == NULL || (triggeredByAura->GetMiscValue() & procSpell->SchoolMask) == 0)
+ continue;
+ break;
+ case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT:
+ case SPELL_AURA_MOD_POWER_COST_SCHOOL:
+ // Skip melee hits and spells ws wrong school or zero cost
+ if (procSpell == NULL ||
+ (procSpell->manaCost == 0 && procSpell->ManaCostPercentage == 0) || // Cost check
+ (triggeredByAura->GetMiscValue() & procSpell->SchoolMask) == 0) // School check
+ continue;
+ break;
+ case SPELL_AURA_MECHANIC_IMMUNITY:
+ // Compare mechanic
+ if (procSpell==NULL || procSpell->Mechanic != triggeredByAura->GetMiscValue())
+ continue;
+ break;
+ case SPELL_AURA_MOD_MECHANIC_RESISTANCE:
+ // Compare mechanic
+ if (procSpell==NULL || procSpell->Mechanic != triggeredByAura->GetMiscValue())
+ continue;
+ break;
+ case SPELL_AURA_MOD_DAMAGE_FROM_CASTER:
+ // Compare casters
+ if (triggeredByAura->GetCasterGUID() != pTarget->GetGUID())
+ continue;
+ break;
+ default:
+ // nothing do, just charges counter
+ break;
}
+ takeCharges=true;
+ }
+ // Remove charge (aura can be removed by triggers)
+ if(useCharges && takeCharges)
+ {
+ i->aura->DropAuraCharge();
}
}
- if (removedSpells.size())
- {
- // Sort spells and remove dublicates
- removedSpells.sort();
- removedSpells.unique();
- // Remove auras from removedAuras
- for(RemoveSpellList::const_iterator i = removedSpells.begin(); i != removedSpells.end();i++)
- RemoveAurasDueToSpell(*i);
- }
- --m_procDeep;
}
SpellSchoolMask Unit::GetMeleeDamageSchoolMask() const
@@ -11673,15 +11939,21 @@ Player* Unit::GetSpellModOwner() const
}
///----------Pet responses methods-----------------
-void Unit::SendPetCastFail(uint32 spellid, uint8 msg)
+void Unit::SendPetCastFail(uint32 spellid, SpellCastResult msg)
{
+ if(msg == SPELL_CAST_OK)
+ return;
+
Unit *owner = GetCharmerOrOwner();
if(!owner || owner->GetTypeId() != TYPEID_PLAYER)
return;
WorldPacket data(SMSG_PET_CAST_FAILED, (4+1));
+ data << uint8(0); // cast count?
data << uint32(spellid);
data << uint8(msg);
+ // uint32 for some reason
+ // uint32 for some reason
((Player*)owner)->GetSession()->SendPacket(&data);
}
@@ -11800,8 +12072,8 @@ void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID)
// attack caster if can
Unit* caster = ObjectAccessor::GetObjectInWorld(casterGUID, (Unit*)NULL);
- if(caster && caster != getVictim() && ((Creature*)this)->IsAIEnabled)
- ((Creature*)this)->AI()->AttackStart(caster);
+ if(caster && ((Creature*)this)->AI())
+ ((Creature*)this)->AI()->AttackedBy(caster);
}
}
@@ -11841,15 +12113,16 @@ void Unit::SetConfused(bool apply, uint64 casterGUID, uint32 spellID)
bool Unit::IsSitState() const
{
uint8 s = getStandState();
- return s == PLAYER_STATE_SIT_CHAIR || s == PLAYER_STATE_SIT_LOW_CHAIR ||
- s == PLAYER_STATE_SIT_MEDIUM_CHAIR || s == PLAYER_STATE_SIT_HIGH_CHAIR ||
- s == PLAYER_STATE_SIT;
+ return
+ s == UNIT_STAND_STATE_SIT_CHAIR || s == UNIT_STAND_STATE_SIT_LOW_CHAIR ||
+ s == UNIT_STAND_STATE_SIT_MEDIUM_CHAIR || s == UNIT_STAND_STATE_SIT_HIGH_CHAIR ||
+ s == UNIT_STAND_STATE_SIT;
}
bool Unit::IsStandState() const
{
uint8 s = getStandState();
- return !IsSitState() && s != PLAYER_STATE_SLEEP && s != PLAYER_STATE_KNEEL;
+ return !IsSitState() && s != UNIT_STAND_STATE_SLEEP && s != UNIT_STAND_STATE_KNEEL;
}
void Unit::SetStandState(uint8 state)
@@ -11903,7 +12176,6 @@ void Unit::ClearComboPointHolders()
void Unit::ClearAllReactives()
{
-
for(int i=0; i < MAX_REACTIVE; ++i)
m_reactiveTimer[i] = 0;
@@ -11911,11 +12183,6 @@ void Unit::ClearAllReactives()
ModifyAuraState(AURA_STATE_DEFENSE, false);
if (getClass() == CLASS_HUNTER && HasAuraState( AURA_STATE_HUNTER_PARRY))
ModifyAuraState(AURA_STATE_HUNTER_PARRY, false);
- if (HasAuraState( AURA_STATE_CRIT))
- ModifyAuraState(AURA_STATE_CRIT, false);
- if (getClass() == CLASS_HUNTER && HasAuraState( AURA_STATE_HUNTER_CRIT_STRIKE) )
- ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, false);
-
if(getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER)
((Player*)this)->ClearComboPoints();
}
@@ -11943,14 +12210,6 @@ void Unit::UpdateReactives( uint32 p_time )
if ( getClass() == CLASS_HUNTER && HasAuraState(AURA_STATE_HUNTER_PARRY))
ModifyAuraState(AURA_STATE_HUNTER_PARRY, false);
break;
- case REACTIVE_CRIT:
- if (HasAuraState(AURA_STATE_CRIT))
- ModifyAuraState(AURA_STATE_CRIT, false);
- break;
- case REACTIVE_HUNTER_CRIT:
- if ( getClass() == CLASS_HUNTER && HasAuraState(AURA_STATE_HUNTER_CRIT_STRIKE) )
- ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, false);
- break;
case REACTIVE_OVERPOWER:
if(getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER)
((Player*)this)->ClearComboPoints();
@@ -11970,7 +12229,7 @@ Unit* Unit::SelectNearbyTarget(float dist) const
{
std::list<Unit *> targets;
Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, this, dist);
- Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(targets, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(this, targets, u_check);
VisitNearbyObject(dist, searcher);
// remove current target
@@ -12003,6 +12262,16 @@ Unit* Unit::SelectNearbyTarget(float dist) const
return *tcIter;
}
+bool Unit::hasNegativeAuraWithInterruptFlag(uint32 flag)
+{
+ for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ++iter)
+ {
+ if (!iter->second->IsPositive() && iter->second->GetSpellProto()->AuraInterruptFlags & flag)
+ return true;
+ }
+ return false;
+}
+
void Unit::ApplyAttackTimePercentMod( WeaponAttackType att,float val, bool apply )
{
float remainingTimePct = (float)m_attackTimer[att] / (GetAttackTime(att) * m_modAttackSpeedPct[att]);
@@ -12119,13 +12388,15 @@ uint32 Unit::GetCastingTimeForBonus( SpellEntry const *spellProto, DamageEffectT
void Unit::UpdateAuraForGroup(uint8 slot)
{
+ if(slot >= MAX_AURAS) // slot not found, return
+ return;
if(GetTypeId() == TYPEID_PLAYER)
{
Player* player = (Player*)this;
if(player->GetGroup())
{
player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_AURAS);
- player->SetAuraUpdateMask(slot);
+ player->SetAuraUpdateMaskForRaid(slot);
}
}
else if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet())
@@ -12137,7 +12408,7 @@ void Unit::UpdateAuraForGroup(uint8 slot)
if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
{
((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_AURAS);
- pet->SetAuraUpdateMask(slot);
+ pet->SetAuraUpdateMaskForRaid(slot);
}
}
}
@@ -12168,10 +12439,10 @@ float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized)
}
}
-Aura* Unit::GetDummyAura( uint32 spell_id ) const
+AuraEffect* Unit::GetDummyAura( uint32 spell_id ) const
{
- Unit::AuraList const& mDummy = GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr)
+ Unit::AuraEffectList const& mDummy = GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraEffectList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr)
if ((*itr)->GetId() == spell_id)
return *itr;
@@ -12208,21 +12479,30 @@ void Unit::SetContestedPvP(Player *attackedPlayer)
void Unit::AddPetAura(PetAura const* petSpell)
{
+ if(GetTypeId() != TYPEID_PLAYER)
+ return;
+
m_petAuras.insert(petSpell);
- if(Pet* pet = GetPet())
+ if(Pet* pet = ((Player*)this)->GetPet())
pet->CastPetAura(petSpell);
}
void Unit::RemovePetAura(PetAura const* petSpell)
{
+ if(GetTypeId() != TYPEID_PLAYER)
+ return;
+
m_petAuras.erase(petSpell);
- if(Pet* pet = GetPet())
+ if(Pet* pet = ((Player*)this)->GetPet())
pet->RemoveAurasDueToSpell(petSpell->GetAura(pet->GetEntry()));
}
Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id)
{
- Pet* pet = new Pet(HUNTER_PET);
+ if(GetTypeId()!=TYPEID_PLAYER)
+ return NULL;
+
+ Pet* pet = new Pet((Player*)this, HUNTER_PET);
if(!pet->CreateBaseAtCreature(creatureTarget))
{
@@ -12230,43 +12510,38 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id)
return NULL;
}
- pet->SetOwnerGUID(GetGUID());
pet->SetCreatorGUID(GetGUID());
pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction());
pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, spell_id);
- if(!pet->InitStatsForLevel(creatureTarget->getLevel()))
+ if(GetTypeId()==TYPEID_PLAYER)
+ pet->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+
+ uint32 level = (creatureTarget->getLevel() < (getLevel() - 5)) ? (getLevel() - 5) : creatureTarget->getLevel();
+
+ if(!pet->InitStatsForLevel(level))
{
- sLog.outError("ERROR: Pet::InitStatsForLevel() failed for creature (Entry: %u)!",creatureTarget->GetEntry());
+ sLog.outError("Pet::InitStatsForLevel() failed for creature (Entry: %u)!",creatureTarget->GetEntry());
delete pet;
return NULL;
}
pet->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true);
// this enables pet details window (Shift+P)
- pet->AIM_Initialize();
pet->InitPetCreateSpells();
+ pet->InitTalentForLevel();
pet->SetHealth(pet->GetMaxHealth());
return pet;
}
-bool Unit::IsTriggeredAtSpellProcEvent(Aura* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent )
+bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura * aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const *& spellProcEvent )
{
SpellEntry const* spellProto = aura->GetSpellProto ();
// Get proc Event Entry
spellProcEvent = spellmgr.GetSpellProcEvent(spellProto->Id);
- // Aura info stored here
- Modifier *mod = aura->GetModifier();
- // Skip this auras
- if (isNonTriggerAura[mod->m_auraname])
- return false;
- // If not trigger by default and spellProcEvent==NULL - skip
- if (!isTriggerAura[mod->m_auraname] && spellProcEvent==NULL)
- return false;
-
// Get EventProcFlag
uint32 EventProcFlag;
if (spellProcEvent && spellProcEvent->procFlags) // if exist get custom spellProcEvent->procFlags
@@ -12277,11 +12552,27 @@ bool Unit::IsTriggeredAtSpellProcEvent(Aura* aura, SpellEntry const* procSpell,
if (!EventProcFlag)
return false;
+ // Additional checks for triggered spells
+ if (procExtra & PROC_EX_INTERNAL_TRIGGERED)
+ {
+ if (!(spellProto->AttributesEx3 & SPELL_ATTR_EX3_CAN_PROC_TRIGGERED))
+ return false;
+ }
+
// Check spellProcEvent data requirements
- if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, EventProcFlag, procSpell, procFlag, procExtra, active))
+ if(!spellmgr.IsSpellProcEventCanTriggeredBy(spellProcEvent, EventProcFlag, procSpell, procFlag, procExtra, active))
return false;
-
- // Aura added by spell can`t trogger from self (prevent drop cahres/do triggers)
+ // In most cases req get honor or XP from kill
+ if (EventProcFlag & PROC_FLAG_KILL && GetTypeId() == TYPEID_PLAYER)
+ {
+ bool allow = ((Player*)this)->isHonorOrXPTarget(pVictim);
+ // Shadow Word: Death - can trigger from every kill
+ if (aura->GetId() == 32409)
+ allow = true;
+ if (!allow)
+ return false;
+ }
+ // Aura added by spell can`t trogger from self (prevent drop charges/do triggers)
// But except periodic triggers (can triggered from self)
if(procSpell && procSpell->Id == spellProto->Id && !(spellProto->procFlags&PROC_FLAG_ON_TAKE_PERIODIC))
return false;
@@ -12293,13 +12584,13 @@ bool Unit::IsTriggeredAtSpellProcEvent(Aura* aura, SpellEntry const* procSpell,
{
Item *item = NULL;
if(attType == BASE_ATTACK)
- item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
else if (attType == OFF_ATTACK)
- item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
else
- item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
- if (!((Player*)this)->IsUseEquipedWeapon(attType==BASE_ATTACK))
+ if (((Player*)this)->IsInFeralForm())
return false;
if(!item || item->IsBroken() || item->GetProto()->Class != ITEM_CLASS_WEAPON || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))
@@ -12308,7 +12599,7 @@ bool Unit::IsTriggeredAtSpellProcEvent(Aura* aura, SpellEntry const* procSpell,
else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR)
{
// Check if player is wearing shield
- Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ Item *item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
if(!item || item->IsBroken() || item->GetProto()->Class != ITEM_CLASS_ARMOR || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))
return false;
}
@@ -12322,60 +12613,58 @@ bool Unit::IsTriggeredAtSpellProcEvent(Aura* aura, SpellEntry const* procSpell,
if(!isVictim && spellProcEvent && spellProcEvent->ppmRate != 0)
{
uint32 WeaponSpeed = GetAttackTime(attType);
- chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate);
+ chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate, spellProto);
}
// Apply chance modifer aura
if(Player* modOwner = GetSpellModOwner())
+ {
modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance);
+ }
return roll_chance_f(chance);
}
-bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura )
+bool Unit::HandleAuraRaidProcFromChargeWithValue( AuraEffect* triggeredByAura )
{
// aura can be deleted at casts
SpellEntry const* spellProto = triggeredByAura->GetSpellProto();
uint32 effIdx = triggeredByAura->GetEffIndex();
- int32 heal = triggeredByAura->GetModifier()->m_amount;
+ int32 heal = triggeredByAura->GetAmount();
uint64 caster_guid = triggeredByAura->GetCasterGUID();
+ //Currently only Prayer Of Mending
+ if (!(spellProto->SpellFamilyName==SPELLFAMILY_PRIEST && spellProto->SpellFamilyFlags[1] & 0x20))
+ {
+ sLog.outDebug("Unit::HandleAuraRaidProcFromChargeWithValue, received not handled spell: %u", spellProto->Id);
+ return false;
+ }
// jumps
- int32 jumps = triggeredByAura->m_procCharges-1;
+ int32 jumps = triggeredByAura->GetParentAura()->GetAuraCharges()-1;
// current aura expire
- triggeredByAura->m_procCharges = 1; // will removed at next charges decrease
+ triggeredByAura->GetParentAura()->SetAuraCharges(1); // will removed at next charges decrease
// next target selection
- if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid))
+ if(jumps > 0 && IS_PLAYER_GUID(caster_guid))
{
float radius;
if (spellProto->EffectRadiusIndex[effIdx])
- radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx]));
+ radius = GetSpellRadiusForTarget(triggeredByAura->GetCaster(), sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx]));
else
- radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex));
+ radius = GetSpellMaxRangeForTarget(triggeredByAura->GetCaster() ,sSpellRangeStore.LookupEntry(spellProto->rangeIndex));
if(Player* caster = ((Player*)triggeredByAura->GetCaster()))
{
caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL);
- if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius))
+ if (Unit* target= GetNextRandomRaidMemberOrPet(radius))
{
- // aura will applied from caster, but spell casted from current aura holder
- SpellModifier *mod = new SpellModifier;
- mod->op = SPELLMOD_CHARGES;
- mod->value = jumps-5; // negative
- mod->type = SPELLMOD_FLAT;
- mod->spellId = spellProto->Id;
- mod->effectId = effIdx;
- mod->lastAffected = NULL;
- mod->mask = spellProto->SpellFamilyFlags;
- mod->charges = 0;
-
- caster->AddSpellMod(mod, true);
CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,triggeredByAura,caster->GetGUID());
- caster->AddSpellMod(mod, false);
+ if (Aura * aur = target->GetAura(spellProto->Id, caster->GetGUID()))
+ aur->SetAuraCharges(jumps);
- heal = caster->SpellHealingBonus(spellProto, heal, HEAL, this);
+ //bonus must be applied after aura cast on target
+ heal = caster->SpellHealingBonus(this, spellProto, heal, HEAL);
}
}
}
@@ -12384,29 +12673,64 @@ bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura )
CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid);
return true;
}
-
-void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo, Unit * caster)
+bool Unit::HandleAuraRaidProcFromCharge( AuraEffect* triggeredByAura )
{
-/* uint64 target_guid = GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT);
- if(target_guid == GetGUID())
- return;
+ // aura can be deleted at casts
+ SpellEntry const* spellProto = triggeredByAura->GetSpellProto();
- if(!IS_UNIT_GUID(target_guid))
- return;
+ uint32 damageSpellId;
+ switch(spellProto->Id)
+ {
+ case 57949: //shiver
+ damageSpellId=57952;
+// animationSpellId=57951; dummy effects for jump spell have unknown use (see also 41637)
+ break;
+ case 59978: //shiver
+ damageSpellId=59979;
+ break;
+ case 43593: //Cold Stare
+ damageSpellId=43594;
+ break;
+ default:
+ sLog.outDebug("Unit::HandleAuraRaidProcFromCharge, received not handled spell: %u", spellProto->Id);
+ return false;
+ }
- Unit* target = ObjectAccessor::GetUnit(*this, target_guid);*/
- if(!caster)
- return;
+ uint64 caster_guid = triggeredByAura->GetCasterGUID();
+ uint32 effIdx = triggeredByAura->GetEffIndex();
+
+ // jumps
+ int32 jumps = triggeredByAura->GetParentAura()->GetAuraCharges()-1;
- for (AuraMap::iterator iter = GetAuras().begin(); iter != GetAuras().end(); )
+ // current aura expire
+ triggeredByAura->GetParentAura()->SetAuraCharges(1); // will removed at next charges decrease
+
+ // next target selection
+ if(jumps > 0 && IS_PLAYER_GUID(caster_guid))
{
- if (iter->second->GetId() == spellInfo->Id && iter->second->GetCasterGUID() == caster->GetGUID())
- RemoveAura(iter);
+ float radius;
+ if (spellProto->EffectRadiusIndex[effIdx])
+ radius = GetSpellRadiusForTarget(triggeredByAura->GetCaster(), sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx]));
else
- ++iter;
+ radius = GetSpellMaxRangeForTarget(triggeredByAura->GetCaster() ,sSpellRangeStore.LookupEntry(spellProto->rangeIndex));
+
+ if(Player* caster = ((Player*)triggeredByAura->GetCaster()))
+ {
+ caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL);
+
+ if (Unit* target= GetNextRandomRaidMemberOrPet(radius))
+ {
+ CastSpell(target, spellProto, true,NULL,triggeredByAura,caster_guid);
+ if (Aura * aur = target->GetAura(spellProto->Id, caster->GetGUID()))
+ aur->SetAuraCharges(jumps);
+ }
+ }
}
-}
+ CastSpell(this, damageSpellId, true,NULL,triggeredByAura,caster_guid);
+
+ return true;
+}
/*-----------------------TRINITY-----------------------------*/
void Unit::SetToNotify()
@@ -12420,6 +12744,9 @@ void Unit::SetToNotify()
void Unit::Kill(Unit *pVictim, bool durabilityLoss)
{
+ // Prevent killing unit twice (and giving reward from kill twice)
+ if (!pVictim->isAlive())
+ return;
pVictim->SetHealth(0);
// find player: owner of controlled `this` or `this` itself maybe
@@ -12432,7 +12759,7 @@ void Unit::Kill(Unit *pVictim, bool durabilityLoss)
if(player && player!=pVictim)
{
if(player->RewardPlayerAndGroupAtKill(pVictim))
- player->ProcDamageAndSpell(pVictim, PROC_FLAG_KILL_AND_GET_XP, PROC_FLAG_KILLED, PROC_EX_NONE, 0);
+ player->ProcDamageAndSpell(pVictim, PROC_FLAG_KILL, PROC_FLAG_KILLED, PROC_EX_NONE, 0);
else
player->ProcDamageAndSpell(pVictim, PROC_FLAG_NONE, PROC_FLAG_KILLED,PROC_EX_NONE, 0);
}
@@ -12441,8 +12768,8 @@ void Unit::Kill(Unit *pVictim, bool durabilityLoss)
bool SpiritOfRedemption = false;
if(pVictim->GetTypeId()==TYPEID_PLAYER && pVictim->getClass()==CLASS_PRIEST )
{
- AuraList const& vDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
- for(AuraList::const_iterator itr = vDummyAuras.begin(); itr != vDummyAuras.end(); ++itr)
+ AuraEffectList const& vDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
+ for(AuraEffectList::const_iterator itr = vDummyAuras.begin(); itr != vDummyAuras.end(); ++itr)
{
if((*itr)->GetSpellProto()->SpellIconID==1654)
{
@@ -12564,6 +12891,15 @@ void Unit::Kill(Unit *pVictim, bool durabilityLoss)
bg->HandleKillUnit((Creature*)pVictim, player);
}
}
+
+ // achievement stuff
+ if (pVictim->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (GetTypeId() == TYPEID_UNIT)
+ ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE, GetEntry());
+ else if(GetTypeId() == TYPEID_PLAYER && pVictim != this)
+ ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1, ((Player*)this)->GetTeam());
+ }
}
void Unit::SetControlled(bool apply, UnitState state)
@@ -12633,7 +12969,7 @@ void Unit::SetStunned(bool apply)
if(apply)
{
SetUInt64Value(UNIT_FIELD_TARGET, 0);
- SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
+ SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
CastStop();
// Creature specific
@@ -12651,7 +12987,7 @@ void Unit::SetStunned(bool apply)
{
if(isAlive() && getVictim())
SetUInt64Value(UNIT_FIELD_TARGET, getVictim()->GetGUID());
- RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
+ RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
if(!hasUnitState(UNIT_STAT_ROOT)) // prevent allow move if have also root effect
{
@@ -12704,7 +13040,7 @@ void Unit::SetFeared(bool apply)
if(apply)
{
Unit *caster = NULL;
- Unit::AuraList const& fearAuras = GetAurasByType(SPELL_AURA_MOD_FEAR);
+ Unit::AuraEffectList const& fearAuras = GetAurasByType(SPELL_AURA_MOD_FEAR);
if(!fearAuras.empty())
caster = ObjectAccessor::GetUnit(*this, fearAuras.front()->GetCasterGUID());
if(!caster)
@@ -12747,7 +13083,7 @@ void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess)
if(this == charmer)
return;
- if(isInFlight())
+ if(hasUnitState(UNIT_STAT_UNATTACKABLE))
return;
if(GetTypeId() == TYPEID_PLAYER && ((Player*)this)->GetTransport())
@@ -12760,21 +13096,26 @@ void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess)
// Charmer stop charming
if(charmer->GetTypeId() == TYPEID_PLAYER)
+ {
((Player*)charmer)->StopCastingCharm();
+ ((Player*)charmer)->StopCastingBindSight();
+ }
// Charmed stop charming
if(GetTypeId() == TYPEID_PLAYER)
+ {
((Player*)this)->StopCastingCharm();
+ ((Player*)this)->StopCastingBindSight();
+ }
// StopCastingCharm may remove a possessed pet?
if(!IsInWorld())
return;
// Set charmed
- charmer->SetCharm(this);
- SetCharmerGUID(charmer->GetGUID());
setFaction(charmer->getFaction());
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+ charmer->SetCharm(this, true);
if(GetTypeId() == TYPEID_UNIT)
{
@@ -12786,11 +13127,12 @@ void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess)
{
if(((Player*)this)->isAFK())
((Player*)this)->ToggleAFK();
- ((Player*)this)->SetViewport(GetGUID(), false);
+ ((Player*)this)->SetClientControl(this, 0);
}
// Pets already have a properly initialized CharmInfo, don't overwrite it.
- if(GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet())
+ if(GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT
+ && !((Creature*)this)->HasSummonMask(SUMMON_MASK_GUARDIAN))
{
CharmInfo *charmInfo = InitCharmInfo();
if(possess)
@@ -12803,9 +13145,9 @@ void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess)
if(possess)
{
addUnitState(UNIT_STAT_POSSESSED);
- SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
- AddPlayerToVision((Player*)charmer);
- ((Player*)charmer)->SetViewport(GetGUID(), true);
+ SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
+ ((Player*)charmer)->SetClientControl(this, 1);
+ ((Player*)charmer)->SetViewpoint(this, true);
charmer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
}
// Charm demon
@@ -12848,13 +13190,13 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
CombatStop(); //TODO: CombatStop(true) may cause crash (interrupt spells)
getHostilRefManager().deleteReferences();
DeleteThreatList();
- SetCharmerGUID(0);
RestoreFaction();
+ GetMotionMaster()->InitDefault();
if(possess)
{
clearUnitState(UNIT_STAT_POSSESSED);
- RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
+ RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
}
if(GetTypeId() == TYPEID_UNIT)
@@ -12875,7 +13217,7 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
}
}
else
- ((Player*)this)->SetViewport(GetGUID(), true);
+ ((Player*)this)->SetClientControl(this, 1);
// If charmer still exists
if(!charmer)
@@ -12883,11 +13225,11 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
assert(!possess || charmer->GetTypeId() == TYPEID_PLAYER);
- charmer->SetCharm(0);
+ charmer->SetCharm(this, false);
if(possess)
{
- RemovePlayerFromVision((Player*)charmer);
- ((Player*)charmer)->SetViewport(charmer->GetGUID(), true);
+ ((Player*)charmer)->SetClientControl(charmer, 1);
+ ((Player*)charmer)->SetViewpoint(this, false);
charmer->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
}
// restore UNIT_FIELD_BYTES_0
@@ -12909,7 +13251,9 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
}
}
- if(GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet())
+ //a guardian should always have charminfo
+ if(GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT
+ && !((Creature*)this)->HasSummonMask(SUMMON_MASK_GUARDIAN))
{
DeleteCharmInfo();
}
@@ -12982,17 +13326,30 @@ void Unit::GetRaidMember(std::list<Unit*> &nearMembers, float radius)
return;
Group *pGroup = owner->GetGroup();
- if(!pGroup)
- return;
-
- for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+ if(pGroup)
{
- Player* Target = itr->getSource();
+ for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+ {
+ Player* Target = itr->getSource();
- // IsHostileTo check duel and controlled by enemy
- if( Target && Target != this && Target->isAlive()
- && IsWithinDistInMap(Target, radius) && !IsHostileTo(Target) )
- nearMembers.push_back(Target);
+ if( Target && !IsHostileTo(Target) )
+ {
+ if(Target->isAlive() && IsWithinDistInMap(Target, radius) )
+ nearMembers.push_back(Target);
+
+ if(Guardian* pet = Target->GetGuardianPet())
+ if(pet->isAlive() && IsWithinDistInMap(pet, radius) )
+ nearMembers.push_back(pet);
+ }
+ }
+ }
+ else
+ {
+ if(owner->isAlive() && (owner == this || IsWithinDistInMap(owner, radius)))
+ nearMembers.push_back(owner);
+ if(Guardian* pet = owner->GetGuardianPet())
+ if(pet->isAlive() && (pet == this && IsWithinDistInMap(pet, radius)))
+ nearMembers.push_back(pet);
}
}
@@ -13017,7 +13374,7 @@ void Unit::GetPartyMember(std::list<Unit*> &TagUnitMap, float radius)
if(Target->isAlive() && IsWithinDistInMap(Target, radius) )
TagUnitMap.push_back(Target);
- if(Pet* pet = Target->GetPet())
+ if(Guardian* pet = Target->GetGuardianPet())
if(pet->isAlive() && IsWithinDistInMap(pet, radius) )
TagUnitMap.push_back(pet);
}
@@ -13027,12 +13384,38 @@ void Unit::GetPartyMember(std::list<Unit*> &TagUnitMap, float radius)
{
if(owner->isAlive() && (owner == this || IsWithinDistInMap(owner, radius)))
TagUnitMap.push_back(owner);
- if(Pet* pet = owner->GetPet())
+ if(Guardian* pet = owner->GetGuardianPet())
if(pet->isAlive() && (pet == this && IsWithinDistInMap(pet, radius)))
TagUnitMap.push_back(pet);
}
}
+void Unit::HandleAuraEffect(AuraEffect * aureff, bool apply)
+{
+ if (aureff->GetParentAura()->IsRemoved())
+ return;
+ if (apply)
+ {
+ m_modAuras[aureff->GetAuraName()].push_back(aureff);
+ aureff->ApplyModifier(true, true);
+ }
+ else
+ {
+ // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order)
+ m_modAuras[aureff->GetAuraName()].remove(aureff);
+ aureff->ApplyModifier(false, true);
+ Unit * caster = aureff->GetParentAura()->GetCaster();
+ if(caster && aureff->IsPersistent())
+ {
+ DynamicObject *dynObj = caster->GetDynObject(aureff->GetId(), aureff->GetEffIndex());
+ if (dynObj)
+ dynObj->RemoveAffected(this);
+ }
+ // Remove all triggered by aura spells vs unlimited duration
+ aureff->CleanupTriggeredSpells();
+ }
+}
+
void Unit::AddAura(uint32 spellId, Unit* target)
{
if(!target || !target->isAlive())
@@ -13045,24 +13428,350 @@ void Unit::AddAura(uint32 spellId, Unit* target)
if (target->IsImmunedToSpell(spellInfo))
return;
+ uint8 eff_mask=0;
+
for(uint32 i = 0; i < 3; ++i)
{
- if(spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA)
+ if(spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA || IsAreaAuraEffect(spellInfo->Effect[i]))
{
- if(target->IsImmunedToSpellEffect(spellInfo->Effect[i], spellInfo->EffectMechanic[i]))
+ if(target->IsImmunedToSpellEffect(spellInfo, i))
continue;
+ eff_mask|=1<<i;
+ }
+ }
- /*if(spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_CASTER)
- {
- Aura *Aur = CreateAura(spellInfo, i, NULL, this, this);
- AddAura(Aur);
- }
- else*/
- {
- Aura *Aur = CreateAura(spellInfo, i, NULL, target, this);
- target->AddAura(Aur);
- }
+ if (!eff_mask)
+ return;
+
+ Aura *Aur = new Aura(spellInfo, eff_mask, NULL, target, this);
+ target->AddAura(Aur);
+}
+
+Aura * Unit::AddAuraEffect(uint32 spellId, uint8 effIndex, Unit* caster)
+{
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
+ if(!spellInfo || !caster)
+ return NULL;
+
+ // can't do that for passive auras - they stack from same caster so there is no way to get exact aura which should get effect
+ //assert (!IsPassiveSpell(spellInfo));
+
+ Aura * aur = GetAura(spellId, caster->GetGUID());
+
+ if (aur)
+ {
+ AuraEffect *aurEffect = CreateAuraEffect(aur, effIndex, NULL, caster);
+ if (!aurEffect)
+ return aur;
+ if (!aur->SetPartAura(aurEffect, effIndex))
+ delete aurEffect;
+ }
+ else
+ {
+ aur = new Aura(spellInfo, 1<<effIndex, NULL, this ,caster);
+ AddAura(aur);
+ }
+ return aur;
+}
+
+// Melee based spells can be miss, parry or dodge on this step
+// Crit or block - determined on damage calculation phase! (and can be both in some time)
+float Unit::MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const
+{
+ // Calculate hit chance (more correct for chance mod)
+ int32 HitChance;
+
+ // PvP - PvE melee chances
+ /*int32 lchance = pVictim->GetTypeId() == TYPEID_PLAYER ? 5 : 7;
+ int32 leveldif = pVictim->getLevelForTarget(this) - getLevelForTarget(pVictim);
+ if(leveldif < 3)
+ HitChance = 95 - leveldif;
+ else
+ HitChance = 93 - (leveldif - 2) * lchance;*/
+ if (spellId || attType == RANGED_ATTACK || !haveOffhandWeapon())
+ HitChance = 95.0f;
+ else
+ HitChance = 76.0f;
+
+ // Hit chance depends from victim auras
+ if(attType == RANGED_ATTACK)
+ HitChance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE);
+ else
+ HitChance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE);
+
+ // Spellmod from SPELLMOD_RESIST_MISS_CHANCE
+ if(spellId)
+ {
+ if(Player *modOwner = GetSpellModOwner())
+ modOwner->ApplySpellMod(spellId, SPELLMOD_RESIST_MISS_CHANCE, HitChance);
+ }
+
+ // Miss = 100 - hit
+ float miss_chance= 100.0f - HitChance;
+
+ // Bonuses from attacker aura and ratings
+ if (attType == RANGED_ATTACK)
+ miss_chance -= m_modRangedHitChance;
+ else
+ miss_chance -= m_modMeleeHitChance;
+
+ // bonus from skills is 0.04%
+ //miss_chance -= skillDiff * 0.04f;
+ int32 diff = -skillDiff;
+ if(pVictim->GetTypeId()==TYPEID_PLAYER)
+ miss_chance += diff > 0 ? diff * 0.04 : diff * 0.02;
+ else
+ miss_chance += diff > 10 ? 2 + (diff - 10) * 0.4 : diff * 0.1;
+
+ // Limit miss chance from 0 to 60%
+ if (miss_chance < 0.0f)
+ return 0.0f;
+ if (miss_chance > 60.0f)
+ return 60.0f;
+ return miss_chance;
+}
+
+void Unit::SetPhaseMask(uint32 newPhaseMask, bool update)
+{
+ WorldObject::SetPhaseMask(newPhaseMask,update);
+
+ if(!IsInWorld())
+ return;
+
+ for(ControlList::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
+ if((*itr)->GetOwnerGUID() == GetGUID())
+ (*itr)->SetPhaseMask(newPhaseMask,true);
+
+ for(int8 i = 0; i < MAX_SUMMON_SLOT; ++i)
+ if(m_SummonSlot[i])
+ if(Creature *summon = GetMap()->GetCreature(m_SummonSlot[i]))
+ summon->SetPhaseMask(newPhaseMask,true);
+}
+
+void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ)
+{
+ if(GetTypeId() == TYPEID_UNIT)
+ {
+ GetMotionMaster()->MoveKnockbackFrom(x, y, speedXY, speedZ);
+ }
+ else
+ {
+ float vcos, vsin;
+ GetSinCos(x, y, vsin, vcos);
+
+ WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8+4+4+4+4+4));
+ data.append(GetPackGUID());
+ data << uint32(0); // Sequence
+ data << float(vcos); // x direction
+ data << float(vsin); // y direction
+ data << float(speedXY); // Horizontal speed
+ data << float(-speedZ); // Z Movement speed (vertical)
+
+ ((Player*)this)->GetSession()->SendPacket(&data);
+ }
+}
+
+void Unit::JumpTo(float speedXY, float speedZ, bool forward)
+{
+ float angle = forward ? 0 : M_PI;
+ if(GetTypeId() == TYPEID_UNIT)
+ {
+ GetMotionMaster()->MoveJumpTo(angle, speedXY, speedZ);
+ }
+ else
+ {
+ float vcos = cos(angle+GetOrientation());
+ float vsin = sin(angle+GetOrientation());
+
+ WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8+4+4+4+4+4));
+ data.append(GetPackGUID());
+ data << uint32(0); // Sequence
+ data << float(vcos); // x direction
+ data << float(vsin); // y direction
+ data << float(speedXY); // Horizontal speed
+ data << float(-speedZ); // Z Movement speed (vertical)
+
+ ((Player*)this)->GetSession()->SendPacket(&data);
+ }
+}
+
+void Unit::JumpTo(WorldObject *obj, float speedZ)
+{
+ float x, y, z;
+ obj->GetContactPoint(this, x, y, z);
+ float speedXY = GetExactDistance2d(x, y) * 10.0f / speedZ;
+ GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
+}
+
+void Unit::EnterVehicle(Vehicle *vehicle, int8 seatId)
+{
+ if(m_Vehicle)
+ {
+ if(m_Vehicle == vehicle)
+ {
+ if(seatId >= 0)
+ ChangeSeat(seatId);
+ return;
}
+ else
+ ExitVehicle();
+ }
+
+ if(GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)this)->StopCastingCharm();
+ ((Player*)this)->StopCastingBindSight();
+ }
+
+ assert(!m_Vehicle);
+ m_Vehicle = vehicle;
+ if(!m_Vehicle->AddPassenger(this, seatId))
+ {
+ m_Vehicle = NULL;
+ return;
+ }
+
+ m_Vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
+ m_Vehicle->setFaction(getFaction());
+
+ addUnitState(UNIT_STAT_ONVEHICLE);
+ //movementInfo is set in AddPassenger
+ //packets are sent in AddPassenger
+
+ if(GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)this)->SetClientControl(vehicle, 1);
+ WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
+ ((Player*)this)->GetSession()->SendPacket(&data);
}
}
+void Unit::ChangeSeat(int8 seatId, bool next)
+{
+ if(!m_Vehicle)
+ return;
+
+ if(seatId < 0)
+ {
+ seatId = m_Vehicle->GetNextEmptySeat(GetTransSeat(), next);
+ if(seatId < 0)
+ return;
+ }
+ else if(seatId == GetTransSeat() || !m_Vehicle->HasEmptySeat(seatId))
+ return;
+
+ m_Vehicle->RemovePassenger(this);
+ if(!m_Vehicle->AddPassenger(this, seatId))
+ assert(false);
+}
+
+void Unit::ExitVehicle()
+{
+ if(!m_Vehicle)
+ return;
+
+ m_Vehicle->RemovePassenger(this);
+
+ m_Vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
+ //setFaction((GetTeam() == ALLIANCE) ? GetCreatureInfo()->faction_A : GetCreatureInfo()->faction_H);
+
+ clearUnitState(UNIT_STAT_ONVEHICLE);
+ RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+
+ m_movementInfo.t_x = 0;
+ m_movementInfo.t_y = 0;
+ m_movementInfo.t_z = 0;
+ m_movementInfo.t_o = 0;
+ m_movementInfo.t_time = 0;
+ m_movementInfo.t_seat = 0;
+
+ //Send leave vehicle
+ WorldPacket data;
+ if(GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)this)->SetClientControl(this, 1);
+ ((Player*)this)->BuildTeleportAckMsg(&data, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
+ ((Player*)this)->GetSession()->SendPacket(&data);
+ }
+
+ BuildHeartBeatMsg(&data);
+ SendMessageToSet(&data, false);
+
+ if(m_Vehicle->GetOwnerGUID() == GetGUID())
+ m_Vehicle->Dismiss();
+
+ m_Vehicle = NULL;
+}
+
+void Unit::BuildMovementPacket(ByteBuffer *data) const
+{
+ // 0x00000200
+ if(GetUnitMovementFlags() & MOVEMENTFLAG_ONTRANSPORT)
+ {
+ if(m_Vehicle)
+ *data << (uint64)m_Vehicle->GetGUID();
+ else if(GetTransport())
+ *data << (uint64)GetTransport()->GetGUID();
+ else
+ *data << (uint64)0; //This will cause client crash
+ *data << float (GetTransOffsetX());
+ *data << float (GetTransOffsetY());
+ *data << float (GetTransOffsetZ());
+ *data << float (GetTransOffsetO());
+ *data << uint32(GetTransTime());
+ *data << uint8 (GetTransSeat());
+ }
+
+ // 0x02200000
+ if((GetUnitMovementFlags() & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2))
+ || (m_movementInfo.unk1 & 0x20))
+ *data << (float)m_movementInfo.s_pitch;
+
+ *data << (uint32)m_movementInfo.fallTime;
+
+ // 0x00001000
+ if(GetUnitMovementFlags() & MOVEMENTFLAG_JUMPING)
+ {
+ *data << (float)m_movementInfo.j_zspeed;
+ *data << (float)m_movementInfo.j_sinAngle;
+ *data << (float)m_movementInfo.j_cosAngle;
+ *data << (float)m_movementInfo.j_xyspeed;
+ }
+
+ // 0x04000000
+ if(GetUnitMovementFlags() & MOVEMENTFLAG_SPLINE)
+ *data << (float)m_movementInfo.u_unk1;
+}
+
+void Unit::NearTeleportTo( float x, float y, float z, float orientation, bool casting /*= false*/ )
+{
+ if(GetTypeId() == TYPEID_PLAYER)
+ ((Player*)this)->TeleportTo(GetMapId(), x, y, z, orientation, TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (casting ? TELE_TO_SPELL : 0));
+ else
+ {
+ WorldPacket data;
+ /*data.Initialize(MSG_MOVE_TELEPORT, 30);
+ data.append(GetPackGUID());
+ data << uint32(GetUnitMovementFlags());
+ data << uint16(0); // Probably walk flags here
+ data << getMSTime(); // time
+ data << x; // destination coords
+ data << y;
+ data << z;
+ data << orientation;
+ data << uint32 (0);
+ // Other information here: jumping angle etc
+ SendMessageToSet(&data, false);*/
+
+ // FIXME: this interrupts spell visual
+ DestroyForNearbyPlayers();
+
+ GetMap()->CreatureRelocation((Creature*)this, x, y, z, orientation);
+
+ //WorldPacket data;
+ // Work strange for many spells: triggered active mover set for targeted player to creature
+ //BuildTeleportAckMsg(&data, x, y, z, orientation);
+ BuildHeartBeatMsg(&data);
+ SendMessageToSet(&data, false);
+ }
+}
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 79fff7a7351..8e008e1357e 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -24,7 +24,6 @@
#include "Common.h"
#include "Object.h"
#include "Opcodes.h"
-#include "Mthread.h"
#include "SpellAuraDefines.h"
#include "UpdateFields.h"
#include "SharedDefines.h"
@@ -34,7 +33,7 @@
#include "FollowerRefManager.h"
#include "Utilities/EventProcessor.h"
#include "MotionMaster.h"
-#include "Database/DBCStructure.h"
+#include "DBCStructure.h"
#include <list>
#define WORLD_TRIGGER 12999
@@ -45,7 +44,8 @@ enum SpellInterruptFlags
SPELL_INTERRUPT_FLAG_PUSH_BACK = 0x02, // push back
SPELL_INTERRUPT_FLAG_INTERRUPT = 0x04, // interrupt
SPELL_INTERRUPT_FLAG_AUTOATTACK = 0x08, // no
- SPELL_INTERRUPT_FLAG_DAMAGE = 0x10 // _complete_ interrupt on direct damage?
+ SPELL_INTERRUPT_FLAG_ABORT_ON_DMG = 0x10, // _complete_ interrupt on direct damage
+ //SPELL_INTERRUPT_UNK = 0x20 // unk, 564 of 727 spells having this spell start with "Glyph"
};
enum SpellChannelInterruptFlags
@@ -79,7 +79,7 @@ enum SpellAuraInterruptFlags
AURA_INTERRUPT_FLAG_MOUNT = 0x00020000, // 17 misdirect, aspect, swim speed
AURA_INTERRUPT_FLAG_NOT_SEATED = 0x00040000, // 18 removed by standing up
AURA_INTERRUPT_FLAG_CHANGE_MAP = 0x00080000, // 19 leaving map/getting teleported
- AURA_INTERRUPT_FLAG_UNATTACKABLE = 0x00100000, // 20 invulnerable or stealth
+ AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION = 0x00100000, // 20 removed by auras that make you invulnerable, or make other to loose selection on you
AURA_INTERRUPT_FLAG_UNK21 = 0x00200000, // 21
AURA_INTERRUPT_FLAG_TELEPORTED = 0x00400000, // 22
AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT = 0x00800000, // 23 removed by entering pvp combat
@@ -101,7 +101,7 @@ enum SpellModOp
SPELLMOD_CASTING_TIME = 10,
SPELLMOD_COOLDOWN = 11,
SPELLMOD_EFFECT2 = 12,
- // spellmod 13 unused
+ SPELLMOD_IGNORE_ARMOR = 13,
SPELLMOD_COST = 14,
SPELLMOD_CRIT_DAMAGE_BONUS = 15,
SPELLMOD_RESIST_MISS_CHANCE = 16,
@@ -109,13 +109,16 @@ enum SpellModOp
SPELLMOD_CHANCE_OF_SUCCESS = 18,
SPELLMOD_ACTIVATION_TIME = 19,
SPELLMOD_EFFECT_PAST_FIRST = 20,
- SPELLMOD_CASTING_TIME_OLD = 21,
+ SPELLMOD_GLOBAL_COOLDOWN = 21, //TODO: GCD is not checked by server currently
SPELLMOD_DOT = 22,
SPELLMOD_EFFECT3 = 23,
SPELLMOD_SPELL_BONUS_DAMAGE = 24,
- // spellmod 25, 26 unused
+ // spellmod 25
+ SPELLMOD_PROC_PER_MINUTE = 26,
SPELLMOD_MULTIPLE_VALUE = 27,
- SPELLMOD_RESIST_DISPEL_CHANCE = 28
+ SPELLMOD_RESIST_DISPEL_CHANCE = 28,
+ SPELLMOD_CRIT_DAMAGE_BONUS_2 = 29, //one not used spell
+ SPELLMOD_SPELL_COST_REFUND_ON_FAIL = 30
};
#define MAX_SPELLMOD 32
@@ -125,6 +128,7 @@ enum SpellValueMod
SPELLVALUE_BASE_POINT0,
SPELLVALUE_BASE_POINT1,
SPELLVALUE_BASE_POINT2,
+ SPELLVALUE_RADIUS_MOD,
SPELLVALUE_MAX_TARGETS,
};
@@ -147,6 +151,35 @@ enum SpellFacingFlags
#define BASE_MAXDAMAGE 2.0f
#define BASE_ATTACK_TIME 2000
+// byte value (UNIT_FIELD_BYTES_1,0)
+enum UnitStandStateType
+{
+ UNIT_STAND_STATE_STAND = 0,
+ UNIT_STAND_STATE_SIT = 1,
+ UNIT_STAND_STATE_SIT_CHAIR = 2,
+ UNIT_STAND_STATE_SLEEP = 3,
+ UNIT_STAND_STATE_SIT_LOW_CHAIR = 4,
+ UNIT_STAND_STATE_SIT_MEDIUM_CHAIR = 5,
+ UNIT_STAND_STATE_SIT_HIGH_CHAIR = 6,
+ UNIT_STAND_STATE_DEAD = 7,
+ UNIT_STAND_STATE_KNEEL = 8
+};
+
+// byte flag value (UNIT_FIELD_BYTES_1,2)
+enum UnitStandFlags
+{
+ UNIT_STAND_FLAGS_CREEP = 0x02,
+ UNIT_STAND_FLAGS_ALL = 0xFF
+};
+
+// byte flags value (UNIT_FIELD_BYTES_1,3)
+enum UnitBytes1_Flags
+{
+ UNIT_BYTE1_FLAG_ALWAYS_STAND = 0x01,
+ UNIT_BYTE1_FLAG_UNTRACKABLE = 0x04,
+ UNIT_BYTE1_FLAG_ALL = 0xFF
+};
+
// high byte (3 from 0..3) of UNIT_FIELD_BYTES_2
enum ShapeshiftForm
{
@@ -167,6 +200,7 @@ enum ShapeshiftForm
FORM_BERSERKERSTANCE = 0x13,
FORM_TEST = 0x14,
FORM_ZOMBIE = 0x15,
+ FORM_METAMORPHOSIS = 0x16,
FORM_FLIGHT_EPIC = 0x1B,
FORM_SHADOW = 0x1C,
FORM_FLIGHT = 0x1D,
@@ -186,14 +220,14 @@ enum SheathState
// byte (1 from 0..3) of UNIT_FIELD_BYTES_2
enum UnitBytes2_Flags
{
- UNIT_BYTE2_FLAG_UNK0 = 0x01,
- UNIT_BYTE2_FLAG_UNK1 = 0x02,
- UNIT_BYTE2_FLAG_UNK2 = 0x04,
+ UNIT_BYTE2_FLAG_PVP = 0x01,
+ UNIT_BYTE2_FLAG_UNK1 = 0x02,
+ UNIT_BYTE2_FLAG_FFA_PVP = 0x04,
UNIT_BYTE2_FLAG_SANCTUARY = 0x08,
- UNIT_BYTE2_FLAG_AURAS = 0x10, // show possitive auras as positive, and allow its dispel
- UNIT_BYTE2_FLAG_UNK5 = 0x20,
- UNIT_BYTE2_FLAG_UNK6 = 0x40,
- UNIT_BYTE2_FLAG_UNK7 = 0x80
+ UNIT_BYTE2_FLAG_UNK4 = 0x10,
+ UNIT_BYTE2_FLAG_UNK5 = 0x20,
+ UNIT_BYTE2_FLAG_UNK6 = 0x40,
+ UNIT_BYTE2_FLAG_UNK7 = 0x80
};
// byte (2 from 0..3) of UNIT_FIELD_BYTES_2
@@ -203,7 +237,11 @@ enum UnitRename
UNIT_RENAME_ALLOWED = 0x03
};
-#define CREATURE_MAX_SPELLS 4
+#define CREATURE_MAX_SPELLS 8
+#define MAX_SPELL_CHARM 4
+#define MAX_SPELL_VEHICLE 6
+#define MAX_SPELL_POSSESS 8
+#define MAX_SPELL_CONTROL_BAR 10
enum Swing
{
@@ -231,16 +269,27 @@ enum HitInfo
HITINFO_UNK1 = 0x00000001, // req correct packet structure
HITINFO_NORMALSWING2 = 0x00000002,
HITINFO_LEFTSWING = 0x00000004,
+ HITINFO_UNK2 = 0x00000008,
HITINFO_MISS = 0x00000010,
- HITINFO_ABSORB = 0x00000020, // plays absorb sound
- HITINFO_RESIST = 0x00000040, // resisted at least some damage
- HITINFO_CRITICALHIT = 0x00000080,
- HITINFO_UNK2 = 0x00000100, // wotlk?
- HITINFO_UNK3 = 0x00002000, // wotlk?
- HITINFO_GLANCING = 0x00004000,
- HITINFO_CRUSHING = 0x00008000,
- HITINFO_NOACTION = 0x00010000,
- HITINFO_SWINGNOHITSOUND = 0x00080000
+ HITINFO_ABSORB = 0x00000020, // absorbed damage
+ HITINFO_ABSORB2 = 0x00000040, // absorbed damage
+ HITINFO_RESIST = 0x00000080, // resisted atleast some damage
+ HITINFO_RESIST2 = 0x00000100, // resisted atleast some damage
+ HITINFO_CRITICALHIT = 0x00000200, // critical hit
+ // 0x00000400
+ // 0x00000800
+ // 0x00001000
+ HITINFO_BLOCK = 0x00002000, // blocked damage
+ // 0x00004000
+ // 0x00008000
+ HITINFO_GLANCING = 0x00010000,
+ HITINFO_CRUSHING = 0x00020000,
+ HITINFO_NOACTION = 0x00040000, // guessed
+ // 0x00080000
+ // 0x00100000
+ HITINFO_SWINGNOHITSOUND = 0x00200000, // guessed
+ // 0x00400000
+ HITINFO_UNK3 = 0x00800000
};
//i would like to remove this: (it is defined in item.h
@@ -251,11 +300,11 @@ enum InventorySlot
};
struct FactionTemplateEntry;
-struct Modifier;
struct SpellEntry;
struct SpellValue;
class Aura;
+class AuraEffect;
class Creature;
class Spell;
class DynamicObject;
@@ -264,6 +313,9 @@ class Item;
class Pet;
class Path;
class PetAura;
+class Guardian;
+class UnitAI;
+class Transport;
struct SpellImmune
{
@@ -297,10 +349,11 @@ enum DamageTypeToSchool
enum AuraRemoveMode
{
- AURA_REMOVE_BY_DEFAULT,
- AURA_REMOVE_BY_STACK, // at replace by semillar aura
+ AURA_REMOVE_BY_DEFAULT=0,
+ AURA_REMOVE_BY_STACK, // change stack, single aura remove,
AURA_REMOVE_BY_CANCEL,
- AURA_REMOVE_BY_DISPEL,
+ AURA_REMOVE_BY_ENEMY_SPELL, // dispel and absorb aura destroy
+ AURA_REMOVE_BY_EXPIRE, // dispel and absorb aura destroy
AURA_REMOVE_BY_DEATH
};
@@ -312,11 +365,13 @@ enum UnitMods
UNIT_MOD_STAT_INTELLECT,
UNIT_MOD_STAT_SPIRIT,
UNIT_MOD_HEALTH,
- UNIT_MOD_MANA, // UNIT_MOD_MANA..UNIT_MOD_HAPPINESS must be in existed order, it's accessed by index values of Powers enum.
+ UNIT_MOD_MANA, // UNIT_MOD_MANA..UNIT_MOD_RUNIC_POWER must be in existed order, it's accessed by index values of Powers enum.
UNIT_MOD_RAGE,
UNIT_MOD_FOCUS,
UNIT_MOD_ENERGY,
UNIT_MOD_HAPPINESS,
+ UNIT_MOD_RUNE,
+ UNIT_MOD_RUNIC_POWER,
UNIT_MOD_ARMOR, // UNIT_MOD_ARMOR..UNIT_MOD_RESISTANCE_ARCANE must be in existed order, it's accessed by index values of SpellSchools enum.
UNIT_MOD_RESISTANCE_HOLY,
UNIT_MOD_RESISTANCE_FIRE,
@@ -336,7 +391,7 @@ enum UnitMods
UNIT_MOD_RESISTANCE_START = UNIT_MOD_ARMOR,
UNIT_MOD_RESISTANCE_END = UNIT_MOD_RESISTANCE_ARCANE + 1,
UNIT_MOD_POWER_START = UNIT_MOD_MANA,
- UNIT_MOD_POWER_END = UNIT_MOD_HAPPINESS + 1
+ UNIT_MOD_POWER_END = UNIT_MOD_RUNIC_POWER + 1
};
enum BaseModGroup
@@ -386,8 +441,12 @@ enum UnitState
UNIT_STAT_CASTING = 0x00008000,
UNIT_STAT_POSSESSED = 0x00010000,
UNIT_STAT_CHARGING = 0x00020000,
+ UNIT_STAT_JUMPING = 0x00040000,
+ UNIT_STAT_ONVEHICLE = 0x00080000,
+ UNIT_STAT_UNATTACKABLE = (UNIT_STAT_IN_FLIGHT | UNIT_STAT_ONVEHICLE),
UNIT_STAT_MOVING = (UNIT_STAT_ROAMING | UNIT_STAT_CHASE),
- UNIT_STAT_LOST_CONTROL = (UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_CHARGING),
+ UNIT_STAT_CONTROLLED = (UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING),
+ UNIT_STAT_LOST_CONTROL = (UNIT_STAT_CONTROLLED | UNIT_STAT_JUMPING | UNIT_STAT_CHARGING),
UNIT_STAT_SIGHTLESS = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CHASE),
UNIT_STAT_CANNOT_AUTOATTACK = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CASTING),
UNIT_STAT_ALL_STATE = 0xffffffff //(UNIT_STAT_STOPPED | UNIT_STAT_MOVING | UNIT_STAT_IN_COMBAT | UNIT_STAT_IN_FLIGHT)
@@ -403,23 +462,21 @@ enum UnitMoveType
MOVE_TURN_RATE = 5,
MOVE_FLIGHT = 6,
MOVE_FLIGHT_BACK = 7,
+ MOVE_PITCH_RATE = 8
};
-#define MAX_MOVE_TYPE 8
+#define MAX_MOVE_TYPE 9
extern float baseMoveSpeed[MAX_MOVE_TYPE];
-// assume it is 25 yard per 0.6 second
-#define SPEED_CHARGE 42.0f
enum WeaponAttackType
{
BASE_ATTACK = 0,
OFF_ATTACK = 1,
- RANGED_ATTACK = 2
+ RANGED_ATTACK = 2,
+ MAX_ATTACK
};
-#define MAX_ATTACK 3
-
enum CombatRating
{
CR_WEAPON_SKILL = 0,
@@ -445,10 +502,11 @@ enum CombatRating
CR_WEAPON_SKILL_MAINHAND = 20,
CR_WEAPON_SKILL_OFFHAND = 21,
CR_WEAPON_SKILL_RANGED = 22,
- CR_EXPERTISE = 23
+ CR_EXPERTISE = 23,
+ CR_ARMOR_PENETRATION = 24
};
-#define MAX_COMBAT_RATING 24
+#define MAX_COMBAT_RATING 25
enum DamageEffectType
{
@@ -473,45 +531,50 @@ enum UnitVisibility
// Value masks for UNIT_FIELD_FLAGS
enum UnitFlags
{
- UNIT_FLAG_UNKNOWN7 = 0x00000001,
+ UNIT_FLAG_UNK_0 = 0x00000001,
UNIT_FLAG_NON_ATTACKABLE = 0x00000002, // not attackable
UNIT_FLAG_DISABLE_MOVE = 0x00000004,
UNIT_FLAG_PVP_ATTACKABLE = 0x00000008, // allow apply pvp rules to attackable state in addition to faction dependent state
UNIT_FLAG_RENAME = 0x00000010,
UNIT_FLAG_PREPARATION = 0x00000020, // don't take reagents for spells with SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP
- UNIT_FLAG_UNKNOWN9 = 0x00000040,
+ UNIT_FLAG_UNK_6 = 0x00000040,
UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080, // ?? (UNIT_FLAG_PVP_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE
UNIT_FLAG_NOT_ATTACKABLE_2 = 0x00000100, // 2.0.8
- UNIT_FLAG_UNKNOWN11 = 0x00000200,
+ UNIT_FLAG_UNK_9 = 0x00000200, // 3.0.3 - makes you unable to attack everything
UNIT_FLAG_LOOTING = 0x00000400, // loot animation
UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // in combat?, 2.0.8
- UNIT_FLAG_PVP = 0x00001000,
+ UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3
UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1
- UNIT_FLAG_UNKNOWN4 = 0x00004000, // 2.0.8
- UNIT_FLAG_UNKNOWN13 = 0x00008000,
- UNIT_FLAG_UNKNOWN14 = 0x00010000,
- UNIT_FLAG_PACIFIED = 0x00020000,
- UNIT_FLAG_DISABLE_ROTATE = 0x00040000, // stunned, 2.1.1
+ UNIT_FLAG_UNK_14 = 0x00004000, // 2.0.8
+ UNIT_FLAG_UNK_15 = 0x00008000,
+ UNIT_FLAG_UNK_16 = 0x00010000,
+ UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok
+ UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok
UNIT_FLAG_IN_COMBAT = 0x00080000,
UNIT_FLAG_TAXI_FLIGHT = 0x00100000, // disable casting at client side spell not allowed by taxi flight (mounted?), probably used with 0x4 flag
- UNIT_FLAG_DISARMED = 0x00200000, // disable melee spells casting..., "Required melee weapon" added to melee spells tooltip.
+ UNIT_FLAG_DISARMED = 0x00200000, // 3.0.3, disable melee spells casting..., "Required melee weapon" added to melee spells tooltip.
UNIT_FLAG_CONFUSED = 0x00400000,
UNIT_FLAG_FLEEING = 0x00800000,
- UNIT_FLAG_UNKNOWN5 = 0x01000000, // used in spell Eyes of the Beast for pet...
+ UNIT_FLAG_UNK_24 = 0x01000000, // used in spell Eyes of the Beast for pet...
UNIT_FLAG_NOT_SELECTABLE = 0x02000000,
UNIT_FLAG_SKINNABLE = 0x04000000,
UNIT_FLAG_MOUNT = 0x08000000,
- UNIT_FLAG_UNKNOWN17 = 0x10000000,
- UNIT_FLAG_UNKNOWN6 = 0x20000000, // used in Feing Death spell
- UNIT_FLAG_SHEATHE = 0x40000000
+ UNIT_FLAG_UNK_28 = 0x10000000,
+ UNIT_FLAG_UNK_29 = 0x20000000, // used in Feing Death spell
+ UNIT_FLAG_SHEATHE = 0x40000000,
+ UNIT_FLAG_UNK_31 = 0x80000000
};
// Value masks for UNIT_FIELD_FLAGS_2
enum UnitFlags2
{
- UNIT_FLAG2_FEIGN_DEATH = 0x00000001,
- UNIT_FLAG2_COMPREHEND_LANG= 0x00000008,
- UNIT_FLAG2_FORCE_MOVE = 0x00000040
+ UNIT_FLAG2_FEIGN_DEATH = 0x00000001,
+ UNIT_FLAG2_UNK1 = 0x00000002, // Hide unit model (show only player equip)
+ UNIT_FLAG2_COMPREHEND_LANG = 0x00000008,
+ UNIT_FLAG2_FORCE_MOVE = 0x00000040,
+ UNIT_FLAG2_DISARM_OFFHAND = 0x00000080,
+ UNIT_FLAG2_DISARM_RANGED = 0x00000400, //this does not disable ranged weapon display (maybe additional flag needed?)
+ UNIT_FLAG2_REGENERATE_POWER = 0x00000800
};
/// Non Player Character flags
@@ -589,6 +652,37 @@ enum MovementFlags
MOVEMENTFLAG_UNK3 = 0x40000000
};
+struct MovementInfo
+{
+ // common
+ uint32 flags;
+ uint16 unk1;
+ uint32 time;
+ float x, y, z, o;
+ // transport
+ uint64 t_guid;
+ float t_x, t_y, t_z, t_o;
+ uint32 t_time;
+ int8 t_seat;
+ // swimming and unknown
+ float s_pitch;
+ // last fall time
+ uint32 fallTime;
+ // jumping
+ float j_zspeed, j_sinAngle, j_cosAngle, j_xyspeed;
+ // spline
+ float u_unk1;
+
+ MovementInfo()
+ {
+ flags = 0;
+ time = t_time = fallTime = 0;
+ unk1 = 0;
+ x = y = z = o = t_x = t_y = t_z = t_o = s_pitch = j_zspeed = j_sinAngle = j_cosAngle = j_xyspeed = u_unk1 = 0.0f;
+ t_guid = 0;
+ }
+};
+
enum DiminishingLevels
{
DIMINISHING_LEVEL_1 = 0,
@@ -599,7 +693,9 @@ enum DiminishingLevels
struct DiminishingReturn
{
- DiminishingReturn(DiminishingGroup group, uint32 t, uint32 count) : DRGroup(group), hitTime(t), hitCount(count), stack(0) {}
+ DiminishingReturn(DiminishingGroup group, uint32 t, uint32 count)
+ : DRGroup(group), stack(0), hitTime(t), hitCount(count)
+ {}
DiminishingGroup DRGroup:16;
uint16 stack:16;
@@ -610,8 +706,9 @@ struct DiminishingReturn
enum MeleeHitOutcome
{
MELEE_HIT_EVADE, MELEE_HIT_MISS, MELEE_HIT_DODGE, MELEE_HIT_BLOCK, MELEE_HIT_PARRY,
- MELEE_HIT_GLANCING, MELEE_HIT_CRIT, MELEE_HIT_CRUSHING, MELEE_HIT_NORMAL, MELEE_HIT_BLOCK_CRIT
+ MELEE_HIT_GLANCING, MELEE_HIT_CRIT, MELEE_HIT_CRUSHING, MELEE_HIT_NORMAL
};
+
struct CleanDamage
{
CleanDamage(uint32 _damage, WeaponAttackType _attackType, MeleeHitOutcome _hitOutCome) :
@@ -646,9 +743,11 @@ struct CalcDamageInfo
// Spell damage info structure based on structure sending in SMSG_SPELLNONMELEEDAMAGELOG opcode
struct SpellNonMeleeDamage{
- SpellNonMeleeDamage(Unit *_attacker, Unit *_target, uint32 _SpellID, uint32 _schoolMask) :
- attacker(_attacker), target(_target), SpellID(_SpellID), damage(0), schoolMask(_schoolMask),
- absorb(0), resist(0), phusicalLog(false), unused(false), blocked(0), HitInfo(0), cleanDamage(0) {}
+ SpellNonMeleeDamage(Unit *_attacker, Unit *_target, uint32 _SpellID, uint32 _schoolMask)
+ : target(_target), attacker(_attacker), SpellID(_SpellID), damage(0), schoolMask(_schoolMask),
+ absorb(0), resist(0), phusicalLog(false), unused(false), blocked(0), HitInfo(0), cleanDamage(0)
+ {}
+
Unit *target;
Unit *attacker;
uint32 SpellID;
@@ -668,8 +767,20 @@ uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missC
struct UnitActionBarEntry
{
- uint32 Type;
- uint32 SpellOrAction;
+ UnitActionBarEntry() : Raw(0) {}
+
+ union
+ {
+ struct
+ {
+ uint16 SpellOrAction;
+ uint16 Type;
+ };
+ struct
+ {
+ uint32 Raw;
+ };
+ };
};
#define MAX_DECLINED_NAME_CASES 5
@@ -691,13 +802,12 @@ enum CurrentSpellTypes
enum ActiveStates
{
- ACT_ENABLED = 0xC100,
- ACT_DISABLED = 0x8100,
- ACT_COMMAND = 0x0700,
- ACT_REACTION = 0x0600,
- ACT_CAST = 0x0100,
- ACT_PASSIVE = 0x0000,
- ACT_DECIDE = 0x0001
+ ACT_PASSIVE = 0x0100, // 0x0100 - passive
+ ACT_DISABLED = 0x8100, // 0x8000 - castable
+ ACT_ENABLED = 0xC100, // 0x4000 | 0x8000 - auto cast + castable
+ ACT_COMMAND = 0x0700, // 0x0100 | 0x0200 | 0x0400
+ ACT_REACTION = 0x0600, // 0x0200 | 0x0400
+ ACT_DECIDE = 0x0001 // what is it?
};
enum ReactStates
@@ -766,15 +876,18 @@ struct TRINITY_DLL_SPEC CharmInfo
enum ReactiveType
{
- REACTIVE_DEFENSE = 1,
- REACTIVE_HUNTER_PARRY = 2,
- REACTIVE_CRIT = 3,
- REACTIVE_HUNTER_CRIT = 4,
- REACTIVE_OVERPOWER = 5
+ REACTIVE_DEFENSE = 0,
+ REACTIVE_HUNTER_PARRY = 1,
+ REACTIVE_OVERPOWER = 2
};
-#define MAX_REACTIVE 6
-#define MAX_TOTEM 4
+#define MAX_REACTIVE 3
+#define SUMMON_SLOT_PET 0
+#define SUMMON_SLOT_TOTEM 1
+#define MAX_TOTEM_SLOT 5
+#define SUMMON_SLOT_MINIPET 5
+#define SUMMON_SLOT_QUEST 6
+#define MAX_SUMMON_SLOT 7
// delay time next attack to prevent client attack animation problems
#define ATTACK_DISPLAY_DELAY 200
@@ -785,13 +898,16 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
{
public:
typedef std::set<Unit*> AttackerSet;
+ typedef std::set<Unit*> ControlList;
typedef std::pair<uint32, uint8> spellEffectPair;
- typedef std::multimap< spellEffectPair, Aura*> AuraMap;
+ typedef std::multimap<uint32, Aura*> AuraMap;
+ typedef std::list<AuraEffect *> AuraEffectList;
typedef std::list<Aura *> AuraList;
typedef std::list<DiminishingReturn> Diminishing;
- typedef std::set<AuraType> AuraTypeSet;
typedef std::set<uint32> ComboPointHolderSet;
+ typedef std::map<uint8, Aura*> VisibleAuraMap;
+
virtual ~Unit ( );
void AddToWorld();
@@ -805,6 +921,11 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void ApplyDiminishingAura(DiminishingGroup group, bool apply);
void ClearDiminishings() { m_Diminishing.clear(); }
+ //target dependent range checks
+ uint32 GetSpellMaxRangeForTarget(Unit* target,const SpellRangeEntry * rangeEntry);
+ uint32 GetSpellMinRangeForTarget(Unit* target,const SpellRangeEntry * rangeEntry);
+ uint32 GetSpellRadiusForTarget(Unit* target,const SpellRadiusEntry * radiusEntry);
+
virtual void Update( uint32 time );
void setAttackTimer(WeaponAttackType type, uint32 time) { m_attackTimer[type] = time; }
@@ -824,15 +945,11 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void _addAttacker(Unit *pAttacker) // must be called only from Unit::Attack(Unit*)
{
- AttackerSet::iterator itr = m_attackers.find(pAttacker);
- if(itr == m_attackers.end())
- m_attackers.insert(pAttacker);
+ m_attackers.insert(pAttacker);
}
void _removeAttacker(Unit *pAttacker) // must be called only from Unit::AttackStop()
{
- AttackerSet::iterator itr = m_attackers.find(pAttacker);
- if(itr != m_attackers.end())
- m_attackers.erase(itr);
+ m_attackers.erase(pAttacker);
}
Unit * getAttackerForHelper() // If someone wants to help, who to give them
{
@@ -851,9 +968,10 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
AttackerSet const& getAttackers() const { return m_attackers; }
bool isAttackingPlayer() const;
Unit* getVictim() const { return m_attacking; }
- void CombatStop(bool cast = false);
- void CombatStopWithPets(bool cast = false);
+ void CombatStop(bool includingCast = false);
+ void CombatStopWithPets(bool includingCast = false);
Unit* SelectNearbyTarget(float dist = NOMINAL_MELEE_RANGE) const;
+ bool hasNegativeAuraWithInterruptFlag(uint32 flag);
void addUnitState(uint32 f) { m_state |= f; }
bool hasUnitState(const uint32 f) const { return (m_state & f); }
@@ -886,6 +1004,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void SetHealth( uint32 val);
void SetMaxHealth(uint32 val);
int32 ModifyHealth(int32 val);
+ int32 GetHealthGain(int32 dVal);
Powers getPowerType() const { return Powers(GetByteValue(UNIT_FIELD_BYTES_0, 3)); }
void setPowerType(Powers power);
@@ -921,8 +1040,14 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
return false;
}
- bool IsPvP() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); }
- void SetPvP(bool state) { if(state) SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); else RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); }
+ bool IsPvP() const { return HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); }
+ void SetPvP(bool state)
+ {
+ if(state)
+ SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP);
+ else
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP);
+ }
uint32 GetCreatureType() const;
uint32 GetCreatureTypeMask() const
{
@@ -935,6 +1060,9 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
bool IsStandState() const;
void SetStandState(uint8 state);
+ void SetStandFlags(uint8 flags) { SetByteFlag(UNIT_FIELD_BYTES_1, 2,flags); }
+ void RemoveStandFlags(uint8 flags) { RemoveByteFlag(UNIT_FIELD_BYTES_1, 2,flags); }
+
bool IsMounted() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT ); }
uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); }
void Mount(uint32 mount);
@@ -944,6 +1072,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void RemoveSpellbyDamageTaken(uint32 damage, uint32 spell);
uint32 DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage = NULL, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *spellProto = NULL, bool durabilityLoss = true);
void Kill(Unit *pVictim, bool durabilityLoss = true);
+ int32 DealHeal(Unit *pVictim, uint32 addhealth, SpellEntry const *spellProto, bool critical = false);
void ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType = BASE_ATTACK, SpellEntry const *procSpell = NULL);
void ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage );
@@ -957,6 +1086,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss);
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType = BASE_ATTACK);
+ int32 GetIgnoredArmorMultiplier(SpellEntry const *spellInfo, WeaponAttackType attackType);
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss);
float MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const;
@@ -968,16 +1098,26 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
float GetUnitParryChance() const;
float GetUnitBlockChance() const;
float GetUnitCriticalChance(WeaponAttackType attackType, const Unit *pVictim) const;
+ bool CanUseAttackType( uint8 attacktype ) const
+ {
+ switch(attacktype)
+ {
+ case BASE_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISARMED);
+ case OFF_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS_2,UNIT_FLAG2_DISARM_OFFHAND);
+ case RANGED_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS_2,UNIT_FLAG2_DISARM_RANGED);
+ }
+ return true;
+ }
virtual uint32 GetShieldBlockValue() const =0;
uint32 GetUnitMeleeSkill(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
uint32 GetDefenseSkillValue(Unit const* target = NULL) const;
uint32 GetWeaponSkillValue(WeaponAttackType attType, Unit const* target = NULL) const;
float GetWeaponProcChance() const;
- float GetPPMProcChance(uint32 WeaponSpeed, float PPM) const;
+ float GetPPMProcChance(uint32 WeaponSpeed, float PPM, const SpellEntry * spellProto) const;
MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType) const;
- MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance, bool SpellCasted ) const;
+ MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance) const;
bool isVendor() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_VENDOR ); }
bool isTrainer() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TRAINER ); }
@@ -1010,15 +1150,11 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
bool isInCombat() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); }
void CombatStart(Unit* target);
- void SetInCombatState(bool PvP);
+ void SetInCombatState(bool PvP, Unit* enemy = NULL);
void SetInCombatWith(Unit* enemy);
void ClearInCombat();
uint32 GetCombatTimer() const { return m_CombatTimer; }
- bool HasAuraType(AuraType auraType) const;
- bool HasAura(uint32 spellId, uint32 effIndex) const
- { return m_Auras.find(spellEffectPair(spellId, effIndex)) != m_Auras.end(); }
-
bool virtual HasSpell(uint32 /*spellID*/) const { return false; }
bool HasStealthAura() const { return HasAuraType(SPELL_AURA_MOD_STEALTH); }
@@ -1036,17 +1172,19 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
virtual bool IsUnderWater() const;
bool isInAccessiblePlaceFor(Creature const* c) const;
- void SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, bool critical = false);
+ void SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, bool critical, int32 gain);
void SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage,Powers powertype);
uint32 SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage, bool isTriggeredSpell = false, bool useSpellDamage = true);
- void CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castItem = NULL, Aura* triggeredByAura = NULL, uint64 originalCaster = 0);
- void CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, Item *castItem= NULL, Aura* triggeredByAura = NULL, uint64 originalCaster = 0);
- void CastCustomSpell(Unit* Victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem= NULL, Aura* triggeredByAura = NULL, uint64 originalCaster = 0);
- void CastCustomSpell(uint32 spellId, SpellValueMod mod, uint32 value, Unit* Victim = NULL, bool triggered = true, Item *castItem = NULL, Aura* triggeredByAura = NULL, uint64 originalCaster = 0);
- void CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* Victim = NULL, bool triggered = true, Item *castItem = NULL, Aura* triggeredByAura = NULL, uint64 originalCaster = 0);
- void CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item *castItem = NULL, Aura* triggeredByAura = NULL, uint64 originalCaster = 0);
- void CastSpell(GameObject *go, uint32 spellId, bool triggered, Item *castItem = NULL, Aura* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastSpell(Unit* Victim, SpellEntry const *spellInfo, bool triggered, Item *castItem= NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastCustomSpell(Unit* Victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem= NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastCustomSpell(uint32 spellId, SpellValueMod mod, uint32 value, Unit* Victim = NULL, bool triggered = true, Item *castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* Victim = NULL, bool triggered = true, Item *castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastSpell(GameObject *go, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0);
void AddAura(uint32 spellId, Unit *target);
+ void HandleAuraEffect(AuraEffect * aureff, bool apply);
+ Aura *AddAuraEffect(uint32 spellId, uint8 effIndex, Unit* caster);
bool IsDamageToThreatSpell(SpellEntry const * spellInfo) const;
@@ -1059,29 +1197,37 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchoolMask damageSchoolMask,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit = false);
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo);
+ void NearTeleportTo(float x, float y, float z, float orientation, bool casting = false);
+
+ void KnockbackFrom(float x, float y, float speedXY, float speedZ);
+ void JumpTo(float speedXY, float speedZ, bool forward = true);
+ void JumpTo(WorldObject *obj, float speedZ);
+
void SendMonsterStop();
void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 Time, Player* player = NULL);
+ void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 MoveFlags, uint32 time, float speedZ, Player *player = NULL);
//void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL);
void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end);
- void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 MovementFlags, uint32 transitTime = 0, Player* player = NULL);
+ void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL);
void SendMonsterMoveWithSpeedToCurrentDestination(Player* player = NULL);
- virtual void MoveOutOfRange(Player &) { };
-
bool isAlive() const { return (m_deathState == ALIVE); };
bool isDead() const { return ( m_deathState == DEAD || m_deathState == CORPSE ); };
DeathState getDeathState() { return m_deathState; };
virtual void setDeathState(DeathState s); // overwrited in Creature/Player/Pet
uint64 GetOwnerGUID() const { return GetUInt64Value(UNIT_FIELD_SUMMONEDBY); }
- void SetOwnerGUID(uint64 owner) { SetUInt64Value(UNIT_FIELD_SUMMONEDBY, owner); }
uint64 GetCreatorGUID() const { return GetUInt64Value(UNIT_FIELD_CREATEDBY); }
void SetCreatorGUID(uint64 creator) { SetUInt64Value(UNIT_FIELD_CREATEDBY, creator); }
- uint64 GetPetGUID() const { return GetUInt64Value(UNIT_FIELD_SUMMON); }
+ uint64 GetGuardianGUID() const { return GetUInt64Value(UNIT_FIELD_SUMMON); }
+ void SetGuardianGUID(uint64 guid) { SetUInt64Value(UNIT_FIELD_SUMMON, guid); }
uint64 GetCharmerGUID() const { return GetUInt64Value(UNIT_FIELD_CHARMEDBY); }
void SetCharmerGUID(uint64 owner) { SetUInt64Value(UNIT_FIELD_CHARMEDBY, owner); }
uint64 GetCharmGUID() const { return GetUInt64Value(UNIT_FIELD_CHARM); }
+ void SetPetGUID(uint64 guid) { m_SummonSlot[SUMMON_SLOT_PET] = guid; }
+ uint64 GetPetGUID() const { return m_SummonSlot[SUMMON_SLOT_PET]; }
+ bool IsControlledByPlayer() const { return m_ControlledByPlayer; }
uint64 GetCharmerOrOwnerGUID() const { return GetCharmerGUID() ? GetCharmerGUID() : GetOwnerGUID(); }
uint64 GetCharmerOrOwnerOrOwnGUID() const
{
@@ -1094,7 +1240,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
Player* GetSpellModOwner() const;
Unit* GetOwner() const;
- Pet* GetPet() const;
+ Guardian *GetGuardianPet() const;
Unit* GetCharmer() const;
Unit* GetCharm() const;
Unit* GetCharmerOrOwner() const { return GetCharmerGUID() ? GetCharmer() : GetOwner(); }
@@ -1107,12 +1253,17 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
}
Player* GetCharmerOrOwnerPlayerOrPlayerItself() const;
- void SetPet(Pet* pet);
- void SetCharm(Unit* pet);
+ void SetGuardian(Guardian* target, bool apply);
+ void SetCharm(Unit* target, bool apply);
+ Unit* GetNextRandomRaidMemberOrPet(float radius);
void SetCharmedOrPossessedBy(Unit* charmer, bool possess);
void RemoveCharmedOrPossessedBy(Unit* charmer);
void RestoreFaction();
+ ControlList m_Controlled;
+ Unit* GetFirstControlled() const;
+ void RemoveAllControlled();
+
bool isCharmed() const { return GetCharmerGUID() != 0; }
bool isPossessed() const { return hasUnitState(UNIT_STAT_POSSESSED); }
bool isPossessedByPlayer() const { return hasUnitState(UNIT_STAT_POSSESSED) && IS_PLAYER_GUID(GetCharmerGUID()); }
@@ -1141,31 +1292,23 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
bool AddAura(Aura *aur);
void RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
- void RemoveAura(uint32 spellId, uint32 effindex, Aura* except = NULL);
- void RemoveSingleAuraFromStackByDispel(uint32 spellId);
- void RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex);
- void RemoveAurasDueToSpell(uint32 spellId, Aura* except = NULL);
- void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId);
- void RemoveAurasByCasterSpell(uint32 spellId, uint64 casterGUID);
- void SetAurasDurationByCasterSpell(uint32 spellId, uint64 casterGUID, int32 duration);
- Aura* GetAuraByCasterSpell(uint32 spellId, uint64 casterGUID);
+ void RemoveAura(uint32 spellId, uint64 caster = 0 ,AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
+ void RemoveAura(Aura * aur, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
+ void RemoveAurasDueToSpell(uint32 spellId, uint64 caster = NULL ,AuraRemoveMode removeMode= AURA_REMOVE_BY_DEFAULT);
+ void RemoveAuraFromStack(uint32 spellId, uint64 caster = NULL ,AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
+ inline void RemoveAuraFromStack(AuraMap::iterator &iter,AuraRemoveMode removeMode);
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler);
void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer);
- void RemoveAurasDueToSpellByCancel(uint32 spellId);
- void RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo, Unit * caster);
+ void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId);
+ void RemoveAurasByType(AuraType auraType, uint64 casterGUID = 0, Aura * except=NULL);
+ void RemoveAurasByTypeWithDispel(AuraType auraType, Spell * spell = NULL);
void RemoveNotOwnSingleTargetAuras();
-
- void RemoveSpellsCausingAura(AuraType auraType);
- void RemoveAuraTypeByCaster(AuraType auraType, uint64 casterGUID);
- void RemoveRankAurasDueToSpell(uint32 spellId);
bool RemoveNoStackAurasDueToAura(Aura *Aur);
- void RemoveAurasWithInterruptFlags(uint32 flags, uint32 except = 0);
- void RemoveAurasWithDispelType( DispelType type );
-
+ void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except = NULL);
void RemoveAllAuras();
void RemoveArenaAuras(bool onleave = false);
void RemoveAllAurasOnDeath();
- void DelayAura(uint32 spellId, uint32 effindex, int32 delaytime);
+ void DelayAura(uint32 spellId, uint64 caster, int32 delaytime);
float GetResistanceBuffMods(SpellSchools school, bool positive) const { return GetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school ); }
void SetResistanceBuffMods(SpellSchools school, bool positive, float val) { SetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school,val); }
@@ -1210,12 +1353,15 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
Spell* m_currentSpells[CURRENT_MAX_SPELL];
uint32 m_addDmgOnce;
- uint64 m_TotemSlot[MAX_TOTEM];
+ uint64 m_SummonSlot[MAX_SUMMON_SLOT];
uint64 m_ObjectSlot[4];
uint32 m_detectInvisibilityMask;
uint32 m_invisibilityMask;
+
uint32 m_ShapeShiftFormSpellId;
ShapeshiftForm m_form;
+ bool IsInFeralForm() const { return m_form == FORM_CAT || m_form == FORM_BEAR || m_form == FORM_DIREBEAR; }
+
float m_modMeleeHitChance;
float m_modRangedHitChance;
float m_modSpellHitChance;
@@ -1261,17 +1407,17 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void DestroyForNearbyPlayers();
// common function for visibility checks for player/creatures with detection code
- virtual bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const;
+ virtual bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const = 0;
bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const;
bool canDetectInvisibilityOf(Unit const* u) const;
bool canDetectStealthOf(Unit const* u, float distance) const;
+ void SetPhaseMask(uint32 newPhaseMask, bool update);// overwrite WorldObject::SetPhaseMask
// virtual functions for all world objects types
bool isVisibleForInState(Player const* u, bool inVisibleList) const;
// function for low level grid visibility checks in player/creature cases
virtual bool IsVisibleInGridForPlayer(Player const* pl) const = 0;
- bool waterbreath;
AuraList & GetSingleCastAuras() { return m_scAuras; }
AuraList const& GetSingleCastAuras() const { return m_scAuras; }
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY];
@@ -1288,15 +1434,33 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void removeHatedBy(HostilReference* /*pHostilReference*/ ) { /* nothing to do yet */ }
HostilRefManager& getHostilRefManager() { return m_HostilRefManager; }
- Aura* GetAura(uint32 spellId, uint32 effindex);
+ VisibleAuraMap const *GetVisibleAuras() { return &m_visibleAuras; }
+ Aura * GetVisibleAura(uint8 slot)
+ {
+ VisibleAuraMap::iterator itr = m_visibleAuras.find(slot);
+ if(itr != m_visibleAuras.end())
+ return itr->second;
+ return 0;
+ }
+ void SetVisibleAura(uint8 slot, Aura * aur){ m_visibleAuras[slot]=aur; }
+ void RemoveVisibleAura(uint8 slot){ m_visibleAuras.erase(slot); }
+
AuraMap & GetAuras() { return m_Auras; }
AuraMap const& GetAuras() const { return m_Auras; }
- AuraList const& GetAurasByType(AuraType type) const { return m_modAuras[type]; }
- void ApplyAuraProcTriggerDamage(Aura* aura, bool apply);
+ AuraEffectList const& GetAurasByType(AuraType type) const { return m_modAuras[type]; }
+
+ AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, uint64 casterGUID = 0) const;
+ Aura * GetAura(uint32 spellId, uint64 casterGUID = 0) const;
+ AuraEffect* GetAura(AuraType type, uint32 family, uint32 familyFlag1 , uint32 familyFlag2=0, uint32 familyFlag3=0, uint64 casterGUID=0);
+ bool HasAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster = 0) const;
+ bool HasAura(uint32 spellId, uint64 caster = 0) const;
+ bool HasAura(Aura * aur) const;
+ bool HasAuraType(AuraType auraType) const;
+ bool HasAuraTypeWithMiscvalue(AuraType auratype, uint32 miscvalue) const;
int32 GetTotalAuraModifier(AuraType auratype) const;
float GetTotalAuraMultiplier(AuraType auratype) const;
- int32 GetMaxPositiveAuraModifier(AuraType auratype) const;
+ int32 GetMaxPositiveAuraModifier(AuraType auratype);
int32 GetMaxNegativeAuraModifier(AuraType auratype) const;
int32 GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const;
@@ -1309,7 +1473,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
int32 GetMaxPositiveAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const;
int32 GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const;
- Aura* GetDummyAura(uint32 spell_id) const;
+ AuraEffect* GetDummyAura(uint32 spell_id) const;
uint32 GetInterruptMask() const { return m_interruptMask; }
void AddInterruptMask(uint32 mask) { m_interruptMask |= mask; }
void UpdateInterruptMask();
@@ -1320,30 +1484,37 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void SetNativeDisplayId(uint32 modelId) { SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, modelId); }
void setTransForm(uint32 spellid) { m_transform = spellid;}
uint32 getTransForm() const { return m_transform;}
+
+ DynamicObject* GetDynObject(uint32 spellId, uint32 effIndex);
+ DynamicObject* GetDynObject(uint32 spellId);
void AddDynObject(DynamicObject* dynObj);
void RemoveDynObject(uint32 spellid);
void RemoveDynObjectWithGUID(uint64 guid) { m_dynObjGUIDs.remove(guid); }
void RemoveAllDynObjects();
+
+ GameObject* GetGameObject(uint32 spellId) const;
void AddGameObject(GameObject* gameObj);
void RemoveGameObject(GameObject* gameObj, bool del);
void RemoveGameObject(uint32 spellid, bool del);
void RemoveAllGameObjects();
- DynamicObject *GetDynObject(uint32 spellId, uint32 effIndex);
- DynamicObject *GetDynObject(uint32 spellId);
+
uint32 CalculateDamage(WeaponAttackType attType, bool normalized);
float GetAPMultiplier(WeaponAttackType attType, bool normalized);
void ModifyAuraState(AuraState flag, bool apply);
- bool HasAuraState(AuraState flag) const { return HasFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1)); }
+ bool HasAuraState(AuraState flag, SpellEntry const *spellProto = NULL, Unit * Caster = NULL) const ;
void UnsummonAllTotems();
+ Unit* SelectMagnetTarget(Unit *victim, SpellEntry const *spellInfo = NULL);
int32 SpellBaseDamageBonus(SpellSchoolMask schoolMask);
int32 SpellBaseHealingBonus(SpellSchoolMask schoolMask);
int32 SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim);
int32 SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim);
- uint32 SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 damage, DamageEffectType damagetype);
- uint32 SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, Unit *pVictim);
+ uint32 SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 damage, DamageEffectType damagetype, uint32 stack = 1);
+ uint32 SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1);
bool isSpellBlocked(Unit *pVictim, SpellEntry const *spellProto, WeaponAttackType attackType = BASE_ATTACK);
+ bool isBlockCritical();
bool isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK);
- uint32 SpellCriticalBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim);
+ uint32 SpellCriticalDamageBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim);
+ uint32 SpellCriticalHealingBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim);
void SetLastManaUse(uint32 spellCastTime) { m_lastManaUse = spellCastTime; }
bool IsUnderLastManaUseEffect() const;
@@ -1355,19 +1526,21 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply);
void ApplySpellDispelImmunity(const SpellEntry * spellProto, DispelType type, bool apply);
- virtual bool IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges = false);
+ virtual bool IsImmunedToSpell(SpellEntry const* spellInfo);
// redefined in Creature
- bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask, bool useCharges = false);
- virtual bool IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const;
+ bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask);
+ bool IsImmunedToDamage(SpellEntry const* spellInfo);
+ virtual bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const;
// redefined in Creature
- uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage);
- void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist);
+ uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType=MAX_ATTACK);
+ void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, SpellEntry const *spellInfo = NULL);
void UpdateSpeed(UnitMoveType mtype, bool forced);
float GetSpeed( UnitMoveType mtype ) const;
float GetSpeedRate( UnitMoveType mtype ) const { return m_speed_rate[mtype]; }
void SetSpeed(UnitMoveType mtype, float rate, bool forced = false);
+ float m_TempSpeed;
void SetHover(bool on);
bool isHover() const { return HasAuraType(SPELL_AURA_HOVER); }
@@ -1376,7 +1549,9 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void _ApplyAllAuraMods();
int32 CalculateSpellDamage(SpellEntry const* spellProto, uint8 effect_index, int32 basePoints, Unit const* target);
- int32 CalculateSpellDuration(SpellEntry const* spellProto, uint8 effect_index, Unit const* target);
+ int32 CalcSpellDuration(SpellEntry const* spellProto);
+ int32 ModSpellDuration(SpellEntry const* spellProto, Unit const* target, int32 duration, bool positive);
+ void ModSpellCastTime(SpellEntry const* spellProto, int32 & castTime, Spell const * spell=NULL);
float CalculateLevelPenalty(SpellEntry const* spellProto) const;
void addFollower(FollowerReference* pRef) { m_FollowingRefManager.insertFirst(pRef); }
@@ -1401,17 +1576,13 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void SetUnitMovementFlags(uint32 f) { m_unit_movement_flags = f; }
void SetControlled(bool apply, UnitState state);
- void SetFeared(bool apply/*, uint64 casterGUID = 0, uint32 spellID = 0*/);
- void SetConfused(bool apply/*, uint64 casterGUID = 0, uint32 spellID = 0*/);
- void SetStunned(bool apply);
- void SetRooted(bool apply);
void AddComboPointHolder(uint32 lowguid) { m_ComboPointHolders.insert(lowguid); }
void RemoveComboPointHolder(uint32 lowguid) { m_ComboPointHolders.erase(lowguid); }
void ClearComboPointHolders();
///----------Pet responses methods-----------------
- void SendPetCastFail(uint32 spellid, uint8 msg);
+ void SendPetCastFail(uint32 spellid, SpellCastResult msg);
void SendPetActionFeedback (uint8 msg);
void SendPetTalk (uint32 pettalk);
void SendPetSpellCooldown (uint32 spellid, time_t cooltime);
@@ -1449,12 +1620,36 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
Unit *GetMisdirectionTarget() { return m_misdirectionTargetGUID ? GetUnit(*this, m_misdirectionTargetGUID) : NULL; }
bool IsAIEnabled, NeedChangeAI;
+ MovementInfo m_movementInfo;
+ Vehicle *m_Vehicle;
+ float GetTransOffsetX() const { return m_movementInfo.t_x; }
+ float GetTransOffsetY() const { return m_movementInfo.t_y; }
+ float GetTransOffsetZ() const { return m_movementInfo.t_z; }
+ float GetTransOffsetO() const { return m_movementInfo.t_o; }
+ uint32 GetTransTime() const { return m_movementInfo.t_time; }
+ int8 GetTransSeat() const { return m_movementInfo.t_seat; }
+
+ bool m_ControlledByPlayer;
+
+ void EnterVehicle(Vehicle *vehicle, int8 seatId = -1);
+ void ExitVehicle();
+ void ChangeSeat(int8 seatId, bool next = true);
+
+ // Transports
+ Transport * GetTransport() const { return m_transport; }
+ void SetTransport(Transport * t) { m_transport = t; }
+
+ void BuildMovementPacket(ByteBuffer *data) const;
protected:
explicit Unit ();
UnitAI *i_AI, *i_disabledAI;
+ // Transports
+ Transport * m_transport;
+
void _UpdateSpells(uint32 time);
+ void _DeleteAuras();
void _UpdateAutoRepeatSpell();
bool m_AutoRepeatFirstCast;
@@ -1469,25 +1664,28 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
DeathState m_deathState;
AuraMap m_Auras;
+ uint32 m_removedAurasCount;
typedef std::list<uint64> DynObjectGUIDs;
DynObjectGUIDs m_dynObjGUIDs;
- std::list<GameObject*> m_gameObj;
+ typedef std::list<GameObject*> GameObjectList;
+ GameObjectList m_gameObj;
bool m_isSorted;
uint32 m_transform;
- uint32 m_removedAuras;
- AuraList m_modAuras[TOTAL_AURAS];
+ AuraEffectList m_modAuras[TOTAL_AURAS];
AuraList m_scAuras; // casted singlecast auras
AuraList m_interruptableAuras;
AuraList m_ccAuras;
+ AuraList m_removedAuras;
uint32 m_interruptMask;
float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END];
float m_weaponDamage[MAX_ATTACK][2];
bool m_canModifyStats;
//std::list< spellEffectPair > AuraSpells[TOTAL_AURAS]; // TODO: use this if ok for mem
+ VisibleAuraMap m_visibleAuras;
float m_speed_rate[MAX_MOVE_TYPE];
@@ -1500,6 +1698,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
uint32 m_unit_movement_flags;
uint32 m_reactiveTimer[MAX_REACTIVE];
+ uint32 m_regenTimer;
ThreatManager m_ThreatManager;
@@ -1507,12 +1706,20 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void SendAttackStop(Unit* victim); // only from AttackStop(Unit*)
//void SendAttackStart(Unit* pVictim); // only from Unit::AttackStart(Unit*)
- bool IsTriggeredAtSpellProcEvent( Aura* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent );
- bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
- bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
- bool HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
- bool HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura* triggredByAura, SpellEntry const *procSpell, uint32 cooldown);
- bool HandleMeandingAuraProc(Aura* triggeredByAura);
+ bool IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry const * procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const *& spellProcEvent );
+ bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
+ bool HandleObsModEnergyAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
+ bool HandleModDamagePctTakenAuraProc(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
+ bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
+ bool HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
+ bool HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 cooldown);
+ bool HandleAuraRaidProcFromChargeWithValue(AuraEffect* triggeredByAura);
+ bool HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura);
+
+ void SetFeared(bool apply);
+ void SetConfused(bool apply);
+ void SetStunned(bool apply);
+ void SetRooted(bool apply);
uint32 m_state; // Even derived shouldn't modify
uint32 m_CombatTimer;
@@ -1532,8 +1739,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
uint32 m_reducedThreatPercent;
uint64 m_misdirectionTargetGUID;
-
- uint32 m_procDeep;
};
namespace Trinity
diff --git a/src/game/UnitEvents.h b/src/game/UnitEvents.h
index 4bc362893a3..67f8d01f0d6 100644
--- a/src/game/UnitEvents.h
+++ b/src/game/UnitEvents.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/UpdateData.cpp b/src/game/UpdateData.cpp
index 91ef84bb372..8eb8278d071 100644
--- a/src/game/UpdateData.cpp
+++ b/src/game/UpdateData.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -108,7 +108,7 @@ bool UpdateData::BuildPacket(WorldPacket *packet, bool hasTransport)
ByteBuffer buf(m_data.size() + 10 + m_outOfRangeGUIDs.size()*8);
buf << (uint32) (!m_outOfRangeGUIDs.empty() ? m_blockCount + 1 : m_blockCount);
- buf << (uint8) (hasTransport ? 1 : 0);
+ //buf << (uint8) (hasTransport ? 1 : 0);
if(!m_outOfRangeGUIDs.empty())
{
@@ -116,7 +116,7 @@ bool UpdateData::BuildPacket(WorldPacket *packet, bool hasTransport)
buf << (uint32) m_outOfRangeGUIDs.size();
for(std::set<uint64>::const_iterator i = m_outOfRangeGUIDs.begin();
- i != m_outOfRangeGUIDs.end(); i++)
+ i != m_outOfRangeGUIDs.end(); ++i)
{
//buf.appendPackGUID(*i);
buf << (uint8)0xFF;
diff --git a/src/game/UpdateData.h b/src/game/UpdateData.h
index 256c572bb1d..71a9258b90b 100644
--- a/src/game/UpdateData.h
+++ b/src/game/UpdateData.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -38,11 +38,12 @@ enum OBJECT_UPDATE_FLAGS
UPDATEFLAG_NONE = 0x00,
UPDATEFLAG_SELF = 0x01,
UPDATEFLAG_TRANSPORT = 0x02,
- UPDATEFLAG_FULLGUID = 0x04,
+ UPDATEFLAG_HAS_TARGET = 0x04,
UPDATEFLAG_LOWGUID = 0x08,
UPDATEFLAG_HIGHGUID = 0x10,
UPDATEFLAG_LIVING = 0x20,
- UPDATEFLAG_HASPOSITION = 0x40
+ UPDATEFLAG_HAS_POSITION = 0x40,
+ UPDATEFLAG_VEHICLE = 0x80
};
class UpdateData
diff --git a/src/game/UpdateFields.h b/src/game/UpdateFields.h
index c8e70fc2198..97fcbeb05d6 100644
--- a/src/game/UpdateFields.h
+++ b/src/game/UpdateFields.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,7 +21,7 @@
#ifndef _UPDATEFIELDS_AUTO_H
#define _UPDATEFIELDS_AUTO_H
-// Auto generated for version 2, 4, 3, 8606
+// Auto generated for version 3, 0, 3, 9183
enum EObjectFields
{
@@ -43,13 +43,37 @@ enum EItemFields
ITEM_FIELD_DURATION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2
ITEM_FIELD_SPELL_CHARGES = OBJECT_END + 0x000A, // Size: 5, Type: INT, Flags: OWNER_ONLY, UNK2
ITEM_FIELD_FLAGS = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT = OBJECT_END + 0x0010, // Size: 33, Type: INT, Flags: PUBLIC
- ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x0031, // Size: 1, Type: INT, Flags: PUBLIC
- ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x0032, // Size: 1, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ITEM_TEXT_ID = OBJECT_END + 0x0033, // Size: 1, Type: INT, Flags: OWNER_ONLY
- ITEM_FIELD_DURABILITY = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2
- ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2
- ITEM_END = OBJECT_END + 0x0036,
+ ITEM_FIELD_ENCHANTMENT_1_1 = OBJECT_END + 0x0010, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_1_3 = OBJECT_END + 0x0012, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_2_1 = OBJECT_END + 0x0013, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_2_3 = OBJECT_END + 0x0015, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_3_1 = OBJECT_END + 0x0016, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_3_3 = OBJECT_END + 0x0018, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_4_1 = OBJECT_END + 0x0019, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_4_3 = OBJECT_END + 0x001B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_5_1 = OBJECT_END + 0x001C, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_5_3 = OBJECT_END + 0x001E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_6_1 = OBJECT_END + 0x001F, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_6_3 = OBJECT_END + 0x0021, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_7_1 = OBJECT_END + 0x0022, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_7_3 = OBJECT_END + 0x0024, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_8_1 = OBJECT_END + 0x0025, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_8_3 = OBJECT_END + 0x0027, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_9_1 = OBJECT_END + 0x0028, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_9_3 = OBJECT_END + 0x002A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_10_1 = OBJECT_END + 0x002B, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_10_3 = OBJECT_END + 0x002D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_11_1 = OBJECT_END + 0x002E, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_11_3 = OBJECT_END + 0x0030, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_12_1 = OBJECT_END + 0x0031, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_12_3 = OBJECT_END + 0x0033, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ITEM_TEXT_ID = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: OWNER_ONLY
+ ITEM_FIELD_DURABILITY = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2
+ ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0038, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2
+ ITEM_FIELD_PAD = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: NONE
+ ITEM_END = OBJECT_END + 0x003A,
};
enum EContainerFields
@@ -64,93 +88,94 @@ enum EUnitFields
{
UNIT_FIELD_CHARM = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
UNIT_FIELD_SUMMON = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_CHARMEDBY = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_SUMMONEDBY = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_CREATEDBY = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_TARGET = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_PERSUADED = OBJECT_END + 0x000C, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_CRITTER = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PRIVATE
+ UNIT_FIELD_CHARMEDBY = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_SUMMONEDBY = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_CREATEDBY = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_TARGET = OBJECT_END + 0x000C, // Size: 2, Type: LONG, Flags: PUBLIC
UNIT_FIELD_CHANNEL_OBJECT = OBJECT_END + 0x000E, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_HEALTH = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: DYNAMIC
- UNIT_FIELD_POWER1 = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER2 = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER3 = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER4 = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER5 = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: DYNAMIC
- UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_LEVEL = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_BYTES_0 = OBJECT_END + 0x001E, // Size: 1, Type: BYTES, Flags: PUBLIC
- UNIT_VIRTUAL_ITEM_SLOT_DISPLAY = OBJECT_END + 0x001F, // Size: 3, Type: INT, Flags: PUBLIC
- UNIT_VIRTUAL_ITEM_INFO = OBJECT_END + 0x0022, // Size: 6, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_FLAGS = OBJECT_END + 0x0028, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x0029, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_AURA = OBJECT_END + 0x002A, // Size: 56, Type: INT, Flags: PUBLIC
- UNIT_FIELD_AURAFLAGS = OBJECT_END + 0x0062, // Size: 14, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_AURALEVELS = OBJECT_END + 0x0070, // Size: 14, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_AURAAPPLICATIONS = OBJECT_END + 0x007E, // Size: 14, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_AURASTATE = OBJECT_END + 0x008C, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x008D, // Size: 2, Type: INT, Flags: PUBLIC
- UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x008F, // Size: 1, Type: INT, Flags: PRIVATE
- UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x0090, // Size: 1, Type: FLOAT, Flags: PUBLIC
- UNIT_FIELD_COMBATREACH = OBJECT_END + 0x0091, // Size: 1, Type: FLOAT, Flags: PUBLIC
- UNIT_FIELD_DISPLAYID = OBJECT_END + 0x0092, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x0093, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x0094, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x0095, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
- UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0096, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
- UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x0097, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
- UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x0098, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
- UNIT_FIELD_BYTES_1 = OBJECT_END + 0x0099, // Size: 1, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_PETNUMBER = OBJECT_END + 0x009A, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x009B, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x009C, // Size: 1, Type: INT, Flags: OWNER_ONLY
- UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x009D, // Size: 1, Type: INT, Flags: OWNER_ONLY
- UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x009E, // Size: 1, Type: INT, Flags: DYNAMIC
- UNIT_CHANNEL_SPELL = OBJECT_END + 0x009F, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_MOD_CAST_SPEED = OBJECT_END + 0x00A0, // Size: 1, Type: FLOAT, Flags: PUBLIC
- UNIT_CREATED_BY_SPELL = OBJECT_END + 0x00A1, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_NPC_FLAGS = OBJECT_END + 0x00A2, // Size: 1, Type: INT, Flags: DYNAMIC
- UNIT_NPC_EMOTESTATE = OBJECT_END + 0x00A3, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_TRAINING_POINTS = OBJECT_END + 0x00A4, // Size: 1, Type: TWO_SHORT, Flags: OWNER_ONLY
- UNIT_FIELD_STAT0 = OBJECT_END + 0x00A5, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_STAT1 = OBJECT_END + 0x00A6, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_STAT2 = OBJECT_END + 0x00A7, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_STAT3 = OBJECT_END + 0x00A8, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_STAT4 = OBJECT_END + 0x00A9, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x00AA, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x00AB, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x00AC, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x00AD, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x00AE, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x00AF, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x00B0, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x00B1, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x00B2, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x00B3, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_RESISTANCES = OBJECT_END + 0x00B4, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY, UNK3
- UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x00BB, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x00C2, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_BASE_MANA = OBJECT_END + 0x00C9, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x00CA, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_BYTES_2 = OBJECT_END + 0x00CB, // Size: 1, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x00CC, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_ATTACK_POWER_MODS = OBJECT_END + 0x00CD, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x00CE, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x00CF, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_RANGED_ATTACK_POWER_MODS = OBJECT_END + 0x00D0, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x00D1, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x00D2, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x00D3, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x00D4, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x00DB, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x00E2, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_PADDING = OBJECT_END + 0x00E3, // Size: 1, Type: INT, Flags: NONE
- UNIT_END = OBJECT_END + 0x00E4,
+ UNIT_FIELD_BYTES_0 = OBJECT_END + 0x0010, // Size: 1, Type: BYTES, Flags: PUBLIC
+ UNIT_FIELD_HEALTH = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER1 = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER2 = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER3 = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER4 = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER5 = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER6 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER7 = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001E, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER6 = OBJECT_END + 0x001F, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER7 = OBJECT_END + 0x0020, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER = OBJECT_END + 0x0021, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER = OBJECT_END + 0x0028, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_LEVEL = OBJECT_END + 0x002F, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x0030, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_VIRTUAL_ITEM_SLOT_ID = OBJECT_END + 0x0031, // Size: 3, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_FLAGS = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_AURASTATE = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x0037, // Size: 2, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: PRIVATE
+ UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x003A, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ UNIT_FIELD_COMBATREACH = OBJECT_END + 0x003B, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ UNIT_FIELD_DISPLAYID = OBJECT_END + 0x003C, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x003D, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x003E, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x003F, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
+ UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0040, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
+ UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x0041, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
+ UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x0042, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
+ UNIT_FIELD_BYTES_1 = OBJECT_END + 0x0043, // Size: 1, Type: BYTES, Flags: PUBLIC
+ UNIT_FIELD_PETNUMBER = OBJECT_END + 0x0044, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x0045, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x0046, // Size: 1, Type: INT, Flags: OWNER_ONLY
+ UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x0047, // Size: 1, Type: INT, Flags: OWNER_ONLY
+ UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x0048, // Size: 1, Type: INT, Flags: DYNAMIC
+ UNIT_CHANNEL_SPELL = OBJECT_END + 0x0049, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_MOD_CAST_SPEED = OBJECT_END + 0x004A, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ UNIT_CREATED_BY_SPELL = OBJECT_END + 0x004B, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_NPC_FLAGS = OBJECT_END + 0x004C, // Size: 1, Type: INT, Flags: DYNAMIC
+ UNIT_NPC_EMOTESTATE = OBJECT_END + 0x004D, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_STAT0 = OBJECT_END + 0x004E, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_STAT1 = OBJECT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_STAT2 = OBJECT_END + 0x0050, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_STAT3 = OBJECT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_STAT4 = OBJECT_END + 0x0052, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x0053, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x0055, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x0056, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x0057, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x0058, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x005A, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x005C, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_RESISTANCES = OBJECT_END + 0x005D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY, UNK3
+ UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x0064, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x006B, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_BASE_MANA = OBJECT_END + 0x0072, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x0073, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_BYTES_2 = OBJECT_END + 0x0074, // Size: 1, Type: BYTES, Flags: PUBLIC
+ UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x0075, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_ATTACK_POWER_MODS = OBJECT_END + 0x0076, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x0077, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x0078, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_RANGED_ATTACK_POWER_MODS = OBJECT_END + 0x0079, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x007A, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x007B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x007C, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x007D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x0084, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x008B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_HOVERHEIGHT = OBJECT_END + 0x008C, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ UNIT_FIELD_PADDING = OBJECT_END + 0x008D, // Size: 1, Type: INT, Flags: NONE
+ UNIT_END = OBJECT_END + 0x008E,
PLAYER_DUEL_ARBITER = UNIT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
PLAYER_FLAGS = UNIT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
@@ -262,160 +287,184 @@ enum EUnitFields
PLAYER_QUEST_LOG_25_3 = UNIT_END + 0x006C, // Size: 1, Type: BYTES, Flags: PRIVATE
PLAYER_QUEST_LOG_25_4 = UNIT_END + 0x006D, // Size: 1, Type: INT, Flags: PRIVATE
PLAYER_VISIBLE_ITEM_1_CREATOR = UNIT_END + 0x006E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_1_0 = UNIT_END + 0x0070, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_1_PROPERTIES = UNIT_END + 0x007C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_1_PAD = UNIT_END + 0x007D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_2_CREATOR = UNIT_END + 0x007E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_2_0 = UNIT_END + 0x0080, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_2_PROPERTIES = UNIT_END + 0x008C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_2_PAD = UNIT_END + 0x008D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_3_CREATOR = UNIT_END + 0x008E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_3_0 = UNIT_END + 0x0090, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_3_PROPERTIES = UNIT_END + 0x009C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_3_PAD = UNIT_END + 0x009D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_4_CREATOR = UNIT_END + 0x009E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_4_0 = UNIT_END + 0x00A0, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_4_PROPERTIES = UNIT_END + 0x00AC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_4_PAD = UNIT_END + 0x00AD, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_5_CREATOR = UNIT_END + 0x00AE, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_5_0 = UNIT_END + 0x00B0, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_5_PROPERTIES = UNIT_END + 0x00BC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_5_PAD = UNIT_END + 0x00BD, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_6_CREATOR = UNIT_END + 0x00BE, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_6_0 = UNIT_END + 0x00C0, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_6_PROPERTIES = UNIT_END + 0x00CC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_6_PAD = UNIT_END + 0x00CD, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_7_CREATOR = UNIT_END + 0x00CE, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_7_0 = UNIT_END + 0x00D0, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_7_PROPERTIES = UNIT_END + 0x00DC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_7_PAD = UNIT_END + 0x00DD, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_8_CREATOR = UNIT_END + 0x00DE, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_8_0 = UNIT_END + 0x00E0, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_8_PROPERTIES = UNIT_END + 0x00EC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_8_PAD = UNIT_END + 0x00ED, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_9_CREATOR = UNIT_END + 0x00EE, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_9_0 = UNIT_END + 0x00F0, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_9_PROPERTIES = UNIT_END + 0x00FC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_9_PAD = UNIT_END + 0x00FD, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_10_CREATOR = UNIT_END + 0x00FE, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_10_0 = UNIT_END + 0x0100, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_10_PROPERTIES = UNIT_END + 0x010C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_10_PAD = UNIT_END + 0x010D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_11_CREATOR = UNIT_END + 0x010E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_11_0 = UNIT_END + 0x0110, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_11_PROPERTIES = UNIT_END + 0x011C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_11_PAD = UNIT_END + 0x011D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_12_CREATOR = UNIT_END + 0x011E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_12_0 = UNIT_END + 0x0120, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_12_PROPERTIES = UNIT_END + 0x012C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_12_PAD = UNIT_END + 0x012D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_13_CREATOR = UNIT_END + 0x012E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_13_0 = UNIT_END + 0x0130, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_13_PROPERTIES = UNIT_END + 0x013C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_13_PAD = UNIT_END + 0x013D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_14_CREATOR = UNIT_END + 0x013E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_14_0 = UNIT_END + 0x0140, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_14_PROPERTIES = UNIT_END + 0x014C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_14_PAD = UNIT_END + 0x014D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_15_CREATOR = UNIT_END + 0x014E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_15_0 = UNIT_END + 0x0150, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_15_PROPERTIES = UNIT_END + 0x015C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_15_PAD = UNIT_END + 0x015D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_16_CREATOR = UNIT_END + 0x015E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_16_0 = UNIT_END + 0x0160, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_16_PROPERTIES = UNIT_END + 0x016C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_16_PAD = UNIT_END + 0x016D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_17_CREATOR = UNIT_END + 0x016E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_17_0 = UNIT_END + 0x0170, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_17_PROPERTIES = UNIT_END + 0x017C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_17_PAD = UNIT_END + 0x017D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_18_CREATOR = UNIT_END + 0x017E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_18_0 = UNIT_END + 0x0180, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_18_PROPERTIES = UNIT_END + 0x018C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_18_PAD = UNIT_END + 0x018D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_19_CREATOR = UNIT_END + 0x018E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_19_0 = UNIT_END + 0x0190, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_19_PROPERTIES = UNIT_END + 0x019C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_19_PAD = UNIT_END + 0x019D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_CHOSEN_TITLE = UNIT_END + 0x019E, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_FIELD_PAD_0 = UNIT_END + 0x019F, // Size: 1, Type: INT, Flags: NONE
- PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x01A0, // Size: 46, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x01CE, // Size: 32, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x01EE, // Size: 56, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x0226, // Size: 14, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x0234, // Size: 24, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x024C, // Size: 64, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_VANITYPET_SLOT_1 = UNIT_END + 0x028C, // Size: 36, Type: LONG, Flags: PRIVATE
- PLAYER_FARSIGHT = UNIT_END + 0x02B0, // Size: 2, Type: LONG, Flags: PRIVATE
- PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x02B2, // Size: 2, Type: LONG, Flags: PRIVATE
- PLAYER_XP = UNIT_END + 0x02B4, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x02B5, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x02B6, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_CHARACTER_POINTS1 = UNIT_END + 0x0436, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_CHARACTER_POINTS2 = UNIT_END + 0x0437, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_TRACK_CREATURES = UNIT_END + 0x0438, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_TRACK_RESOURCES = UNIT_END + 0x0439, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x043A, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x043B, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x043C, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_EXPERTISE = UNIT_END + 0x043D, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x043E, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x043F, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x0440, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x0441, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x0442, // Size: 7, Type: FLOAT, Flags: PRIVATE
- PLAYER_SHIELD_BLOCK = UNIT_END + 0x0449, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x044A, // Size: 128, Type: BYTES, Flags: PRIVATE
- PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x04CA, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_COINAGE = UNIT_END + 0x04CB, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x04CC, // Size: 7, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x04D3, // Size: 7, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x04DA, // Size: 7, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x04E1, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x04E2, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x04E3, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_BYTES = UNIT_END + 0x04E4, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_AMMO_ID = UNIT_END + 0x04E5, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_SELF_RES_SPELL = UNIT_END + 0x04E6, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x04E7, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x04E8, // Size: 12, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x04F4, // Size: 12, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_KILLS = UNIT_END + 0x0500, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x0501, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x0502, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_LIFETIME_HONORBALE_KILLS = UNIT_END + 0x0503, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_BYTES2 = UNIT_END + 0x0504, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x0505, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x0506, // Size: 24, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x051E, // Size: 18, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x0530, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x0531, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_MANA_REGEN = UNIT_END + 0x0532, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT = UNIT_END + 0x0533, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x0534, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x0535, // Size: 25, Type: INT, Flags: PRIVATE
- PLAYER_END = UNIT_END + 0x054E,
+ PLAYER_VISIBLE_ITEM_1_0 = UNIT_END + 0x0070, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_1_PROPERTIES = UNIT_END + 0x007D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_1_SEED = UNIT_END + 0x007E, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_1_PAD = UNIT_END + 0x007F, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_2_CREATOR = UNIT_END + 0x0080, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_2_0 = UNIT_END + 0x0082, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_2_PROPERTIES = UNIT_END + 0x008F, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_2_SEED = UNIT_END + 0x0090, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_2_PAD = UNIT_END + 0x0091, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_3_CREATOR = UNIT_END + 0x0092, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_3_0 = UNIT_END + 0x0094, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_3_PROPERTIES = UNIT_END + 0x00A1, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_3_SEED = UNIT_END + 0x00A2, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_3_PAD = UNIT_END + 0x00A3, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_4_CREATOR = UNIT_END + 0x00A4, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_4_0 = UNIT_END + 0x00A6, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_4_PROPERTIES = UNIT_END + 0x00B3, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_4_SEED = UNIT_END + 0x00B4, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_4_PAD = UNIT_END + 0x00B5, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_5_CREATOR = UNIT_END + 0x00B6, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_5_0 = UNIT_END + 0x00B8, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_5_PROPERTIES = UNIT_END + 0x00C5, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_5_SEED = UNIT_END + 0x00C6, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_5_PAD = UNIT_END + 0x00C7, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_6_CREATOR = UNIT_END + 0x00C8, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_6_0 = UNIT_END + 0x00CA, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_6_PROPERTIES = UNIT_END + 0x00D7, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_6_SEED = UNIT_END + 0x00D8, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_6_PAD = UNIT_END + 0x00D9, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_7_CREATOR = UNIT_END + 0x00DA, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_7_0 = UNIT_END + 0x00DC, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_7_PROPERTIES = UNIT_END + 0x00E9, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_7_SEED = UNIT_END + 0x00EA, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_7_PAD = UNIT_END + 0x00EB, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_8_CREATOR = UNIT_END + 0x00EC, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_8_0 = UNIT_END + 0x00EE, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_8_PROPERTIES = UNIT_END + 0x00FB, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_8_SEED = UNIT_END + 0x00FC, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_8_PAD = UNIT_END + 0x00FD, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_9_CREATOR = UNIT_END + 0x00FE, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_9_0 = UNIT_END + 0x0100, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_9_PROPERTIES = UNIT_END + 0x010D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_9_SEED = UNIT_END + 0x010E, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_9_PAD = UNIT_END + 0x010F, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_10_CREATOR = UNIT_END + 0x0110, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_10_0 = UNIT_END + 0x0112, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_10_PROPERTIES = UNIT_END + 0x011F, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_10_SEED = UNIT_END + 0x0120, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_10_PAD = UNIT_END + 0x0121, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_11_CREATOR = UNIT_END + 0x0122, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_11_0 = UNIT_END + 0x0124, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_11_PROPERTIES = UNIT_END + 0x0131, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_11_SEED = UNIT_END + 0x0132, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_11_PAD = UNIT_END + 0x0133, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_12_CREATOR = UNIT_END + 0x0134, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_12_0 = UNIT_END + 0x0136, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_12_PROPERTIES = UNIT_END + 0x0143, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_12_SEED = UNIT_END + 0x0144, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_12_PAD = UNIT_END + 0x0145, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_13_CREATOR = UNIT_END + 0x0146, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_13_0 = UNIT_END + 0x0148, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_13_PROPERTIES = UNIT_END + 0x0155, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_13_SEED = UNIT_END + 0x0156, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_13_PAD = UNIT_END + 0x0157, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_14_CREATOR = UNIT_END + 0x0158, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_14_0 = UNIT_END + 0x015A, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_14_PROPERTIES = UNIT_END + 0x0167, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_14_SEED = UNIT_END + 0x0168, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_14_PAD = UNIT_END + 0x0169, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_15_CREATOR = UNIT_END + 0x016A, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_15_0 = UNIT_END + 0x016C, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_15_PROPERTIES = UNIT_END + 0x0179, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_15_SEED = UNIT_END + 0x017A, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_15_PAD = UNIT_END + 0x017B, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_16_CREATOR = UNIT_END + 0x017C, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_16_0 = UNIT_END + 0x017E, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_16_PROPERTIES = UNIT_END + 0x018B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_16_SEED = UNIT_END + 0x018C, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_16_PAD = UNIT_END + 0x018D, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_17_CREATOR = UNIT_END + 0x018E, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_17_0 = UNIT_END + 0x0190, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_17_PROPERTIES = UNIT_END + 0x019D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_17_SEED = UNIT_END + 0x019E, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_17_PAD = UNIT_END + 0x019F, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_18_CREATOR = UNIT_END + 0x01A0, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_18_0 = UNIT_END + 0x01A2, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_18_PROPERTIES = UNIT_END + 0x01AF, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_18_SEED = UNIT_END + 0x01B0, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_18_PAD = UNIT_END + 0x01B1, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_19_CREATOR = UNIT_END + 0x01B2, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_19_0 = UNIT_END + 0x01B4, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_19_PROPERTIES = UNIT_END + 0x01C1, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_19_SEED = UNIT_END + 0x01C2, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_19_PAD = UNIT_END + 0x01C3, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_CHOSEN_TITLE = UNIT_END + 0x01C4, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_FIELD_PAD_0 = UNIT_END + 0x01C5, // Size: 1, Type: INT, Flags: NONE
+ PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x01C6, // Size: 46, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x01F4, // Size: 32, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x0214, // Size: 56, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x024C, // Size: 14, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x025A, // Size: 24, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x0272, // Size: 64, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_VANITYPET_SLOT_1 = UNIT_END + 0x02B2, // Size: 36, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_CURRENCYTOKEN_SLOT_1 = UNIT_END + 0x02D6, // Size: 64, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_QUESTBAG_SLOT_1 = UNIT_END + 0x0316, // Size: 64, Type: LONG, Flags: PRIVATE
+ PLAYER_FARSIGHT = UNIT_END + 0x0356, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x0358, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER__FIELD_KNOWN_TITLES1 = UNIT_END + 0x035A, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_KNOWN_CURRENCIES = UNIT_END + 0x035C, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER_XP = UNIT_END + 0x035E, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x035F, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x0360, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_CHARACTER_POINTS1 = UNIT_END + 0x04E0, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_CHARACTER_POINTS2 = UNIT_END + 0x04E1, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_TRACK_CREATURES = UNIT_END + 0x04E2, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_TRACK_RESOURCES = UNIT_END + 0x04E3, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x04E4, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x04E5, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x04E6, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_EXPERTISE = UNIT_END + 0x04E7, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x04E8, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x04E9, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x04EA, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x04EB, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x04EC, // Size: 7, Type: FLOAT, Flags: PRIVATE
+ PLAYER_SHIELD_BLOCK = UNIT_END + 0x04F3, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE = UNIT_END + 0x04F4, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x04F5, // Size: 128, Type: BYTES, Flags: PRIVATE
+ PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x0575, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_COINAGE = UNIT_END + 0x0576, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x0577, // Size: 7, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x057E, // Size: 7, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x0585, // Size: 7, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x058C, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x058D, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x058E, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BYTES = UNIT_END + 0x058F, // Size: 1, Type: BYTES, Flags: PRIVATE
+ PLAYER_AMMO_ID = UNIT_END + 0x0590, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_SELF_RES_SPELL = UNIT_END + 0x0591, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x0592, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x0593, // Size: 12, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x059F, // Size: 12, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_KILLS = UNIT_END + 0x05AB, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x05AC, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x05AD, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_LIFETIME_HONORBALE_KILLS = UNIT_END + 0x05AE, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BYTES2 = UNIT_END + 0x05AF, // Size: 1, Type: BYTES, Flags: PRIVATE
+ PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x05B0, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x05B1, // Size: 25, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x05CA, // Size: 18, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x05DC, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x05DD, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x05DE, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x05DF, // Size: 25, Type: INT, Flags: PRIVATE
+ PLAYER_RUNE_REGEN_1 = UNIT_END + 0x05F8, // Size: 4, Type: FLOAT, Flags: PRIVATE
+ PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0x05FC, // Size: 3, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_GLYPH_SLOTS_1 = UNIT_END + 0x05FF, // Size: 8, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_GLYPHS_1 = UNIT_END + 0x0607, // Size: 8, Type: INT, Flags: PRIVATE
+ PLAYER_GLYPHS_ENABLED = UNIT_END + 0x060F, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_END = UNIT_END + 0x0610,
};
enum EGameObjectFields
{
OBJECT_FIELD_CREATED_BY = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
GAMEOBJECT_DISPLAYID = OBJECT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_FLAGS = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_ROTATION = OBJECT_END + 0x0004, // Size: 4, Type: FLOAT, Flags: PUBLIC
- GAMEOBJECT_STATE = OBJECT_END + 0x0008, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_POS_X = OBJECT_END + 0x0009, // Size: 1, Type: FLOAT, Flags: PUBLIC
- GAMEOBJECT_POS_Y = OBJECT_END + 0x000A, // Size: 1, Type: FLOAT, Flags: PUBLIC
- GAMEOBJECT_POS_Z = OBJECT_END + 0x000B, // Size: 1, Type: FLOAT, Flags: PUBLIC
- GAMEOBJECT_FACING = OBJECT_END + 0x000C, // Size: 1, Type: FLOAT, Flags: PUBLIC
- GAMEOBJECT_DYN_FLAGS = OBJECT_END + 0x000D, // Size: 1, Type: INT, Flags: DYNAMIC
- GAMEOBJECT_FACTION = OBJECT_END + 0x000E, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_TYPE_ID = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC
+ GAMEOBJECT_FLAGS = OBJECT_END + 0x0003, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ GAMEOBJECT_ROTATION = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC
+ GAMEOBJECT_PARENTROTATION = OBJECT_END + 0x0006, // Size: 4, Type: FLOAT, Flags: PUBLIC
+ GAMEOBJECT_POS_X = OBJECT_END + 0x000A, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ GAMEOBJECT_POS_Y = OBJECT_END + 0x000B, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ GAMEOBJECT_POS_Z = OBJECT_END + 0x000C, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ GAMEOBJECT_FACING = OBJECT_END + 0x000D, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ GAMEOBJECT_DYNAMIC = OBJECT_END + 0x000E, // Size: 1, Type: TWO_SHORT, Flags: DYNAMIC
+ GAMEOBJECT_FACTION = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC
GAMEOBJECT_LEVEL = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_ARTKIT = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_ANIMPROGRESS = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: DYNAMIC
- GAMEOBJECT_PADDING = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: NONE
- GAMEOBJECT_END = OBJECT_END + 0x0014,
+ GAMEOBJECT_BYTES_1 = OBJECT_END + 0x0011, // Size: 1, Type: BYTES, Flags: PUBLIC
+ GAMEOBJECT_END = OBJECT_END + 0x0012,
};
enum EDynamicObjectFields
diff --git a/src/game/UpdateMask.h b/src/game/UpdateMask.h
index 436aa523440..66a6947fc37 100644
--- a/src/game/UpdateMask.h
+++ b/src/game/UpdateMask.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -36,27 +36,27 @@ class UpdateMask
delete [] mUpdateMask;
}
- inline void SetBit (uint32 index)
+ void SetBit (uint32 index)
{
( (uint8 *)mUpdateMask )[ index >> 3 ] |= 1 << ( index & 0x7 );
}
- inline void UnsetBit (uint32 index)
+ void UnsetBit (uint32 index)
{
( (uint8 *)mUpdateMask )[ index >> 3 ] &= (0xff ^ (1 << ( index & 0x7 ) ) );
}
- inline bool GetBit (uint32 index)
+ bool GetBit (uint32 index) const
{
return ( ( (uint8 *)mUpdateMask)[ index >> 3 ] & ( 1 << ( index & 0x7 ) )) != 0;
}
- inline uint32 GetBlockCount() { return mBlocks; }
- inline uint32 GetLength() { return mBlocks << 2; }
- inline uint32 GetCount() { return mCount; }
- inline uint8* GetMask() { return (uint8*)mUpdateMask; }
+ uint32 GetBlockCount() const { return mBlocks; }
+ uint32 GetLength() const { return mBlocks << 2; }
+ uint32 GetCount() const { return mCount; }
+ uint8* GetMask() { return (uint8*)mUpdateMask; }
- inline void SetCount (uint32 valuesCount)
+ void SetCount (uint32 valuesCount)
{
if(mUpdateMask)
delete [] mUpdateMask;
@@ -68,13 +68,13 @@ class UpdateMask
memset(mUpdateMask, 0, mBlocks << 2);
}
- inline void Clear()
+ void Clear()
{
if (mUpdateMask)
memset(mUpdateMask, 0, mBlocks << 2);
}
- inline UpdateMask& operator = ( const UpdateMask& mask )
+ UpdateMask& operator = ( const UpdateMask& mask )
{
SetCount(mask.mCount);
memcpy(mUpdateMask, mask.mUpdateMask, mBlocks << 2);
@@ -82,21 +82,21 @@ class UpdateMask
return *this;
}
- inline void operator &= ( const UpdateMask& mask )
+ void operator &= ( const UpdateMask& mask )
{
ASSERT(mask.mCount <= mCount);
- for (uint32 i = 0; i < mBlocks; i++)
+ for (uint32 i = 0; i < mBlocks; ++i)
mUpdateMask[i] &= mask.mUpdateMask[i];
}
- inline void operator |= ( const UpdateMask& mask )
+ void operator |= ( const UpdateMask& mask )
{
ASSERT(mask.mCount <= mCount);
- for (uint32 i = 0; i < mBlocks; i++)
+ for (uint32 i = 0; i < mBlocks; ++i)
mUpdateMask[i] |= mask.mUpdateMask[i];
}
- inline UpdateMask operator & ( const UpdateMask& mask ) const
+ UpdateMask operator & ( const UpdateMask& mask ) const
{
ASSERT(mask.mCount <= mCount);
@@ -107,7 +107,7 @@ class UpdateMask
return newmask;
}
- inline UpdateMask operator | ( const UpdateMask& mask ) const
+ UpdateMask operator | ( const UpdateMask& mask ) const
{
ASSERT(mask.mCount <= mCount);
diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp
new file mode 100644
index 00000000000..9dd36895d56
--- /dev/null
+++ b/src/game/Vehicle.cpp
@@ -0,0 +1,387 @@
+/*
+ * Copyright (C) 2005-2009 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 "Common.h"
+#include "Log.h"
+#include "ObjectMgr.h"
+#include "Vehicle.h"
+#include "Unit.h"
+#include "Util.h"
+#include "WorldPacket.h"
+
+#include "Chat.h"
+
+Vehicle::Vehicle() : Creature(), m_vehicleInfo(NULL)
+{
+ m_summonMask |= SUMMON_MASK_VEHICLE;
+ m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_VEHICLE);
+}
+
+Vehicle::~Vehicle()
+{
+}
+
+void Vehicle::AddToWorld()
+{
+ if(!IsInWorld())
+ {
+ ObjectAccessor::Instance().AddObject(this);
+ Unit::AddToWorld();
+ AIM_Initialize();
+ switch(GetEntry())
+ {
+ case 27850:InstallAccessory(27905,1);break;
+ case 28312:InstallAccessory(28319,7);break;
+ case 32627:InstallAccessory(32629,7);break;
+ }
+ }
+}
+
+void Vehicle::RemoveFromWorld()
+{
+ if(IsInWorld())
+ {
+ RemoveAllPassengers();
+ ///- Don't call the function for Creature, normal mobs + totems go in a different storage
+ Unit::RemoveFromWorld();
+ ObjectAccessor::Instance().RemoveObject(this);
+ }
+}
+
+void Vehicle::setDeathState(DeathState s) // overwrite virtual Creature::setDeathState and Unit::setDeathState
+{
+ if(s == JUST_DIED)
+ {
+ for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
+ {
+ if(Unit *passenger = itr->second.passenger)
+ if(passenger->GetTypeId() == TYPEID_UNIT && ((Creature*)passenger)->isVehicle())
+ {
+ passenger->ExitVehicle();
+ ((Vehicle*)passenger)->setDeathState(s);
+ }
+ }
+ RemoveAllPassengers();
+ }
+ Creature::setDeathState(s);
+}
+
+void Vehicle::Update(uint32 diff)
+{
+ Creature::Update(diff);
+}
+
+bool Vehicle::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehicleId, uint32 team)
+{
+ //sLog.outError("create vehicle begin");
+ SetMapId(map->GetId());
+ SetInstanceId(map->GetInstanceId());
+
+ Object::_Create(guidlow, Entry, HIGHGUID_VEHICLE);
+
+ if(!InitEntry(Entry, team))
+ return false;
+
+ m_defaultMovementType = IDLE_MOTION_TYPE;
+
+ SetVehicleId(vehicleId);
+
+ SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f);
+
+ CreatureInfo const *ci = GetCreatureInfo();
+ setFaction(team == ALLIANCE ? ci->faction_A : ci->faction_H);
+ SetMaxHealth(ci->maxhealth);
+ SelectLevel(ci);
+ SetHealth(GetMaxHealth());
+
+ //sLog.outError("create vehicle end");
+ return true;
+}
+
+void Vehicle::RemoveAllPassengers()
+{
+ for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
+ if(Unit *passenger = itr->second.passenger)
+ {
+ if(passenger->GetTypeId() == TYPEID_UNIT && ((Creature*)passenger)->isVehicle())
+ ((Vehicle*)passenger)->RemoveAllPassengers();
+ passenger->ExitVehicle();
+ assert(!itr->second.passenger);
+ }
+}
+
+void Vehicle::SetVehicleId(uint32 id)
+{
+ if(m_vehicleInfo && id == m_vehicleInfo->m_ID)
+ return;
+
+ VehicleEntry const *ve = sVehicleStore.LookupEntry(id);
+ if(!ve)
+ return;
+
+ m_vehicleInfo = ve;
+
+ RemoveAllPassengers();
+ m_Seats.clear();
+
+ for(uint32 i = 0; i < 8; ++i)
+ {
+ uint32 seatId = m_vehicleInfo->m_seatID[i];
+ if(seatId)
+ if(VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(seatId))
+ m_Seats.insert(std::make_pair(i, VehicleSeat(veSeat)));
+ }
+
+ assert(!m_Seats.empty());
+}
+
+bool Vehicle::HasEmptySeat(int8 seatId) const
+{
+ SeatMap::const_iterator seat = m_Seats.find(seatId);
+ if(seat == m_Seats.end()) return false;
+ return !seat->second.passenger;
+}
+
+int8 Vehicle::GetNextEmptySeat(int8 seatId, bool next) const
+{
+ SeatMap::const_iterator seat = m_Seats.find(seatId);
+ if(seat == m_Seats.end()) return -1;
+ while(seat->second.passenger)
+ {
+ if(next)
+ {
+ ++seat;
+ if(seat == m_Seats.end())
+ seat = m_Seats.begin();
+ }
+ else
+ {
+ if(seat == m_Seats.begin())
+ seat = m_Seats.end();
+ --seat;
+ }
+ if(seat->first == seatId)
+ return -1;
+ }
+ return seat->first;
+}
+
+void Vehicle::InstallAccessory(uint32 entry, int8 seatId)
+{
+ //Creature *accessory = SummonCreature(entry, GetPositionX(), GetPositionY(), GetPositionZ());
+ Creature *accessory = SummonVehicle(entry, GetPositionX(), GetPositionY(), GetPositionZ());
+ if(!accessory)
+ return;
+
+ accessory->m_Vehicle = this;
+ AddPassenger(accessory, seatId);
+}
+
+bool Vehicle::AddPassenger(Unit *unit, int8 seatId)
+{
+ if(unit->m_Vehicle != this)
+ return false;
+
+ SeatMap::iterator seat;
+ if(seatId < 0) // no specific seat requirement
+ {
+ for(seat = m_Seats.begin(); seat != m_Seats.end(); ++seat)
+ if(!seat->second.passenger)
+ break;
+
+ if(seat == m_Seats.end()) // no available seat
+ return false;
+ }
+ else
+ {
+ seat = m_Seats.find(seatId);
+ if(seat == m_Seats.end())
+ return false;
+
+ if(seat->second.passenger)
+ seat->second.passenger->ExitVehicle();
+
+ assert(!seat->second.passenger);
+ }
+
+ sLog.outDebug("Unit %s enter vehicle entry %u id %u dbguid %u", unit->GetName(), GetEntry(), m_vehicleInfo->m_ID, GetDBTableGUIDLow());
+
+ seat->second.passenger = unit;
+
+ //RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ //SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
+
+ unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+ VehicleSeatEntry const *veSeat = seat->second.seatInfo;
+ unit->m_movementInfo.t_x = veSeat->m_attachmentOffsetX;
+ unit->m_movementInfo.t_y = veSeat->m_attachmentOffsetY;
+ unit->m_movementInfo.t_z = veSeat->m_attachmentOffsetZ;
+ unit->m_movementInfo.t_o = 0;
+ unit->m_movementInfo.t_time = 4;
+ unit->m_movementInfo.t_seat = seat->first;
+
+ unit->Relocate(GetPositionX() + unit->m_movementInfo.t_x,
+ GetPositionY() + unit->m_movementInfo.t_y,
+ GetPositionZ() + unit->m_movementInfo.t_z,
+ GetOrientation());
+
+ WorldPacket data;
+ if(unit->GetTypeId() == TYPEID_PLAYER)
+ {
+ //ChatHandler(player).PSendSysMessage("Enter seat %u %u", veSeat->m_ID, seat->first);
+
+ if(seat->first == 0)
+ {
+ ((Player*)unit)->SetCharm(this, true);
+ ((Player*)unit)->SetViewpoint(this, true);
+ ((Player*)unit)->VehicleSpellInitialize();
+ }
+
+ ((Player*)unit)->BuildTeleportAckMsg(&data, unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetOrientation());
+ ((Player*)unit)->GetSession()->SendPacket(&data);
+ }
+
+ unit->BuildHeartBeatMsg(&data);
+ unit->SendMessageToSet(&data, false);
+
+ return true;
+}
+
+void Vehicle::RemovePassenger(Unit *unit)
+{
+ if(unit->m_Vehicle != this)
+ return;
+
+ SeatMap::iterator seat;
+ for(seat = m_Seats.begin(); seat != m_Seats.end(); ++seat)
+ {
+ if(seat->second.passenger == unit)
+ {
+ seat->second.passenger = NULL;
+ break;
+ }
+ }
+
+ assert(seat != m_Seats.end());
+
+ sLog.outDebug("Unit %s exit vehicle entry %u id %u dbguid %u", unit->GetName(), GetEntry(), m_vehicleInfo->m_ID, GetDBTableGUIDLow());
+
+ //SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+
+ if(unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0)
+ {
+ ((Player*)unit)->SetCharm(this, false);
+ ((Player*)unit)->SetViewpoint(this, false);
+ ((Player*)unit)->SendRemoveControlBar();
+ }
+
+ // only for flyable vehicles?
+ //CastSpell(this, 45472, true); // Parachute
+}
+
+void Vehicle::Dismiss()
+{
+ for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
+ {
+ if(Unit *passenger = itr->second.passenger)
+ if(passenger->GetTypeId() == TYPEID_UNIT && ((Creature*)passenger)->isVehicle())
+ {
+ passenger->ExitVehicle();
+ ((Vehicle*)passenger)->Dismiss();
+ }
+ }
+ RemoveAllPassengers();
+ SendObjectDeSpawnAnim(GetGUID());
+ CombatStop();
+ CleanupsBeforeDelete();
+ AddObjectToRemoveList();
+}
+
+bool Vehicle::LoadFromDB(uint32 guid, Map *map)
+{
+ CreatureData const* data = objmgr.GetCreatureData(guid);
+
+ if(!data)
+ {
+ sLog.outErrorDb("Creature (GUID: %u) not found in table `creature`, can't load. ",guid);
+ return false;
+ }
+
+ uint32 id = 0;
+ if(const CreatureInfo *cInfo = objmgr.GetCreatureTemplate(data->id))
+ id = cInfo->VehicleId;
+ if(!id || !sVehicleStore.LookupEntry(id))
+ return false;
+
+ m_DBTableGuid = guid;
+ if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_VEHICLE);
+
+ uint16 team = 0;
+ if(!Create(guid,map,data->phaseMask,data->id,id,team))
+ return false;
+
+ Relocate(data->posX,data->posY,data->posZ,data->orientation);
+
+ if(!IsPositionValid())
+ {
+ sLog.outError("Creature (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)",GetGUIDLow(),GetEntry(),GetPositionX(),GetPositionY());
+ return false;
+ }
+ //We should set first home position, because then AI calls home movement
+ SetHomePosition(data->posX,data->posY,data->posZ,data->orientation);
+
+ m_respawnradius = data->spawndist;
+
+ m_respawnDelay = data->spawntimesecs;
+ m_isDeadByDefault = data->is_dead;
+ m_deathState = m_isDeadByDefault ? DEAD : ALIVE;
+
+ m_respawnTime = objmgr.GetCreatureRespawnTime(m_DBTableGuid,GetInstanceId());
+ if(m_respawnTime > time(NULL)) // not ready to respawn
+ {
+ m_deathState = DEAD;
+ if(canFly())
+ {
+ float tz = GetMap()->GetHeight(data->posX,data->posY,data->posZ,false);
+ if(data->posZ - tz > 0.1)
+ Relocate(data->posX,data->posY,tz);
+ }
+ }
+ else if(m_respawnTime) // respawn time set but expired
+ {
+ m_respawnTime = 0;
+ objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0);
+ }
+
+ uint32 curhealth = data->curhealth;
+ if(curhealth)
+ {
+ curhealth = uint32(curhealth*_GetHealthMod(GetCreatureInfo()->rank));
+ if(curhealth < 1)
+ curhealth = 1;
+ }
+
+ SetHealth(m_deathState == ALIVE ? curhealth : 0);
+ SetPower(POWER_MANA,data->curmana);
+
+ // checked at creature_template loading
+ m_defaultMovementType = MovementGeneratorType(data->movementType);
+
+ return true;
+}
diff --git a/src/game/Vehicle.h b/src/game/Vehicle.h
new file mode 100644
index 00000000000..4ff7ec90c53
--- /dev/null
+++ b/src/game/Vehicle.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2005-2009 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 MANGOSSERVER_VEHICLE_H
+#define MANGOSSERVER_VEHICLE_H
+
+#include "ObjectDefines.h"
+#include "Creature.h"
+#include "Unit.h"
+
+struct VehicleEntry;
+struct VehicleSeatEntry;
+
+struct VehicleSeat
+{
+ explicit VehicleSeat(VehicleSeatEntry const *_seatInfo) : seatInfo(_seatInfo), passenger(NULL) {}
+ VehicleSeatEntry const *seatInfo;
+ Unit* passenger;
+};
+
+typedef std::map<int8, VehicleSeat> SeatMap;
+
+class Vehicle : public Creature
+{
+ public:
+ explicit Vehicle();
+ virtual ~Vehicle();
+
+ void AddToWorld();
+ void RemoveFromWorld();
+
+ bool Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehicleId, uint32 team);
+
+ void setDeathState(DeathState s); // overwrite virtual Creature::setDeathState and Unit::setDeathState
+ void Update(uint32 diff); // overwrite virtual Creature::Update and Unit::Update
+
+ VehicleEntry const *GetVehicleInfo() { return m_vehicleInfo; }
+ void SetVehicleId(uint32 vehicleid);
+
+ bool HasEmptySeat(int8 seatId) const;
+ int8 GetNextEmptySeat(int8 seatId, bool next) const;
+ bool AddPassenger(Unit *passenger, int8 seatId = -1);
+ void RemovePassenger(Unit *passenger);
+ void InstallAccessory(uint32 entry, int8 seatId);
+ void Dismiss();
+
+ bool LoadFromDB(uint32 guid, Map *map);
+
+ SeatMap m_Seats;
+ protected:
+ VehicleEntry const *m_vehicleInfo;
+
+ void RemoveAllPassengers();
+
+ private:
+ void SaveToDB(uint32, uint8) // overwrited of Creature::SaveToDB - don't must be called
+ {
+ assert(false);
+ }
+ void DeleteFromDB() // overwrited of Creature::DeleteFromDB - don't must be called
+ {
+ assert(false);
+ }
+};
+#endif
diff --git a/src/game/VoiceChatHandler.cpp b/src/game/VoiceChatHandler.cpp
index ba03ee1c543..8e787549e33 100644
--- a/src/game/VoiceChatHandler.cpp
+++ b/src/game/VoiceChatHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,7 +21,6 @@
#include "Common.h"
#include "WorldPacket.h"
#include "WorldSession.h"
-#include "World.h"
#include "Opcodes.h"
#include "Log.h"
diff --git a/src/game/WaypointManager.cpp b/src/game/WaypointManager.cpp
index 30947abe4c8..a677fd5b6d2 100644
--- a/src/game/WaypointManager.cpp
+++ b/src/game/WaypointManager.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/WaypointManager.h b/src/game/WaypointManager.h
index 1c41617fff7..85f8b765d45 100644
--- a/src/game/WaypointManager.h
+++ b/src/game/WaypointManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp
index 0cc32eefdf4..397b4adadab 100644
--- a/src/game/WaypointMovementGenerator.cpp
+++ b/src/game/WaypointMovementGenerator.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 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
@@ -24,6 +24,7 @@
//Creature-specific headers
#include "Creature.h"
#include "CreatureAI.h"
+#include "CreatureGroups.h"
//Player-specific
#include "Player.h"
@@ -54,7 +55,7 @@ bool WaypointMovementGenerator<Creature>::GetDestination(float &x, float &y, flo
{
if(i_destinationHolder.HasArrived())
return false;
-
+
i_destinationHolder.GetDestination(x, y, z);
return true;
}
@@ -109,6 +110,10 @@ WaypointMovementGenerator<Creature>::Initialize(Creature &u)
InitTraveller(u, *node);
i_destinationHolder.SetDestination(traveller, node->x, node->y, node->z);
i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
+
+ //Call for creature group update
+ if(u.GetFormation() && u.GetFormation()->getLeader() == &u)
+ u.GetFormation()->LeaderMoveTo(node->x, node->y, node->z);
}
else
node = NULL;
@@ -180,6 +185,10 @@ WaypointMovementGenerator<Creature>::Update(Creature &unit, const uint32 &diff)
InitTraveller(unit, *node);
i_destinationHolder.SetDestination(traveller, node->x, node->y, node->z);
i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
+
+ //Call for creature group update
+ if(unit.GetFormation() && unit.GetFormation()->getLeader() == &unit)
+ unit.GetFormation()->LeaderMoveTo(node->x, node->y, node->z);
}
else
{
@@ -255,12 +264,13 @@ FlightPathMovementGenerator::Initialize(Player &player)
void FlightPathMovementGenerator::Finalize(Player & player)
{
+ // remove flag to prevent send object build movement packets for flight state and crash (movement generator already not at top of stack)
+ player.clearUnitState(UNIT_STAT_IN_FLIGHT);
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);
@@ -481,7 +491,7 @@ int CreatePathAStar(gentity_t *bot, int from, int to, short int *pathlist)
break;
}
- for (i = 0; i < nodes[atNode].enodenum; i++) //loop through all the links for this node
+ for (i = 0; i < nodes[atNode].enodenum; ++i) //loop through all the links for this node
{
newnode = nodes[atNode].links[i].targetNode;
@@ -539,7 +549,7 @@ int CreatePathAStar(gentity_t *bot, int from, int to, short int *pathlist)
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
+ 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
{
diff --git a/src/game/WaypointMovementGenerator.h b/src/game/WaypointMovementGenerator.h
index eec6ad70e5c..9804c150d63 100644
--- a/src/game/WaypointMovementGenerator.h
+++ b/src/game/WaypointMovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -48,7 +48,7 @@ class TRINITY_DLL_SPEC PathMovementBase
PathMovementBase() : i_currentNode(0) {}
virtual ~PathMovementBase() {};
- inline bool MovementInProgress(void) const { return i_currentNode < i_path.Size(); }
+ bool MovementInProgress(void) const { return i_currentNode < i_path.Size(); }
void LoadPath(T &);
void ReloadPath(T &);
@@ -109,7 +109,7 @@ public PathMovementBase<Player>
Path& GetPath() { return i_path; }
uint32 GetPathAtMapEnd() const;
- inline bool HasArrived() const { return (i_currentNode >= i_path.Size()); }
+ bool HasArrived() const { return (i_currentNode >= i_path.Size()); }
void SetCurrentNodeAfterTeleport();
void SkipCurrentNode() { ++i_currentNode; }
bool GetDestination(float& x, float& y, float& z) const { i_destinationHolder.GetDestination(x,y,z); return true; }
diff --git a/src/game/Weather.cpp b/src/game/Weather.cpp
index 498beab0412..5d8d1fbd9ba 100644
--- a/src/game/Weather.cpp
+++ b/src/game/Weather.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -24,7 +24,6 @@
#include "Weather.h"
#include "WorldPacket.h"
-#include "WorldSession.h"
#include "Player.h"
#include "World.h"
#include "Log.h"
@@ -38,11 +37,11 @@ Weather::Weather(uint32 zone, WeatherZoneChances const* weatherChances) : m_zone
m_type = WEATHER_TYPE_FINE;
m_grade = 0;
- sLog.outDetail("WORLD: Starting weather system for zone %u (change every %u minutes).", m_zone, (uint32)(m_timer.GetInterval() / (1000*MINUTE)) );
+ sLog.outDetail("WORLD: Starting weather system for zone %u (change every %u minutes).", m_zone, (uint32)(m_timer.GetInterval() / (MINUTE*IN_MILISECONDS)) );
}
/// Launch a weather update
-bool Weather::Update(time_t diff)
+bool Weather::Update(uint32 diff)
{
if (m_timer.GetCurrent()>=0)
m_timer.Update(diff);
diff --git a/src/game/Weather.h b/src/game/Weather.h
index cbd4daad1ad..e312f004060 100644
--- a/src/game/Weather.h
+++ b/src/game/Weather.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -62,7 +62,7 @@ class Weather
void SetWeather(WeatherType type, float grade);
/// For which zone is this weather?
uint32 GetZone() { return m_zone; };
- bool Update(time_t diff);
+ bool Update(uint32 diff);
private:
WeatherState GetWeatherState() const;
uint32 m_zone;
diff --git a/src/game/World.cpp b/src/game/World.cpp
index b50e8476283..9615a378faa 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -23,7 +23,6 @@
*/
#include "Common.h"
-//#include "WorldSocket.h"
#include "Database/DatabaseEnv.h"
#include "Config/ConfigEnv.h"
#include "SystemConfig.h"
@@ -33,15 +32,18 @@
#include "WorldPacket.h"
#include "Weather.h"
#include "Player.h"
+#include "Vehicle.h"
#include "SkillExtraItems.h"
#include "SkillDiscovery.h"
#include "World.h"
#include "AccountMgr.h"
+#include "AchievementMgr.h"
#include "AuctionHouseMgr.h"
#include "ObjectMgr.h"
+#include "CreatureEventAIMgr.h"
#include "SpellMgr.h"
#include "Chat.h"
-#include "Database/DBCStores.h"
+#include "DBCStores.h"
#include "LootMgr.h"
#include "ItemEnchantmentMgr.h"
#include "MapManager.h"
@@ -55,7 +57,8 @@
#include "WaypointMovementGenerator.h"
#include "VMapFactory.h"
#include "GlobalEvents.h"
-#include "GameEvent.h"
+#include "GameEventMgr.h"
+#include "PoolHandler.h"
#include "Database/DatabaseImpl.h"
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
@@ -81,16 +84,6 @@ float World::m_MaxVisibleDistanceInFlight = DEFAULT_VISIBILITY_DISTANCE;
float World::m_VisibleUnitGreyDistance = 0;
float World::m_VisibleObjectGreyDistance = 0;
-// ServerMessages.dbc
-enum ServerMessageType
-{
- SERVER_MSG_SHUTDOWN_TIME = 1,
- SERVER_MSG_RESTART_TIME = 2,
- SERVER_MSG_STRING = 3,
- SERVER_MSG_SHUTDOWN_CANCELLED = 4,
- SERVER_MSG_RESTART_CANCELLED = 5
-};
-
struct ScriptAction
{
uint64 sourceGUID;
@@ -118,6 +111,8 @@ World::World()
m_updateTimeSum = 0;
m_updateTimeCount = 0;
+
+ m_isClosed = false;
}
/// World destructor
@@ -132,7 +127,7 @@ World::~World()
}
///- Empty the WeatherMap
- for (WeatherMap::iterator itr = m_weathers.begin(); itr != m_weathers.end(); ++itr)
+ for (WeatherMap::const_iterator itr = m_weathers.begin(); itr != m_weathers.end(); ++itr)
delete itr->second;
m_weathers.clear();
@@ -151,7 +146,7 @@ World::~World()
Player* World::FindPlayerInZone(uint32 zone)
{
///- circle through active sessions and return the first player found in the zone
- SessionMap::iterator itr;
+ SessionMap::const_iterator itr;
for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
{
if(!itr->second)
@@ -183,7 +178,7 @@ WorldSession* World::FindSession(uint32 id) const
bool World::RemoveSession(uint32 id)
{
///- Find the session, kick the user, but we can't delete session at this moment to prevent iterator invalidation
- SessionMap::iterator itr = m_sessions.find(id);
+ SessionMap::const_iterator itr = m_sessions.find(id);
if(itr != m_sessions.end() && itr->second)
{
@@ -238,7 +233,7 @@ World::AddSession_ (WorldSession* s)
uint32 Sessions = GetActiveAndQueuedSessionCount ();
uint32 pLimit = GetPlayerAmountLimit ();
- uint32 QueueSize = GetQueueSize (); //number of players in the queue
+ uint32 QueueSize = GetQueueSize (); //number of players in the queue
//so we don't count the user trying to
//login as a session and queue the socket that we are using
@@ -255,18 +250,19 @@ World::AddSession_ (WorldSession* s)
WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1);
packet << uint8 (AUTH_OK);
- packet << uint32 (0); // unknown random value...
- packet << uint8 (0);
- packet << uint32 (0);
- packet << uint8 (s->Expansion()); // 0 - normal, 1 - TBC, must be set in database manually for each account
+ packet << uint32 (0); // BillingTimeRemaining
+ packet << uint8 (0); // BillingPlanFlags
+ packet << uint32 (0); // BillingTimeRested
+ packet << uint8 (s->Expansion()); // 0 - normal, 1 - TBC, must be set in database manually for each account
s->SendPacket (&packet);
+ s->SendAddonsInfo();
UpdateMaxSessionCounters ();
// Updates the population
if (pLimit > 0)
{
- float popu = GetActiveSessionCount (); //updated number of users on the server
+ float popu = GetActiveSessionCount (); //updated number of users on the server
popu /= pLimit;
popu *= 2;
LoginDatabase.PExecute ("UPDATE realmlist SET population = '%f' WHERE id = '%d'", popu, realmID);
@@ -280,12 +276,13 @@ bool World::HasRecentlyDisconnected(WorldSession* session)
if(uint32 tolerance = getConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE))
{
- for(DisconnectMap::iterator i = m_disconnects.begin(); i != m_disconnects.end(); ++i)
+ for(DisconnectMap::iterator i = m_disconnects.begin(); i != m_disconnects.end(); )
{
if(difftime(i->second, time(NULL)) < tolerance)
{
if(i->first == session->GetAccountId())
return true;
+ ++i;
}
else
m_disconnects.erase(i);
@@ -298,7 +295,7 @@ int32 World::GetQueuePos(WorldSession* sess)
{
uint32 position = 1;
- for(Queue::iterator iter = m_QueuedPlayer.begin(); iter != m_QueuedPlayer.end(); ++iter, ++position)
+ for(Queue::const_iterator iter = m_QueuedPlayer.begin(); iter != m_QueuedPlayer.end(); ++iter, ++position)
if((*iter) == sess)
return position;
@@ -313,10 +310,10 @@ void World::AddQueuedPlayer(WorldSession* sess)
// The 1st SMSG_AUTH_RESPONSE needs to contain other info too.
WorldPacket packet (SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1);
packet << uint8 (AUTH_WAIT_QUEUE);
- packet << uint32 (0); // unknown random value...
- packet << uint8 (0);
- packet << uint32 (0);
- packet << uint8 (sess->Expansion () ? 1 : 0); // 0 - normal, 1 - TBC, must be set in database manually for each account
+ packet << uint32 (0); // BillingTimeRemaining
+ packet << uint8 (0); // BillingPlanFlags
+ packet << uint32 (0); // BillingTimeRested
+ packet << uint8 (sess->Expansion () ? 1 : 0); // 0 - normal, 1 - TBC, must be set in database manually for each account
packet << uint32(GetQueuePos (sess));
sess->SendPacket (&packet);
@@ -440,24 +437,30 @@ void World::LoadConfigSettings(bool reload)
rate_values[RATE_HEALTH] = sConfig.GetFloatDefault("Rate.Health", 1);
if(rate_values[RATE_HEALTH] < 0)
{
- sLog.outError("Rate.Health (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_HEALTH]);
+ sLog.outError("Rate.Health (%f) must be > 0. Using 1 instead.",rate_values[RATE_HEALTH]);
rate_values[RATE_HEALTH] = 1;
}
rate_values[RATE_POWER_MANA] = sConfig.GetFloatDefault("Rate.Mana", 1);
if(rate_values[RATE_POWER_MANA] < 0)
{
- sLog.outError("Rate.Mana (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_POWER_MANA]);
+ sLog.outError("Rate.Mana (%f) must be > 0. Using 1 instead.",rate_values[RATE_POWER_MANA]);
rate_values[RATE_POWER_MANA] = 1;
}
rate_values[RATE_POWER_RAGE_INCOME] = sConfig.GetFloatDefault("Rate.Rage.Income", 1);
rate_values[RATE_POWER_RAGE_LOSS] = sConfig.GetFloatDefault("Rate.Rage.Loss", 1);
if(rate_values[RATE_POWER_RAGE_LOSS] < 0)
{
- sLog.outError("Rate.Rage.Loss (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_POWER_RAGE_LOSS]);
+ sLog.outError("Rate.Rage.Loss (%f) must be > 0. Using 1 instead.",rate_values[RATE_POWER_RAGE_LOSS]);
rate_values[RATE_POWER_RAGE_LOSS] = 1;
}
+ rate_values[RATE_POWER_RUNICPOWER_INCOME] = sConfig.GetFloatDefault("Rate.RunicPower.Income", 1);
+ rate_values[RATE_POWER_RUNICPOWER_LOSS] = sConfig.GetFloatDefault("Rate.RunicPower.Loss", 1);
+ if(rate_values[RATE_POWER_RUNICPOWER_LOSS] < 0)
+ {
+ sLog.outError("Rate.RunicPower.Loss (%f) must be > 0. Using 1 instead.",rate_values[RATE_POWER_RUNICPOWER_LOSS]);
+ rate_values[RATE_POWER_RUNICPOWER_LOSS] = 1;
+ }
rate_values[RATE_POWER_FOCUS] = sConfig.GetFloatDefault("Rate.Focus", 1.0f);
- rate_values[RATE_LOYALTY] = sConfig.GetFloatDefault("Rate.Loyalty", 1.0f);
rate_values[RATE_SKILL_DISCOVERY] = sConfig.GetFloatDefault("Rate.Skill.Discovery", 1.0f);
rate_values[RATE_DROP_ITEM_POOR] = sConfig.GetFloatDefault("Rate.Drop.Item.Poor", 1.0f);
rate_values[RATE_DROP_ITEM_NORMAL] = sConfig.GetFloatDefault("Rate.Drop.Item.Normal", 1.0f);
@@ -471,8 +474,9 @@ void World::LoadConfigSettings(bool reload)
rate_values[RATE_XP_KILL] = sConfig.GetFloatDefault("Rate.XP.Kill", 1.0f);
rate_values[RATE_XP_QUEST] = sConfig.GetFloatDefault("Rate.XP.Quest", 1.0f);
rate_values[RATE_XP_EXPLORE] = sConfig.GetFloatDefault("Rate.XP.Explore", 1.0f);
- rate_values[RATE_XP_PAST_70] = sConfig.GetFloatDefault("Rate.XP.PastLevel70", 1.0f);
rate_values[RATE_REPUTATION_GAIN] = sConfig.GetFloatDefault("Rate.Reputation.Gain", 1.0f);
+ rate_values[RATE_REPUTATION_LOWLEVEL_KILL] = sConfig.GetFloatDefault("Rate.Reputation.LowLevel.Kill", 1.0f);
+ rate_values[RATE_REPUTATION_LOWLEVEL_QUEST] = sConfig.GetFloatDefault("Rate.Reputation.LowLevel.Quest", 1.0f);
rate_values[RATE_CREATURE_NORMAL_DAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Normal.Damage", 1.0f);
rate_values[RATE_CREATURE_ELITE_ELITE_DAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Elite.Elite.Damage", 1.0f);
rate_values[RATE_CREATURE_ELITE_RAREELITE_DAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Elite.RAREELITE.Damage", 1.0f);
@@ -556,10 +560,10 @@ void World::LoadConfigSettings(bool reload)
}
m_configs[CONFIG_ADDON_CHANNEL] = sConfig.GetBoolDefault("AddonChannel", true);
m_configs[CONFIG_GRID_UNLOAD] = sConfig.GetBoolDefault("GridUnload", true);
- m_configs[CONFIG_INTERVAL_SAVE] = sConfig.GetIntDefault("PlayerSaveInterval", 900000);
+ m_configs[CONFIG_INTERVAL_SAVE] = sConfig.GetIntDefault("PlayerSaveInterval", 15 * MINUTE * IN_MILISECONDS);
m_configs[CONFIG_INTERVAL_DISCONNECT_TOLERANCE] = sConfig.GetIntDefault("DisconnectToleranceInterval", 0);
- m_configs[CONFIG_INTERVAL_GRIDCLEAN] = sConfig.GetIntDefault("GridCleanUpDelay", 300000);
+ m_configs[CONFIG_INTERVAL_GRIDCLEAN] = sConfig.GetIntDefault("GridCleanUpDelay", 5 * MINUTE * IN_MILISECONDS);
if(m_configs[CONFIG_INTERVAL_GRIDCLEAN] < MIN_GRID_DELAY)
{
sLog.outError("GridCleanUpDelay (%i) must be greater %u. Use this minimal value.",m_configs[CONFIG_INTERVAL_GRIDCLEAN],MIN_GRID_DELAY);
@@ -577,7 +581,7 @@ void World::LoadConfigSettings(bool reload)
if(reload)
MapManager::Instance().SetMapUpdateInterval(m_configs[CONFIG_INTERVAL_MAPUPDATE]);
- m_configs[CONFIG_INTERVAL_CHANGEWEATHER] = sConfig.GetIntDefault("ChangeWeatherInterval", 600000);
+ m_configs[CONFIG_INTERVAL_CHANGEWEATHER] = sConfig.GetIntDefault("ChangeWeatherInterval", 10 * MINUTE * IN_MILISECONDS);
if(reload)
{
@@ -592,7 +596,7 @@ void World::LoadConfigSettings(bool reload)
{
uint32 val = sConfig.GetIntDefault("SocketSelectTime", DEFAULT_SOCKET_SELECT_TIME);
if(val!=m_configs[CONFIG_SOCKET_SELECTTIME])
- sLog.outError("SocketSelectTime option can't be changed at Trinityd.conf reload, using current value (%u).",m_configs[DEFAULT_SOCKET_SELECT_TIME]);
+ sLog.outError("SocketSelectTime option can't be changed at Trinityd.conf reload, using current value (%u).",m_configs[CONFIG_SOCKET_SELECTTIME]);
}
else
m_configs[CONFIG_SOCKET_SELECTTIME] = sConfig.GetIntDefault("SocketSelectTime", DEFAULT_SOCKET_SELECT_TIME);
@@ -620,21 +624,21 @@ void World::LoadConfigSettings(bool reload)
else
m_configs[CONFIG_REALM_ZONE] = sConfig.GetIntDefault("RealmZone", REALM_ZONE_DEVELOPMENT);
- m_configs[CONFIG_ALLOW_TWO_SIDE_ACCOUNTS] = sConfig.GetBoolDefault("AllowTwoSide.Accounts", false);
+ m_configs[CONFIG_ALLOW_TWO_SIDE_ACCOUNTS] = sConfig.GetBoolDefault("AllowTwoSide.Accounts", false);
m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Chat",false);
m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Channel",false);
m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Group",false);
m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Guild",false);
m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Auction",false);
m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Mail",false);
- m_configs[CONFIG_ALLOW_TWO_SIDE_WHO_LIST] = sConfig.GetBoolDefault("AllowTwoSide.WhoList", false);
- m_configs[CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND] = sConfig.GetBoolDefault("AllowTwoSide.AddFriend", false);
- m_configs[CONFIG_ALLOW_TWO_SIDE_TRADE] = sConfig.GetBoolDefault("AllowTwoSide.trade", false);
- m_configs[CONFIG_STRICT_PLAYER_NAMES] = sConfig.GetIntDefault("StrictPlayerNames", 0);
- m_configs[CONFIG_STRICT_CHARTER_NAMES] = sConfig.GetIntDefault("StrictCharterNames", 0);
- m_configs[CONFIG_STRICT_PET_NAMES] = sConfig.GetIntDefault("StrictPetNames", 0);
+ m_configs[CONFIG_ALLOW_TWO_SIDE_WHO_LIST] = sConfig.GetBoolDefault("AllowTwoSide.WhoList", false);
+ m_configs[CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND] = sConfig.GetBoolDefault("AllowTwoSide.AddFriend", false);
+ m_configs[CONFIG_ALLOW_TWO_SIDE_TRADE] = sConfig.GetBoolDefault("AllowTwoSide.trade", false);
+ m_configs[CONFIG_STRICT_PLAYER_NAMES] = sConfig.GetIntDefault ("StrictPlayerNames", 0);
+ m_configs[CONFIG_STRICT_CHARTER_NAMES] = sConfig.GetIntDefault ("StrictCharterNames", 0);
+ m_configs[CONFIG_STRICT_PET_NAMES] = sConfig.GetIntDefault ("StrictPetNames", 0);
- m_configs[CONFIG_CHARACTERS_CREATING_DISABLED] = sConfig.GetIntDefault("CharactersCreatingDisabled", 0);
+ m_configs[CONFIG_CHARACTERS_CREATING_DISABLED] = sConfig.GetIntDefault ("CharactersCreatingDisabled", 0);
m_configs[CONFIG_CHARACTERS_PER_REALM] = sConfig.GetIntDefault("CharactersPerRealm", 10);
if(m_configs[CONFIG_CHARACTERS_PER_REALM] < 1 || m_configs[CONFIG_CHARACTERS_PER_REALM] > 10)
@@ -651,8 +655,17 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_CHARACTERS_PER_ACCOUNT] = m_configs[CONFIG_CHARACTERS_PER_REALM];
}
+ m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] = sConfig.GetIntDefault("HeroicCharactersPerRealm", 1);
+ if(int32(m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM]) < 0 || m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] > 10)
+ {
+ sLog.outError("HeroicCharactersPerRealm (%i) must be in range 0..10. Set to 1.",m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM]);
+ m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] = 1;
+ }
+
+ m_configs[CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING] = sConfig.GetIntDefault("MinLevelForHeroicCharacterCreating", 55);
+
m_configs[CONFIG_SKIP_CINEMATICS] = sConfig.GetIntDefault("SkipCinematics", 0);
- if(m_configs[CONFIG_SKIP_CINEMATICS] < 0 || m_configs[CONFIG_SKIP_CINEMATICS] > 2)
+ if(int32(m_configs[CONFIG_SKIP_CINEMATICS]) < 0 || m_configs[CONFIG_SKIP_CINEMATICS] > 2)
{
sLog.outError("SkipCinematics (%i) must be in range 0..2. Set to 0.",m_configs[CONFIG_SKIP_CINEMATICS]);
m_configs[CONFIG_SKIP_CINEMATICS] = 0;
@@ -660,12 +673,12 @@ void World::LoadConfigSettings(bool reload)
if(reload)
{
- uint32 val = sConfig.GetIntDefault("MaxPlayerLevel", 60);
+ uint32 val = sConfig.GetIntDefault("MaxPlayerLevel", 80);
if(val!=m_configs[CONFIG_MAX_PLAYER_LEVEL])
sLog.outError("MaxPlayerLevel option can't be changed at config reload, using current value (%u).",m_configs[CONFIG_MAX_PLAYER_LEVEL]);
}
else
- m_configs[CONFIG_MAX_PLAYER_LEVEL] = sConfig.GetIntDefault("MaxPlayerLevel", 60);
+ m_configs[CONFIG_MAX_PLAYER_LEVEL] = sConfig.GetIntDefault("MaxPlayerLevel", 80);
if(m_configs[CONFIG_MAX_PLAYER_LEVEL] > MAX_LEVEL)
{
@@ -685,8 +698,22 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_START_PLAYER_LEVEL] = m_configs[CONFIG_MAX_PLAYER_LEVEL];
}
+ m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = sConfig.GetIntDefault("StartHeroicPlayerLevel", 55);
+ if(m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] < 1)
+ {
+ sLog.outError("StartHeroicPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to 55.",
+ m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL]);
+ m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = 55;
+ }
+ else if(m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] > m_configs[CONFIG_MAX_PLAYER_LEVEL])
+ {
+ sLog.outError("StartHeroicPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to %u.",
+ m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL]);
+ m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = m_configs[CONFIG_MAX_PLAYER_LEVEL];
+ }
+
m_configs[CONFIG_START_PLAYER_MONEY] = sConfig.GetIntDefault("StartPlayerMoney", 0);
- if(m_configs[CONFIG_START_PLAYER_MONEY] < 0)
+ if(int32(m_configs[CONFIG_START_PLAYER_MONEY]) < 0)
{
sLog.outError("StartPlayerMoney (%i) must be in range 0..%u. Set to %u.",m_configs[CONFIG_START_PLAYER_MONEY],MAX_MONEY_AMOUNT,0);
m_configs[CONFIG_START_PLAYER_MONEY] = 0;
@@ -699,18 +726,18 @@ void World::LoadConfigSettings(bool reload)
}
m_configs[CONFIG_MAX_HONOR_POINTS] = sConfig.GetIntDefault("MaxHonorPoints", 75000);
- if(m_configs[CONFIG_MAX_HONOR_POINTS] < 0)
+ if(int32(m_configs[CONFIG_MAX_HONOR_POINTS]) < 0)
{
sLog.outError("MaxHonorPoints (%i) can't be negative. Set to 0.",m_configs[CONFIG_MAX_HONOR_POINTS]);
m_configs[CONFIG_MAX_HONOR_POINTS] = 0;
}
m_configs[CONFIG_START_HONOR_POINTS] = sConfig.GetIntDefault("StartHonorPoints", 0);
- if(m_configs[CONFIG_START_HONOR_POINTS] < 0)
+ if(int32(m_configs[CONFIG_START_HONOR_POINTS]) < 0)
{
sLog.outError("StartHonorPoints (%i) must be in range 0..MaxHonorPoints(%u). Set to %u.",
m_configs[CONFIG_START_HONOR_POINTS],m_configs[CONFIG_MAX_HONOR_POINTS],0);
- m_configs[CONFIG_MAX_HONOR_POINTS] = 0;
+ m_configs[CONFIG_START_HONOR_POINTS] = 0;
}
else if(m_configs[CONFIG_START_HONOR_POINTS] > m_configs[CONFIG_MAX_HONOR_POINTS])
{
@@ -720,14 +747,14 @@ void World::LoadConfigSettings(bool reload)
}
m_configs[CONFIG_MAX_ARENA_POINTS] = sConfig.GetIntDefault("MaxArenaPoints", 5000);
- if(m_configs[CONFIG_MAX_ARENA_POINTS] < 0)
+ if(int32(m_configs[CONFIG_MAX_ARENA_POINTS]) < 0)
{
sLog.outError("MaxArenaPoints (%i) can't be negative. Set to 0.",m_configs[CONFIG_MAX_ARENA_POINTS]);
m_configs[CONFIG_MAX_ARENA_POINTS] = 0;
}
m_configs[CONFIG_START_ARENA_POINTS] = sConfig.GetIntDefault("StartArenaPoints", 0);
- if(m_configs[CONFIG_START_ARENA_POINTS] < 0)
+ if(int32(m_configs[CONFIG_START_ARENA_POINTS]) < 0)
{
sLog.outError("StartArenaPoints (%i) must be in range 0..MaxArenaPoints(%u). Set to %u.",
m_configs[CONFIG_START_ARENA_POINTS],m_configs[CONFIG_MAX_ARENA_POINTS],0);
@@ -745,27 +772,25 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_INSTANCE_IGNORE_LEVEL] = sConfig.GetBoolDefault("Instance.IgnoreLevel", false);
m_configs[CONFIG_INSTANCE_IGNORE_RAID] = sConfig.GetBoolDefault("Instance.IgnoreRaid", false);
- m_configs[CONFIG_BATTLEGROUND_CAST_DESERTER] = sConfig.GetBoolDefault("Battleground.CastDeserter", true);
- m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.Enable", true);
- m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.PlayerOnly", false);
-
m_configs[CONFIG_CAST_UNSTUCK] = sConfig.GetBoolDefault("CastUnstuck", true);
m_configs[CONFIG_INSTANCE_RESET_TIME_HOUR] = sConfig.GetIntDefault("Instance.ResetTimeHour", 4);
- m_configs[CONFIG_INSTANCE_UNLOAD_DELAY] = sConfig.GetIntDefault("Instance.UnloadDelay", 1800000);
+ m_configs[CONFIG_INSTANCE_UNLOAD_DELAY] = sConfig.GetIntDefault("Instance.UnloadDelay", 30 * MINUTE * IN_MILISECONDS);
m_configs[CONFIG_MAX_PRIMARY_TRADE_SKILL] = sConfig.GetIntDefault("MaxPrimaryTradeSkill", 2);
m_configs[CONFIG_MIN_PETITION_SIGNS] = sConfig.GetIntDefault("MinPetitionSigns", 9);
if(m_configs[CONFIG_MIN_PETITION_SIGNS] > 9)
{
- sLog.outError("MinPetitionSigns (%i) must be in range 0..9. Set to 9.",m_configs[CONFIG_MIN_PETITION_SIGNS]);
+ sLog.outError("MinPetitionSigns (%i) must be in range 0..9. Set to 9.", m_configs[CONFIG_MIN_PETITION_SIGNS]);
m_configs[CONFIG_MIN_PETITION_SIGNS] = 9;
}
- m_configs[CONFIG_GM_LOGIN_STATE] = sConfig.GetIntDefault("GM.LoginState",2);
- m_configs[CONFIG_GM_CHAT] = sConfig.GetIntDefault("GM.Chat",2);
- m_configs[CONFIG_GM_WISPERING_TO] = sConfig.GetIntDefault("GM.WhisperingTo",2);
- m_configs[CONFIG_GM_IN_GM_LIST] = sConfig.GetBoolDefault("GM.InGMList",false);
- m_configs[CONFIG_GM_IN_WHO_LIST] = sConfig.GetBoolDefault("GM.InWhoList",false);
+ m_configs[CONFIG_GM_LOGIN_STATE] = sConfig.GetIntDefault("GM.LoginState", 2);
+ m_configs[CONFIG_GM_VISIBLE_STATE] = sConfig.GetIntDefault("GM.Visible", 2);
+ //m_configs[CONFIG_GM_ACCEPT_TICKETS] = sConfig.GetIntDefault("GM.AcceptTickets", 2);
+ m_configs[CONFIG_GM_CHAT] = sConfig.GetIntDefault("GM.Chat", 2);
+ m_configs[CONFIG_GM_WISPERING_TO] = sConfig.GetIntDefault("GM.WhisperingTo", 2);
+ m_configs[CONFIG_GM_IN_GM_LIST] = sConfig.GetBoolDefault("GM.InGMList", false);
+ m_configs[CONFIG_GM_IN_WHO_LIST] = sConfig.GetBoolDefault("GM.InWhoList", false);
m_configs[CONFIG_GM_LOG_TRADE] = sConfig.GetBoolDefault("GM.LogTrade", false);
m_configs[CONFIG_START_GM_LEVEL] = sConfig.GetIntDefault("GM.StartLevel", 1);
if(m_configs[CONFIG_START_GM_LEVEL] < m_configs[CONFIG_START_PLAYER_LEVEL])
@@ -779,23 +804,41 @@ void World::LoadConfigSettings(bool reload)
sLog.outError("GM.StartLevel (%i) must be in range 1..%u. Set to %u.", m_configs[CONFIG_START_GM_LEVEL], MAX_LEVEL, MAX_LEVEL);
m_configs[CONFIG_START_GM_LEVEL] = MAX_LEVEL;
}
+ m_configs[CONFIG_GM_LOWER_SECURITY] = sConfig.GetBoolDefault("GM.LowerSecurity", false);
+ m_configs[CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS] = sConfig.GetBoolDefault("GM.AllowAchievementGain", true);
m_configs[CONFIG_GROUP_VISIBILITY] = sConfig.GetIntDefault("Visibility.GroupMode",0);
m_configs[CONFIG_MAIL_DELIVERY_DELAY] = sConfig.GetIntDefault("MailDeliveryDelay",HOUR);
m_configs[CONFIG_UPTIME_UPDATE] = sConfig.GetIntDefault("UpdateUptimeInterval", 10);
- if(m_configs[CONFIG_UPTIME_UPDATE]<=0)
+ if(int32(m_configs[CONFIG_UPTIME_UPDATE])<=0)
{
sLog.outError("UpdateUptimeInterval (%i) must be > 0, set to default 10.",m_configs[CONFIG_UPTIME_UPDATE]);
m_configs[CONFIG_UPTIME_UPDATE] = 10;
}
if(reload)
{
- m_timers[WUPDATE_UPTIME].SetInterval(m_configs[CONFIG_UPTIME_UPDATE]*MINUTE*1000);
+ m_timers[WUPDATE_UPTIME].SetInterval(m_configs[CONFIG_UPTIME_UPDATE]*MINUTE*IN_MILISECONDS);
m_timers[WUPDATE_UPTIME].Reset();
}
+ // log db cleanup interval
+ m_configs[CONFIG_LOGDB_CLEARINTERVAL] = sConfig.GetIntDefault("LogDB.Opt.ClearInterval", 10);
+ if(int32(m_configs[CONFIG_LOGDB_CLEARINTERVAL]) <= 0)
+ {
+ sLog.outError("LogDB.Opt.ClearInterval (%i) must be > 0, set to default 10.", m_configs[CONFIG_LOGDB_CLEARINTERVAL]);
+ m_configs[CONFIG_LOGDB_CLEARINTERVAL] = 10;
+ }
+ if(reload)
+ {
+ m_timers[WUPDATE_CLEANDB].SetInterval(m_configs[CONFIG_LOGDB_CLEARINTERVAL] * MINUTE * IN_MILISECONDS);
+ m_timers[WUPDATE_CLEANDB].Reset();
+ }
+ m_configs[CONFIG_LOGDB_CLEARTIME] = sConfig.GetIntDefault("LogDB.Opt.ClearTime", 1209600); // 14 days default
+ sLog.outString("Will clear `logs` table of entries older than %i seconds every %u minutes.",
+ m_configs[CONFIG_LOGDB_CLEARTIME], m_configs[CONFIG_LOGDB_CLEARINTERVAL]);
+
m_configs[CONFIG_SKILL_CHANCE_ORANGE] = sConfig.GetIntDefault("SkillChance.Orange",100);
m_configs[CONFIG_SKILL_CHANCE_YELLOW] = sConfig.GetIntDefault("SkillChance.Yellow",75);
m_configs[CONFIG_SKILL_CHANCE_GREEN] = sConfig.GetIntDefault("SkillChance.Green",25);
@@ -805,6 +848,7 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_SKILL_CHANCE_SKINNING_STEPS] = sConfig.GetIntDefault("SkillChance.SkinningSteps",75);
m_configs[CONFIG_SKILL_PROSPECTING] = sConfig.GetBoolDefault("SkillChance.Prospecting",false);
+ m_configs[CONFIG_SKILL_MILLING] = sConfig.GetBoolDefault("SkillChance.Milling",false);
m_configs[CONFIG_SKILL_GAIN_CRAFTING] = sConfig.GetIntDefault("SkillGain.Crafting", 1);
if(m_configs[CONFIG_SKILL_GAIN_CRAFTING] < 0)
@@ -878,21 +922,23 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_DETECT_POS_COLLISION] = sConfig.GetBoolDefault("DetectPosCollision", true);
- m_configs[CONFIG_RESTRICTED_LFG_CHANNEL] = sConfig.GetBoolDefault("Channel.RestrictedLfg", true);
+ m_configs[CONFIG_RESTRICTED_LFG_CHANNEL] = sConfig.GetBoolDefault("Channel.RestrictedLfg", true);
m_configs[CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL] = sConfig.GetBoolDefault("Channel.SilentlyGMJoin", false);
- m_configs[CONFIG_TALENTS_INSPECTING] = sConfig.GetBoolDefault("TalentsInspecting", true);
+ m_configs[CONFIG_TALENTS_INSPECTING] = sConfig.GetBoolDefault("TalentsInspecting", true);
m_configs[CONFIG_CHAT_FAKE_MESSAGE_PREVENTING] = sConfig.GetBoolDefault("ChatFakeMessagePreventing", false);
- m_configs[CONFIG_CORPSE_DECAY_NORMAL] = sConfig.GetIntDefault("Corpse.Decay.NORMAL", 60);
- m_configs[CONFIG_CORPSE_DECAY_RARE] = sConfig.GetIntDefault("Corpse.Decay.RARE", 300);
- m_configs[CONFIG_CORPSE_DECAY_ELITE] = sConfig.GetIntDefault("Corpse.Decay.ELITE", 300);
+ m_configs[CONFIG_CORPSE_DECAY_NORMAL] = sConfig.GetIntDefault("Corpse.Decay.NORMAL", 60);
+ m_configs[CONFIG_CORPSE_DECAY_RARE] = sConfig.GetIntDefault("Corpse.Decay.RARE", 300);
+ m_configs[CONFIG_CORPSE_DECAY_ELITE] = sConfig.GetIntDefault("Corpse.Decay.ELITE", 300);
m_configs[CONFIG_CORPSE_DECAY_RAREELITE] = sConfig.GetIntDefault("Corpse.Decay.RAREELITE", 300);
m_configs[CONFIG_CORPSE_DECAY_WORLDBOSS] = sConfig.GetIntDefault("Corpse.Decay.WORLDBOSS", 3600);
- m_configs[CONFIG_DEATH_SICKNESS_LEVEL] = sConfig.GetIntDefault("Death.SicknessLevel", 11);
+ m_configs[CONFIG_DEATH_SICKNESS_LEVEL] = sConfig.GetIntDefault ("Death.SicknessLevel", 11);
m_configs[CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP] = sConfig.GetBoolDefault("Death.CorpseReclaimDelay.PvP", true);
m_configs[CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE] = sConfig.GetBoolDefault("Death.CorpseReclaimDelay.PvE", true);
+ m_configs[CONFIG_DEATH_BONES_WORLD] = sConfig.GetBoolDefault("Death.Bones.World", true);
+ m_configs[CONFIG_DEATH_BONES_BG_OR_ARENA] = sConfig.GetBoolDefault("Death.Bones.BattlegroundOrArena", true);
m_configs[CONFIG_THREAT_RADIUS] = sConfig.GetIntDefault("ThreatRadius", 60);
@@ -904,12 +950,22 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_LISTEN_RANGE_TEXTEMOTE] = sConfig.GetIntDefault("ListenRange.TextEmote", 25);
m_configs[CONFIG_LISTEN_RANGE_YELL] = sConfig.GetIntDefault("ListenRange.Yell", 300);
- m_configs[CONFIG_ARENA_MAX_RATING_DIFFERENCE] = sConfig.GetIntDefault("Arena.MaxRatingDifference", 0);
- m_configs[CONFIG_ARENA_RATING_DISCARD_TIMER] = sConfig.GetIntDefault("Arena.RatingDiscardTimer",300000);
- m_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS] = sConfig.GetBoolDefault("Arena.AutoDistributePoints", false);
- m_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS] = sConfig.GetIntDefault("Arena.AutoDistributeInterval", 7);
+ m_configs[CONFIG_BATTLEGROUND_CAST_DESERTER] = sConfig.GetBoolDefault("Battleground.CastDeserter", true);
+ m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.Enable", false);
+ m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.PlayerOnly", false);
+ m_configs[CONFIG_BATTLEGROUND_INVITATION_TYPE] = sConfig.GetIntDefault ("Battleground.InvitationType", 0);
+ m_configs[CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER] = sConfig.GetIntDefault ("BattleGround.PrematureFinishTimer", 5 * MINUTE * IN_MILISECONDS);
+ m_configs[CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH] = sConfig.GetIntDefault ("BattleGround.PremadeGroupWaitForMatch", 30 * MINUTE * IN_MILISECONDS);
+ m_configs[CONFIG_ARENA_MAX_RATING_DIFFERENCE] = sConfig.GetIntDefault ("Arena.MaxRatingDifference", 150);
+ m_configs[CONFIG_ARENA_RATING_DISCARD_TIMER] = sConfig.GetIntDefault ("Arena.RatingDiscardTimer", 10 * MINUTE * IN_MILISECONDS);
+ m_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS] = sConfig.GetBoolDefault("Arena.AutoDistributePoints", false);
+ m_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS] = sConfig.GetIntDefault ("Arena.AutoDistributeInterval", 7);
+ m_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE] = sConfig.GetBoolDefault("Arena.QueueAnnouncer.Enable", false);
+ m_configs[CONFIG_ARENA_SEASON_ID] = sConfig.GetIntDefault ("Arena.ArenaSeason.ID", 1);
+ m_configs[CONFIG_ARENA_SEASON_IN_PROGRESS] = sConfig.GetBoolDefault("Arena.ArenaSeason.InProgress", true);
+
+ m_configs[CONFIG_OFFHAND_CHECK_AT_TALENTS_RESET] = sConfig.GetBoolDefault("OffhandCheckAtTalentsReset", false);
- m_configs[CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER] = sConfig.GetIntDefault("BattleGround.PrematureFinishTimer", 0);
m_configs[CONFIG_INSTANT_LOGOUT] = sConfig.GetIntDefault("InstantLogout", SEC_MODERATOR);
m_VisibleUnitGreyDistance = sConfig.GetFloatDefault("Visibility.Distance.Grey.Unit", 1);
@@ -950,7 +1006,7 @@ void World::LoadConfigSettings(bool reload)
}
m_MaxVisibleDistance = std::max(m_MaxVisibleDistanceForPlayer, m_MaxVisibleDistanceForCreature);
- m_MaxVisibleDistanceForObject = sConfig.GetFloatDefault("Visibility.Distance.Gameobject", DEFAULT_VISIBILITY_DISTANCE);
+ m_MaxVisibleDistanceForObject = sConfig.GetFloatDefault("Visibility.Distance.Object", DEFAULT_VISIBILITY_DISTANCE);
if(m_MaxVisibleDistanceForObject < INTERACTION_DISTANCE)
{
sLog.outError("Visibility.Distance.Object can't be less max aggro radius %f",float(INTERACTION_DISTANCE));
@@ -1005,7 +1061,6 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_MAX_WHO] = sConfig.GetIntDefault("MaxWhoListReturns", 49);
- m_configs[CONFIG_PREMATURE_BG_REWARD] = sConfig.GetBoolDefault("Battleground.PrematureReward", true);
m_configs[CONFIG_BG_START_MUSIC] = sConfig.GetBoolDefault("MusicInBattleground", false);
m_configs[CONFIG_START_ALL_SPELLS] = sConfig.GetBoolDefault("PlayerStart.AllSpells", false);
m_configs[CONFIG_HONOR_AFTER_DUEL] = sConfig.GetIntDefault("HonorPointsAfterDuel", 0);
@@ -1038,6 +1093,17 @@ void World::LoadConfigSettings(bool reload)
token = strtok(NULL,delim);
}
delete[] forbiddenMaps;
+
+ // chat logging
+ m_configs[CONFIG_CHATLOG_CHANNEL] = sConfig.GetBoolDefault("ChatLogs.Channel", false);
+ m_configs[CONFIG_CHATLOG_WHISPER] = sConfig.GetBoolDefault("ChatLogs.Whisper", false);
+ m_configs[CONFIG_CHATLOG_SYSCHAN] = sConfig.GetBoolDefault("ChatLogs.SysChan", false);
+ m_configs[CONFIG_CHATLOG_PARTY] = sConfig.GetBoolDefault("ChatLogs.Party", false);
+ m_configs[CONFIG_CHATLOG_RAID] = sConfig.GetBoolDefault("ChatLogs.Raid", false);
+ m_configs[CONFIG_CHATLOG_GUILD] = sConfig.GetBoolDefault("ChatLogs.Guild", false);
+ m_configs[CONFIG_CHATLOG_PUBLIC] = sConfig.GetBoolDefault("ChatLogs.Public", false);
+ m_configs[CONFIG_CHATLOG_ADDON] = sConfig.GetBoolDefault("ChatLogs.Addon", false);
+ m_configs[CONFIG_CHATLOG_BGROUND] = sConfig.GetBoolDefault("ChatLogs.BattleGround", false);
}
/// Initialize the World
@@ -1068,7 +1134,7 @@ void World::SetInitialWorldSettings()
}
///- Loading strings. Getting no records means core load has to be canceled because no error message can be output.
- sLog.outString( "" );
+ sLog.outString();
sLog.outString( "Loading Trinity strings..." );
if (!objmgr.LoadTrinityStrings())
exit(1); // Error message displayed in function already
@@ -1092,7 +1158,7 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Script Names...");
objmgr.LoadScriptNames();
- sLog.outString( "Loading InstanceTemplate" );
+ sLog.outString( "Loading InstanceTemplate..." );
objmgr.LoadInstanceTemplate();
sLog.outString( "Loading SkillLineAbilityMultiMap Data..." );
@@ -1100,11 +1166,12 @@ void World::SetInitialWorldSettings()
///- Clean up and pack instances
sLog.outString( "Cleaning up instances..." );
- sInstanceSaveManager.CleanupInstances(); // must be called before `creature_respawn`/`gameobject_respawn` tables
+ sInstanceSaveManager.CleanupInstances(); // must be called before `creature_respawn`/`gameobject_respawn` tables
sLog.outString( "Packing instances..." );
sInstanceSaveManager.PackInstances();
+ sLog.outString();
sLog.outString( "Loading Localization strings..." );
objmgr.LoadCreatureLocales();
objmgr.LoadGameObjectLocales();
@@ -1113,7 +1180,10 @@ void World::SetInitialWorldSettings()
objmgr.LoadNpcTextLocales();
objmgr.LoadPageTextLocales();
objmgr.LoadNpcOptionLocales();
+ objmgr.LoadPointOfInterestLocales();
objmgr.SetDBCLocaleIndex(GetDefaultDbcLocale()); // Get once for all the locale index of DBC language (console/broadcasts)
+ sLog.outString( ">>> Localization strings loaded" );
+ sLog.outString();
sLog.outString( "Loading Page Texts..." );
objmgr.LoadPageTexts();
@@ -1142,6 +1212,9 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Spell Proc Event conditions..." );
spellmgr.LoadSpellProcEvents();
+ sLog.outString( "Loading Spell Bonus Data..." );
+ spellmgr.LoadSpellBonusess();
+
sLog.outString( "Loading Aggro Spells Definitions...");
spellmgr.LoadSpellThreats();
@@ -1172,6 +1245,9 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Creature Reputation OnKill Data..." );
objmgr.LoadReputationOnKill();
+ sLog.outString( "Loading Points Of Interest Data..." );
+ objmgr.LoadPointsOfInterest();
+
sLog.outString( "Loading Pet Create Spells..." );
objmgr.LoadPetCreateSpells();
@@ -1182,7 +1258,10 @@ void World::SetInitialWorldSettings()
objmgr.LoadCreatureLinkedRespawn(); // must be after LoadCreatures()
sLog.outString( "Loading Creature Addon Data..." );
+ sLog.outString();
objmgr.LoadCreatureAddons(); // must be after LoadCreatureTemplates() and LoadCreatures()
+ sLog.outString( ">>> Creature Addon Data loaded" );
+ sLog.outString();
sLog.outString( "Loading Creature Respawn Data..." ); // must be after PackInstances()
objmgr.LoadCreatureRespawnTimes();
@@ -1193,8 +1272,14 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Gameobject Respawn Data..." ); // must be after PackInstances()
objmgr.LoadGameobjectRespawnTimes();
+ sLog.outString( "Loading Objects Pooling Data...");
+ poolhandler.LoadFromDB();
+
sLog.outString( "Loading Game Event Data...");
+ sLog.outString();
gameeventmgr.LoadFromDB();
+ sLog.outString( ">>> Game Event Data loaded" );
+ sLog.outString();
sLog.outString( "Loading Weather Data..." );
objmgr.LoadWeatherZoneChances();
@@ -1203,7 +1288,13 @@ void World::SetInitialWorldSettings()
objmgr.LoadQuests(); // must be loaded after DBCs, creature_template, item_template, gameobject tables
sLog.outString( "Loading Quests Relations..." );
+ sLog.outString();
objmgr.LoadQuestRelations(); // must be after quest load
+ sLog.outString( ">>> Quests Relations loaded" );
+ sLog.outString();
+
+ sLog.outString( "Loading SpellArea Data..." ); // must be after quest load
+ spellmgr.LoadSpellAreas();
sLog.outString( "Loading AreaTrigger definitions..." );
objmgr.LoadAreaTriggerTeleports();
@@ -1232,14 +1323,20 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading spell pet auras..." );
spellmgr.LoadSpellPetAuras();
+ sLog.outString( "Loading pet levelup spells..." );
+ spellmgr.LoadPetLevelupSpellMap();
+
sLog.outString( "Loading spell extra attributes...(TODO)" );
spellmgr.LoadSpellCustomAttr();
sLog.outString( "Loading linked spells..." );
spellmgr.LoadSpellLinked();
- sLog.outString( "Loading player Create Info & Level Stats..." );
+ sLog.outString( "Loading Player Create Info & Level Stats..." );
+ sLog.outString();
objmgr.LoadPlayerInfo();
+ sLog.outString( ">>> Player Create Info & Level Stats loaded" );
+ sLog.outString();
sLog.outString( "Loading Exploration BaseXP Data..." );
objmgr.LoadExplorationBaseXP();
@@ -1260,7 +1357,10 @@ void World::SetInitialWorldSettings()
objmgr.LoadSpellDisabledEntrys();
sLog.outString( "Loading Loot Tables..." );
+ sLog.outString();
LoadLootTables();
+ sLog.outString( ">>> Loot Tables loaded" );
+ sLog.outString();
sLog.outString( "Loading Skill Discovery Table..." );
LoadSkillDiscoveryTable();
@@ -1271,10 +1371,24 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Skill Fishing base level requirements..." );
objmgr.LoadFishingBaseSkillLevel();
+ sLog.outString( "Loading Achievements..." );
+ sLog.outString();
+ achievementmgr.LoadAchievementReferenceList();
+ achievementmgr.LoadAchievementCriteriaList();
+ achievementmgr.LoadAchievementCriteriaData();
+ achievementmgr.LoadRewards();
+ achievementmgr.LoadRewardLocales();
+ achievementmgr.LoadCompletedAchievements();
+ sLog.outString( ">>> Achievements loaded" );
+ sLog.outString();
+
///- Load dynamic data tables from the database
sLog.outString( "Loading Auctions..." );
+ sLog.outString();
auctionmgr.LoadAuctionItems();
auctionmgr.LoadAuctions();
+ sLog.outString( ">>> Auctions loaded" );
+ sLog.outString();
sLog.outString( "Loading Guilds..." );
objmgr.LoadGuilds();
@@ -1288,11 +1402,11 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading ReservedNames..." );
objmgr.LoadReservedPlayersNames();
- sLog.outString( "Loading GameObject for quests..." );
+ sLog.outString( "Loading GameObjects for quests..." );
objmgr.LoadGameObjectForQuests();
sLog.outString( "Loading BattleMasters..." );
- objmgr.LoadBattleMastersEntry();
+ sBattleGroundMgr.LoadBattleMastersEntry();
sLog.outString( "Loading GameTeleports..." );
objmgr.LoadGameTele();
@@ -1303,13 +1417,14 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Npc Options..." );
objmgr.LoadNpcOptions();
- sLog.outString( "Loading vendors..." );
+ sLog.outString( "Loading Vendors..." );
objmgr.LoadVendors(); // must be after load CreatureTemplate and ItemTemplate
- sLog.outString( "Loading trainers..." );
+ sLog.outString( "Loading Trainers..." );
objmgr.LoadTrainerSpell(); // must be after load CreatureTemplate
sLog.outString( "Loading Waypoints..." );
+ sLog.outString();
WaypointMgr.Load();
sLog.outString( "Loading Creature Formations..." );
@@ -1324,16 +1439,28 @@ void World::SetInitialWorldSettings()
///- Load and initialize scripts
sLog.outString( "Loading Scripts..." );
+ sLog.outString();
objmgr.LoadQuestStartScripts(); // must be after load Creature/Gameobject(Template/Data) and QuestTemplate
objmgr.LoadQuestEndScripts(); // must be after load Creature/Gameobject(Template/Data) and QuestTemplate
objmgr.LoadSpellScripts(); // must be after load Creature/Gameobject(Template/Data)
objmgr.LoadGameObjectScripts(); // must be after load Creature/Gameobject(Template/Data)
objmgr.LoadEventScripts(); // must be after load Creature/Gameobject(Template/Data)
objmgr.LoadWaypointScripts();
+ sLog.outString( ">>> Scripts loaded" );
+ sLog.outString();
sLog.outString( "Loading Scripts text locales..." ); // must be after Load*Scripts calls
objmgr.LoadDbScriptStrings();
+ sLog.outString( "Loading CreatureEventAI Texts...");
+ CreatureEAI_Mgr.LoadCreatureEventAI_Texts();
+
+ sLog.outString( "Loading CreatureEventAI Summons...");
+ CreatureEAI_Mgr.LoadCreatureEventAI_Summons();
+
+ sLog.outString( "Loading CreatureEventAI Scripts...");
+ CreatureEAI_Mgr.LoadCreatureEventAI_Scripts();
+
sLog.outString( "Initializing Scripts..." );
if(!LoadScriptingModule())
exit(1);
@@ -1351,23 +1478,26 @@ void World::SetInitialWorldSettings()
sprintf( isoDate, "%04d-%02d-%02d %02d:%02d:%02d",
local.tm_year+1900, local.tm_mon+1, local.tm_mday, local.tm_hour, local.tm_min, local.tm_sec);
- WorldDatabase.PExecute("INSERT INTO uptime (startstring, starttime, uptime) VALUES('%s', " I64FMTD ", 0)",
- isoDate, uint64(m_startTime));
+ LoginDatabase.PExecute("INSERT INTO uptime (realmid, starttime, startstring, uptime) VALUES('%u', " I64FMTD ", '%s', 0)",
+ realmID, uint64(m_startTime), isoDate);
m_timers[WUPDATE_OBJECTS].SetInterval(0);
m_timers[WUPDATE_SESSIONS].SetInterval(0);
- m_timers[WUPDATE_WEATHERS].SetInterval(1000);
- m_timers[WUPDATE_AUCTIONS].SetInterval(MINUTE*1000); //set auction update interval to 1 minute
- m_timers[WUPDATE_UPTIME].SetInterval(m_configs[CONFIG_UPTIME_UPDATE]*MINUTE*1000);
+ m_timers[WUPDATE_WEATHERS].SetInterval(1*IN_MILISECONDS);
+ m_timers[WUPDATE_AUCTIONS].SetInterval(MINUTE*IN_MILISECONDS);
+ m_timers[WUPDATE_UPTIME].SetInterval(m_configs[CONFIG_UPTIME_UPDATE]*MINUTE*IN_MILISECONDS);
//Update "uptime" table based on configuration entry in minutes.
- m_timers[WUPDATE_CORPSES].SetInterval(20*MINUTE*1000); //erase corpses every 20 minutes
+ m_timers[WUPDATE_CORPSES].SetInterval(20*MINUTE*IN_MILISECONDS);
+ //erase corpses every 20 minutes
+ m_timers[WUPDATE_CLEANDB].SetInterval(m_configs[CONFIG_LOGDB_CLEARINTERVAL]*MINUTE*IN_MILISECONDS);
+ // clean logs table every 14 days by default
//to set mailtimer to return mails every day between 4 and 5 am
//mailtimer is increased when updating auctions
//one second is 1000 -(tested on win system)
- mail_timer = ((((localtime( &m_gameTime )->tm_hour + 20) % 24)* HOUR * 1000) / m_timers[WUPDATE_AUCTIONS].GetInterval() );
+ mail_timer = ((((localtime( &m_gameTime )->tm_hour + 20) % 24)* HOUR * IN_MILISECONDS) / m_timers[WUPDATE_AUCTIONS].GetInterval() );
//1440
- mail_timer_expires = ( (DAY * 1000) / (m_timers[WUPDATE_AUCTIONS].GetInterval()));
+ mail_timer_expires = ( (DAY * IN_MILISECONDS) / (m_timers[WUPDATE_AUCTIONS].GetInterval()));
sLog.outDebug("Mail timer set to: %u, mail return is called every %u minutes", mail_timer, mail_timer_expires);
///- Initilize static helper structures
@@ -1400,6 +1530,9 @@ void World::SetInitialWorldSettings()
sLog.outString("Calculate next daily quest reset time..." );
InitDailyQuestResetTime();
+ sLog.outString("Starting objects Pooling system..." );
+ poolhandler.Initialize();
+
sLog.outString("Starting Game Event system..." );
uint32 nextGameEvent = gameeventmgr.Initialize();
m_timers[WUPDATE_EVENTS].SetInterval(nextGameEvent); //depend on next event
@@ -1407,6 +1540,19 @@ void World::SetInitialWorldSettings()
sLog.outString("Initialize AuctionHouseBot...");
AuctionHouseBotInit();
+ // possibly enable db logging; avoid massive startup spam by doing it here.
+ if (sLog.GetLogDBLater())
+ {
+ sLog.outString("Enabling database logging...");
+ sLog.SetLogDBLater(false);
+ sLog.SetLogDB(true);
+ }
+ else
+ {
+ sLog.SetLogDB(false);
+ sLog.SetLogDBLater(false);
+ }
+
sLog.outString( "WORLD: World initialized" );
}
@@ -1451,6 +1597,7 @@ void World::DetectDBCLang()
m_defaultDbcLocale = LocaleConstant(default_locale);
sLog.outString("Using %s DBC Locale as default. All available DBC locales: %s",localeNames[m_defaultDbcLocale],availableLocalsStr.empty() ? "<none>" : availableLocalsStr.c_str());
+ sLog.outString();
}
void World::RecordTimeDiff(const char *text, ...)
@@ -1480,7 +1627,7 @@ void World::RecordTimeDiff(const char *text, ...)
}
/// Update the World !
-void World::Update(time_t diff)
+void World::Update(uint32 diff)
{
m_updateTime = uint32(diff);
if(m_configs[CONFIG_INTERVAL_LOG_UPDATE])
@@ -1499,7 +1646,7 @@ void World::Update(time_t diff)
}
///- Update the different timers
- for(int i = 0; i < WUPDATE_COUNT; i++)
+ for(int i = 0; i < WUPDATE_COUNT; ++i)
if(m_timers[i].GetCurrent()>=0)
m_timers[i].Update(diff);
else m_timers[i].SetCurrent(0);
@@ -1527,7 +1674,8 @@ void World::Update(time_t diff)
mail_timer = 0;
objmgr.ReturnOrDeleteOldMails(true);
}
- ///-Handle expired auctions
+
+ ///- Handle expired auctions
auctionmgr.Update();
}
@@ -1566,10 +1714,24 @@ void World::Update(time_t diff)
if (m_timers[WUPDATE_UPTIME].Passed())
{
uint32 tmpDiff = (m_gameTime - m_startTime);
- uint32 maxClientsNum = sWorld.GetMaxActiveSessionCount();
+ uint32 maxClientsNum = GetMaxActiveSessionCount();
m_timers[WUPDATE_UPTIME].Reset();
- WorldDatabase.PExecute("UPDATE uptime SET uptime = %d, maxplayers = %d WHERE starttime = " I64FMTD, tmpDiff, maxClientsNum, uint64(m_startTime));
+ LoginDatabase.PExecute("UPDATE uptime SET uptime = %u, maxplayers = %u WHERE realmid = %u AND starttime = " I64FMTD, tmpDiff, maxClientsNum, realmID, uint64(m_startTime));
+ }
+
+ /// <li> Clean logs table
+ if(sWorld.getConfig(CONFIG_LOGDB_CLEARTIME) > 0) // if not enabled, ignore the timer
+ {
+ if (m_timers[WUPDATE_CLEANDB].Passed())
+ {
+ uint32 tmpDiff = (m_gameTime - m_startTime);
+ uint32 maxClientsNum = sWorld.GetMaxActiveSessionCount();
+
+ m_timers[WUPDATE_CLEANDB].Reset();
+ LoginDatabase.PExecute("DELETE FROM logs WHERE (time + %u) < "I64FMTD";",
+ sWorld.getConfig(CONFIG_LOGDB_CLEARTIME), uint64(time(0)));
+ }
}
/// <li> Handle all other objects
@@ -1721,6 +1883,9 @@ void World::ScriptsProcess()
case HIGHGUID_PET:
source = HashMapHolder<Pet>::Find(step.sourceGUID);
break;
+ case HIGHGUID_VEHICLE:
+ source = HashMapHolder<Vehicle>::Find(step.sourceGUID);
+ break;
case HIGHGUID_PLAYER:
source = HashMapHolder<Player>::Find(step.sourceGUID);
break;
@@ -1760,6 +1925,9 @@ void World::ScriptsProcess()
case HIGHGUID_PET:
target = HashMapHolder<Pet>::Find(step.targetGUID);
break;
+ case HIGHGUID_VEHICLE:
+ target = HashMapHolder<Vehicle>::Find(step.targetGUID);
+ break;
case HIGHGUID_PLAYER: // empty GUID case also
target = HashMapHolder<Player>::Find(step.targetGUID);
break;
@@ -1868,7 +2036,7 @@ void World::ScriptsProcess()
sLog.outError("SCRIPT_COMMAND_MOVE_TO call for non-creature (TypeId: %u), skipping.",source->GetTypeId());
break;
}
- ((Unit *)source)->SendMonsterMoveWithSpeed(step.script->x, step.script->y, step.script->z, ((Unit *)source)->GetUnitMovementFlags(), step.script->datalong2 );
+ ((Unit *)source)->SendMonsterMoveWithSpeed(step.script->x, step.script->y, step.script->z, step.script->datalong2 );
((Unit *)source)->GetMap()->CreatureRelocation(((Creature *)source), step.script->x, step.script->y, step.script->z, 0);
break;
case SCRIPT_COMMAND_FLAG_SET:
@@ -1990,8 +2158,8 @@ void World::ScriptsProcess()
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
- Trinity::GameObjectWithDbGUIDCheck go_check(*summoner,step.script->datalong);
- Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck> checker(go,go_check);
+ MaNGOS::GameObjectWithDbGUIDCheck go_check(*summoner,step.script->datalong);
+ MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(summoner, go,go_check);
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -2004,7 +2172,6 @@ void World::ScriptsProcess()
}
if( go->GetGoType()==GAMEOBJECT_TYPE_FISHINGNODE ||
- go->GetGoType()==GAMEOBJECT_TYPE_FISHINGNODE ||
go->GetGoType()==GAMEOBJECT_TYPE_DOOR ||
go->GetGoType()==GAMEOBJECT_TYPE_BUTTON ||
go->GetGoType()==GAMEOBJECT_TYPE_TRAP )
@@ -2051,25 +2218,25 @@ void World::ScriptsProcess()
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
- Trinity::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong);
- Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck> checker(door,go_check);
+ MaNGOS::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong);
+ MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(caster,door,go_check);
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(caster->GetMapId(), (Unit*)source));
- if ( !door )
+ if (!door)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR failed for gameobject(guid: %u).", step.script->datalong);
break;
}
- if ( door->GetGoType() != GAMEOBJECT_TYPE_DOOR )
+ if (door->GetGoType() != GAMEOBJECT_TYPE_DOOR)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR failed for non-door(GoType: %u).", door->GetGoType());
break;
}
- if( !door->GetGoState() )
+ if (door->GetGoState() != GO_STATE_READY)
break; //door already open
door->UseDoorOrButton(time_to_close);
@@ -2107,8 +2274,8 @@ void World::ScriptsProcess()
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
- Trinity::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong);
- Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck> checker(door,go_check);
+ MaNGOS::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong);
+ MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(caster,door,go_check);
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -2125,7 +2292,7 @@ void World::ScriptsProcess()
break;
}
- if( door->GetGoState() )
+ if( door->GetGoState() == GO_STATE_READY )
break; //door already closed
door->UseDoorOrButton(time_to_open);
@@ -2260,24 +2427,40 @@ void World::ScriptsProcess()
break;
}
- Object* cmdTarget = step.script->datalong2 ? source : target;
+ Object* cmdTarget = step.script->datalong2 & 0x01 ? source : target;
if(!cmdTarget)
{
- sLog.outError("SCRIPT_COMMAND_CAST_SPELL call for NULL %s.",step.script->datalong2 ? "source" : "target");
+ sLog.outError("SCRIPT_COMMAND_CAST_SPELL call for NULL %s.",step.script->datalong2 & 0x01 ? "source" : "target");
break;
}
if(!cmdTarget->isType(TYPEMASK_UNIT))
{
- sLog.outError("SCRIPT_COMMAND_CAST_SPELL %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 ? "source" : "target",cmdTarget->GetTypeId());
+ sLog.outError("SCRIPT_COMMAND_CAST_SPELL %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 & 0x01 ? "source" : "target",cmdTarget->GetTypeId());
break;
}
Unit* spellTarget = (Unit*)cmdTarget;
+ Object* cmdSource = step.script->datalong2 & 0x02 ? target : source;
+
+ if(!cmdSource)
+ {
+ sLog.outError("SCRIPT_COMMAND_CAST_SPELL call for NULL %s.",step.script->datalong2 & 0x02 ? "target" : "source");
+ break;
+ }
+
+ if(!cmdSource->isType(TYPEMASK_UNIT))
+ {
+ sLog.outError("SCRIPT_COMMAND_CAST_SPELL %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 & 0x02 ? "target" : "source", cmdSource->GetTypeId());
+ break;
+ }
+
+ Unit* spellSource = (Unit*)cmdSource;
+
//TODO: when GO cast implemented, code below must be updated accordingly to also allow GO spell cast
- ((Unit*)source)->CastSpell(spellTarget,step.script->datalong,false);
+ spellSource->CastSpell(spellTarget,step.script->datalong,false);
break;
}
@@ -2324,7 +2507,7 @@ void World::ScriptsProcess()
//sLog.outDebug("Attempting to find Creature: Db GUID: %i", step.script->datalong);
Trinity::CreatureWithDbGUIDCheck target_check(((Unit*)source), step.script->datalong);
- Trinity::CreatureSearcher<Trinity::CreatureWithDbGUIDCheck> checker(target,target_check);
+ Trinity::CreatureSearcher<Trinity::CreatureWithDbGUIDCheck> checker(((Unit*)source), target, target_check);
TypeContainerVisitor<Trinity::CreatureSearcher <Trinity::CreatureWithDbGUIDCheck>, GridTypeMapContainer > unit_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -2375,15 +2558,6 @@ void World::ScriptsProcess()
break;
}
- case SCRIPT_COMMAND_PLAYSOUND:
- {
- if(!source)
- break;
- //datalong sound_id, datalong2 onlyself
- ((WorldObject*)source)->SendPlaySound(step.script->datalong, step.script->datalong2);
- break;
- }
-
case SCRIPT_COMMAND_KILL:
{
if(!source || ((Creature*)source)->isDead())
@@ -2399,6 +2573,47 @@ void World::ScriptsProcess()
break;
}
+ case SCRIPT_COMMAND_PLAY_SOUND:
+ {
+ if(!source)
+ {
+ sLog.outError("SCRIPT_COMMAND_PLAY_SOUND call for NULL creature.");
+ break;
+ }
+
+ WorldObject* pSource = dynamic_cast<WorldObject*>(source);
+ if(!pSource)
+ {
+ sLog.outError("SCRIPT_COMMAND_PLAY_SOUND call for non-world object (TypeId: %u), skipping.",source->GetTypeId());
+ break;
+ }
+
+ // bitmask: 0/1=anyone/target, 0/2=with distance dependent
+ Player* pTarget = NULL;
+ if(step.script->datalong2 & 1)
+ {
+ if(!target)
+ {
+ sLog.outError("SCRIPT_COMMAND_PLAY_SOUND in targeted mode call for NULL target.");
+ break;
+ }
+
+ if(target->GetTypeId()!=TYPEID_PLAYER)
+ {
+ sLog.outError("SCRIPT_COMMAND_PLAY_SOUND in targeted mode call for non-player (TypeId: %u), skipping.",target->GetTypeId());
+ break;
+ }
+
+ pTarget = (Player*)target;
+ }
+
+ // bitmask: 0/1=anyone/target, 0/2=with distance dependent
+ if(step.script->datalong2 & 2)
+ pSource->PlayDistanceSound(step.script->datalong,pTarget);
+ else
+ pSource->PlayDirectSound(step.script->datalong,pTarget);
+ break;
+ }
default:
sLog.outError("Unknown script command %u called.",step.script->command);
break;
@@ -2414,7 +2629,7 @@ void World::ScriptsProcess()
/// Send a packet to all players (except self if mentioned)
void World::SendGlobalMessage(WorldPacket *packet, WorldSession *self, uint32 team)
{
- SessionMap::iterator itr;
+ SessionMap::const_iterator itr;
for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
{
if (itr->second &&
@@ -2428,16 +2643,17 @@ void World::SendGlobalMessage(WorldPacket *packet, WorldSession *self, uint32 te
}
}
+/// Send a packet to all GMs (except self if mentioned)
void World::SendGlobalGMMessage(WorldPacket *packet, WorldSession *self, uint32 team)
{
SessionMap::iterator itr;
- for (itr = m_sessions.begin(); itr != m_sessions.end(); itr++)
+ for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
{
if (itr->second &&
itr->second->GetPlayer() &&
itr->second->GetPlayer()->IsInWorld() &&
itr->second != self &&
- itr->second->GetSecurity() >SEC_PLAYER &&
+ itr->second->GetSecurity() &&
(team == 0 || itr->second->GetPlayer()->GetTeam() == team) )
{
itr->second->SendPacket(packet);
@@ -2445,115 +2661,105 @@ void World::SendGlobalGMMessage(WorldPacket *packet, WorldSession *self, uint32
}
}
-/// Send a System Message to all players (except self if mentioned)
-void World::SendWorldText(int32 string_id, ...)
+namespace MaNGOS
{
- std::vector<std::vector<WorldPacket*> > data_cache; // 0 = default, i => i-1 locale index
-
- for(SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
+ class WorldWorldTextBuilder
{
- if(!itr->second || !itr->second->GetPlayer() || !itr->second->GetPlayer()->IsInWorld() )
- continue;
+ public:
+ typedef std::vector<WorldPacket*> WorldPacketList;
+ explicit WorldWorldTextBuilder(int32 textId, va_list* args = NULL) : i_textId(textId), i_args(args) {}
+ void operator()(WorldPacketList& data_list, int32 loc_idx)
+ {
+ char const* text = objmgr.GetMangosString(i_textId,loc_idx);
- uint32 loc_idx = itr->second->GetSessionDbLocaleIndex();
- uint32 cache_idx = loc_idx+1;
+ if(i_args)
+ {
+ // we need copy va_list before use or original va_list will corrupted
+ va_list ap;
+ va_copy(ap,*i_args);
- std::vector<WorldPacket*>* data_list;
+ char str [2048];
+ vsnprintf(str,2048,text, ap );
+ va_end(ap);
- // create if not cached yet
- if(data_cache.size() < cache_idx+1 || data_cache[cache_idx].empty())
- {
- if(data_cache.size() < cache_idx+1)
- data_cache.resize(cache_idx+1);
+ do_helper(data_list,&str[0]);
+ }
+ else
+ do_helper(data_list,(char*)text);
+ }
+ private:
+ char* lineFromMessage(char*& pos) { char* start = strtok(pos,"\n"); pos = NULL; return start; }
+ void do_helper(WorldPacketList& data_list, char* text)
+ {
+ char* pos = text;
- data_list = &data_cache[cache_idx];
+ while(char* line = lineFromMessage(pos))
+ {
+ WorldPacket* data = new WorldPacket();
- char const* text = objmgr.GetTrinityString(string_id,loc_idx);
+ uint32 lineLength = (line ? strlen(line) : 0) + 1;
- char buf[1000];
+ data->Initialize(SMSG_MESSAGECHAT, 100); // guess size
+ *data << uint8(CHAT_MSG_SYSTEM);
+ *data << uint32(LANG_UNIVERSAL);
+ *data << uint64(0);
+ *data << uint32(0); // can be chat msg group or something
+ *data << uint64(0);
+ *data << uint32(lineLength);
+ *data << line;
+ *data << uint8(0);
- va_list argptr;
- va_start( argptr, string_id );
- vsnprintf( buf,1000, text, argptr );
- va_end( argptr );
+ data_list.push_back(data);
+ }
+ }
- char* pos = &buf[0];
+ int32 i_textId;
+ va_list* i_args;
+ };
+} // namespace MaNGOS
- while(char* line = ChatHandler::LineFromMessage(pos))
- {
- WorldPacket* data = new WorldPacket();
- ChatHandler::FillMessageData(data, NULL, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, 0, line, NULL);
- data_list->push_back(data);
- }
- }
- else
- data_list = &data_cache[cache_idx];
+/// Send a System Message to all players (except self if mentioned)
+void World::SendWorldText(int32 string_id, ...)
+{
+ va_list ap;
+ va_start(ap, string_id);
- for(int i = 0; i < data_list->size(); ++i)
- itr->second->SendPacket((*data_list)[i]);
+ MaNGOS::WorldWorldTextBuilder wt_builder(string_id, &ap);
+ MaNGOS::LocalizedPacketListDo<MaNGOS::WorldWorldTextBuilder> wt_do(wt_builder);
+ for(SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
+ {
+ if(!itr->second || !itr->second->GetPlayer() || !itr->second->GetPlayer()->IsInWorld() )
+ continue;
+
+ wt_do(itr->second->GetPlayer());
}
- // free memory
- for(int i = 0; i < data_cache.size(); ++i)
- for(int j = 0; j < data_cache[i].size(); ++j)
- delete data_cache[i][j];
+ va_end(ap);
}
+/// Send a System Message to all GMs (except self if mentioned)
void World::SendGMText(int32 string_id, ...)
{
- std::vector<std::vector<WorldPacket*> > data_cache; // 0 = default, i => i-1 locale index
+ va_list ap;
+ va_start(ap, string_id);
+ MaNGOS::WorldWorldTextBuilder wt_builder(string_id, &ap);
+ MaNGOS::LocalizedPacketListDo<MaNGOS::WorldWorldTextBuilder> wt_do(wt_builder);
for(SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
{
if(!itr->second || !itr->second->GetPlayer() || !itr->second->GetPlayer()->IsInWorld() )
continue;
- uint32 loc_idx = itr->second->GetSessionDbLocaleIndex();
- uint32 cache_idx = loc_idx+1;
-
- std::vector<WorldPacket*>* data_list;
-
- // create if not cached yet
- if(data_cache.size() < cache_idx+1 || data_cache[cache_idx].empty())
- {
- if(data_cache.size() < cache_idx+1)
- data_cache.resize(cache_idx+1);
-
- data_list = &data_cache[cache_idx];
-
- char const* text = objmgr.GetTrinityString(string_id,loc_idx);
-
- char buf[1000];
-
- va_list argptr;
- va_start( argptr, string_id );
- vsnprintf( buf,1000, text, argptr );
- va_end( argptr );
-
- char* pos = &buf[0];
-
- while(char* line = ChatHandler::LineFromMessage(pos))
- {
- WorldPacket* data = new WorldPacket();
- ChatHandler::FillMessageData(data, NULL, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, 0, line, NULL);
- data_list->push_back(data);
- }
- }
- else
- data_list = &data_cache[cache_idx];
+ if(!itr->second->GetSecurity())
+ continue;
- for(int i = 0; i < data_list->size(); ++i)
- if(itr->second->GetSecurity() > SEC_PLAYER)
- itr->second->SendPacket((*data_list)[i]);
+ wt_do(itr->second->GetPlayer());
}
- // free memory
- for(int i = 0; i < data_cache.size(); ++i)
- for(int j = 0; j < data_cache[i].size(); ++j)
- delete data_cache[i][j];
+ va_end(ap);
}
-/// Send a System Message to all players (except self if mentioned)
+/// DEPRICATED, only for debug purpose. Send a System Message to all players (except self if mentioned)
void World::SendGlobalText(const char* text, WorldSession *self)
{
WorldPacket data;
@@ -2574,7 +2780,7 @@ void World::SendGlobalText(const char* text, WorldSession *self)
/// Send a packet to all players (or players selected team) in the zone (except self if mentioned)
void World::SendZoneMessage(uint32 zone, WorldPacket *packet, WorldSession *self, uint32 team)
{
- SessionMap::iterator itr;
+ SessionMap::const_iterator itr;
for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
{
if (itr->second &&
@@ -2603,7 +2809,7 @@ void World::KickAll()
m_QueuedPlayer.clear(); // prevent send queue update packet and login queued sessions
// session not removed at kick and will removed in next update tick
- for (SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
+ for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
itr->second->KickPlayer();
}
@@ -2611,7 +2817,7 @@ void World::KickAll()
void World::KickAllLess(AccountTypes sec)
{
// session not removed at kick and will removed in next update tick
- for (SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
+ for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
if(itr->second->GetSecurity() < sec)
itr->second->KickPlayer();
}
@@ -2619,7 +2825,7 @@ void World::KickAllLess(AccountTypes sec)
/// Kick (and save) the designated player
bool World::KickPlayer(const std::string& playerName)
{
- SessionMap::iterator itr;
+ SessionMap::const_iterator itr;
// session not removed at kick and will removed in next update tick
for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
@@ -2806,7 +3012,7 @@ void World::ShutdownMsg(bool show, Player* player)
{
std::string str = secsToTimeString(m_ShutdownTimer);
- uint32 msgid = (m_ShutdownMask & SHUTDOWN_MASK_RESTART) ? SERVER_MSG_RESTART_TIME : SERVER_MSG_SHUTDOWN_TIME;
+ ServerMessageType msgid = (m_ShutdownMask & SHUTDOWN_MASK_RESTART) ? SERVER_MSG_RESTART_TIME : SERVER_MSG_SHUTDOWN_TIME;
SendServerMessage(msgid,str.c_str(),player);
DEBUG_LOG("Server is %s in %s",(m_ShutdownMask & SHUTDOWN_MASK_RESTART ? "restart" : "shuttingdown"),str.c_str());
@@ -2820,7 +3026,7 @@ void World::ShutdownCancel()
if(!m_ShutdownTimer || m_stopEvent)
return;
- uint32 msgid = (m_ShutdownMask & SHUTDOWN_MASK_RESTART) ? SERVER_MSG_RESTART_CANCELLED : SERVER_MSG_SHUTDOWN_CANCELLED;
+ ServerMessageType msgid = (m_ShutdownMask & SHUTDOWN_MASK_RESTART) ? SERVER_MSG_RESTART_CANCELLED : SERVER_MSG_SHUTDOWN_CANCELLED;
m_ShutdownMask = 0;
m_ShutdownTimer = 0;
@@ -2831,7 +3037,7 @@ void World::ShutdownCancel()
}
/// Send a server message to the user(s)
-void World::SendServerMessage(uint32 type, const char *text, Player* player)
+void World::SendServerMessage(ServerMessageType type, const char *text, Player* player)
{
WorldPacket data(SMSG_SERVER_MESSAGE, 50); // guess size
data << uint32(type);
@@ -2844,7 +3050,7 @@ void World::SendServerMessage(uint32 type, const char *text, Player* player)
SendGlobalMessage( &data );
}
-void World::UpdateSessions( time_t diff )
+void World::UpdateSessions( uint32 diff )
{
///- Add new sessions
while(!addSessQueue.empty())
@@ -2969,7 +3175,7 @@ void World::ResetDailyQuests()
{
sLog.outDetail("Daily quests reset for all characters.");
CharacterDatabase.Execute("DELETE FROM character_queststatus_daily");
- for(SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
+ for(SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
if(itr->second->GetPlayer())
itr->second->GetPlayer()->ResetDailyQuestStatus();
}
@@ -2997,14 +3203,20 @@ void World::UpdateMaxSessionCounters()
void World::LoadDBVersion()
{
QueryResult* result = WorldDatabase.Query("SELECT db_version FROM version LIMIT 1");
+ //QueryResult* result = WorldDatabase.Query("SELECT version, creature_ai_version FROM db_version LIMIT 1");
if(result)
{
Field* fields = result->Fetch();
- m_DBVersion = fields[0].GetString();
+ m_DBVersion = fields[0].GetCppString();
+ //m_CreatureEventAIVersion = fields[1].GetCppString();
delete result;
}
- else
- m_DBVersion = "unknown world database";
+
+ if(m_DBVersion.empty())
+ m_DBVersion = "Unknown world database.";
+
+ if(m_CreatureEventAIVersion.empty())
+ m_CreatureEventAIVersion = "Unknown creature EventAI.";
}
diff --git a/src/game/World.h b/src/game/World.h
index ff03f4124b0..27075885368 100644
--- a/src/game/World.h
+++ b/src/game/World.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -45,6 +45,16 @@ class SqlResultQueue;
class QueryResult;
class WorldSocket;
+// ServerMessages.dbc
+enum ServerMessageType
+{
+ SERVER_MSG_SHUTDOWN_TIME = 1,
+ SERVER_MSG_RESTART_TIME = 2,
+ SERVER_MSG_STRING = 3,
+ SERVER_MSG_SHUTDOWN_CANCELLED = 4,
+ SERVER_MSG_RESTART_CANCELLED = 5
+};
+
enum ShutdownMask
{
SHUTDOWN_MASK_RESTART = 1,
@@ -68,7 +78,8 @@ enum WorldTimers
WUPDATE_UPTIME = 4,
WUPDATE_CORPSES = 5,
WUPDATE_EVENTS = 6,
- WUPDATE_COUNT = 7
+ WUPDATE_CLEANDB = 7,
+ WUPDATE_COUNT = 8
};
/// Configuration elements
@@ -104,9 +115,12 @@ enum WorldConfigs
CONFIG_CHARACTERS_CREATING_DISABLED,
CONFIG_CHARACTERS_PER_ACCOUNT,
CONFIG_CHARACTERS_PER_REALM,
+ CONFIG_HEROIC_CHARACTERS_PER_REALM,
+ CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING,
CONFIG_SKIP_CINEMATICS,
CONFIG_MAX_PLAYER_LEVEL,
CONFIG_START_PLAYER_LEVEL,
+ CONFIG_START_HEROIC_PLAYER_LEVEL,
CONFIG_START_PLAYER_MONEY,
CONFIG_MAX_HONOR_POINTS,
CONFIG_START_HONOR_POINTS,
@@ -114,21 +128,22 @@ enum WorldConfigs
CONFIG_START_ARENA_POINTS,
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,
CONFIG_MAX_PRIMARY_TRADE_SKILL,
CONFIG_MIN_PETITION_SIGNS,
CONFIG_GM_LOGIN_STATE,
+ CONFIG_GM_VISIBLE_STATE,
+ CONFIG_GM_ACCEPT_TICKETS,
CONFIG_GM_CHAT,
CONFIG_GM_WISPERING_TO,
CONFIG_GM_IN_GM_LIST,
CONFIG_GM_IN_WHO_LIST,
CONFIG_GM_LOG_TRADE,
CONFIG_START_GM_LEVEL,
+ CONFIG_GM_LOWER_SECURITY,
+ CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS,
CONFIG_GROUP_VISIBILITY,
CONFIG_MAIL_DELIVERY_DELAY,
CONFIG_UPTIME_UPDATE,
@@ -171,6 +186,8 @@ enum WorldConfigs
CONFIG_DEATH_SICKNESS_LEVEL,
CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP,
CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE,
+ CONFIG_DEATH_BONES_WORLD,
+ CONFIG_DEATH_BONES_BG_OR_ARENA,
CONFIG_THREAT_RADIUS,
CONFIG_INSTANT_LOGOUT,
CONFIG_DISABLE_BREATHING,
@@ -179,12 +196,20 @@ enum WorldConfigs
CONFIG_LISTEN_RANGE_SAY,
CONFIG_LISTEN_RANGE_TEXTEMOTE,
CONFIG_LISTEN_RANGE_YELL,
+ CONFIG_SKILL_MILLING,
+ CONFIG_BATTLEGROUND_CAST_DESERTER,
+ CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE,
+ CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY,
+ CONFIG_BATTLEGROUND_INVITATION_TYPE,
+ CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER,
+ CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH,
CONFIG_ARENA_MAX_RATING_DIFFERENCE,
CONFIG_ARENA_RATING_DISCARD_TIMER,
CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS,
CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS,
- CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER,
-
+ CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE,
+ CONFIG_ARENA_SEASON_ID,
+ CONFIG_ARENA_SEASON_IN_PROGRESS,
CONFIG_MAX_WHO,
CONFIG_BG_START_MUSIC,
CONFIG_START_ALL_SPELLS,
@@ -201,8 +226,18 @@ enum WorldConfigs
CONFIG_INTERVAL_LOG_UPDATE,
CONFIG_MIN_LOG_UPDATE,
CONFIG_ENABLE_SINFO_LOGIN,
- CONFIG_PREMATURE_BG_REWARD,
-
+ CONFIG_OFFHAND_CHECK_AT_TALENTS_RESET,
+ CONFIG_CHATLOG_CHANNEL,
+ CONFIG_CHATLOG_WHISPER,
+ CONFIG_CHATLOG_SYSCHAN,
+ CONFIG_CHATLOG_PARTY,
+ CONFIG_CHATLOG_RAID,
+ CONFIG_CHATLOG_GUILD,
+ CONFIG_CHATLOG_PUBLIC,
+ CONFIG_CHATLOG_ADDON,
+ CONFIG_CHATLOG_BGROUND,
+ CONFIG_LOGDB_CLEARINTERVAL,
+ CONFIG_LOGDB_CLEARTIME,
CONFIG_VALUE_COUNT
};
@@ -213,6 +248,8 @@ enum Rates
RATE_POWER_MANA,
RATE_POWER_RAGE_INCOME,
RATE_POWER_RAGE_LOSS,
+ RATE_POWER_RUNICPOWER_INCOME,
+ RATE_POWER_RUNICPOWER_LOSS,
RATE_POWER_FOCUS,
RATE_SKILL_DISCOVERY,
RATE_DROP_ITEM_POOR,
@@ -227,8 +264,9 @@ enum Rates
RATE_XP_KILL,
RATE_XP_QUEST,
RATE_XP_EXPLORE,
- RATE_XP_PAST_70,
RATE_REPUTATION_GAIN,
+ RATE_REPUTATION_LOWLEVEL_KILL,
+ RATE_REPUTATION_LOWLEVEL_QUEST,
RATE_CREATURE_NORMAL_HP,
RATE_CREATURE_ELITE_ELITE_HP,
RATE_CREATURE_ELITE_RAREELITE_HP,
@@ -256,7 +294,6 @@ enum Rates
RATE_MINING_AMOUNT,
RATE_MINING_NEXT,
RATE_TALENT,
- RATE_LOYALTY,
RATE_CORPSE_DECAY_LOOTED,
RATE_INSTANCE_RESET_TIME,
RATE_TARGET_POS_RECALCULATION_RANGE,
@@ -328,12 +365,11 @@ enum RealmZone
#define SCRIPT_COMMAND_CLOSE_DOOR 12 // source = unit, datalong=db_guid, datalong2=reset_delay
#define SCRIPT_COMMAND_ACTIVATE_OBJECT 13 // source = unit, target=GO
#define SCRIPT_COMMAND_REMOVE_AURA 14 // source (datalong2!=0) or target (datalong==0) unit, datalong = spell_id
-#define SCRIPT_COMMAND_CAST_SPELL 15 // source (datalong2!=0) or target (datalong==0) unit, datalong = spell_id
-#define SCRIPT_COMMAND_LOAD_PATH 16 // source = unit, path = datalong, repeatable datalong2
-#define SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT 17 // datalong scriptid, lowguid datalong2, dataint table
-#define SCRIPT_COMMAND_PLAYSOUND 18 // datalong soundid, datalong2 play only self
-#define SCRIPT_COMMAND_KILL 19 // datalong removecorpse
-
+#define SCRIPT_COMMAND_CAST_SPELL 15 // source/target cast spell at target/source (script->datalong2: 0: s->t 1: s->s 2: t->t 3: t->s
+#define SCRIPT_COMMAND_PLAY_SOUND 16 // source = any object, target=any/player, datalong (sound_id), datalong2 (bitmask: 0/1=anyone/target, 0/2=with distance dependent, so 1|2 = 3 is target with distance dependent)
+#define SCRIPT_COMMAND_LOAD_PATH 20 // source = unit, path = datalong, repeatable datalong2
+#define SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT 21 // datalong scriptid, lowguid datalong2, dataint table
+#define SCRIPT_COMMAND_KILL 22 // datalong removecorpse
/// Storage class for commands issued for delayed execution
struct CliCommandHolder
@@ -380,6 +416,12 @@ class World
Weather* AddWeather(uint32 zone_id);
void RemoveWeather(uint32 zone_id);
+ /// Deny clients?
+ bool IsClosed() { return m_isClosed; }
+
+ /// Close world
+ void SetClosed(bool val) { m_isClosed = val; }
+
/// Get the active session server limit (or security level limitations)
uint32 GetPlayerAmountLimit() const { return m_playerLimit >= 0 ? m_playerLimit : 0; }
AccountTypes GetPlayerSecurityLimit() const { return m_playerLimit <= 0 ? AccountTypes(-m_playerLimit) : SEC_PLAYER; }
@@ -443,7 +485,7 @@ class World
void SendGlobalGMMessage(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);
+ void SendServerMessage(ServerMessageType type, const char *text = "", Player* player = NULL);
/// Are we in the middle of a shutdown?
bool IsShutdowning() const { return m_ShutdownTimer > 0; }
@@ -454,9 +496,9 @@ class World
static void StopNow(uint8 exitcode) { m_stopEvent = true; m_ExitCode = exitcode; }
static bool IsStopped() { return m_stopEvent; }
- void Update(time_t diff);
+ void Update(uint32 diff);
- void UpdateSessions( time_t diff );
+ void UpdateSessions( uint32 diff );
/// Set a server rate (see #Rates)
void setRate(Rates rate,float value) { rate_values[rate]=value; }
/// Get a server rate (see #Rates)
@@ -518,6 +560,7 @@ class World
//used World DB version
void LoadDBVersion();
char const* GetDBVersion() { return m_DBVersion.c_str(); }
+ char const* GetCreatureEventAIVersion() { return m_CreatureEventAIVersion.c_str(); }
//used Script version
void SetScriptsVersion(char const* version) { m_ScriptsVersion = version ? version : "unknown scripting library"; }
@@ -538,6 +581,8 @@ class World
uint32 m_ShutdownTimer;
uint32 m_ShutdownMask;
+ bool m_isClosed;
+
time_t m_startTime;
time_t m_gameTime;
IntervalTimer m_timers[WUPDATE_COUNT];
@@ -596,6 +641,7 @@ class World
//used versions
std::string m_DBVersion;
+ std::string m_CreatureEventAIVersion;
std::string m_ScriptsVersion;
};
diff --git a/src/game/WorldLog.cpp b/src/game/WorldLog.cpp
index a1065dced5c..52eb1e8b59c 100644
--- a/src/game/WorldLog.cpp
+++ b/src/game/WorldLog.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -25,6 +25,7 @@
#include "WorldLog.h"
#include "Policies/SingletonImp.h"
#include "Config/ConfigEnv.h"
+#include "Log.h"
#define CLASS_LOCK Trinity::ClassLevelLockable<WorldLog, ZThread::FastMutex>
INSTANTIATE_SINGLETON_2(WorldLog, CLASS_LOCK);
@@ -32,6 +33,18 @@ INSTANTIATE_CLASS_MUTEX(WorldLog, ZThread::FastMutex);
#define WORLD_LOG_FILE_STRING "world.log"
+WorldLog::WorldLog() : i_file(NULL)
+{
+ Initialize();
+}
+
+WorldLog::~WorldLog()
+{
+ if( i_file != NULL )
+ fclose(i_file);
+ i_file = NULL;
+}
+
/// Open the log file (if specified so in the configuration file)
void WorldLog::Initialize()
{
@@ -48,6 +61,63 @@ void WorldLog::Initialize()
{
i_file = fopen((logsDir+logname).c_str(), "w");
}
+
+ m_dbWorld = sConfig.GetBoolDefault("LogDB.World", false); // can be VERY heavy if enabled
+}
+
+void WorldLog::outTimestampLog(char const *fmt, ...)
+{
+ if( LogWorld() )
+ {
+ Guard guard(*this);
+ ASSERT(i_file);
+
+ Log::outTimestamp(i_file);
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(i_file, fmt, args);
+ //fprintf(i_file, "\n" );
+ va_end(args);
+
+ fflush(i_file);
+ }
+
+ if (sLog.GetLogDB() && m_dbWorld)
+ {
+ va_list ap2;
+ va_start(ap2, fmt);
+ char nnew_str[MAX_QUERY_LEN];
+ vsnprintf(nnew_str, MAX_QUERY_LEN, fmt, ap2);
+ sLog.outDB(LOG_TYPE_WORLD, nnew_str);
+ va_end(ap2);
+ }
+}
+
+void WorldLog::outLog(char const *fmt, ...)
+{
+ if( LogWorld() )
+ {
+ Guard guard(*this);
+ ASSERT(i_file);
+
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(i_file, fmt, args);
+ //fprintf(i_file, "\n" );
+ va_end(args);
+
+ fflush(i_file);
+ }
+
+ if (sLog.GetLogDB() && m_dbWorld)
+ {
+ va_list ap2;
+ va_start(ap2, fmt);
+ char nnew_str[MAX_QUERY_LEN];
+ vsnprintf(nnew_str, MAX_QUERY_LEN, fmt, ap2);
+ sLog.outDB(LOG_TYPE_WORLD, nnew_str);
+ va_end(ap2);
+ }
}
#define sWorldLog WorldLog::Instance()
diff --git a/src/game/WorldLog.h b/src/game/WorldLog.h
index 0a7c2a08067..01f34535dd9 100644
--- a/src/game/WorldLog.h
+++ b/src/game/WorldLog.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -35,42 +35,26 @@
class TRINITY_DLL_DECL WorldLog : public Trinity::Singleton<WorldLog, Trinity::ClassLevelLockable<WorldLog, ZThread::FastMutex> >
{
friend class Trinity::OperatorNew<WorldLog>;
- WorldLog() : i_file(NULL) { Initialize(); }
+ WorldLog();
WorldLog(const WorldLog &);
WorldLog& operator=(const WorldLog &);
typedef Trinity::ClassLevelLockable<WorldLog, ZThread::FastMutex>::Lock Guard;
/// Close the file in destructor
- ~WorldLog()
- {
- if( i_file != NULL )
- fclose(i_file);
- i_file = NULL;
- }
+ ~WorldLog();
public:
void Initialize();
/// Is the world logger active?
- inline bool LogWorld(void) const { return (i_file != NULL); }
+ bool LogWorld(void) const { return (i_file != NULL); }
/// %Log to the file
- inline void Log(char const *fmt, ...)
- {
- if( LogWorld() )
- {
- Guard guard(*this);
- ASSERT(i_file);
-
- va_list args;
- va_start(args, fmt);
- vfprintf(i_file, fmt, args);
- va_end(args);
-
- fflush(i_file);
- }
- }
+ void outLog(char const *fmt, ...);
+ void outTimestampLog(char const *fmt, ...);
private:
FILE *i_file;
+
+ bool m_dbWorld;
};
#define sWorldLog WorldLog::Instance()
diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp
index 5b1261e664a..780c02eddca 100644
--- a/src/game/WorldSession.cpp
+++ b/src/game/WorldSession.cpp
@@ -34,16 +34,15 @@
#include "Group.h"
#include "Guild.h"
#include "World.h"
-#include "MapManager.h"
#include "ObjectAccessor.h"
#include "BattleGroundMgr.h"
#include "OutdoorPvPMgr.h"
-#include "Language.h" // for CMSG_CANCEL_MOUNT_AURA handler
-#include "Chat.h"
+//#include "Language.h" // for CMSG_CANCEL_MOUNT_AURA handler
#include "SocialMgr.h"
+#include "zlib/zlib.h"
/// WorldSession constructor
-WorldSession::WorldSession(uint32 id, WorldSocket *sock, uint32 sec, uint8 expansion, time_t mute_time, LocaleConstant locale) :
+WorldSession::WorldSession(uint32 id, WorldSocket *sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale) :
LookingForGroup_auto_join(false), LookingForGroup_auto_add(false), m_muteTime(mute_time),
_player(NULL), m_Socket(sock),_security(sec), _accountId(id), m_expansion(expansion),
m_sessionDbcLocale(sWorld.GetAvailableDbcLocale(locale)), m_sessionDbLocaleIndex(objmgr.GetIndexForLocale(locale)),
@@ -241,7 +240,7 @@ bool WorldSession::Update(uint32 /*diff*/)
void WorldSession::LogoutPlayer(bool Save)
{
// finish pending transfers before starting the logout
- while(_player && _player->IsBeingTeleported())
+ while(_player && _player->IsBeingTeleportedFar())
HandleMoveWorldportAckOpcode();
m_playerLogout = true;
@@ -298,25 +297,28 @@ void WorldSession::LogoutPlayer(bool Save)
else if(_player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
{
// this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION
- _player->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT);
+ _player->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT);
//_player->SetDeathPvP(*); set at SPELL_AURA_SPIRIT_OF_REDEMPTION apply time
_player->KillPlayer();
_player->BuildPlayerRepop();
_player->RepopAtGraveyard();
}
+ //drop a flag if player is carrying it
+ if(BattleGround *bg = _player->GetBattleGround())
+ bg->EventPlayerLoggedOut(_player);
- ///- Remove player from battleground (teleport to entrance)
- if(_player->InBattleGround())
- _player->LeaveBattleground();
+ ///- Teleport to home if the player is in an invalid instance
+ if(!_player->m_InstanceValid && !_player->isGameMaster())
+ _player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation());
sOutdoorPvPMgr.HandlePlayerLeaveZone(_player,_player->GetZoneId());
- for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
+ for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
{
- if(int32 bgTypeId = _player->GetBattleGroundQueueId(i))
+ if(BattleGroundQueueTypeId bgQueueTypeId = _player->GetBattleGroundQueueTypeId(i))
{
- _player->RemoveBattleGroundQueueId(bgTypeId);
- sBattleGroundMgr.m_BattleGroundQueues[ bgTypeId ].RemovePlayer(_player->GetGUID(), true);
+ _player->RemoveBattleGroundQueueId(bgQueueTypeId);
+ sBattleGroundMgr.m_BattleGroundQueues[ bgQueueTypeId ].RemovePlayer(_player->GetGUID(), true);
}
}
@@ -468,6 +470,13 @@ void WorldSession::SendNotification(int32 string_id,...)
}
}
+void WorldSession::SendSetPhaseShift(uint32 PhaseShift)
+{
+ WorldPacket data(SMSG_SET_PHASE_SHIFT, 4);
+ data << uint32(PhaseShift);
+ SendPacket(&data);
+}
+
const char * WorldSession::GetTrinityString( int32 entry ) const
{
return objmgr.GetTrinityString(entry,GetSessionDbLocaleIndex());
@@ -518,3 +527,212 @@ void WorldSession::SendAuthWaitQue(uint32 position)
}
}
+void WorldSession::LoadAccountData()
+{
+ for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
+ {
+ AccountData data;
+ m_accountData[i] = data;
+ }
+
+ QueryResult *result = CharacterDatabase.PQuery("SELECT type, time, data FROM account_data WHERE account='%u'", GetAccountId());
+
+ if(!result)
+ return;
+
+ do
+ {
+ Field *fields = result->Fetch();
+
+ uint32 type = fields[0].GetUInt32();
+ if(type < NUM_ACCOUNT_DATA_TYPES)
+ {
+ m_accountData[type].Time = fields[1].GetUInt32();
+ m_accountData[type].Data = fields[2].GetCppString();
+ }
+ } while (result->NextRow());
+
+ delete result;
+}
+
+void WorldSession::SetAccountData(uint32 type, time_t time_, std::string data)
+{
+ m_accountData[type].Time = time_;
+ m_accountData[type].Data = data;
+
+ uint32 acc = GetAccountId();
+
+ CharacterDatabase.BeginTransaction ();
+ CharacterDatabase.PExecute("DELETE FROM account_data WHERE account='%u' AND type='%u'", acc, type);
+ CharacterDatabase.escape_string(data);
+ CharacterDatabase.PExecute("INSERT INTO account_data VALUES ('%u','%u','%u','%s')", acc, type, (uint32)time_, data.c_str());
+ CharacterDatabase.CommitTransaction ();
+}
+
+void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
+{
+ CHECK_PACKET_SIZE(data, data.rpos()+4+2+4+4+4+4+4);
+ data >> mi->flags;
+ data >> mi->unk1;
+ data >> mi->time;
+ data >> mi->x;
+ data >> mi->y;
+ data >> mi->z;
+ data >> mi->o;
+
+ if(mi->flags & MOVEMENTFLAG_ONTRANSPORT)
+ {
+ CHECK_PACKET_SIZE(data, data.rpos()+8+4+4+4+4+4+1);
+ data >> mi->t_guid;
+ data >> mi->t_x;
+ data >> mi->t_y;
+ data >> mi->t_z;
+ data >> mi->t_o;
+ data >> mi->t_time;
+ data >> mi->t_seat;
+ }
+
+ if((mi->flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) || (mi->unk1 & 0x20))
+ {
+ CHECK_PACKET_SIZE(data, data.rpos()+4);
+ data >> mi->s_pitch;
+ }
+
+ CHECK_PACKET_SIZE(data, data.rpos()+4);
+ data >> mi->fallTime;
+
+ if(mi->flags & MOVEMENTFLAG_JUMPING)
+ {
+ CHECK_PACKET_SIZE(data, data.rpos()+4+4+4+4);
+ data >> mi->j_zspeed;
+ data >> mi->j_sinAngle;
+ data >> mi->j_cosAngle;
+ data >> mi->j_xyspeed;
+ }
+
+ if(mi->flags & MOVEMENTFLAG_SPLINE)
+ {
+ CHECK_PACKET_SIZE(data, data.rpos()+4);
+ data >> mi->u_unk1;
+ }
+}
+
+void WorldSession::ReadAddonsInfo(WorldPacket &data)
+{
+ if (data.rpos() + 4 > data.size())
+ return;
+ uint32 size;
+ data >> size;
+
+ if(!size)
+ return;
+
+ uLongf uSize = size;
+
+ uint32 pos = data.rpos();
+
+ ByteBuffer addonInfo;
+ addonInfo.resize(size);
+
+ if (uncompress(const_cast<uint8*>(addonInfo.contents()), &uSize, const_cast<uint8*>(data.contents() + pos), data.size() - pos) == Z_OK)
+ {
+ uint32 addonsCount;
+ addonInfo >> addonsCount; // addons count
+
+ for(uint32 i = 0; i < addonsCount; ++i)
+ {
+ std::string addonName;
+ uint8 enabled;
+ uint32 crc, unk1;
+
+ // check next addon data format correctness
+ if(addonInfo.rpos()+1 > addonInfo.size())
+ return;
+
+ addonInfo >> addonName;
+
+ // recheck next addon data format correctness
+ if(addonInfo.rpos()+1+4+4 > addonInfo.size())
+ return;
+
+ addonInfo >> enabled >> crc >> unk1;
+
+ sLog.outDebug("ADDON: Name: %s, Enabled: 0x%x, CRC: 0x%x, Unknown2: 0x%x", addonName.c_str(), enabled, crc, unk1);
+
+ m_addonsList.push_back(AddonInfo(addonName, enabled, crc));
+ }
+
+ uint32 unk2;
+ addonInfo >> unk2;
+
+ if(addonInfo.rpos() != addonInfo.size())
+ sLog.outDebug("packet under read!");
+ }
+ else
+ sLog.outError("Addon packet uncompress error!");
+}
+
+void WorldSession::SendAddonsInfo()
+{
+ unsigned char tdata[256] =
+ {
+ 0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54,
+ 0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75,
+ 0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34,
+ 0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8,
+ 0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8,
+ 0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A,
+ 0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3,
+ 0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9,
+ 0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22,
+ 0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E,
+ 0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB,
+ 0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7,
+ 0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0,
+ 0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6,
+ 0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A,
+ 0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2
+ };
+
+ WorldPacket data(SMSG_ADDON_INFO, 4);
+
+ for(AddonsList::iterator itr = m_addonsList.begin(); itr != m_addonsList.end(); ++itr)
+ {
+ uint8 state = (itr->Enabled ? 2 : 1);
+ data << uint8(state);
+
+ uint8 unk1 = (itr->Enabled ? 1 : 0);
+ data << uint8(unk1);
+ if (unk1)
+ {
+ uint8 unk2 = (itr->CRC != 0x4c1c776d); // If addon is Standard addon CRC
+ data << uint8(unk2);
+ if (unk2)
+ data.append(tdata, sizeof(tdata));
+
+ data << uint32(0);
+ }
+
+ uint8 unk3 = (itr->Enabled ? 0 : 1);
+ data << uint8(unk3);
+ if (unk3)
+ {
+ // String, 256 (null terminated?)
+ data << uint8(0);
+ }
+ }
+
+ m_addonsList.clear();
+
+ uint32 count = 0;
+ data << uint32(count);
+ /*for(uint32 i = 0; i < count; ++i)
+ {
+ uint32
+ string (16 bytes)
+ string (16 bytes)
+ uint32
+ }*/
+
+ SendPacket(&data);
+}
diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h
index 1461d47fd2b..d514586957a 100644
--- a/src/game/WorldSession.h
+++ b/src/game/WorldSession.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -26,6 +26,7 @@
#define __WORLDSESSION_H
#include "Common.h"
+#include "SharedDefines.h"
class MailItemsInfo;
struct ItemPrototype;
@@ -47,6 +48,32 @@ class CharacterHandler;
#define CHECK_PACKET_SIZE(P,S) if((P).size() < (S)) return SizeError((P),(S));
+#define NUM_ACCOUNT_DATA_TYPES 8
+
+struct AccountData
+{
+ AccountData() : Time(0), Data("") {}
+
+ time_t Time;
+ std::string Data;
+};
+
+struct AddonInfo
+{
+ AddonInfo(std::string name, uint8 enabled, uint32 crc)
+ {
+ Name = name;
+ Enabled = enabled;
+ CRC = crc;
+ }
+
+ std::string Name;
+ uint8 Enabled;
+ uint32 CRC;
+};
+
+typedef std::list<AddonInfo> AddonsList;
+
enum PartyOperation
{
PARTY_OP_INVITE = 0,
@@ -73,7 +100,7 @@ class TRINITY_DLL_SPEC WorldSession
{
friend class CharacterHandler;
public:
- WorldSession(uint32 id, WorldSocket *sock, uint32 sec, uint8 expansion, time_t mute_time, LocaleConstant locale);
+ WorldSession(uint32 id, WorldSocket *sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale);
~WorldSession();
bool PlayerLoading() const { return m_playerLoading; }
@@ -81,6 +108,11 @@ class TRINITY_DLL_SPEC WorldSession
void SizeError(WorldPacket const& packet, uint32 size) const;
+ void ReadAddonsInfo(WorldPacket &data);
+ void SendAddonsInfo();
+
+ void ReadMovementInfo(WorldPacket &data, MovementInfo *mi);
+
void SendPacket(WorldPacket const* packet);
void SendNotification(const char *format,...) ATTR_PRINTF(2,3);
void SendNotification(int32 string_id,...);
@@ -88,12 +120,13 @@ class TRINITY_DLL_SPEC WorldSession
void SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type);
void SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res);
void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2,3);
+ void SendSetPhaseShift(uint32 phaseShift);
- uint32 GetSecurity() const { return _security; }
+ AccountTypes GetSecurity() const { return _security; }
uint32 GetAccountId() const { return _accountId; }
Player* GetPlayer() const { return _player; }
char const* GetPlayerName() const;
- void SetSecurity(uint32 security) { _security = security; }
+ void SetSecurity(AccountTypes security) { _security = security; }
std::string const& GetRemoteAddress() { return m_Address; }
void SetPlayer(Player *plr) { _player = plr; }
uint8 Expansion() const { return m_expansion; }
@@ -141,7 +174,7 @@ class TRINITY_DLL_SPEC WorldSession
void SendAttackStop(Unit const* enemy);
- void SendBattlegGroundList( uint64 guid, uint32 bgTypeId );
+ void SendBattlegGroundList( uint64 guid, BattleGroundTypeId bgTypeId );
void SendTradeStatus(uint32 status);
void SendCancelTrade();
@@ -153,6 +186,11 @@ class TRINITY_DLL_SPEC WorldSession
//pet
void SendPetNameQuery(uint64 guid, uint32 petnumber);
+ // Account Data
+ AccountData *GetAccountData(uint32 type) { return &m_accountData[type]; }
+ void SetAccountData(uint32 type, time_t time_, std::string data);
+ void LoadAccountData();
+
//mail
//used with item_page table
bool SendItemInfo( uint32 itemid, WorldPacket data );
@@ -309,6 +347,7 @@ class TRINITY_DLL_SPEC WorldSession
void HandleGameObjectUseOpcode(WorldPacket& recPacket);
void HandleMeetingStoneInfo(WorldPacket& recPacket);
+ void HandleGameobjectReportUse(WorldPacket& recvPacket);
void HandleNameQueryOpcode(WorldPacket& recvPacket);
@@ -322,9 +361,11 @@ class TRINITY_DLL_SPEC WorldSession
void HandleMoveWorldportAckOpcode(); // for server-side calls
void HandleMovementOpcodes(WorldPacket& recvPacket);
- void HandlePossessedMovement(WorldPacket& recv_data, MovementInfo& movementInfo, uint32& MovementFlags);
void HandleSetActiveMoverOpcode(WorldPacket &recv_data);
- void HandleNotActiveMoverOpcode(WorldPacket &recv_data);
+ void HandleMoveNotActiveMover(WorldPacket &recv_data);
+ void HandleDismissControlledVehicle(WorldPacket &recv_data);
+ void HandleRequestVehicleExit(WorldPacket &recv_data);
+ void HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data);
void HandleMoveTimeSkippedOpcode(WorldPacket &recv_data);
void HandleRequestRaidInfoOpcode( WorldPacket & recv_data );
@@ -385,7 +426,7 @@ class TRINITY_DLL_SPEC WorldSession
void HandleGuildSaveEmblemOpcode(WorldPacket& recvPacket);
void HandleTaxiNodeStatusQueryOpcode(WorldPacket& recvPacket);
- void HandleTaxiQueryAvailableNodesOpcode(WorldPacket& recvPacket);
+ void HandleTaxiQueryAvailableNodes(WorldPacket& recvPacket);
void HandleActivateTaxiOpcode(WorldPacket& recvPacket);
void HandleActivateTaxiFarOpcode(WorldPacket& recvPacket);
void HandleTaxiNextDestinationOpcode(WorldPacket& recvPacket);
@@ -429,6 +470,7 @@ class TRINITY_DLL_SPEC WorldSession
void HandleAuctionRemoveItem( WorldPacket & recv_data );
void HandleAuctionListOwnerItems( WorldPacket & recv_data );
void HandleAuctionPlaceBid( WorldPacket & recv_data );
+ void HandleAuctionListPendingSales( WorldPacket & recv_data );
void HandleGetMail( WorldPacket & recv_data );
void HandleSendMail( WorldPacket & recv_data );
@@ -536,6 +578,7 @@ class TRINITY_DLL_SPEC WorldSession
//Pet
void HandlePetAction( WorldPacket & recv_data );
+ void HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid, uint16 flag, uint64 guid2);
void HandlePetNameQuery( WorldPacket & recv_data );
void HandlePetSetAction( WorldPacket & recv_data );
void HandlePetAbandon( WorldPacket & recv_data );
@@ -544,6 +587,7 @@ class TRINITY_DLL_SPEC WorldSession
void HandlePetUnlearnOpcode( WorldPacket& recvPacket );
void HandlePetSpellAutocastOpcode( WorldPacket& recvPacket );
void HandlePetCastSpellOpcode( WorldPacket& recvPacket );
+ void HandlePetLearnTalent( WorldPacket& recvPacket );
void HandleSetActionBar(WorldPacket& recv_data);
@@ -580,10 +624,9 @@ class TRINITY_DLL_SPEC WorldSession
void HandleLfmSetNoneOpcode(WorldPacket& recv_data);
void HandleLfmSetOpcode(WorldPacket& recv_data);
void HandleLfgSetCommentOpcode(WorldPacket& recv_data);
- void HandleNewUnknownOpcode(WorldPacket& recv_data);
void HandleChooseTitleOpcode(WorldPacket& recv_data);
void HandleRealmStateRequestOpcode(WorldPacket& recv_data);
- void HandleAllowMoveAckOpcode(WorldPacket& recv_data);
+ void HandleTimeSyncResp(WorldPacket& recv_data);
void HandleWhoisOpcode(WorldPacket& recv_data);
void HandleResetInstancesOpcode(WorldPacket& recv_data);
@@ -629,6 +672,29 @@ class TRINITY_DLL_SPEC WorldSession
void HandleGuildBankBuyTab(WorldPacket& recv_data);
void HandleGuildBankTabText(WorldPacket& recv_data);
void HandleGuildBankSetTabText(WorldPacket& recv_data);
+
+ // Calendar
+ void HandleCalendarGetCalendar(WorldPacket& recv_data);
+ void HandleCalendarGetEvent(WorldPacket& recv_data);
+ void HandleCalendarGuildFilter(WorldPacket& recv_data);
+ void HandleCalendarArenaTeam(WorldPacket& recv_data);
+ void HandleCalendarAddEvent(WorldPacket& recv_data);
+ void HandleCalendarUpdateEvent(WorldPacket& recv_data);
+ void HandleCalendarRemoveEvent(WorldPacket& recv_data);
+ void HandleCalendarCopyEvent(WorldPacket& recv_data);
+ void HandleCalendarEventInvite(WorldPacket& recv_data);
+ void HandleCalendarEventRsvp(WorldPacket& recv_data);
+ void HandleCalendarEventRemoveInvite(WorldPacket& recv_data);
+ void HandleCalendarEventStatus(WorldPacket& recv_data);
+ void HandleCalendarEventModeratorStatus(WorldPacket& recv_data);
+ void HandleCalendarComplain(WorldPacket& recv_data);
+ void HandleCalendarGetNumPending(WorldPacket& recv_data);
+
+ void HandleSpellClick(WorldPacket& recv_data);
+ void HandleAlterAppearance(WorldPacket& recv_data);
+ void HandleRemoveGlyph(WorldPacket& recv_data);
+ void HandleCharCustomize(WorldPacket& recv_data);
+ void HandleInspectAchievements(WorldPacket& recv_data);
private:
// private trade methods
void moveItems(Item* myItems[], Item* hisItems[]);
@@ -639,7 +705,7 @@ class TRINITY_DLL_SPEC WorldSession
WorldSocket *m_Socket;
std::string m_Address;
- uint32 _security;
+ AccountTypes _security;
uint32 _accountId;
uint8 m_expansion;
@@ -651,6 +717,8 @@ class TRINITY_DLL_SPEC WorldSession
LocaleConstant m_sessionDbcLocale;
int m_sessionDbLocaleIndex;
uint32 m_latency;
+ AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES];
+ AddonsList m_addonsList;
ZThread::LockedQueue<WorldPacket*,ZThread::FastMutex> _recvQueue;
};
diff --git a/src/game/WorldSocket.cpp b/src/game/WorldSocket.cpp
index 9a5ec6c48c3..9c2c0c7c9f1 100644
--- a/src/game/WorldSocket.cpp
+++ b/src/game/WorldSocket.cpp
@@ -1,7 +1,7 @@
/*
-* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
-* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+* Copyright (C) 2008-2009 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
@@ -37,7 +37,6 @@
#include "WorldPacket.h"
#include "SharedDefines.h"
#include "ByteBuffer.h"
-#include "AddonHandler.h"
#include "Opcodes.h"
#include "Database/DatabaseEnv.h"
#include "Auth/Sha1.h"
@@ -54,8 +53,37 @@
struct ServerPktHeader
{
- uint16 size;
- uint16 cmd;
+ /**
+ * size is the length of the payload _plus_ the length of the opcode
+ */
+ ServerPktHeader(uint32 size, uint16 cmd) : size(size)
+ {
+ uint8 headerIndex=0;
+ if(isLargePacket())
+ {
+ sLog.outDebug("initializing large server to client packet. Size: %u, cmd: %u", size, cmd);
+ header[headerIndex++] = 0x80|(0xFF &(size>>16));
+ }
+ header[headerIndex++] = 0xFF &(size>>8);
+ header[headerIndex++] = 0xFF &size;
+
+ header[headerIndex++] = 0xFF & cmd;
+ header[headerIndex++] = 0xFF & (cmd>>8);
+ }
+
+ uint8 getHeaderLength()
+ {
+ // cmd = 2 bytes, size= 2||3bytes
+ return 2+(isLargePacket()?3:2);
+ }
+
+ bool isLargePacket()
+ {
+ return size > 0x7FFF;
+ }
+
+ const uint32 size;
+ uint8 header[5];
};
struct ClientPktHeader
@@ -142,7 +170,7 @@ int WorldSocket::SendPacket (const WorldPacket& pct)
// Dump outgoing packet.
if (sWorldLog.LogWorld ())
{
- sWorldLog.Log ("SERVER:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
+ sWorldLog.outTimestampLog ("SERVER:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
(uint32) get_handle (),
pct.size (),
LookupOpcodeName (pct.GetOpcode ()),
@@ -152,12 +180,11 @@ int WorldSocket::SendPacket (const WorldPacket& pct)
while (p < pct.size ())
{
for (uint32 j = 0; j < 16 && p < pct.size (); j++)
- sWorldLog.Log ("%.2X ", const_cast<WorldPacket&>(pct)[p++]);
+ sWorldLog.outLog ("%.2X ", const_cast<WorldPacket&>(pct)[p++]);
- sWorldLog.Log ("\n");
+ sWorldLog.outLog ("\n");
}
-
- sWorldLog.Log ("\n\n");
+ sWorldLog.outLog ("\n");
}
if (iSendPacket (pct) == -1)
@@ -272,7 +299,7 @@ int WorldSocket::handle_input (ACE_HANDLE)
}
case 0:
{
- DEBUG_LOG ("WorldSocket::handle_input: Peer has closed connection\n");
+ DEBUG_LOG ("WorldSocket::handle_input: Peer has closed connection");
errno = ECONNRESET;
return -1;
@@ -374,7 +401,7 @@ int WorldSocket::handle_input_header (void)
ACE_ASSERT (m_Header.length () == sizeof (ClientPktHeader));
- m_Crypt.DecryptRecv ((ACE_UINT8*) m_Header.rd_ptr (), sizeof (ClientPktHeader));
+ m_Crypt.DecryptRecv ((uint8*) m_Header.rd_ptr (), sizeof (ClientPktHeader));
ClientPktHeader& header = *((ClientPktHeader*) m_Header.rd_ptr ());
@@ -574,7 +601,7 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
// Dump received packet.
if (sWorldLog.LogWorld ())
{
- sWorldLog.Log ("CLIENT:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
+ sWorldLog.outTimestampLog ("CLIENT:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
(uint32) get_handle (),
new_pct->size (),
LookupOpcodeName (new_pct->GetOpcode ()),
@@ -584,10 +611,11 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
while (p < new_pct->size ())
{
for (uint32 j = 0; j < 16 && p < new_pct->size (); j++)
- sWorldLog.Log ("%.2X ", (*new_pct)[p++]);
- sWorldLog.Log ("\n");
+ sWorldLog.outLog ("%.2X ", (*new_pct)[p++]);
+
+ sWorldLog.outLog ("\n");
}
- sWorldLog.Log ("\n\n");
+ sWorldLog.outLog ("\n");
}
// like one switch ;)
@@ -626,7 +654,7 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
}
else
{
- sLog.outError ("WorldSocket::ProcessIncoming: Client not authed opcode = ", opcode);
+ sLog.outError ("WorldSocket::ProcessIncoming: Client not authed opcode = %u", uint32(opcode));
return -1;
}
}
@@ -639,7 +667,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
// NOTE: ATM the socket is singlethread, have this in mind ...
uint8 digest[20];
uint32 clientSeed;
- uint32 unk2;
+ uint32 unk2, unk3;
uint32 BuiltNumberClient;
uint32 id, security;
//uint8 expansion = 0;
@@ -657,10 +685,21 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
return -1;
}
+ if(sWorld.IsClosed())
+ {
+ packet.Initialize(SMSG_AUTH_RESPONSE, 1);
+ packet << uint8(AUTH_REJECT);
+ SendPacket (packet);
+
+ sLog.outError ("WorldSocket::HandleAuthSession: World closed, denying client (%s).", m_Session->GetRemoteAddress());
+ return -1;
+ }
+
// Read the content of the packet
recvPacket >> BuiltNumberClient; // for now no use
recvPacket >> unk2;
recvPacket >> account;
+ recvPacket >> unk3;
if (recvPacket.size () < (4 + 4 + (account.size () + 1) + 4 + 20))
{
@@ -684,17 +723,17 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
QueryResult *result =
LoginDatabase.PQuery ("SELECT "
- "id, " //0
- "gmlevel, " //1
- "sessionkey, " //2
- "last_ip, " //3
- "locked, " //4
- "sha_pass_hash, " //5
- "v, " //6
- "s, " //7
- "expansion, " //8
- "mutetime, " //9
- "locale " //10
+ "id, " //0
+ "gmlevel, " //1
+ "sessionkey, " //2
+ "last_ip, " //3
+ "locked, " //4
+ "sha_pass_hash, " //5
+ "v, " //6
+ "s, " //7
+ "expansion, " //8
+ "mutetime, " //9
+ "locale " //10
"FROM account "
"WHERE username = '%s'",
safe_account.c_str ());
@@ -788,6 +827,11 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
id = fields[0].GetUInt32 ();
security = fields[1].GetUInt16 ();
+ /*
+ if(security > SEC_ADMINISTRATOR) // prevent invalid security settings in DB
+ security = SEC_ADMINISTRATOR;
+ */
+
K.SetHexStr (fields[2].GetString ());
time_t mutetime = time_t (fields[9].GetUInt64 ());
@@ -823,7 +867,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
// Check locked state for server
AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit ();
- if (allowedAccountType > SEC_PLAYER && security < allowedAccountType)
+ if (allowedAccountType > SEC_PLAYER && AccountTypes(security) < allowedAccountType)
{
WorldPacket Packet (SMSG_AUTH_RESPONSE, 1);
Packet << uint8 (AUTH_UNAVAILABLE);
@@ -874,21 +918,20 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
address.c_str (),
safe_account.c_str ());
- // NOTE ATM the socket is singlethreaded, have this in mind ...
- ACE_NEW_RETURN (m_Session, WorldSession (id, this, security, expansion, mutetime, locale), -1);
+ // NOTE ATM the socket is single-threaded, have this in mind ...
+ ACE_NEW_RETURN (m_Session, WorldSession (id, this, AccountTypes(security), expansion, mutetime, locale), -1);
m_Crypt.SetKey (&K);
m_Crypt.Init ();
+ m_Session->LoadAccountData();
+ m_Session->ReadAddonsInfo(recvPacket);
+
// In case needed sometime the second arg is in microseconds 1 000 000 = 1 sec
ACE_OS::sleep (ACE_Time_Value (0, 10000));
sWorld.AddSession (m_Session);
- // Create and send the Addon packet
- if (sAddOnHandler.BuildAddonPacket (&recvPacket, &SendAddonPacked))
- SendPacket (SendAddonPacked);
-
return 0;
}
@@ -963,23 +1006,17 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket)
int WorldSocket::iSendPacket (const WorldPacket& pct)
{
- if (m_OutBuffer->space () < pct.size () + sizeof (ServerPktHeader))
+ ServerPktHeader header(pct.size()+2, pct.GetOpcode());
+ if (m_OutBuffer->space () < pct.size () + header.getHeaderLength())
{
errno = ENOBUFS;
return -1;
}
-
- ServerPktHeader header;
-
- header.cmd = pct.GetOpcode ();
- EndianConvert(header.cmd);
-
- header.size = (uint16) pct.size () + 2;
- EndianConvertReverse(header.size);
-
- m_Crypt.EncryptSend ((uint8*) & header, sizeof (header));
-
- if (m_OutBuffer->copy ((char*) & header, sizeof (header)) == -1)
+
+
+ m_Crypt.EncryptSend ( header.header, header.getHeaderLength());
+
+ if (m_OutBuffer->copy ((char*) header.header, header.getHeaderLength()) == -1)
ACE_ASSERT (false);
if (!pct.empty ())
diff --git a/src/game/WorldSocket.h b/src/game/WorldSocket.h
index 7adf16373fe..94f57d8d636 100644
--- a/src/game/WorldSocket.h
+++ b/src/game/WorldSocket.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/game/WorldSocketMgr.cpp b/src/game/WorldSocketMgr.cpp
index e73b8993d0b..cc08962efa5 100644
--- a/src/game/WorldSocketMgr.cpp
+++ b/src/game/WorldSocketMgr.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2005-2008,2007 MaNGOS <http://getmangos.com/>
*
-* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+* Copyright (C) 2008-2009 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
@@ -134,7 +134,7 @@ class ReactorRunnable : protected ACE_Task_Base
if (m_NewSockets.empty ())
return;
- for (SocketSet::iterator i = m_NewSockets.begin (); i != m_NewSockets.end (); ++i)
+ for (SocketSet::const_iterator i = m_NewSockets.begin (); i != m_NewSockets.end (); ++i)
{
WorldSocket* sock = (*i);
@@ -176,14 +176,14 @@ class ReactorRunnable : protected ACE_Task_Base
if ((*i)->Update () == -1)
{
t = i;
- i++;
+ ++i;
(*t)->CloseSocket ();
(*t)->RemoveReference ();
--m_Connections;
m_Sockets.erase (t);
}
else
- i++;
+ ++i;
}
}
diff --git a/src/game/WorldSocketMgr.h b/src/game/WorldSocketMgr.h
index f6e55614d46..94cfa78324c 100644
--- a/src/game/WorldSocketMgr.h
+++ b/src/game/WorldSocketMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Auth/AuthCrypt.cpp b/src/shared/Auth/AuthCrypt.cpp
index 7cbb7f13648..0b2a3f64338 100644
--- a/src/shared/Auth/AuthCrypt.cpp
+++ b/src/shared/Auth/AuthCrypt.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -50,9 +50,8 @@ void AuthCrypt::DecryptRecv(uint8 *data, size_t len)
void AuthCrypt::EncryptSend(uint8 *data, size_t len)
{
if (!_initialized) return;
- if (len < CRYPTED_SEND_LEN) return;
- for (size_t t = 0; t < CRYPTED_SEND_LEN; t++)
+ for (size_t t = 0; t < len; t++)
{
_send_i %= _key.size();
uint8 x = (data[t] ^ _key[_send_i]) + _send_j;
@@ -67,7 +66,7 @@ void AuthCrypt::SetKey(BigNumber *bn)
GenerateKey(key, bn);
_key.resize(SHA_DIGEST_LENGTH);
std::copy(key, key + SHA_DIGEST_LENGTH, _key.begin());
- delete key;
+ delete[] key;
}
AuthCrypt::~AuthCrypt()
diff --git a/src/shared/Auth/AuthCrypt.h b/src/shared/Auth/AuthCrypt.h
index 020f8bcdc96..5c35511ad9f 100644
--- a/src/shared/Auth/AuthCrypt.h
+++ b/src/shared/Auth/AuthCrypt.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -32,7 +32,6 @@ class AuthCrypt
AuthCrypt();
~AuthCrypt();
- const static size_t CRYPTED_SEND_LEN = 4;
const static size_t CRYPTED_RECV_LEN = 6;
void Init();
diff --git a/src/shared/Auth/BigNumber.cpp b/src/shared/Auth/BigNumber.cpp
index da31da3a522..7872b141f3d 100644
--- a/src/shared/Auth/BigNumber.cpp
+++ b/src/shared/Auth/BigNumber.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Auth/BigNumber.h b/src/shared/Auth/BigNumber.h
index df25e4f934d..b9038e86b13 100644
--- a/src/shared/Auth/BigNumber.h
+++ b/src/shared/Auth/BigNumber.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Auth/Hmac.cpp b/src/shared/Auth/Hmac.cpp
index 615edd26ca5..a8572f0e9f8 100644
--- a/src/shared/Auth/Hmac.cpp
+++ b/src/shared/Auth/Hmac.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Auth/Hmac.h b/src/shared/Auth/Hmac.h
index 5b7c4040f13..fc80bdca4c4 100644
--- a/src/shared/Auth/Hmac.h
+++ b/src/shared/Auth/Hmac.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Auth/Makefile.am b/src/shared/Auth/Makefile.am
new file mode 100644
index 00000000000..7398e2f2fa7
--- /dev/null
+++ b/src/shared/Auth/Makefile.am
@@ -0,0 +1,41 @@
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+#
+# Copyright (C) 2008-2009 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
+
+## Process this file with automake to produce Makefile.in
+
+## Sub-directories to parse
+
+## CPP flags for includes, defines, etc.
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared -I$(srcdir)/../../../dep/include/g3dlite
+
+## Build MaNGOS shared library and its parts as convenience library.
+# All libraries will be convenience libraries. Might be changed to shared
+# later.
+noinst_LIBRARIES = libmangosauth.a
+
+libmangosauth_a_SOURCES = \
+ AuthCrypt.cpp \
+ AuthCrypt.h \
+ BigNumber.cpp \
+ BigNumber.h \
+ Hmac.cpp \
+ Hmac.h \
+ Sha1.cpp \
+ Sha1.h \
+ md5.c \
+ md5.h
diff --git a/src/shared/Auth/Sha1.cpp b/src/shared/Auth/Sha1.cpp
index 90334543b82..8743a14b838 100644
--- a/src/shared/Auth/Sha1.cpp
+++ b/src/shared/Auth/Sha1.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Auth/Sha1.h b/src/shared/Auth/Sha1.h
index 6794d3bd103..68c61eb7a8e 100644
--- a/src/shared/Auth/Sha1.h
+++ b/src/shared/Auth/Sha1.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Base.cpp b/src/shared/Base.cpp
deleted file mode 100644
index ca5094810d6..00000000000
--- a/src/shared/Base.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- Base class interface
- Copyright (C) 1998,1999 by Andrew Zabolotny
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "Base.h"
-
-Base::~Base ()
-{
-}
-
-/**
- * Decrement object's reference count; as soon as the last reference
- * to the object is removed, it is destroyed.
- */
-
-void Base::DecRef ()
-{
- if (!--RefCount)
- delete this;
-}
-
-/**
- * Object initialization. The initial reference count is set to one;
- * this means if you call DecRef() immediately after creating the object,
- * it will be destroyed.
- */
-Base::Base ()
-{
- RefCount = 1;
-}
-
-/**
- * Increment reference count.
- * Every time when you copy a pointer to a object and store it for
- * later use you MUST call IncRef() on it; this will allow to keep
- * objects as long as they are referenced by some entity.
- */
-void Base::IncRef ()
-{
- ++RefCount;
-
-}
-
-/**
- * Query number of references to this object.
- * I would rather prefer to have the reference counter strictly private,
- * but sometimes, mostly for debugging, such a function can help.
- */
-int Base::GetRefCount ()
-{
- return RefCount;
-}
-
diff --git a/src/shared/Base.h b/src/shared/Base.h
deleted file mode 100644
index e14ea6b27b9..00000000000
--- a/src/shared/Base.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- Base class interface
- Copyright (C) 1998,1999 by Andrew Zabolotny
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __BASE_H__
-#define __BASE_H__
-
-#include "Common.h"
-
-/**
- * This class is intended to be a base class for every other class.
- * It defines the basic interface available for any object.
- */
-class Base
-{
- private:
- /// Object reference count
- int RefCount;
-
- protected:
- /**
- * Destroy this object. Destructor is virtual, because class contains
- * virtual methods; also it is private because it is never intended
- * to be called directly; use DecRef() instead: when reference counter
- * reaches zero, the object will be destroyed.
- */
- virtual ~Base ();
-
- public:
-
- Base ();
-
- void IncRef ();
-
- void DecRef ();
- int GetRefCount ();
-
-};
-#endif // __BASE_H__
-
diff --git a/src/shared/ByteBuffer.h b/src/shared/ByteBuffer.h
index fb2d7cfc7b9..16988632871 100644
--- a/src/shared/ByteBuffer.h
+++ b/src/shared/ByteBuffer.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -243,6 +243,32 @@ class ByteBuffer
_rpos += len;
}
+ bool readPackGUID(uint64& guid)
+ {
+ if(rpos()+1 > size())
+ return false;
+
+ guid = 0;
+
+ uint8 guidmark=0;
+ (*this) >> guidmark;
+
+ for(int i=0;i<8;i++)
+ {
+ if(guidmark & (uint8(1) << i))
+ {
+ if(rpos()+1 > size())
+ return false;
+
+ uint8 bit;
+ (*this) >> bit;
+ guid |= (uint64(bit) << (i*8));
+ }
+ }
+
+ return true;
+ }
+
const uint8 *contents() const { return &_storage[0]; }
size_t size() const { return _storage.size(); }
@@ -314,7 +340,7 @@ class ByteBuffer
if(!sLog.IsOutDebug()) // optimize disabled debug output
return;
- sLog.outDebug("STORAGE_SIZE: %u", size() );
+ sLog.outDebug("STORAGE_SIZE: %lu", (unsigned long)size() );
for(uint32 i = 0; i < size(); i++)
sLog.outDebugInLine("%u - ", read<uint8>(i) );
sLog.outDebug(" ");
@@ -325,7 +351,7 @@ class ByteBuffer
if(!sLog.IsOutDebug()) // optimize disabled debug output
return;
- sLog.outDebug("STORAGE_SIZE: %u", size() );
+ sLog.outDebug("STORAGE_SIZE: %lu", (unsigned long)size() );
for(uint32 i = 0; i < size(); i++)
sLog.outDebugInLine("%c", read<uint8>(i) );
sLog.outDebug(" ");
@@ -337,10 +363,7 @@ class ByteBuffer
return;
uint32 j = 1, k = 1;
- sLog.outDebug("STORAGE_SIZE: %u", size() );
-
- if(sLog.IsIncludeTime())
- sLog.outDebugInLine(" ");
+ sLog.outDebug("STORAGE_SIZE: %lu", (unsigned long)size() );
for(uint32 i = 0; i < size(); i++)
{
@@ -361,16 +384,12 @@ class ByteBuffer
if (read<uint8>(i) < 0x0F)
{
sLog.outDebugInLine("\n");
- if(sLog.IsIncludeTime())
- sLog.outDebugInLine(" ");
sLog.outDebugInLine("0%X ", read<uint8>(i) );
}
else
{
sLog.outDebugInLine("\n");
- if(sLog.IsIncludeTime())
- sLog.outDebugInLine(" ");
sLog.outDebugInLine("%X ", read<uint8>(i) );
}
@@ -396,7 +415,7 @@ class ByteBuffer
protected:
bool PrintPosError(bool add, size_t pos, size_t esize) const
{
- sLog.outError("ERROR: Attempt %s in ByteBuffer (pos: %u size: %u) value with size: %u",(add ? "put" : "get"),pos, size(), esize);
+ sLog.outError("ERROR: Attempt %s in ByteBuffer (pos: %lu size: %lu) value with size: %lu",(add ? "put" : "get"),(unsigned long)pos, (unsigned long)size(), (unsigned long)esize);
// assert must fail after function call
return false;
@@ -478,5 +497,13 @@ template <typename K, typename V> ByteBuffer &operator>>(ByteBuffer &b, std::map
}
return b;
}
+
+// TODO: Make a ByteBuffer.cpp and move all this inlining to it.
+template<> inline std::string ByteBuffer::read<std::string>()
+{
+ std::string tmp;
+ *this >> tmp;
+ return tmp;
+}
#endif
diff --git a/src/shared/CMakeLists.txt b/src/shared/CMakeLists.txt
index 36d65544d3c..8ecfccad34f 100644
--- a/src/shared/CMakeLists.txt
+++ b/src/shared/CMakeLists.txt
@@ -6,16 +6,12 @@ add_subdirectory(Database)
########### next target ###############
SET(shared_STAT_SRCS
- Base.cpp
- Base.h
ByteBuffer.h
Common.cpp
Common.h
Errors.h
Log.cpp
Log.h
- Mthread.cpp
- Mthread.h
ProgressBar.cpp
ProgressBar.h
Timer.h
diff --git a/src/shared/Common.cpp b/src/shared/Common.cpp
index a31c88fdba5..27ae9184d69 100644
--- a/src/shared/Common.cpp
+++ b/src/shared/Common.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Common.h b/src/shared/Common.h
index 5e6a2cca520..abe804bb3a4 100644
--- a/src/shared/Common.h
+++ b/src/shared/Common.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -80,6 +80,8 @@
#pragma warning(disable:4305)
#pragma warning(disable:4005)
+
+#pragma warning(disable:4522)//warning when class has 2 constructosr
#endif // __SHOW_STUPID_WARNINGS__
#endif // __GNUC__
@@ -161,7 +163,9 @@ enum TimeConstants
MINUTE = 60,
HOUR = MINUTE*60,
DAY = HOUR*24,
- MONTH = DAY*30
+ MONTH = DAY*30,
+ YEAR = MONTH*12,
+ IN_MILISECONDS = 1000
};
enum AccountTypes
diff --git a/src/shared/Config/Config.cpp b/src/shared/Config/Config.cpp
index 4f9402b5f01..b56b804b50a 100644
--- a/src/shared/Config/Config.cpp
+++ b/src/shared/Config/Config.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -60,118 +60,48 @@ bool Config::Reload()
return true;
}
-bool Config::GetString(const char* name, std::string *value)
-{
- if(!mConf)
- return false;
-
- DOTCONFDocumentNode const *node = mConf->findNode(name);
- if(!node || !node->getValue())
- return false;
-
- *value = node->getValue();
-
- return true;
-}
-
-bool Config::GetString(const char* name, char const **value)
-{
- if(!mConf)
- return false;
-
- DOTCONFDocumentNode const *node = mConf->findNode(name);
- if(!node || !node->getValue())
- return false;
-
- *value = node->getValue();
-
- return true;
-}
-
-
-std::string Config::GetStringDefault(const char* name, const char* def)
+std::string Config::GetStringDefault(const char * name, std::string def)
{
if(!mConf)
return std::string(def);
-
- DOTCONFDocumentNode const *node = mConf->findNode(name);
+ const DOTCONFDocumentNode * node = mConf->findNode(name);
if(!node || !node->getValue())
return std::string(def);
-
return std::string(node->getValue());
-}
-
+};
-bool Config::GetBool(const char* name, bool *value)
+bool Config::GetBoolDefault(const char * name, const bool def)
{
if(!mConf)
return false;
-
- DOTCONFDocumentNode const *node = mConf->findNode(name);
+ const DOTCONFDocumentNode * node = mConf->findNode(name);
if(!node || !node->getValue())
- return false;
-
- const char* str = node->getValue();
+ return def;
+ const char * str = node->getValue();
if(strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0 ||
strcmp(str, "yes") == 0 || strcmp(str, "YES") == 0 ||
strcmp(str, "1") == 0)
- {
- *value = true;
- }
+ return true;
else
- *value = false;
-
- return true;
-}
-
-
-bool Config::GetBoolDefault(const char* name, const bool def)
-{
- bool val;
- return GetBool(name, &val) ? val : def;
-}
-
+ return false;
+};
-bool Config::GetInt(const char* name, int *value)
+int32 Config::GetIntDefault(const char * name, const int32 def)
{
if(!mConf)
- return false;
-
- DOTCONFDocumentNode const *node = mConf->findNode(name);
+ return def;
+ const DOTCONFDocumentNode * node = mConf->findNode(name);
if(!node || !node->getValue())
- return false;
-
- *value = atoi(node->getValue());
-
- return true;
-}
-
+ return def;
+ return atoi(node->getValue());
+};
-bool Config::GetFloat(const char* name, float *value)
+float Config::GetFloatDefault(const char * name, const float def)
{
if(!mConf)
- return false;
-
- DOTCONFDocumentNode const *node = mConf->findNode(name);
+ return def;
+ const DOTCONFDocumentNode * node = mConf->findNode(name);
if(!node || !node->getValue())
- return false;
-
- *value = atof(node->getValue());
-
- return true;
-}
-
-
-int Config::GetIntDefault(const char* name, const int def)
-{
- int val;
- return GetInt(name, &val) ? val : def;
-}
-
-
-float Config::GetFloatDefault(const char* name, const float def)
-{
- float val;
- return (GetFloat(name, &val) ? val : def);
-}
-
+ return def;
+ return atof(node->getValue());
+};
diff --git a/src/shared/Config/Config.h b/src/shared/Config/Config.h
index 4dbff1b1153..7070e6180c0 100644
--- a/src/shared/Config/Config.h
+++ b/src/shared/Config/Config.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -35,18 +35,10 @@ class TRINITY_DLL_SPEC Config
bool SetSource(const char *file, bool ignorecase = true);
bool Reload();
- bool GetString(const char* name, std::string *value);
- bool GetString(const char* name, char const **value);
- std::string GetStringDefault(const char* name, const char* def);
-
- bool GetBool(const char* name, bool *value);
- bool GetBoolDefault(const char* name, const bool def = false);
-
- bool GetInt(const char* name, int *value);
- int GetIntDefault(const char* name, const int def);
-
- bool GetFloat(const char* name, float *value);
- float GetFloatDefault(const char* name, const float def);
+ std::string GetStringDefault(const char * name, std::string def);
+ bool GetBoolDefault(const char * name, const bool def);
+ int32 GetIntDefault(const char * name, const int32 def);
+ float GetFloatDefault(const char * name, const float def);
std::string GetFilename() const { return mFilename; }
private:
diff --git a/src/shared/Config/ConfigEnv.h b/src/shared/Config/ConfigEnv.h
index eaa86c882df..75209a7fc6b 100644
--- a/src/shared/Config/ConfigEnv.h
+++ b/src/shared/Config/ConfigEnv.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Config/Makefile.am b/src/shared/Config/Makefile.am
new file mode 100644
index 00000000000..4854095b98c
--- /dev/null
+++ b/src/shared/Config/Makefile.am
@@ -0,0 +1,42 @@
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+#
+# Copyright (C) 2008-2009 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
+
+## Process this file with automake to produce Makefile.in
+
+## Sub-directories to parse
+
+## CPP flags for includes, defines, etc.
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared -I$(srcdir)/../../../dep/include/g3dlite
+
+## Build MaNGOS shared library and its parts as convenience library.
+# All libraries will be convenience libraries. Might be changed to shared
+# later.
+noinst_LIBRARIES = libmangosconfig.a
+
+libmangosconfig_a_SOURCES = \
+ dotconfpp/dotconfpp.cpp \
+ dotconfpp/dotconfpp.h \
+ dotconfpp/mempool.cpp \
+ dotconfpp/mempool.h \
+ Config.cpp \
+ Config.h \
+ ConfigEnv.h
+
+# VC++ project workspace for dotconfpp
+EXTRA_DIST = \
+ ConfigLibrary.vcproj
diff --git a/src/shared/Config/dotconfpp/dotconfpp.cpp b/src/shared/Config/dotconfpp/dotconfpp.cpp
index 3e2aa8683fe..edb85273742 100644
--- a/src/shared/Config/dotconfpp/dotconfpp.cpp
+++ b/src/shared/Config/dotconfpp/dotconfpp.cpp
@@ -55,13 +55,13 @@ DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity)
DOTCONFDocument::~DOTCONFDocument()
{
- for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i != nodeTree.end(); i++){
+ for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i){
delete(*i);
}
- for(std::list<char*>::iterator i = requiredOptions.begin(); i != requiredOptions.end(); i++){
+ for(std::list<char*>::iterator i = requiredOptions.begin(); i != requiredOptions.end(); ++i){
free(*i);
}
- for(std::list<char*>::iterator i = processedFiles.begin(); i != processedFiles.end(); i++){
+ for(std::list<char*>::iterator i = processedFiles.begin(); i != processedFiles.end(); ++i){
free(*i);
}
free(fileName);
@@ -138,7 +138,7 @@ int DOTCONFDocument::cleanupLine(char * line)
quoted = !quoted;
++line; continue;
}
- if(isspace(*line) && !quoted){
+ if(isspace((unsigned char)*line) && !quoted){
*bg++ = 0;
if(strlen(start)){
@@ -154,7 +154,7 @@ int DOTCONFDocument::cleanupLine(char * line)
words.push_back(word);
}
start = bg;
- while(isspace(*++line)) {}
+ while(isspace((unsigned char)*++line)) {}
continue;
}
@@ -177,7 +177,7 @@ int DOTCONFDocument::parseLine()
DOTCONFDocumentNode * tagNode = NULL;
bool newNode = false;
- for(std::list<char*>::iterator i = words.begin(); i != words.end(); i++) {
+ for(std::list<char*>::iterator i = words.begin(); i != words.end(); ++i) {
word = *i;
if(*word == '<'){
@@ -295,7 +295,7 @@ int DOTCONFDocument::checkConfig(const std::list<DOTCONFDocumentNode*>::iterator
DOTCONFDocumentNode * tagNode = NULL;
int vi = 0;
- for(std::list<DOTCONFDocumentNode*>::iterator i = from; i != nodeTree.end(); i++){
+ for(std::list<DOTCONFDocumentNode*>::iterator i = from; i != nodeTree.end(); ++i){
tagNode = *i;
if(!tagNode->closed){
error(tagNode->lineNum, tagNode->fileName, "unclosed tag %s", tagNode->name);
@@ -359,7 +359,7 @@ int DOTCONFDocument::setContent(const char * _fileName)
std::list<DOTCONFDocumentNode*>::iterator from;
DOTCONFDocumentNode * tagNode = NULL;
int vi = 0;
- for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i!=nodeTree.end(); i++){
+ for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i!=nodeTree.end(); ++i){
tagNode = *i;
if(!cmp_func("DOTCONFPPIncludeFile", tagNode->name)){
vi = 0;
@@ -374,7 +374,7 @@ int DOTCONFDocument::setContent(const char * _fileName)
}
bool processed = false;
- for(std::list<char*>::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); itInode++){
+ for(std::list<char*>::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); ++itInode){
if(!strcmp(*itInode, realpathBuf)){
processed = true;
break;
@@ -417,9 +417,9 @@ int DOTCONFDocument::setContent(const char * _fileName)
int DOTCONFDocument::checkRequiredOptions()
{
- for(std::list<char*>::const_iterator ci = requiredOptions.begin(); ci != requiredOptions.end(); ci++){
+ for(std::list<char*>::const_iterator ci = requiredOptions.begin(); ci != requiredOptions.end(); ++ci){
bool matched = false;
- for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i!=nodeTree.end(); i++){
+ for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i!=nodeTree.end(); ++i){
if(!cmp_func((*i)->name, *ci)){
matched = true;
break;
@@ -567,7 +567,7 @@ const DOTCONFDocumentNode * DOTCONFDocument::findNode(const char * nodeName, con
if( i != nodeTree.end() ) ++i;
}
- for(; i!=nodeTree.end(); i++){
+ for(; i!=nodeTree.end(); ++i){
if((*i)->parentNode != parentNode){
continue;
diff --git a/src/shared/Config/dotconfpp/mempool.cpp b/src/shared/Config/dotconfpp/mempool.cpp
index 487dae0bd0a..cec8e8d119f 100644
--- a/src/shared/Config/dotconfpp/mempool.cpp
+++ b/src/shared/Config/dotconfpp/mempool.cpp
@@ -22,7 +22,7 @@ AsyncDNSMemPool::AsyncDNSMemPool(size_t _defaultSize):
AsyncDNSMemPool::~AsyncDNSMemPool()
{
- for(size_t i = 0; i<chunksCount; i++){
+ for(size_t i = 0; i<chunksCount; ++i){
delete chunks[i];
}
::free(chunks);
@@ -53,7 +53,7 @@ void AsyncDNSMemPool::addNewChunk(size_t size)
void * AsyncDNSMemPool::alloc(size_t size)
{
PoolChunk * chunk = NULL;
- for(size_t i = 0; i<chunksCount; i++){
+ for(size_t i = 0; i<chunksCount; ++i){
chunk = chunks[i];
if((chunk->size - chunk->pos) >= size){
chunk->pos += size;
@@ -71,7 +71,7 @@ void AsyncDNSMemPool::free()
size_t psz = 0;
++poolUsageCounter;
- for(size_t i = 0; i<chunksCount; i++){
+ for(size_t i = 0; i<chunksCount; ++i){
pu += chunks[i]->pos;
psz += chunks[i]->size;
chunks[i]->pos = 0;
diff --git a/src/shared/Database/CMakeLists.txt b/src/shared/Database/CMakeLists.txt
index 78cc48436e7..c8d087b518f 100644
--- a/src/shared/Database/CMakeLists.txt
+++ b/src/shared/Database/CMakeLists.txt
@@ -1,18 +1,15 @@
SET(trinitydatabase_STAT_SRCS
- DBCStores.cpp
- DBCStores.h
- DBCStructure.h
- DBCfmt.cpp
+ DBCFileLoader.cpp
+ DBCFileLoader.h
+ DBCStore.h
Database.cpp
Database.h
- DatabaseEnv.h
+ DatabaseEnv.h
DatabaseImpl.h
DatabaseMysql.cpp
DatabasePostgre.cpp
DatabaseMysql.h
DatabasePostgre.h
- DatabaseSqlite.cpp
- DatabaseSqlite.h
Field.cpp
Field.h
MySQLDelayThread.h
@@ -22,16 +19,12 @@ SET(trinitydatabase_STAT_SRCS
QueryResultMysql.h
QueryResultPostgre.cpp
QueryResultPostgre.h
- QueryResultSqlite.cpp
- QueryResultSqlite.h
SQLStorage.cpp
SQLStorage.h
SqlDelayThread.cpp
SqlDelayThread.h
SqlOperations.cpp
SqlOperations.h
- dbcfile.cpp
- dbcfile.h
)
add_library(trinitydatabase STATIC ${trinitydatabase_STAT_SRCS})
diff --git a/src/shared/Database/DBCEnums.h b/src/shared/Database/DBCEnums.h
deleted file mode 100644
index d8699b2c240..00000000000
--- a/src/shared/Database/DBCEnums.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
-* 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
-
-// client supported max level for player/pets/etc. Avoid overflow or client stability affected.
-// also see GT_MAX_LEVEL define
-#define MAX_LEVEL 100
-
-// Server side limitation. Base at used code requirements.
-// also see MAX_LEVEL and GT_MAX_LEVEL define
-#define STRONG_MAX_LEVEL 255
-
-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/dbcfile.cpp b/src/shared/Database/DBCFileLoader.cpp
index 9b363dbff8d..23f602f5c93 100644
--- a/src/shared/Database/dbcfile.cpp
+++ b/src/shared/Database/DBCFileLoader.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -22,15 +22,15 @@
#include <stdlib.h>
#include <string.h>
-#include "dbcfile.h"
+#include "DBCFileLoader.h"
-DBCFile::DBCFile()
+DBCFileLoader::DBCFileLoader()
{
data = NULL;
fieldsOffset = NULL;
}
-bool DBCFile::Load(const char *filename, const char *fmt)
+bool DBCFileLoader::Load(const char *filename, const char *fmt)
{
uint32 header;
@@ -39,23 +39,35 @@ bool DBCFile::Load(const char *filename, const char *fmt)
delete [] data;
data=NULL;
}
+
FILE * f=fopen(filename,"rb");
if(!f)return false;
- fread(&header,4,1,f); // Number of records
+ if(fread(&header,4,1,f)!=1) // Number of records
+ return false;
+
EndianConvert(header);
if(header!=0x43424457)
- {
- //printf("not dbc file");
return false; //'WDBC'
- }
- fread(&recordCount,4,1,f); // Number of records
+
+ if(fread(&recordCount,4,1,f)!=1) // Number of records
+ return false;
+
EndianConvert(recordCount);
- fread(&fieldCount,4,1,f); // Number of fields
+
+ if(fread(&fieldCount,4,1,f)!=1) // Number of fields
+ return false;
+
EndianConvert(fieldCount);
- fread(&recordSize,4,1,f); // Size of a record
+
+ if(fread(&recordSize,4,1,f)!=1) // Size of a record
+ return false;
+
EndianConvert(recordSize);
- fread(&stringSize,4,1,f); // String size
+
+ if(fread(&stringSize,4,1,f)!=1) // String size
+ return false;
+
EndianConvert(stringSize);
fieldsOffset = new uint32[fieldCount];
@@ -71,12 +83,15 @@ bool DBCFile::Load(const char *filename, const char *fmt)
data = new unsigned char[recordSize*recordCount+stringSize];
stringTable = data + recordSize*recordCount;
- fread(data,recordSize*recordCount+stringSize,1,f);
+
+ if(fread(data,recordSize*recordCount+stringSize,1,f)!=1)
+ return false;
+
fclose(f);
return true;
}
-DBCFile::~DBCFile()
+DBCFileLoader::~DBCFileLoader()
{
if(data)
delete [] data;
@@ -84,13 +99,13 @@ DBCFile::~DBCFile()
delete [] fieldsOffset;
}
-DBCFile::Record DBCFile::getRecord(size_t id)
+DBCFileLoader::Record DBCFileLoader::getRecord(size_t id)
{
assert(data);
return Record(*this, data + id*recordSize);
}
-uint32 DBCFile::GetFormatRecordSize(const char * format,int32* index_pos)
+uint32 DBCFileLoader::GetFormatRecordSize(const char * format,int32* index_pos)
{
uint32 recordsize = 0;
int32 i = -1;
@@ -122,7 +137,7 @@ uint32 DBCFile::GetFormatRecordSize(const char * format,int32* index_pos)
return recordsize;
}
-char* DBCFile::AutoProduceData(const char* format, uint32& records, char**& indexTable)
+char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char**& indexTable)
{
/*
format STRING, NA, FLOAT,NA,INT <=>
@@ -205,7 +220,7 @@ char* DBCFile::AutoProduceData(const char* format, uint32& records, char**& inde
return dataTable;
}
-char* DBCFile::AutoProduceStrings(const char* format, char* dataTable)
+char* DBCFileLoader::AutoProduceStrings(const char* format, char* dataTable)
{
if(strlen(format)!=fieldCount)
return NULL;
diff --git a/src/shared/Database/dbcfile.h b/src/shared/Database/DBCFileLoader.h
index aa36f6003dc..13562148dfc 100644
--- a/src/shared/Database/dbcfile.h
+++ b/src/shared/Database/DBCFileLoader.h
@@ -1,7 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
- *
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 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
@@ -18,8 +16,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef DBCFILE_H
-#define DBCFILE_H
+#ifndef DBC_FILE_LOADER_H
+#define DBC_FILE_LOADER_H
#include "Platform/Define.h"
#include "Utilities/ByteConverter.h"
#include <cassert>
@@ -37,11 +35,11 @@ enum
FT_LOGIC='l' //Logical (boolean)
};
-class DBCFile
+class DBCFileLoader
{
public:
- DBCFile();
- ~DBCFile();
+ DBCFileLoader();
+ ~DBCFileLoader();
bool Load(const char *filename, const char *fmt);
@@ -77,11 +75,11 @@ class DBCFile
}
private:
- Record(DBCFile &file_, unsigned char *offset_): offset(offset_), file(file_) {}
+ Record(DBCFileLoader &file_, unsigned char *offset_): offset(offset_), file(file_) {}
unsigned char *offset;
- DBCFile &file;
+ DBCFileLoader &file;
- friend class DBCFile;
+ friend class DBCFileLoader;
};
@@ -107,4 +105,3 @@ class DBCFile
unsigned char *stringTable;
};
#endif
-
diff --git a/src/shared/Database/DBCStore.h b/src/shared/Database/DBCStore.h
new file mode 100644
index 00000000000..523d5c5a0b3
--- /dev/null
+++ b/src/shared/Database/DBCStore.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2005-2009 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 DBCSTORE_H
+#define DBCSTORE_H
+
+#include "DBCFileLoader.h"
+
+template<class T>
+class DBCStorage
+{
+ typedef std::list<char*> StringPoolList;
+ public:
+ explicit DBCStorage(const char *f) : nCount(0), fieldCount(0), fmt(f), indexTable(NULL), m_dataTable(NULL) { }
+ ~DBCStorage() { Clear(); }
+
+ T const* LookupEntry(uint32 id) const { return (id>=nCount)?NULL:indexTable[id]; }
+ uint32 GetNumRows() const { return nCount; }
+ char const* GetFormat() const { return fmt; }
+ uint32 GetFieldCount() const { return fieldCount; }
+
+ bool Load(char const* fn)
+ {
+ DBCFileLoader dbc;
+ // Check if load was sucessful, only then continue
+ if(!dbc.Load(fn, fmt))
+ return false;
+
+ fieldCount = dbc.GetCols();
+ m_dataTable = (T*)dbc.AutoProduceData(fmt,nCount,(char**&)indexTable);
+ m_stringPoolList.push_back(dbc.AutoProduceStrings(fmt,(char*)m_dataTable));
+
+ // error in dbc file at loading if NULL
+ return indexTable!=NULL;
+ }
+
+ bool LoadStringsFrom(char const* fn)
+ {
+ // DBC must be already loaded using Load
+ if(!indexTable)
+ return false;
+
+ DBCFileLoader dbc;
+ // Check if load was successful, only then continue
+ if(!dbc.Load(fn, fmt))
+ return false;
+
+ m_stringPoolList.push_back(dbc.AutoProduceStrings(fmt,(char*)m_dataTable));
+
+ return true;
+ }
+
+ void Clear()
+ {
+ if (!indexTable)
+ return;
+
+ delete[] ((char*)indexTable);
+ indexTable = NULL;
+ delete[] ((char*)m_dataTable);
+ m_dataTable = NULL;
+
+ while(!m_stringPoolList.empty())
+ {
+ delete[] m_stringPoolList.front();
+ m_stringPoolList.pop_front();
+ }
+ nCount = 0;
+ }
+
+ private:
+ uint32 nCount;
+ uint32 fieldCount;
+ char const* fmt;
+ T** indexTable;
+ T* m_dataTable;
+ StringPoolList m_stringPoolList;
+};
+#endif
diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h
deleted file mode 100644
index 95703f9b778..00000000000
--- a/src/shared/Database/DBCStructure.h
+++ /dev/null
@@ -1,904 +0,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
- */
-
-#ifndef DBCSTRUCTURE_H
-#define DBCSTRUCTURE_H
-
-#include "DBCEnums.h"
-#include "Platform/Define.h"
-
-#include <map>
-#include <set>
-#include <vector>
-
-// Structures using to access raw DBC data and required packing to portability
-
-// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
-#if defined( __GNUC__ )
-#pragma pack(1)
-#else
-#pragma pack(push,1)
-#endif
-
-struct AreaTableEntry
-{
- uint32 ID; // 0
- uint32 mapid; // 1
- uint32 zone; // 2 if 0 then it's zone, else it's zone id of this area
- uint32 exploreFlag; // 3, main index
- uint32 flags; // 4, unknown value but 312 for all cities
- // 5-9 unused
- int32 area_level; // 10
- char* area_name[16]; // 11-26
- // 27, string flags, unused
- uint32 team; // 28
-};
-
-struct AreaTriggerEntry
-{
- uint32 id; // 0
- uint32 mapid; // 1
- float x; // 2
- float y; // 3
- float z; // 4
- float radius; // 5
- float box_x; // 6 extent x edge
- float box_y; // 7 extent y edge
- float box_z; // 8 extent z edge
- float box_orientation; // 9 extent rotation by about z axis
-};
-
-struct AuctionHouseEntry
-{
- uint32 houseId; // 0 index
- uint32 faction; // 1 id of faction.dbc for player factions associated with city
- uint32 depositPercent; // 2 1/3 from real
- uint32 cutPercent; // 3
- //char* name[16]; // 4-19
- // 20 string flag, unused
-};
-
-struct BankBagSlotPricesEntry
-{
- uint32 ID;
- uint32 price;
-};
-
-struct BattlemasterListEntry
-{
- uint32 id; // 0
- uint32 mapid[3]; // 1-3 mapid
- // 4-8 unused
- uint32 type; // 9 (3 - BG, 4 - arena)
- uint32 minlvl; // 10
- uint32 maxlvl; // 11
- uint32 maxplayersperteam; // 12
- // 13-14 unused
- char* name[16]; // 15-30
- // 31 string flag, unused
- // 32 unused
-};
-
-#define MAX_OUTFIT_ITEMS 12
-// #define MAX_OUTFIT_ITEMS 24 // 12->24 in 3.0.x
-
-struct CharStartOutfitEntry
-{
- //uint32 Id; // 0
- uint32 RaceClassGender; // 1 (UNIT_FIELD_BYTES_0 & 0x00FFFFFF) comparable (0 byte = race, 1 byte = class, 2 byte = gender)
- int32 ItemId[MAX_OUTFIT_ITEMS]; // 2-13
- //int32 ItemDisplayId[MAX_OUTFIT_ITEMS]; // 14-25 not required at server side
- //int32 ItemInventorySlot[MAX_OUTFIT_ITEMS]; // 26-37 not required at server side
- //uint32 Unknown1; // 38, unique values (index-like with gaps ordered in other way as ids)
- //uint32 Unknown2; // 39
- //uint32 Unknown3; // 40
-};
-
-struct CharTitlesEntry
-{
- uint32 ID; // 0, title ids, for example in Quest::GetCharTitleId()
- //uint32 unk1; // 1 flags?
- //char* name[16]; // 2-17, unused
- // 18 string flag, unused
- //char* name2[16]; // 19-34, unused
- // 35 string flag, unused
- uint32 bit_index; // 36 used in PLAYER_CHOSEN_TITLE and 1<<index in PLAYER__FIELD_KNOWN_TITLES
-};
-
-struct ChatChannelsEntry
-{
- uint32 ChannelID; // 0
- uint32 flags; // 1
- char* pattern[16]; // 3-18
- // 19 string flags, unused
- //char* name[16]; // 20-35 unused
- // 36 string flag, unused
-};
-
-struct ChrClassesEntry
-{
- uint32 ClassID; // 0
- // 1-2, unused
- uint32 powerType; // 3
- // 4, unused
- //char* name[16]; // 5-20 unused
- char* name[16]; // 5-20 unused
- // 21 string flag, unused
- //char* nameFemale[16]; // 21-36 unused, if different from base (male) case
- // 37 string flag, unused
- //char* nameNeutralGender[16]; // 38-53 unused, if different from base (male) case
- // 54 string flag, unused
- // 55, unused
- uint32 spellfamily; // 56
- // 57, unused
-};
-
-struct ChrRacesEntry
-{
- uint32 RaceID; // 0
- // 1 unused
- uint32 FactionID; // 2 facton template id
- // 3 unused
- uint32 model_m; // 4
- uint32 model_f; // 5
- // 6-7 unused
- uint32 TeamID; // 8 (7-Alliance 1-Horde)
- // 9-12 unused
- uint32 startmovie; // 13 id from CinematicCamera.dbc
- char* name[16]; // 14-29 used for DBC language detection/selection
- // 30 string flags, unused
- //char* nameFemale[16]; // 31-46, if different from base (male) case
- // 47 string flags, unused
- //char* nameNeutralGender[16]; // 48-63, if different from base (male) case
- // 64 string flags, unused
- // 65-67 unused
- uint32 addon; // 68 (0 - original race, 1 - tbc addon, ...)
-};
-
-struct CreatureDisplayInfoEntry
-{
- uint32 Displayid; // 0
- // 1-3,unused
- float scale; // 4
- // 5-13,unused
-};
-
-struct CreatureFamilyEntry
-{
- uint32 ID; // 0
- float minScale; // 1
- uint32 minScaleLevel; // 2 0/1
- float maxScale; // 3
- uint32 maxScaleLevel; // 4 0/60
- uint32 skillLine[2]; // 5-6
- uint32 petFoodMask; // 7
- char* Name[16]; // 8-23
- // 24 string flags, unused
- // 25 icon, unused
-};
-
-struct CreatureSpellDataEntry
-{
- uint32 ID; // 0
- //uint32 spellId[4]; // 1-4 hunter pet learned spell (for later use)
-};
-
-struct DurabilityCostsEntry
-{
- uint32 Itemlvl; // 0
- uint32 multiplier[29]; // 1-29
-};
-
-struct DurabilityQualityEntry
-{
- uint32 Id; // 0
- float quality_mod; // 1
-};
-
-struct EmotesTextEntry
-{
- uint32 Id;
- uint32 textid;
-};
-
-struct FactionEntry
-{
- uint32 ID; // 0
- int32 reputationListID; // 1
- uint32 BaseRepRaceMask[4]; // 2-5 Base reputation race masks (see enum Races)
- uint32 BaseRepClassMask[4]; // 6-9 Base reputation class masks (see enum Classes)
- int32 BaseRepValue[4]; // 10-13 Base reputation values
- uint32 ReputationFlags[4]; // 14-17 Default flags to apply
- uint32 team; // 18 enum Team
- char* name[16]; // 19-34
- // 35 string flags, unused
- //char* description[16]; // 36-51 unused
- // 52 string flags, unused
-};
-
-struct FactionTemplateEntry
-{
- uint32 ID; // 0
- uint32 faction; // 1
- uint32 factionFlags; // 2 specific flags for that faction
- uint32 ourMask; // 3 if mask set (see FactionMasks) then faction included in masked team
- uint32 friendlyMask; // 4 if mask set (see FactionMasks) then faction friendly to masked team
- uint32 hostileMask; // 5 if mask set (see FactionMasks) then faction hostile to masked team
- uint32 enemyFaction1; // 6
- uint32 enemyFaction2; // 7
- uint32 enemyFaction3; // 8
- uint32 enemyFaction4; // 9
- uint32 friendFaction1; // 10
- uint32 friendFaction2; // 11
- uint32 friendFaction3; // 12
- uint32 friendFaction4; // 13
- //------------------------------------------------------- end structure
-
- // helpers
- bool IsFriendlyTo(FactionTemplateEntry const& entry) const
- {
- if(ID == entry.ID)
- return true;
- if(enemyFaction1 == entry.faction || enemyFaction2 == entry.faction || enemyFaction3 == entry.faction || enemyFaction4 == entry.faction )
- return false;
- if(friendFaction1 == entry.faction || friendFaction2 == entry.faction || friendFaction3 == entry.faction || friendFaction4 == entry.faction )
- return true;
- return (friendlyMask & entry.ourMask) || (ourMask & entry.friendlyMask);
- }
- bool IsHostileTo(FactionTemplateEntry const& entry) const
- {
- if(ID == entry.ID)
- return false;
- if(enemyFaction1 == entry.faction || enemyFaction2 == entry.faction || enemyFaction3 == entry.faction || enemyFaction4 == entry.faction )
- return true;
- if(friendFaction1 == entry.faction || friendFaction2 == entry.faction || friendFaction3 == entry.faction || friendFaction4 == entry.faction )
- return false;
- return (hostileMask & entry.ourMask) != 0;
- }
- bool IsHostileToPlayers() const { return (hostileMask & FACTION_MASK_PLAYER) !=0; }
- bool IsNeutralToAll() const { return hostileMask == 0 && friendlyMask == 0 && enemyFaction1==0 && enemyFaction2==0 && enemyFaction3==0 && enemyFaction4==0; }
- bool IsContestedGuardFaction() const { return (factionFlags & FACTION_TEMPLATE_FLAG_CONTESTED_GUARD)!=0; }
-};
-
-struct GemPropertiesEntry
-{
- uint32 ID;
- uint32 spellitemenchantement;
- uint32 color;
-};
-
-// All Gt* DBC store data for 100 levels, some by 100 per class/race
-#define GT_MAX_LEVEL 100
-
-struct GtCombatRatingsEntry
-{
- float ratio;
-};
-
-struct GtChanceToMeleeCritBaseEntry
-{
- float base;
-};
-
-struct GtChanceToMeleeCritEntry
-{
- float ratio;
-};
-
-struct GtChanceToSpellCritBaseEntry
-{
- float base;
-};
-
-struct GtChanceToSpellCritEntry
-{
- float ratio;
-};
-
-struct GtOCTRegenHPEntry
-{
- float ratio;
-};
-
-//struct GtOCTRegenMPEntry
-//{
-// float ratio;
-//};
-
-struct GtRegenHPPerSptEntry
-{
- float ratio;
-};
-
-struct GtRegenMPPerSptEntry
-{
- float ratio;
-};
-
-struct ItemEntry
-{
- uint32 ID;
- uint32 DisplayId;
- uint32 InventoryType;
- uint32 Sheath;
-};
-
-struct ItemDisplayInfoEntry
-{
- uint32 ID;
- uint32 randomPropertyChance;
-};
-
-//struct ItemCondExtCostsEntry
-//{
-// uint32 ID;
-// uint32 condExtendedCost; // ItemPrototype::CondExtendedCost
-// uint32 itemextendedcostentry; // ItemPrototype::ExtendedCost
-// uint32 arenaseason; // arena season number(1-4)
-//};
-
-struct ItemExtendedCostEntry
-{
- uint32 ID; // 0 extended-cost entry id
- uint32 reqhonorpoints; // 1 required honor points
- uint32 reqarenapoints; // 2 required arena points
- uint32 reqitem[5]; // 3-7 required item id
- uint32 reqitemcount[5]; // 8-12 required count of 1st item
- uint32 reqpersonalarenarating; // 13 required personal arena rating
-};
-
-struct ItemRandomPropertiesEntry
-{
- uint32 ID; // 0
- //char* internalName // 1 unused
- uint32 enchant_id[3]; // 2-4
- // 5-6 unused, 0 only values, reserved for additional enchantments?
- //char* nameSuffix[16] // 7-22, unused
- // 23 nameSufix flags, unused
-};
-
-struct ItemRandomSuffixEntry
-{
- uint32 ID; // 0
- //char* name[16] // 1-16 unused
- // 17, name flags, unused
- // 18 unused
- uint32 enchant_id[3]; // 19-21
- uint32 prefix[3]; // 22-24
-};
-
-struct ItemSetEntry
-{
- //uint32 id // 0 item set ID
- char* name[16]; // 1-16
- // 17 string flags, unused
- // 18-28 items from set, but not have all items listed, use ItemPrototype::ItemSet instead
- // 29-34 unused
- uint32 spells[8]; // 35-42
- uint32 items_to_triggerspell[8]; // 43-50
- uint32 required_skill_id; // 51
- uint32 required_skill_value; // 52
-};
-
-struct LockEntry
-{
- uint32 ID; // 0
- uint32 keytype[5]; // 1-5
- // 6-8, not used
- uint32 key[5]; // 9-13
- // 14-16, not used
- uint32 requiredminingskill; // 17
- uint32 requiredlockskill; // 18
- // 19-32, not used
-};
-
-struct MailTemplateEntry
-{
- uint32 ID; // 0
- //char* subject[16]; // 1-16
- // 17 name flags, unused
- //char* content[16]; // 18-33
-};
-
-struct MapEntry
-{
- uint32 MapID; // 0
- //char* internalname; // 1 unused
- uint32 map_type; // 2
- // 3 unused
- char* name[16]; // 4-19
- // 20 name flags, unused
- // 21-23 unused (something PvPZone related - levels?)
- // 24-26
- uint32 linked_zone; // 27 common zone for instance and continent map
- //char* hordeIntro // 28-43 text for PvP Zones
- // 44 intro text flags
- //char* allianceIntro // 45-60 text for PvP Zones
- // 46 intro text flags
- // 47-61 not used
- uint32 multimap_id; // 62
- // 63-65 not used
- //chat* unknownText1 // 66-81 unknown empty text fields, possible normal Intro text.
- // 82 text flags
- //chat* heroicIntroText // 83-98 heroic mode requirement text
- // 99 text flags
- //chat* unknownText2 // 100-115 unknown empty text fields
- // 116 text flags
- int32 entrance_map; // 117 map_id of entrance map
- float entrance_x; // 118 entrance x coordinate (if exist single entry)
- float entrance_y; // 119 entrance y coordinate (if exist single entry)
- uint32 resetTimeRaid; // 120
- uint32 resetTimeHeroic; // 121
- // 122-123
- uint32 addon; // 124 (0-original maps,1-tbc addon)
-
- // Helpers
- uint32 Expansion() const { return addon; }
-
-
- bool IsDungeon() const { return map_type == MAP_INSTANCE || map_type == MAP_RAID; }
- bool Instanceable() const { return map_type == MAP_INSTANCE || map_type == MAP_RAID || map_type == MAP_BATTLEGROUND || map_type == MAP_ARENA; }
- bool IsRaid() const { return map_type == MAP_RAID; }
- bool IsBattleGround() const { return map_type == MAP_BATTLEGROUND; }
- bool IsBattleArena() const { return map_type == MAP_ARENA; }
- bool IsBattleGroundOrArena() const { return map_type == MAP_BATTLEGROUND || map_type == MAP_ARENA; }
- bool SupportsHeroicMode() const { return resetTimeHeroic && !resetTimeRaid; }
- bool HasResetTime() const { return resetTimeHeroic || resetTimeRaid; }
-
- bool IsMountAllowed() const
- {
- return !IsDungeon() ||
- MapID==568 || MapID==309 || MapID==209 || MapID==534 ||
- MapID==560 || MapID==509 || MapID==269;
- }
-};
-
-struct QuestSortEntry
-{
- uint32 id; // 0, sort id
- //char* name[16]; // 1-16, unused
- // 17 name flags, unused
-};
-
-struct RandomPropertiesPointsEntry
-{
- //uint32 Id; // 0 hidden key
- uint32 itemLevel; // 1
- uint32 EpicPropertiesPoints[5]; // 2-6
- uint32 RarePropertiesPoints[5]; // 7-11
- uint32 UncommonPropertiesPoints[5]; // 12-16
-};
-
-//struct SkillLineCategoryEntry{
-// uint32 id; // 0 hidden key
-// char* name[16]; // 1 - 17 Category name
-// // 18 string flag
-// uint32 displayOrder; // Display order in character tab
-//};
-
-//struct SkillRaceClassInfoEntry{
-// uint32 id; // 0
-// uint32 skillId; // 1 present some refrences to unknown skill
-// uint32 raceMask; // 2
-// uint32 classMask; // 3
-// uint32 flags; // 4 mask for some thing
-// uint32 reqLevel; // 5
-// uint32 skillTierId; // 6
-// uint32 skillCostID; // 7
-//};
-
-//struct SkillTiersEntry{
-// uint32 id; // 0
-// uint32 skillValue[16]; // 1-17 unknown possibly add value on learn?
-// uint32 maxSkillValue[16]; // Max value for rank
-//};
-
-struct SkillLineEntry
-{
- uint32 id; // 0
- uint32 categoryId; // 1 (index from SkillLineCategory.dbc)
- //uint32 skillCostID; // 2 not used
- char* name[16]; // 3-18
- // 19 string flags, not used
- //char* description[16]; // 20-35, not used
- // 36 string flags, not used
- uint32 spellIcon; // 37
-};
-
-struct SkillLineAbilityEntry
-{
- uint32 id; // 0, INDEX
- uint32 skillId; // 1
- uint32 spellId; // 2
- uint32 racemask; // 3
- uint32 classmask; // 4
- //uint32 racemaskNot; // 5 always 0 in 2.4.2
- //uint32 classmaskNot; // 6 always 0 in 2.4.2
- uint32 req_skill_value; // 7 for trade skill.not for training.
- uint32 forward_spellid; // 8
- uint32 learnOnGetSkill; // 9 can be 1 or 2 for spells learned on get skill
- uint32 max_value; // 10
- uint32 min_value; // 11
- // 12-13, unknown, always 0
- uint32 reqtrainpoints; // 14
-};
-
-struct SoundEntriesEntry
-{
- uint32 Id; // 0, sound id
- //uint32 Type; // 1, sound type (10 generally for creature, etc)
- //char* InternalName; // 2, internal name, for use in lookup command for example
- //char* FileName[10]; // 3-12, file names
- //uint32 Unk13[10]; // 13-22, linked with file names?
- //char* Path; // 23
- // 24-28, unknown
-};
-
-struct SpellEntry
-{
- uint32 Id; // 0 normally counted from 0 field (but some tools start counting from 1, check this before tool use for data view!)
- uint32 Category; // 1
- //uint32 castUI // 2 not used
- uint32 Dispel; // 3
- uint32 Mechanic; // 4
- uint32 Attributes; // 5
- uint32 AttributesEx; // 6
- uint32 AttributesEx2; // 7
- uint32 AttributesEx3; // 8
- uint32 AttributesEx4; // 9
- uint32 AttributesEx5; // 10
- //uint32 AttributesEx6; // 11 not used
- uint32 Stances; // 12
- uint32 StancesNot; // 13
- uint32 Targets; // 14
- uint32 TargetCreatureType; // 15
- uint32 RequiresSpellFocus; // 16
- uint32 FacingCasterFlags; // 17
- uint32 CasterAuraState; // 18
- uint32 TargetAuraState; // 19
- uint32 CasterAuraStateNot; // 20
- uint32 TargetAuraStateNot; // 21
- uint32 CastingTimeIndex; // 22
- uint32 RecoveryTime; // 23
- uint32 CategoryRecoveryTime; // 24
- uint32 InterruptFlags; // 25
- uint32 AuraInterruptFlags; // 26
- uint32 ChannelInterruptFlags; // 27
- uint32 procFlags; // 28
- uint32 procChance; // 29
- uint32 procCharges; // 30
- uint32 maxLevel; // 31
- uint32 baseLevel; // 32
- uint32 spellLevel; // 33
- uint32 DurationIndex; // 34
- uint32 powerType; // 35
- uint32 manaCost; // 36
- uint32 manaCostPerlevel; // 37
- uint32 manaPerSecond; // 38
- uint32 manaPerSecondPerLevel; // 39
- uint32 rangeIndex; // 40
- float speed; // 41
- //uint32 modalNextSpell; // 42
- uint32 StackAmount; // 43
- uint32 Totem[2]; // 44-45
- int32 Reagent[8]; // 46-53
- uint32 ReagentCount[8]; // 54-61
- int32 EquippedItemClass; // 62 (value)
- int32 EquippedItemSubClassMask; // 63 (mask)
- int32 EquippedItemInventoryTypeMask; // 64 (mask)
- uint32 Effect[3]; // 65-67
- int32 EffectDieSides[3]; // 68-70
- uint32 EffectBaseDice[3]; // 71-73
- float EffectDicePerLevel[3]; // 74-76
- float EffectRealPointsPerLevel[3]; // 77-79
- int32 EffectBasePoints[3]; // 80-82 (don't must be used in spell/auras explicitly, must be used cached Spell::m_currentBasePoints)
- uint32 EffectMechanic[3]; // 83-85
- uint32 EffectImplicitTargetA[3]; // 86-88
- uint32 EffectImplicitTargetB[3]; // 89-91
- uint32 EffectRadiusIndex[3]; // 92-94 - spellradius.dbc
- uint32 EffectApplyAuraName[3]; // 95-97
- uint32 EffectAmplitude[3]; // 98-100
- float EffectMultipleValue[3]; // 101-103
- uint32 EffectChainTarget[3]; // 104-106
- uint32 EffectItemType[3]; // 107-109
- int32 EffectMiscValue[3]; // 110-112
- int32 EffectMiscValueB[3]; // 113-115
- uint32 EffectTriggerSpell[3]; // 116-118
- float EffectPointsPerComboPoint[3]; // 119-121
- uint32 SpellVisual; // 122
- // 123 not used
- uint32 SpellIconID; // 124
- uint32 activeIconID; // 125
- //uint32 spellPriority; // 126
- char* SpellName[16]; // 127-142
- //uint32 SpellNameFlag; // 143
- char* Rank[16]; // 144-159
- //uint32 RankFlags; // 160
- //char* Description[16]; // 161-176 not used
- //uint32 DescriptionFlags; // 177 not used
- //char* ToolTip[16]; // 178-193 not used
- //uint32 ToolTipFlags; // 194 not used
- uint32 ManaCostPercentage; // 195
- uint32 StartRecoveryCategory; // 196
- uint32 StartRecoveryTime; // 197
- uint32 MaxTargetLevel; // 198
- uint32 SpellFamilyName; // 199
- uint64 SpellFamilyFlags; // 200+201
- uint32 MaxAffectedTargets; // 202
- uint32 DmgClass; // 203 defenseType
- uint32 PreventionType; // 204
- //uint32 StanceBarOrder; // 205 not used
- float DmgMultiplier[3]; // 206-208
- //uint32 MinFactionId; // 209 not used, and 0 in 2.4.2
- //uint32 MinReputation; // 210 not used, and 0 in 2.4.2
- //uint32 RequiredAuraVision; // 211 not used
- uint32 TotemCategory[2]; // 212-213
- uint32 AreaId; // 214
- uint32 SchoolMask; // 215 school mask
-
- private:
- // prevent creating custom entries (copy data from original in fact)
- SpellEntry(SpellEntry const&); // DON'T must have implementation
-};
-
-typedef std::set<uint32> SpellCategorySet;
-typedef std::map<uint32,SpellCategorySet > SpellCategoryStore;
-typedef std::set<uint32> PetFamilySpellsSet;
-typedef std::map<uint32,PetFamilySpellsSet > PetFamilySpellsStore;
-
-struct SpellCastTimesEntry
-{
- uint32 ID; // 0
- int32 CastTime; // 1
- //float CastTimePerLevel; // 2 unsure / per skill?
- //int32 MinCastTime; // 3 unsure
-};
-
-struct SpellFocusObjectEntry
-{
- uint32 ID; // 0
- //char* Name[16]; // 1-15 unused
- // 16 string flags, unused
-};
-
-// stored in SQL table
-struct SpellThreatEntry
-{
- uint32 spellId;
- int32 threat;
-};
-
-struct SpellRadiusEntry
-{
- uint32 ID;
- float Radius;
- float Radius2;
-};
-
-struct SpellRangeEntry
-{
- uint32 ID;
- float minRange;
- float maxRange;
- uint32 type;
-};
-
-struct SpellShapeshiftEntry
-{
- uint32 ID; // 0
- //uint32 buttonPosition; // 1 unused
- //char* Name[16]; // 2-17 unused
- //uint32 NameFlags; // 18 unused
- uint32 flags1; // 19
- int32 creatureType; // 20 <=0 humanoid, other normal creature types
- //uint32 unk1; // 21 unused
- uint32 attackSpeed; // 22
- //uint32 modelID; // 23 unused, alliance modelid (where horde case?)
- //uint32 unk2; // 24 unused
- //uint32 unk3; // 25 unused
- //uint32 unk4; // 26 unused
- //uint32 unk5; // 27 unused
- //uint32 unk6; // 28 unused
- //uint32 unk7; // 29 unused
- //uint32 unk8; // 30 unused
- //uint32 unk9; // 31 unused
- //uint32 unk10; // 32 unused
- //uint32 unk11; // 33 unused
- //uint32 unk12; // 34 unused
-};
-
-struct SpellDurationEntry
-{
- uint32 ID;
- int32 Duration[3];
-};
-
-struct SpellItemEnchantmentEntry
-{
- uint32 ID; // 0
- uint32 type[3]; // 1-3
- uint32 amount[3]; // 4-6
- //uint32 amount2[3] // 7-9 always same as similar `amount` value
- uint32 spellid[3]; // 10-12
- char* description[16]; // 13-29
- // 30 description flags
- uint32 aura_id; // 31
- uint32 slot; // 32
- uint32 GemID; // 33
- uint32 EnchantmentCondition; // 34
-};
-
-struct SpellItemEnchantmentConditionEntry
-{
- uint32 ID;
- uint8 Color[5];
- uint8 Comparator[5];
- uint8 CompareColor[5];
- uint32 Value[5];
-};
-
-struct StableSlotPricesEntry
-{
- uint32 Slot;
- uint32 Price;
-};
-
-struct TalentEntry
-{
- uint32 TalentID; // 0
- uint32 TalentTab; // 1 index in TalentTab.dbc (TalentTabEntry)
- uint32 Row; // 2
- uint32 Col; // 3
- uint32 RankID[5]; // 4-8
- // 9-12 not used, always 0, maybe not used high ranks
- uint32 DependsOn; // 13 index in Talent.dbc (TalentEntry)
- // 14-15 not used
- uint32 DependsOnRank; // 16
- // 17-19 not used
- uint32 DependsOnSpell; // 20 req.spell
-};
-
-struct TalentTabEntry
-{
- uint32 TalentTabID; // 0
- //char* name[16]; // 1-16, unused
- //uint32 nameFlags; // 17, unused
- //unit32 spellicon; // 18
- // 19 not used
- uint32 ClassMask; // 20
- uint32 tabpage; // 21
- //char* internalname; // 22
-};
-
-struct TaxiNodesEntry
-{
- uint32 ID; // 0
- uint32 map_id; // 1
- float x; // 2
- float y; // 3
- float z; // 4
- //char* name[16]; // 5-21
- // 22 string flags, unused
- uint32 horde_mount_type; // 23
- uint32 alliance_mount_type; // 24
-};
-
-struct TaxiPathEntry
-{
- uint32 ID;
- uint32 from;
- uint32 to;
- uint32 price;
-};
-
-struct TaxiPathNodeEntry
-{
- uint32 path;
- uint32 index;
- uint32 mapid;
- float x;
- float y;
- float z;
- uint32 actionFlag;
- uint32 delay;
-};
-
-struct TotemCategoryEntry
-{
- uint32 ID; // 0
- //char* name[16]; // 1-16
- // 17 string flags, unused
- uint32 categoryType; // 18 (one for specialization)
- uint32 categoryMask; // 19 (compatibility mask for same type: different for totems, compatible from high to low for rods)
-};
-
-struct WorldMapAreaEntry
-{
- //uint32 ID; // 0
- uint32 map_id; // 1
- uint32 area_id; // 2 index (continent 0 areas ignored)
- //char* internal_name // 3
- float y1; // 4
- float y2; // 5
- float x1; // 6
- float x2; // 7
- int32 virtual_map_id; // 8 -1 (map_id have correct map) other: virtual map where zone show (map_id - where zone in fact internally)
-};
-
-struct WorldSafeLocsEntry
-{
- uint32 ID; // 0
- uint32 map_id; // 1
- float x; // 2
- float y; // 3
- float z; // 4
- //char* name[16] // 5-20 name, unused
- // 21 name flags, unused
-};
-
-// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
-#if defined( __GNUC__ )
-#pragma pack()
-#else
-#pragma pack(pop)
-#endif
-
-// Structures not used for casting to loaded DBC data and not required then packing
-struct TalentSpellPos
-{
- TalentSpellPos() : talent_id(0), rank(0) {}
- TalentSpellPos(uint16 _talent_id, uint8 _rank) : talent_id(_talent_id), rank(_rank) {}
-
- uint16 talent_id;
- uint8 rank;
-};
-
-typedef std::map<uint32,TalentSpellPos> TalentSpellPosMap;
-
-struct TaxiPathBySourceAndDestination
-{
- TaxiPathBySourceAndDestination() : ID(0),price(0) {}
- TaxiPathBySourceAndDestination(uint32 _id,uint32 _price) : ID(_id),price(_price) {}
-
- uint32 ID;
- uint32 price;
-};
-typedef std::map<uint32,TaxiPathBySourceAndDestination> TaxiPathSetForSource;
-typedef std::map<uint32,TaxiPathSetForSource> TaxiPathSetBySource;
-
-struct TaxiPathNode
-{
- TaxiPathNode() : mapid(0), x(0),y(0),z(0),actionFlag(0),delay(0) {}
- TaxiPathNode(uint32 _mapid, float _x, float _y, float _z, uint32 _actionFlag, uint32 _delay) : mapid(_mapid), x(_x),y(_y),z(_z),actionFlag(_actionFlag),delay(_delay) {}
-
- uint32 mapid;
- float x;
- float y;
- float z;
- uint32 actionFlag;
- uint32 delay;
-};
-typedef std::vector<TaxiPathNode> TaxiPathNodeList;
-typedef std::vector<TaxiPathNodeList> TaxiPathNodesByPath;
-
-#define TaxiMaskSize 16
-typedef uint32 TaxiMask[TaxiMaskSize];
-#endif
-
diff --git a/src/shared/Database/DBCfmt.cpp b/src/shared/Database/DBCfmt.cpp
deleted file mode 100644
index 14cf6486933..00000000000
--- a/src/shared/Database/DBCfmt.cpp
+++ /dev/null
@@ -1,86 +0,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
- */
-
-const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxx";
-const char AuctionHouseEntryfmt[]="niiixxxxxxxxxxxxxxxxx";
-const char AreaTriggerEntryfmt[]="niffffffff";
-const char BankBagSlotPricesEntryfmt[]="ni";
-const char BattlemasterListEntryfmt[]="niiixxxxxiiiixxssssssssssssssssxx";
-const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxx";
-// 3*12 new item fields in 3.0.x
-//const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
-const char CharTitlesEntryfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
-const char ChatChannelsEntryfmt[]="iixssssssssssssssssxxxxxxxxxxxxxxxxxx";
- // ChatChannelsEntryfmt, index not used (more compact store)
-//const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix";
-const char ChrClassesEntryfmt[]="nxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix";
-const char ChrRacesEntryfmt[]="nxixiixxixxxxissssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
-const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxx";
-const char CreatureFamilyfmt[]="nfifiiiissssssssssssssssxx";
-const char CreatureSpellDatafmt[]="nxxxxxxxx";
-const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii";
-const char DurabilityQualityfmt[]="nf";
-const char EmoteEntryfmt[]="nxixxxxxxxxxxxxxxxx";
-const char FactionEntryfmt[]="niiiiiiiiiiiiiiiiiissssssssssssssssxxxxxxxxxxxxxxxxxx";
-const char FactionTemplateEntryfmt[]="niiiiiiiiiiiii";
-const char GemPropertiesEntryfmt[]="nixxi";
-const char GtCombatRatingsfmt[]="f";
-const char GtChanceToMeleeCritBasefmt[]="f";
-const char GtChanceToMeleeCritfmt[]="f";
-const char GtChanceToSpellCritBasefmt[]="f";
-const char GtChanceToSpellCritfmt[]="f";
-const char GtOCTRegenHPfmt[]="f";
-//const char GtOCTRegenMPfmt[]="f";
-const char GtRegenHPPerSptfmt[]="f";
-const char GtRegenMPPerSptfmt[]="f";
-const char Itemfmt[]="niii";
-//const char ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx";
-//const char ItemCondExtCostsEntryfmt[]="xiii";
-const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiii";
-const char ItemRandomPropertiesfmt[]="nxiiixxxxxxxxxxxxxxxxxxx";
-const char ItemRandomSuffixfmt[]="nxxxxxxxxxxxxxxxxxxiiiiii";
-const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii";
-const char LockEntryfmt[]="niiiiixxxiiiiixxxiixxxxxxxxxxxxxx";
-const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
-const char MapEntryfmt[]="nxixssssssssssssssssxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiffiixxi";
-const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx";
-const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii";
-const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxi";
-const char SkillLineAbilityfmt[]="niiiixxiiiiixxi";
-const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
-const char SpellCastTimefmt[]="nixx";
-const char SpellDurationfmt[]="niii";
-const char SpellEntryfmt[]="nixiiiiiiiixiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffixiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiixfffxxxiiii";
-const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx";
-const char SpellItemEnchantmentfmt[]="niiiiiixxxiiissssssssssssssssxiiii";
-const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX";
-const char SpellRadiusfmt[]="nfxf";
-const char SpellRangefmt[]="nffixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
-const char SpellShapeshiftfmt[]="nxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxx";
-const char StableSlotPricesfmt[] = "ni";
-const char TalentEntryfmt[]="niiiiiiiixxxxixxixxxi";
-const char TalentTabEntryfmt[]="nxxxxxxxxxxxxxxxxxxxiix";
-const char TaxiNodesEntryfmt[]="nifffxxxxxxxxxxxxxxxxxii";
-const char TaxiPathEntryfmt[]="niii";
-const char TaxiPathNodeEntryfmt[]="diiifffiixx";
-const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii";
-const char WorldMapAreaEntryfmt[]="xinxffffi";
-const char WorldSafeLocsEntryfmt[]="nifffxxxxxxxxxxxxxxxxx";
-
diff --git a/src/shared/Database/Database.cpp b/src/shared/Database/Database.cpp
index 7110fe44c54..07ece3b0cd9 100644
--- a/src/shared/Database/Database.cpp
+++ b/src/shared/Database/Database.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Database/Database.h b/src/shared/Database/Database.h
index c2ee9349979..92a1c991dcc 100644
--- a/src/shared/Database/Database.h
+++ b/src/shared/Database/Database.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -33,7 +33,7 @@ class SqlQueryHolder;
typedef UNORDERED_MAP<ZThread::ThreadImpl*, SqlTransaction*> TransactionQueues;
typedef UNORDERED_MAP<ZThread::ThreadImpl*, SqlResultQueue*> QueryQueues;
-#define MAX_QUERY_LEN 1024
+#define MAX_QUERY_LEN 32*1024
class TRINITY_DLL_SPEC Database
{
diff --git a/src/shared/Database/DatabaseEnv.h b/src/shared/Database/DatabaseEnv.h
index 664459473af..1d3d735881c 100644
--- a/src/shared/Database/DatabaseEnv.h
+++ b/src/shared/Database/DatabaseEnv.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -25,7 +25,6 @@
#include "Log.h"
#include "Errors.h"
-#include "Database/DBCStores.h"
#include "Database/Field.h"
#include "Database/QueryResult.h"
@@ -40,10 +39,8 @@ typedef DatabasePostgre DatabaseType;
#define _OFFSET_ "LIMIT 1 OFFSET %d"
#else
#include "Database/QueryResultMysql.h"
-#include "Database/QueryResultSqlite.h"
#include "Database/Database.h"
#include "Database/DatabaseMysql.h"
-#include "Database/DatabaseSqlite.h"
typedef DatabaseMysql DatabaseType;
#define _LIKE_ "LIKE"
#define _TABLE_SIM_ "`"
diff --git a/src/shared/Database/DatabaseImpl.h b/src/shared/Database/DatabaseImpl.h
index 5ab4ec04a65..3d3c53f0873 100644
--- a/src/shared/Database/DatabaseImpl.h
+++ b/src/shared/Database/DatabaseImpl.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Database/DatabaseMysql.cpp b/src/shared/Database/DatabaseMysql.cpp
index 77a59a69c57..5dc02c0a738 100644
--- a/src/shared/Database/DatabaseMysql.cpp
+++ b/src/shared/Database/DatabaseMysql.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Database/DatabaseMysql.h b/src/shared/Database/DatabaseMysql.h
index 1826a08f2aa..2fa157e75a5 100644
--- a/src/shared/Database/DatabaseMysql.h
+++ b/src/shared/Database/DatabaseMysql.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Database/DatabasePostgre.cpp b/src/shared/Database/DatabasePostgre.cpp
index 25b5a58b863..79e1c87f5e3 100644
--- a/src/shared/Database/DatabasePostgre.cpp
+++ b/src/shared/Database/DatabasePostgre.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -79,14 +79,14 @@ bool DatabasePostgre::Initialize(const char *infoString)
Tokens::iterator iter;
- std::string host, port_or_socket, user, password, database;
+ std::string host, port_or_socket_dir, user, password, database;
iter = tokens.begin();
if(iter != tokens.end())
host = *iter++;
if(iter != tokens.end())
- port_or_socket = *iter++;
+ port_or_socket_dir = *iter++;
if(iter != tokens.end())
user = *iter++;
if(iter != tokens.end())
@@ -94,7 +94,10 @@ bool DatabasePostgre::Initialize(const char *infoString)
if(iter != tokens.end())
database = *iter++;
- mPGconn = PQsetdbLogin(host.c_str(), port_or_socket.c_str(), NULL, NULL, database.c_str(), user.c_str(), password.c_str());
+ if (host == ".")
+ mPGconn = PQsetdbLogin(NULL, port_or_socket_dir == "." ? NULL : port_or_socket_dir.c_str(), NULL, NULL, database.c_str(), user.c_str(), password.c_str());
+ else
+ mPGconn = PQsetdbLogin(host.c_str(), port_or_socket_dir.c_str(), NULL, NULL, database.c_str(), user.c_str(), password.c_str());
/* check to see that the backend connection was successfully made */
if (PQstatus(mPGconn) != CONNECTION_OK)
diff --git a/src/shared/Database/DatabasePostgre.h b/src/shared/Database/DatabasePostgre.h
index 6dc0c509869..c7242add572 100644
--- a/src/shared/Database/DatabasePostgre.h
+++ b/src/shared/Database/DatabasePostgre.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Database/DatabaseSqlite.cpp b/src/shared/Database/DatabaseSqlite.cpp
deleted file mode 100644
index a7a4a2a9847..00000000000
--- a/src/shared/Database/DatabaseSqlite.cpp
+++ /dev/null
@@ -1,104 +0,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
- */
-
-#ifndef DO_POSTGRESQL
-
-#include "DatabaseEnv.h"
-
-DatabaseSqlite::DatabaseSqlite() : Database(), mSqlite(0)
-{
-}
-
-DatabaseSqlite::~DatabaseSqlite()
-{
- if (mSqlite)
- sqlite_close(mSqlite);
-}
-
-bool DatabaseSqlite::Initialize(const char *infoString)
-{
- if(!Database::Initialize(infoString))
- return false;
-
- char *errmsg;
-
- mSqlite = sqlite_open(infoString, 0, &errmsg);
-
- if (!mSqlite)
- {
-
- if (errmsg)
- sqlite_freemem(errmsg);
- return false;
- }
-
- return true;
-}
-
-QueryResult* DatabaseSqlite::Query(const char *sql)
-{
- char *errmsg;
-
- if (!mSqlite)
- return 0;
-
- char **tableData;
- int rowCount;
- int fieldCount;
-
- sqlite_get_table(mSqlite, sql, &tableData, &rowCount, &fieldCount, &errmsg);
-
- if (!rowCount)
- return 0;
-
- if (!tableData)
- {
-
- if (errmsg)
- sqlite_freemem(errmsg);
- return 0;
- }
-
- QueryResultSqlite *queryResult = new QueryResultSqlite(tableData, rowCount, fieldCount);
- if(!queryResult)
- {
-
- return 0;
- }
-
- queryResult->NextRow();
-
- return queryResult;
-}
-
-bool DatabaseSqlite::Execute(const char *sql)
-{
- char *errmsg;
-
- if (!mSqlite)
- return false;
-
- if(sqlite_exec(mSqlite, sql, NULL, NULL, &errmsg) != SQLITE_OK)
- return false;
-
- return true;
-}
-#endif
-
diff --git a/src/shared/Database/Field.cpp b/src/shared/Database/Field.cpp
index a7817d9a630..9a1fbfa5178 100644
--- a/src/shared/Database/Field.cpp
+++ b/src/shared/Database/Field.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Database/Field.h b/src/shared/Database/Field.h
index 3e5f26376bb..da6a865c6f2 100644
--- a/src/shared/Database/Field.h
+++ b/src/shared/Database/Field.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Database/Makefile.am b/src/shared/Database/Makefile.am
new file mode 100644
index 00000000000..518ea4c98a3
--- /dev/null
+++ b/src/shared/Database/Makefile.am
@@ -0,0 +1,59 @@
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+#
+# Copyright (C) 2008-2009 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
+
+## Process this file with automake to produce Makefile.in
+
+## Sub-directories to parse
+
+## CPP flags for includes, defines, etc.
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared -I$(srcdir)/../../../dep/include/g3dlite
+
+## Build MaNGOS shared library and its parts as convenience library.
+# All libraries will be convenience libraries. Might be changed to shared
+# later.
+noinst_LIBRARIES = libmangosdatabase.a
+
+libmangosdatabase_a_SOURCES = \
+ DBCFileLoader.cpp \
+ DBCFileLoader.h \
+ DBCStore.h \
+ Database.cpp \
+ Database.h \
+ DatabaseEnv.h \
+ DatabaseImpl.h \
+ DatabaseMysql.cpp \
+ DatabasePostgre.cpp \
+ DatabaseMysql.h \
+ DatabasePostgre.h \
+ DBCEnums.h \
+ Field.cpp \
+ Field.h \
+ MySQLDelayThread.h \
+ PGSQLDelayThread.h \
+ QueryResult.h \
+ QueryResultMysql.cpp \
+ QueryResultMysql.h \
+ QueryResultPostgre.cpp \
+ QueryResultPostgre.h \
+ SQLStorage.cpp \
+ SQLStorage.h \
+ SQLStorageImpl.h \
+ SqlDelayThread.cpp \
+ SqlDelayThread.h \
+ SqlOperations.cpp \
+ SqlOperations.h
diff --git a/src/shared/Database/MySQLDelayThread.h b/src/shared/Database/MySQLDelayThread.h
index 14cf1a64617..fcebe3fbd35 100644
--- a/src/shared/Database/MySQLDelayThread.h
+++ b/src/shared/Database/MySQLDelayThread.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Database/PGSQLDelayThread.h b/src/shared/Database/PGSQLDelayThread.h
index 19941464cca..8d219bd9c1e 100644
--- a/src/shared/Database/PGSQLDelayThread.h
+++ b/src/shared/Database/PGSQLDelayThread.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Database/QueryResult.h b/src/shared/Database/QueryResult.h
index 32e47c0959f..01da45ed281 100644
--- a/src/shared/Database/QueryResult.h
+++ b/src/shared/Database/QueryResult.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Database/QueryResultMysql.cpp b/src/shared/Database/QueryResultMysql.cpp
index d995b9f2473..5bc11ae308f 100644
--- a/src/shared/Database/QueryResultMysql.cpp
+++ b/src/shared/Database/QueryResultMysql.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Database/QueryResultMysql.h b/src/shared/Database/QueryResultMysql.h
index 3131bd4bbe4..06b1353c12e 100644
--- a/src/shared/Database/QueryResultMysql.h
+++ b/src/shared/Database/QueryResultMysql.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Database/QueryResultPostgre.cpp b/src/shared/Database/QueryResultPostgre.cpp
index def1b0061e5..500ca053885 100644
--- a/src/shared/Database/QueryResultPostgre.cpp
+++ b/src/shared/Database/QueryResultPostgre.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Database/QueryResultPostgre.h b/src/shared/Database/QueryResultPostgre.h
index 61311728f2d..30d69114dc6 100644
--- a/src/shared/Database/QueryResultPostgre.h
+++ b/src/shared/Database/QueryResultPostgre.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Database/QueryResultSqlite.cpp b/src/shared/Database/QueryResultSqlite.cpp
deleted file mode 100644
index a041232f600..00000000000
--- a/src/shared/Database/QueryResultSqlite.cpp
+++ /dev/null
@@ -1,99 +0,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
- */
-
-#ifndef DO_POSTGRESQL
-
-#include "DatabaseEnv.h"
-
-QueryResultSqlite::QueryResultSqlite(char **tableData, uint32 rowCount, uint32 fieldCount) :
-QueryResult(rowCount, fieldCount), mTableData(tableData), mTableIndex(0)
-{
- mCurrentRow = new Field[mFieldCount];
-
- for (uint32 i = 0; i < mFieldCount; i++)
- {
- mFieldNames[i] = mTableData[i];
- mCurrentRow[i].SetType(Field::DB_TYPE_UNKNOWN);
- }
-}
-
-QueryResultSqlite::~QueryResultSqlite()
-{
- EndQuery();
-}
-
-bool QueryResultSqlite::NextRow()
-{
- int startIndex;
- uint32 i;
-
- if (!mTableData)
- return false;
-
- if (mTableIndex >= mRowCount)
- {
- EndQuery();
- return false;
- }
-
- startIndex = (mTableIndex + 1) * mFieldCount;
- for (i = 0; i < mFieldCount; i++)
- {
- mCurrentRow[i].SetValue(mTableData[startIndex + i]);
- }
-
- ++mTableIndex;
- return true;
-}
-
-void QueryResultSqlite::EndQuery()
-{
- if (mCurrentRow)
- {
- delete [] mCurrentRow;
- mCurrentRow = NULL;
- }
- if (mTableData)
- {
- sqlite_free_table(mTableData);
- mTableData = NULL;
- }
-}
-
-enum Field::DataTypes QueryResultSqlite::ConvertNativeType(const char* sqliteType) const
-{
- if (sqliteType)
- {
- switch (*sqliteType)
- {
- case 'S':
- return Field::DB_TYPE_STRING;
- case 'I':
- return Field::DB_TYPE_INTEGER;
- case 'F':
- return Field::DB_TYPE_FLOAT;
- default:
- return Field::DB_TYPE_UNKNOWN;
- };
- }
- return Field::DB_TYPE_UNKNOWN;
-}
-#endif
-
diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp
index 0eeefbf10ca..8561afc4a33 100644
--- a/src/shared/Database/SQLStorage.cpp
+++ b/src/shared/Database/SQLStorage.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -27,20 +27,20 @@ extern DatabasePostgre WorldDatabase;
extern DatabaseMysql WorldDatabase;
#endif
-const char CreatureInfosrcfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiilliiis";
-const char CreatureInfodstfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiilliiii";
+const char CreatureInfosrcfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifflliiis";
+const char CreatureInfodstfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifflliiii";
const char CreatureDataAddonInfofmt[]="iiiiiiiis";
const char CreatureModelfmt[]="iffbi";
const char CreatureInfoAddonInfofmt[]="iiiiiiiis";
-const char EquipmentInfofmt[]="iiiiiiiiii";
-const char GameObjectInfosrcfmt[]="iiissiifiiiiiiiiiiiiiiiiiiiiiiiis";
-const char GameObjectInfodstfmt[]="iiissiifiiiiiiiiiiiiiiiiiiiiiiiii";
-const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifsiiiii";
-const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiii";
+const char EquipmentInfofmt[]="iiii";
+const char GameObjectInfosrcfmt[]="iiisssiifiiiiiiiiiiiiiiiiiiiiiiiis";
+const char GameObjectInfodstfmt[]="iiisssiifiiiiiiiiiiiiiiiiiiiiiiiii";
+const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiisiiii";
+const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiii";
const char PageTextfmt[]="isi";
const char SpellThreatfmt[]="ii";
-const char InstanceTemplatesrcfmt[]="iiiiiffffs";
-const char InstanceTemplatedstfmt[]="iiiiiffffi";
+const char InstanceTemplatesrcfmt[]="iiiiiiffffs";
+const char InstanceTemplatedstfmt[]="iiiiiiffffi";
SQLStorage sCreatureStorage(CreatureInfosrcfmt, CreatureInfodstfmt, "entry","creature_template");
SQLStorage sCreatureDataAddonStorage(CreatureDataAddonInfofmt,"guid","creature_addon");
diff --git a/src/shared/Database/SQLStorage.h b/src/shared/Database/SQLStorage.h
index 43e34532607..1b5b9d5dcf1 100644
--- a/src/shared/Database/SQLStorage.h
+++ b/src/shared/Database/SQLStorage.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Database/SQLStorageImpl.h b/src/shared/Database/SQLStorageImpl.h
index 82ff0beb60e..b511bdad68c 100644
--- a/src/shared/Database/SQLStorageImpl.h
+++ b/src/shared/Database/SQLStorageImpl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
+ * Copyright (C) 2005-2009 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
@@ -18,17 +18,17 @@
#include "ProgressBar.h"
#include "Log.h"
-#include "dbcfile.h"
+#include "DBCFileLoader.h"
template<class T>
template<class S, class D>
-void SQLStorageLoaderBase<T>::convert(uint32 field_pos, S src, D &dst)
+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)
+void SQLStorageLoaderBase<T>::convert_str_to_str(uint32 /*field_pos*/, char *src, char *&dst)
{
if(!src)
{
@@ -45,7 +45,7 @@ void SQLStorageLoaderBase<T>::convert_str_to_str(uint32 field_pos, char *src, ch
template<class T>
template<class S>
-void SQLStorageLoaderBase<T>::convert_to_str(uint32 field_pos, S src, char * & dst)
+void SQLStorageLoaderBase<T>::convert_to_str(uint32 /*field_pos*/, S /*src*/, char * & dst)
{
dst = new char[1];
*dst = 0;
@@ -53,7 +53,7 @@ void SQLStorageLoaderBase<T>::convert_to_str(uint32 field_pos, S src, char * & d
template<class T>
template<class D>
-void SQLStorageLoaderBase<T>::convert_from_str(uint32 field_pos, char * src, D& dst)
+void SQLStorageLoaderBase<T>::convert_from_str(uint32 /*field_pos*/, char * /*src*/, D& dst)
{
dst = 0;
}
diff --git a/src/shared/Database/SqlDelayThread.cpp b/src/shared/Database/SqlDelayThread.cpp
index 16d5146fc53..27f58510a0a 100644
--- a/src/shared/Database/SqlDelayThread.cpp
+++ b/src/shared/Database/SqlDelayThread.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Database/SqlDelayThread.h b/src/shared/Database/SqlDelayThread.h
index 4c77c122f1e..cbae0c1e5eb 100644
--- a/src/shared/Database/SqlDelayThread.h
+++ b/src/shared/Database/SqlDelayThread.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -42,7 +42,7 @@ class SqlDelayThread : public ZThread::Runnable
SqlDelayThread(Database* db);
///< Put sql statement to delay queue
- inline bool Delay(SqlOperation* sql) { m_sqlQueue.add(sql); return true; }
+ bool Delay(SqlOperation* sql) { m_sqlQueue.add(sql); return true; }
virtual void Stop(); ///< Stop event
virtual void run(); ///< Main Thread loop
diff --git a/src/shared/Database/SqlOperations.cpp b/src/shared/Database/SqlOperations.cpp
index c11c5b9269d..53b99359c09 100644
--- a/src/shared/Database/SqlOperations.cpp
+++ b/src/shared/Database/SqlOperations.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -97,7 +97,7 @@ bool SqlQueryHolder::SetQuery(size_t index, const char *sql)
{
if(m_queries.size() <= index)
{
- sLog.outError("Query index (%u) out of range (size: %u) for query: %s",index,m_queries.size(),sql);
+ sLog.outError("Query index (%u) out of range (size: %u) for query: %s",index,(uint32)m_queries.size(),sql);
return false;
}
diff --git a/src/shared/Database/SqlOperations.h b/src/shared/Database/SqlOperations.h
index 1a0d3c78d1b..61eef4bb7c4 100644
--- a/src/shared/Database/SqlOperations.h
+++ b/src/shared/Database/SqlOperations.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Errors.h b/src/shared/Errors.h
index 7203f1c5420..b7bd19a1d94 100644
--- a/src/shared/Errors.h
+++ b/src/shared/Errors.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Log.cpp b/src/shared/Log.cpp
index d042be82b77..f3fcae1faf7 100644
--- a/src/shared/Log.cpp
+++ b/src/shared/Log.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -25,139 +25,42 @@
#include "Util.h"
#include <stdarg.h>
+#include <stdio.h>
INSTANTIATE_SINGLETON_1( Log );
-enum LogType
-{
- LogNormal = 0,
- LogDetails,
- LogDebug,
- LogError
-};
-
-const int LogType_count = int(LogError) +1;
-
Log::Log() :
raLogfile(NULL), logfile(NULL), gmLogfile(NULL), charLogfile(NULL),
- dberLogfile(NULL), m_colored(false), m_includeTime(false), m_gmlog_per_account(false)
+ dberLogfile(NULL), chatLogfile(NULL), m_gmlog_per_account(false), m_colored(false)
{
Initialize();
}
-void Log::InitColors(const std::string& str)
-{
- if(str.empty())
- {
- m_colored = false;
- return;
- }
-
- int color[4];
-
- std::istringstream ss(str);
-
- for(int i = 0; i < LogType_count; ++i)
- {
- ss >> color[i];
-
- if(!ss)
- return;
-
- if(color[i] < 0 || color[i] >= Color_count)
- return;
- }
-
- for(int i = 0; i < LogType_count; ++i)
- m_colors[i] = Color(color[i]);
-
- m_colored = true;
-}
-
-void Log::SetColor(bool stdout_stream, Color color)
+Log::~Log()
{
- #if PLATFORM == PLATFORM_WINDOWS
-
- static WORD WinColorFG[Color_count] =
- {
- 0, // BLACK
- FOREGROUND_RED, // RED
- FOREGROUND_GREEN, // GREEN
- FOREGROUND_RED | FOREGROUND_GREEN, // BROWN
- FOREGROUND_BLUE, // BLUE
- FOREGROUND_RED | FOREGROUND_BLUE,// MAGENTA
- FOREGROUND_GREEN | FOREGROUND_BLUE, // CYAN
- FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,// WHITE
- // YELLOW
- FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
- // RED_BOLD
- FOREGROUND_RED | FOREGROUND_INTENSITY,
- // GREEN_BOLD
- FOREGROUND_GREEN | FOREGROUND_INTENSITY,
- FOREGROUND_BLUE | FOREGROUND_INTENSITY, // BLUE_BOLD
- // MAGENTA_BOLD
- FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
- // CYAN_BOLD
- FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
- // WHITE_BOLD
- FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
- };
-
- HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE );
- SetConsoleTextAttribute(hConsole, WinColorFG[color]);
- #else
-
- enum ANSITextAttr
- {
- TA_NORMAL=0,
- TA_BOLD=1,
- TA_BLINK=5,
- TA_REVERSE=7
- };
+ if( logfile != NULL )
+ fclose(logfile);
+ logfile = NULL;
- enum ANSIFgTextAttr
- {
- FG_BLACK=30, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
- FG_MAGENTA, FG_CYAN, FG_WHITE, FG_YELLOW
- };
+ if( gmLogfile != NULL )
+ fclose(gmLogfile);
+ gmLogfile = NULL;
- enum ANSIBgTextAttr
- {
- BG_BLACK=40, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
- BG_MAGENTA, BG_CYAN, BG_WHITE
- };
+ if (charLogfile != NULL)
+ fclose(charLogfile);
+ charLogfile = NULL;
- static uint8 UnixColorFG[Color_count] =
- {
- FG_BLACK, // BLACK
- FG_RED, // RED
- FG_GREEN, // GREEN
- FG_BROWN, // BROWN
- FG_BLUE, // BLUE
- FG_MAGENTA, // MAGENTA
- FG_CYAN, // CYAN
- FG_WHITE, // WHITE
- FG_YELLOW, // YELLOW
- FG_RED, // LRED
- FG_GREEN, // LGREEN
- FG_BLUE, // LBLUE
- FG_MAGENTA, // LMAGENTA
- FG_CYAN, // LCYAN
- FG_WHITE // LWHITE
- };
+ if( dberLogfile != NULL )
+ fclose(dberLogfile);
+ dberLogfile = NULL;
- fprintf((stdout_stream? stdout : stderr), "\x1b[%d%sm",UnixColorFG[color],(color>=YELLOW&&color<Color_count ?";1":""));
- #endif
-}
+ if (raLogfile != NULL)
+ fclose(raLogfile);
+ raLogfile = NULL;
-void Log::ResetColor(bool stdout_stream)
-{
- #if PLATFORM == PLATFORM_WINDOWS
- HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE );
- SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED );
- #else
- fprintf(( stdout_stream ? stdout : stderr ), "\x1b[0m");
- #endif
+ if (chatLogfile != NULL)
+ fclose(chatLogfile);
+ chatLogfile = NULL;
}
void Log::SetLogLevel(char *Level)
@@ -167,7 +70,7 @@ void Log::SetLogLevel(char *Level)
NewLevel = 0;
m_logLevel = NewLevel;
- printf( "LogLevel is %u\n",m_logLevel );
+ outString( "LogLevel is %u",m_logLevel );
}
void Log::SetLogFileLevel(char *Level)
@@ -177,11 +80,30 @@ void Log::SetLogFileLevel(char *Level)
NewLevel = 0;
m_logFileLevel = NewLevel;
- printf( "LogFileLevel is %u\n",m_logFileLevel );
+ outString( "LogFileLevel is %u",m_logFileLevel );
+}
+
+void Log::SetDBLogLevel(char *Level)
+{
+ int32 NewLevel = atoi((char*)Level);
+ if ( NewLevel < 0 )
+ NewLevel = 0;
+ m_dbLogLevel = NewLevel;
+
+ outString( "DBLogLevel is %u",m_dbLogLevel );
}
void Log::Initialize()
{
+ /// Check whether we'll log GM commands/RA events/character outputs/chat stuffs
+ m_dbChar = sConfig.GetBoolDefault("LogDB.Char", false);
+ m_dbRA = sConfig.GetBoolDefault("LogDB.RA", false);
+ m_dbGM = sConfig.GetBoolDefault("LogDB.GM", false);
+ m_dbChat = sConfig.GetBoolDefault("LogDB.Chat", false);
+
+ /// Realm must be 0 by default
+ SetRealmID(0);
+
/// Common log files data
m_logsDir = sConfig.GetStringDefault("LogsDir","");
if(!m_logsDir.empty())
@@ -194,6 +116,7 @@ void Log::Initialize()
/// Open specific log files
logfile = openLogFile("LogFile","LogTimestamp","w");
+ InitColors(sConfig.GetStringDefault("LogColors", ""));
m_gmlog_per_account = sConfig.GetBoolDefault("GmLogPerAccount",false);
if(!m_gmlog_per_account)
@@ -230,12 +153,12 @@ void Log::Initialize()
dberLogfile = openLogFile("DBErrorLogFile",NULL,"a");
raLogfile = openLogFile("RaLogFile",NULL,"a");
+ chatLogfile = openLogFile("ChatLogFile","ChatLogTimestamp","a");
// Main log file settings
- m_includeTime = sConfig.GetBoolDefault("LogTime", false);
- m_logLevel = sConfig.GetIntDefault("LogLevel", 0);
- m_logFileLevel = sConfig.GetIntDefault("LogFileLevel", 0);
- InitColors(sConfig.GetStringDefault("LogColors", ""));
+ m_logLevel = sConfig.GetIntDefault("LogLevel", LOGL_NORMAL);
+ m_logFileLevel = sConfig.GetIntDefault("LogFileLevel", LOGL_NORMAL);
+ m_dbLogLevel = sConfig.GetIntDefault("DBLogLevel", LOGL_NORMAL);
m_logFilter = 0;
@@ -245,6 +168,8 @@ void Log::Initialize()
m_logFilter |= LOG_FILTER_CREATURE_MOVES;
if(sConfig.GetBoolDefault("LogFilter_VisibilityChanges", true))
m_logFilter |= LOG_FILTER_VISIBILITY_CHANGES;
+ if(sConfig.GetBoolDefault("LogFilter_AchievementUpdates", true))
+ m_logFilter |= LOG_FILTER_ACHIEVEMENT_UPDATES;
// Char log settings
m_charLog_Dump = sConfig.GetBoolDefault("CharLogDump", false);
@@ -291,17 +216,117 @@ void Log::outTimestamp(FILE* file)
fprintf(file,"%-4d-%02d-%02d %02d:%02d:%02d ",aTm->tm_year+1900,aTm->tm_mon+1,aTm->tm_mday,aTm->tm_hour,aTm->tm_min,aTm->tm_sec);
}
-void Log::outTime()
+void Log::InitColors(const std::string& str)
{
- time_t t = time(NULL);
- tm* aTm = localtime(&t);
- // YYYY year
- // MM month (2 digits 01-12)
- // DD day (2 digits 01-31)
- // HH hour (2 digits 00-23)
- // MM minutes (2 digits 00-59)
- // SS seconds (2 digits 00-59)
- printf("%02d:%02d:%02d ",aTm->tm_hour,aTm->tm_min,aTm->tm_sec);
+ if(str.empty())
+ {
+ m_colored = false;
+ return;
+ }
+
+ int color[4];
+
+ std::istringstream ss(str);
+
+ for(int i = 0; i < LogLevels; ++i)
+ {
+ ss >> color[i];
+
+ if(!ss)
+ return;
+
+ if(color[i] < 0 || color[i] >= Colors)
+ return;
+ }
+
+ for(int i = 0; i < LogLevels; ++i)
+ m_colors[i] = ColorTypes(color[i]);
+
+ m_colored = true;
+}
+
+void Log::SetColor(bool stdout_stream, ColorTypes color)
+{
+ #if PLATFORM == PLATFORM_WINDOWS
+ static WORD WinColorFG[Colors] =
+ {
+ 0, // BLACK
+ FOREGROUND_RED, // RED
+ FOREGROUND_GREEN, // GREEN
+ FOREGROUND_RED | FOREGROUND_GREEN, // BROWN
+ FOREGROUND_BLUE, // BLUE
+ FOREGROUND_RED | FOREGROUND_BLUE,// MAGENTA
+ FOREGROUND_GREEN | FOREGROUND_BLUE, // CYAN
+ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,// WHITE
+ // YELLOW
+ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
+ // RED_BOLD
+ FOREGROUND_RED | FOREGROUND_INTENSITY,
+ // GREEN_BOLD
+ FOREGROUND_GREEN | FOREGROUND_INTENSITY,
+ FOREGROUND_BLUE | FOREGROUND_INTENSITY, // BLUE_BOLD
+ // MAGENTA_BOLD
+ FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
+ // CYAN_BOLD
+ FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
+ // WHITE_BOLD
+ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
+ };
+
+ HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE );
+ SetConsoleTextAttribute(hConsole, WinColorFG[color]);
+ #else
+ enum ANSITextAttr
+ {
+ TA_NORMAL=0,
+ TA_BOLD=1,
+ TA_BLINK=5,
+ TA_REVERSE=7
+ };
+
+ enum ANSIFgTextAttr
+ {
+ FG_BLACK=30, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
+ FG_MAGENTA, FG_CYAN, FG_WHITE, FG_YELLOW
+ };
+
+ enum ANSIBgTextAttr
+ {
+ BG_BLACK=40, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
+ BG_MAGENTA, BG_CYAN, BG_WHITE
+ };
+
+ static uint8 UnixColorFG[Colors] =
+ {
+ FG_BLACK, // BLACK
+ FG_RED, // RED
+ FG_GREEN, // GREEN
+ FG_BROWN, // BROWN
+ FG_BLUE, // BLUE
+ FG_MAGENTA, // MAGENTA
+ FG_CYAN, // CYAN
+ FG_WHITE, // WHITE
+ FG_YELLOW, // YELLOW
+ FG_RED, // LRED
+ FG_GREEN, // LGREEN
+ FG_BLUE, // LBLUE
+ FG_MAGENTA, // LMAGENTA
+ FG_CYAN, // LCYAN
+ FG_WHITE // LWHITE
+ };
+
+ fprintf((stdout_stream? stdout : stderr), "\x1b[%d%sm", UnixColorFG[color], (color >= YELLOW && color < Colors ? ";1" : ""));
+ #endif
+}
+
+void Log::ResetColor(bool stdout_stream)
+{
+ #if PLATFORM == PLATFORM_WINDOWS
+ HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE );
+ SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED );
+ #else
+ fprintf(( stdout_stream ? stdout : stderr ), "\x1b[0m");
+ #endif
}
std::string Log::GetTimestampStr()
@@ -319,16 +344,42 @@ std::string Log::GetTimestampStr()
return std::string(buf);
}
-void Log::outTitle( const char * str)
+void Log::outDB( LogTypes type, const char * str )
+{
+ if(!str || std::string(str).empty() || type >= MAX_LOG_TYPES)
+ return;
+
+ std::string new_str(str);
+ LoginDatabase.escape_string(new_str);
+
+ LoginDatabase.PExecute("INSERT INTO logs (time, realm, type, string) "
+ "VALUES ("I64FMTD", %u, %u, '%s');", uint64(time(0)), realm, (uint32)type, new_str.c_str());
+}
+
+void Log::outString( const char * str, ... )
{
if( !str )
return;
+ if (m_enableLogDB)
+ {
+ // we don't want empty strings in the DB
+ std::string s(str);
+ if(s.empty() || s == " ")
+ return;
+
+ va_list ap2;
+ va_start(ap2, str);
+ char nnew_str[MAX_QUERY_LEN];
+ vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
+ outDB(LOG_TYPE_STRING, nnew_str);
+ va_end(ap2);
+ }
+
if(m_colored)
- SetColor(true,WHITE);
+ SetColor(true,m_colors[LOGL_NORMAL]);
- // not expected utf8 and then send as-is
- printf( str );
+ UTF8PRINTF(stdout,str,);
if(m_colored)
ResetColor(true);
@@ -336,18 +387,20 @@ void Log::outTitle( const char * str)
printf( "\n" );
if(logfile)
{
- fprintf(logfile, str);
+ outTimestamp(logfile);
+ va_list ap;
+ va_start(ap, str);
+ vfprintf(logfile, str, ap);
fprintf(logfile, "\n" );
+ va_end(ap);
+
fflush(logfile);
}
-
fflush(stdout);
}
-void Log::outString()
+void Log::outString( )
{
- if(m_includeTime)
- outTime();
printf( "\n" );
if(logfile)
{
@@ -358,36 +411,44 @@ void Log::outString()
fflush(stdout);
}
-void Log::outString( const char * str, ... )
+void Log::outCrash( const char * err, ... )
{
- if( !str )
+ if( !err )
return;
- if(m_colored)
- SetColor(true,m_colors[LogNormal]);
+ if (m_enableLogDB)
+ {
+ va_list ap2;
+ va_start(ap2, err);
+ char nnew_str[MAX_QUERY_LEN];
+ vsnprintf(nnew_str, MAX_QUERY_LEN, err, ap2);
+ outDB(LOG_TYPE_CRASH, nnew_str);
+ va_end(ap2);
+ }
- if(m_includeTime)
- outTime();
+ if(m_colored)
+ SetColor(false,RED);
- UTF8PRINTF(stdout,str,);
+ UTF8PRINTF(stderr,err,);
if(m_colored)
- ResetColor(true);
+ ResetColor(false);
- printf( "\n" );
+ fprintf( stderr, "\n" );
if(logfile)
{
outTimestamp(logfile);
+ fprintf(logfile, "CRASH ALERT: " );
va_list ap;
- va_start(ap, str);
- vfprintf(logfile, str, ap);
- fprintf(logfile, "\n" );
+ va_start(ap, err);
+ vfprintf(logfile, err, ap);
va_end(ap);
+ fprintf(logfile, "\n" );
fflush(logfile);
}
- fflush(stdout);
+ fflush(stderr);
}
void Log::outError( const char * err, ... )
@@ -395,11 +456,18 @@ void Log::outError( const char * err, ... )
if( !err )
return;
- if(m_colored)
- SetColor(false,m_colors[LogError]);
+ if (m_enableLogDB)
+ {
+ va_list ap2;
+ va_start(ap2, err);
+ char nnew_str[MAX_QUERY_LEN];
+ vsnprintf(nnew_str, MAX_QUERY_LEN, err, ap2);
+ outDB(LOG_TYPE_ERROR, nnew_str);
+ va_end(ap2);
+ }
- if(m_includeTime)
- outTime();
+ if(m_colored)
+ SetColor(false,RED);
UTF8PRINTF(stderr,err,);
@@ -410,7 +478,7 @@ void Log::outError( const char * err, ... )
if(logfile)
{
outTimestamp(logfile);
- fprintf(logfile, "ERROR:" );
+ fprintf(logfile, "ERROR: " );
va_list ap;
va_start(ap, err);
@@ -429,10 +497,7 @@ void Log::outErrorDb( const char * err, ... )
return;
if(m_colored)
- SetColor(false,m_colors[LogError]);
-
- if(m_includeTime)
- outTime();
+ SetColor(false,RED);
UTF8PRINTF(stderr,err,);
@@ -444,7 +509,7 @@ void Log::outErrorDb( const char * err, ... )
if(logfile)
{
outTimestamp(logfile);
- fprintf(logfile, "ERROR:" );
+ fprintf(logfile, "ERROR: " );
va_list ap;
va_start(ap, err);
@@ -458,7 +523,6 @@ void Log::outErrorDb( const char * err, ... )
if(dberLogfile)
{
outTimestamp(dberLogfile);
-
va_list ap;
va_start(ap, err);
vfprintf(dberLogfile, err, ap);
@@ -475,13 +539,20 @@ void Log::outBasic( const char * str, ... )
if( !str )
return;
- if( m_logLevel > 0 )
+ if (m_enableLogDB && m_dbLogLevel > LOGL_NORMAL)
{
- if(m_colored)
- SetColor(true,m_colors[LogDetails]);
+ va_list ap2;
+ va_start(ap2, str);
+ char nnew_str[MAX_QUERY_LEN];
+ vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
+ outDB(LOG_TYPE_BASIC, nnew_str);
+ va_end(ap2);
+ }
- if(m_includeTime)
- outTime();
+ if( m_logLevel > LOGL_NORMAL )
+ {
+ if(m_colored)
+ SetColor(true,m_colors[LOGL_BASIC]);
UTF8PRINTF(stdout,str,);
@@ -491,10 +562,10 @@ void Log::outBasic( const char * str, ... )
printf( "\n" );
}
- if(logfile && m_logFileLevel > 0)
+ if(logfile && m_logFileLevel > LOGL_NORMAL)
{
- va_list ap;
outTimestamp(logfile);
+ va_list ap;
va_start(ap, str);
vfprintf(logfile, str, ap);
fprintf(logfile, "\n" );
@@ -509,14 +580,20 @@ void Log::outDetail( const char * str, ... )
if( !str )
return;
- if( m_logLevel > 1 )
+ if (m_enableLogDB && m_dbLogLevel > LOGL_BASIC)
{
+ va_list ap2;
+ va_start(ap2, str);
+ char nnew_str[MAX_QUERY_LEN];
+ vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
+ outDB(LOG_TYPE_DETAIL, nnew_str);
+ va_end(ap2);
+ }
+ if( m_logLevel > LOGL_BASIC )
+ {
if(m_colored)
- SetColor(true,m_colors[LogDetails]);
-
- if(m_includeTime)
- outTime();
+ SetColor(true,m_colors[LOGL_DETAIL]);
UTF8PRINTF(stdout,str,);
@@ -525,10 +602,10 @@ void Log::outDetail( const char * str, ... )
printf( "\n" );
}
- if(logfile && m_logFileLevel > 1)
+ if(logfile && m_logFileLevel > LOGL_BASIC)
{
- va_list ap;
outTimestamp(logfile);
+ va_list ap;
va_start(ap, str);
vfprintf(logfile, str, ap);
fprintf(logfile, "\n" );
@@ -543,17 +620,12 @@ void Log::outDebugInLine( const char * str, ... )
{
if( !str )
return;
- if( m_logLevel > 2 )
- {
- if(m_colored)
- SetColor(true,m_colors[LogDebug]);
+ if( m_logLevel > LOGL_DETAIL )
+ {
UTF8PRINTF(stdout,str,);
-
- if(m_colored)
- ResetColor(true);
}
- if(logfile && m_logFileLevel > 2)
+ if(logfile && m_logFileLevel > LOGL_DETAIL)
{
va_list ap;
va_start(ap, str);
@@ -566,13 +638,21 @@ void Log::outDebug( const char * str, ... )
{
if( !str )
return;
- if( m_logLevel > 2 )
+
+ if (m_enableLogDB && m_dbLogLevel > LOGL_DETAIL)
{
- if(m_colored)
- SetColor(true,m_colors[LogDebug]);
+ va_list ap2;
+ va_start(ap2, str);
+ char nnew_str[MAX_QUERY_LEN];
+ vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
+ outDB(LOG_TYPE_DEBUG, nnew_str);
+ va_end(ap2);
+ }
- if(m_includeTime)
- outTime();
+ if( m_logLevel > LOGL_DETAIL )
+ {
+ if(m_colored)
+ SetColor(true,m_colors[LOGL_DEBUG]);
UTF8PRINTF(stdout,str,);
@@ -581,10 +661,9 @@ void Log::outDebug( const char * str, ... )
printf( "\n" );
}
- if(logfile && m_logFileLevel > 2)
+ if(logfile && m_logFileLevel > LOGL_DETAIL)
{
outTimestamp(logfile);
-
va_list ap;
va_start(ap, str);
vfprintf(logfile, str, ap);
@@ -601,13 +680,21 @@ void Log::outCommand( uint32 account, const char * str, ... )
if( !str )
return;
- if( m_logLevel > 1 )
+ // TODO: support accountid
+ if (m_enableLogDB && m_dbGM)
{
- if(m_colored)
- SetColor(true,m_colors[LogDetails]);
+ va_list ap2;
+ va_start(ap2, str);
+ char nnew_str[MAX_QUERY_LEN];
+ vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
+ outDB(LOG_TYPE_GM, nnew_str);
+ va_end(ap2);
+ }
- if(m_includeTime)
- outTime();
+ if( m_logLevel > LOGL_NORMAL )
+ {
+ if(m_colored)
+ SetColor(true,m_colors[LOGL_BASIC]);
UTF8PRINTF(stdout,str,);
@@ -616,10 +703,10 @@ void Log::outCommand( uint32 account, const char * str, ... )
printf( "\n" );
}
- if(logfile && m_logFileLevel > 1)
+ if(logfile && m_logFileLevel > LOGL_NORMAL)
{
- va_list ap;
outTimestamp(logfile);
+ va_list ap;
va_start(ap, str);
vfprintf(logfile, str, ap);
fprintf(logfile, "\n" );
@@ -631,8 +718,8 @@ void Log::outCommand( uint32 account, const char * str, ... )
{
if (FILE* per_file = openGmlogPerAccount (account))
{
- va_list ap;
outTimestamp(per_file);
+ va_list ap;
va_start(ap, str);
vfprintf(per_file, str, ap);
fprintf(per_file, "\n" );
@@ -642,8 +729,8 @@ void Log::outCommand( uint32 account, const char * str, ... )
}
else if (gmLogfile)
{
- va_list ap;
outTimestamp(gmLogfile);
+ va_list ap;
va_start(ap, str);
vfprintf(gmLogfile, str, ap);
fprintf(gmLogfile, "\n" );
@@ -656,14 +743,23 @@ void Log::outCommand( uint32 account, const char * str, ... )
void Log::outChar(const char * str, ... )
{
-
if (!str)
return;
+ if (m_enableLogDB && m_dbChar)
+ {
+ va_list ap2;
+ va_start(ap2, str);
+ char nnew_str[MAX_QUERY_LEN];
+ vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
+ outDB(LOG_TYPE_CHAR, nnew_str);
+ va_end(ap2);
+ }
+
if(charLogfile)
{
- va_list ap;
outTimestamp(charLogfile);
+ va_list ap;
va_start(ap, str);
vfprintf(charLogfile, str, ap);
fprintf(charLogfile, "\n" );
@@ -681,48 +777,58 @@ void Log::outCharDump( const char * str, uint32 account_id, uint32 guid, const c
}
}
-void Log::outMenu( const char * str, ... )
+void Log::outRemote( const char * str, ... )
{
if( !str )
return;
- SetColor(true,m_colors[LogNormal]);
-
- if(m_includeTime)
- outTime();
-
- UTF8PRINTF(stdout,str,);
-
- ResetColor(true);
-
- if(logfile)
+ if (m_enableLogDB && m_dbRA)
{
- outTimestamp(logfile);
+ va_list ap2;
+ va_start(ap2, str);
+ char nnew_str[MAX_QUERY_LEN];
+ vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
+ outDB(LOG_TYPE_RA, nnew_str);
+ va_end(ap2);
+ }
+ if (raLogfile)
+ {
+ outTimestamp(raLogfile);
va_list ap;
va_start(ap, str);
- vfprintf(logfile, str, ap);
+ vfprintf(raLogfile, str, ap);
+ fprintf(raLogfile, "\n" );
va_end(ap);
-
- fprintf(logfile, "\n" );
- fflush(logfile);
+ fflush(raLogfile);
}
fflush(stdout);
}
-void Log::outRALog( const char * str, ... )
+void Log::outChat( const char * str, ... )
{
if( !str )
return;
- va_list ap;
- if (raLogfile)
+
+ if (m_enableLogDB && m_dbChat)
{
- outTimestamp(raLogfile);
+ va_list ap2;
+ va_start(ap2, str);
+ char nnew_str[MAX_QUERY_LEN];
+ vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
+ outDB(LOG_TYPE_CHAT, nnew_str);
+ va_end(ap2);
+ }
+
+ if (chatLogfile)
+ {
+ outTimestamp(chatLogfile);
+ va_list ap;
va_start(ap, str);
- vfprintf(raLogfile, str, ap);
- fprintf(raLogfile, "\n" );
+ vfprintf(chatLogfile, str, ap);
+ fprintf(chatLogfile, "\n" );
+ fflush(chatLogfile);
va_end(ap);
- fflush(raLogfile);
}
fflush(stdout);
}
diff --git a/src/shared/Log.h b/src/shared/Log.h
index ab8c24571fb..654f3c0f04c 100644
--- a/src/shared/Log.h
+++ b/src/shared/Log.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -23,18 +23,45 @@
#include "Common.h"
#include "Policies/Singleton.h"
+#include "Database/DatabaseEnv.h"
class Config;
-// bitmask
enum LogFilters
{
- LOG_FILTER_TRANSPORT_MOVES = 1,
- LOG_FILTER_CREATURE_MOVES = 2,
- LOG_FILTER_VISIBILITY_CHANGES = 4
+ LOG_FILTER_TRANSPORT_MOVES = 1,
+ LOG_FILTER_CREATURE_MOVES = 2,
+ LOG_FILTER_VISIBILITY_CHANGES = 4,
+ LOG_FILTER_ACHIEVEMENT_UPDATES = 8
};
-enum Color
+enum LogTypes
+{
+ LOG_TYPE_STRING = 0,
+ LOG_TYPE_ERROR = 1,
+ LOG_TYPE_BASIC = 2,
+ LOG_TYPE_DETAIL = 3,
+ LOG_TYPE_DEBUG = 4,
+ LOG_TYPE_CHAR = 5,
+ LOG_TYPE_WORLD = 6,
+ LOG_TYPE_RA = 7,
+ LOG_TYPE_GM = 8,
+ LOG_TYPE_CRASH = 9,
+ LOG_TYPE_CHAT = 10,
+ MAX_LOG_TYPES
+};
+
+enum LogLevel
+{
+ LOGL_NORMAL = 0,
+ LOGL_BASIC,
+ LOGL_DETAIL,
+ LOGL_DEBUG
+};
+
+const int LogLevels = int(LOGL_DEBUG)+1;
+
+enum ColorTypes
{
BLACK,
RED,
@@ -53,73 +80,53 @@ enum Color
WHITE
};
-const int Color_count = int(WHITE)+1;
+const int Colors = int(WHITE)+1;
class Log : public Trinity::Singleton<Log, Trinity::ClassLevelLockable<Log, ZThread::FastMutex> >
{
friend class Trinity::OperatorNew<Log>;
Log();
+ ~Log();
- ~Log()
- {
- if( logfile != NULL )
- fclose(logfile);
- logfile = NULL;
-
- if( gmLogfile != NULL )
- fclose(gmLogfile);
- gmLogfile = NULL;
-
- if (charLogfile != NULL)
- fclose(charLogfile);
- charLogfile = NULL;
-
- if( dberLogfile != NULL )
- fclose(dberLogfile);
- dberLogfile = NULL;
-
- if (raLogfile != NULL)
- fclose(raLogfile);
- raLogfile = NULL;
- }
public:
void Initialize();
+
void InitColors(const std::string& init_str);
- void outTitle( const char * str);
+ void SetColor(bool stdout_stream, ColorTypes color);
+ void ResetColor(bool stdout_stream);
+
+ void outDB( LogTypes type, const char * str );
+ void outString( const char * str, ... ) ATTR_PRINTF(2,3);
+ void outString( );
+ void outError( const char * err, ... ) ATTR_PRINTF(2,3);
+ void outCrash( const char * err, ... ) ATTR_PRINTF(2,3);
+ void outBasic( const char * str, ... ) ATTR_PRINTF(2,3);
+ void outDetail( const char * str, ... ) ATTR_PRINTF(2,3);
+ void outDebug( const char * str, ... ) ATTR_PRINTF(2,3);
+ void outDebugInLine( const char * str, ... ) ATTR_PRINTF(2,3);
+ void outErrorDb( const char * str, ... ) ATTR_PRINTF(2,3);
+ void outChar( const char * str, ... ) ATTR_PRINTF(2,3);
void outCommand( uint32 account, const char * str, ...) ATTR_PRINTF(3,4);
- void outString(); // any log level
- // any log level
- void outString( const char * str, ... ) ATTR_PRINTF(2,3);
- // any log level
- void outError( const char * err, ... ) ATTR_PRINTF(2,3);
- // log level >= 1
- void outBasic( const char * str, ... ) ATTR_PRINTF(2,3);
- // log level >= 2
- void outDetail( const char * str, ... ) ATTR_PRINTF(2,3);
- // log level >= 3
- void outDebugInLine( const char * str, ... ) ATTR_PRINTF(2,3);
- // log level >= 3
- void outDebug( const char * str, ... ) ATTR_PRINTF(2,3);
- // any log level
- void outMenu( const char * str, ... ) ATTR_PRINTF(2,3);
- // any log level
- void outErrorDb( const char * str, ... ) ATTR_PRINTF(2,3);
- // any log level
- void outChar( const char * str, ... ) ATTR_PRINTF(2,3);
- // any log level
+ void outRemote( const char * str, ... ) ATTR_PRINTF(2,3);
+ void outChat( const char * str, ... ) ATTR_PRINTF(2,3);
void outCharDump( const char * str, uint32 account_id, uint32 guid, const char * name );
- void outRALog( const char * str, ... ) ATTR_PRINTF(2,3);
- void SetLogLevel(char * Level);
- void SetLogFileLevel(char * Level);
- void SetColor(bool stdout_stream, Color color);
- void ResetColor(bool stdout_stream);
- void outTime();
+
static void outTimestamp(FILE* file);
static std::string GetTimestampStr();
+
+ void SetLogLevel(char * Level);
+ void SetLogFileLevel(char * Level);
+ void SetDBLogLevel(char * Level);
+ void SetRealmID(uint32 id) { realm = id; }
+
uint32 getLogFilter() const { return m_logFilter; }
bool IsOutDebug() const { return m_logLevel > 2 || (m_logFileLevel > 2 && logfile); }
bool IsOutCharDump() const { return m_charLog_Dump; }
- bool IsIncludeTime() const { return m_includeTime; }
+
+ bool GetLogDB() { return m_enableLogDB; }
+ bool GetLogDBLater() { return m_enableLogDBLater; }
+ void SetLogDB(bool enable) { m_enableLogDB = enable; }
+ void SetLogDBLater(bool value) { m_enableLogDBLater = value; }
private:
FILE* openLogFile(char const* configFileName,char const* configTimeStampFlag, char const* mode);
FILE* openGmlogPerAccount(uint32 account);
@@ -129,25 +136,35 @@ class Log : public Trinity::Singleton<Log, Trinity::ClassLevelLockable<Log, ZThr
FILE* gmLogfile;
FILE* charLogfile;
FILE* dberLogfile;
-
- // log/console control
- uint32 m_logLevel;
- uint32 m_logFileLevel;
- bool m_colored;
- bool m_includeTime;
- Color m_colors[4];
- uint32 m_logFilter;
+ FILE* chatLogfile;
// cache values for after initilization use (like gm log per account case)
std::string m_logsDir;
std::string m_logsTimestamp;
- // char log control
- bool m_charLog_Dump;
-
// gm log control
bool m_gmlog_per_account;
std::string m_gmlog_filename_format;
+
+ bool m_enableLogDBLater;
+ bool m_enableLogDB;
+ uint32 realm;
+
+ // log coloring
+ bool m_colored;
+ ColorTypes m_colors[4];
+
+ // log levels:
+ // 0 minimum/string, 1 basic/error, 2 detail, 3 full/debug
+ uint8 m_dbLogLevel;
+ uint8 m_logLevel;
+ uint8 m_logFileLevel;
+ uint8 m_logFilter;
+ bool m_dbChar;
+ bool m_dbRA;
+ bool m_dbGM;
+ bool m_dbChat;
+ bool m_charLog_Dump;
};
#define sLog Trinity::Singleton<Log>::Instance()
diff --git a/src/shared/Makefile.am b/src/shared/Makefile.am
new file mode 100644
index 00000000000..6b99351cb26
--- /dev/null
+++ b/src/shared/Makefile.am
@@ -0,0 +1,82 @@
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+#
+# Copyright (C) 2008-2009 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
+
+## Process this file with automake to produce Makefile.in
+
+## Sub-directories to parse
+SUBDIRS = Auth Config Database vmap
+
+## CPP flags for includes, defines, etc.
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../dep/include -I$(srcdir)/../framework -I$(srcdir)/../shared -I$(srcdir)/../../dep/include/g3dlite -DSYSCONFDIR=\"$(sysconfdir)/\"
+## AM_CPPFLAGS += -I$(srcdir)/../game -I$(srcdir)/../realmd
+
+## Build MaNGOS shared library and its parts as convenience library.
+# All libraries will be convenience libraries. Might be changed to shared
+# later.
+noinst_LIBRARIES = libmangosshared.a
+
+# libmangosshared library will later be reused by ...
+libmangosshared_a_SOURCES = \
+ Base.cpp \
+ Base.h \
+ ByteBuffer.h \
+ Common.cpp \
+ Common.h \
+ Errors.h \
+ Log.cpp \
+ Log.h \
+ MemoryLeaks.cpp \
+ MemoryLeaks.h \
+ ProgressBar.cpp \
+ ProgressBar.h \
+ Timer.h \
+ Util.cpp \
+ Util.h \
+ WorldPacket.h \
+ revision_nr.h \
+ revision.h
+
+# Get revision (git or svn)
+# Get HG revision
+REVISION_FILE = revision.h
+
+BUILT_SOURCES = $(REVISION_FILE)
+CLEANFILES = $(REVISION_FILE)
+
+FORCE:
+
+$(REVISION_FILE) : $(top_builddir)/src/tools/genrevision/genrevision FORCE
+ $(top_builddir)/src/tools/genrevision/genrevision $(top_srcdir)
+ cp $(top_builddir)/src/shared/revision.h $(top_srcdir)/src/shared
+
+## Additional files to include when running 'make dist'
+# Disabled packet logger
+EXTRA_DIST = \
+ PacketLog.cpp \
+ PacketLog.h
+
+# System configuration
+EXTRA_DIST += \
+ SystemConfig.h
+
+# System Win32 files
+EXTRA_DIST += \
+ ServiceWin32.cpp \
+ ServiceWin32.h \
+ WheatyExceptionReport.cpp \
+ WheatyExceptionReport.h
diff --git a/src/shared/MemoryLeaks.cpp b/src/shared/MemoryLeaks.cpp
new file mode 100644
index 00000000000..ef7e36c3b57
--- /dev/null
+++ b/src/shared/MemoryLeaks.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2005-2009 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 "MemoryLeaks.h"
+#include "Policies/SingletonImp.h"
+
+INSTANTIATE_SINGLETON_1( MemoryManager ) ;
+
+MemoryManager::MemoryManager( )
+{
+ #if COMPILER == MICROSOFT
+ // standard leak check initialization
+ //_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+ // uncomment to disable Visual Leak Detector from code
+ //VLDDisable();
+ #endif
+}
diff --git a/src/shared/MemoryLeaks.h b/src/shared/MemoryLeaks.h
new file mode 100644
index 00000000000..fcea1f557b1
--- /dev/null
+++ b/src/shared/MemoryLeaks.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2005-2009 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 TRINITYSERVER_MEMORY_H
+#define TRINITYSERVER_MEMORY_H
+
+#include "Platform/CompilerDefs.h"
+
+#if COMPILER == COMPILER_MICROSOFT
+
+#ifndef _WIN64
+// Visual Leak Detector support enabled
+//#include <vld/vld.h>
+// standard Visual Studio leak check disabled,
+//# define _CRTDBG_MAP_ALLOC
+//# include <stdlib.h>
+//# include <crtdbg.h>
+#else
+# define _CRTDBG_MAP_ALLOC
+# include <stdlib.h>
+# include <crtdbg.h>
+#endif
+
+#endif
+
+
+#include "Policies/Singleton.h"
+
+struct MemoryManager : public Trinity::Singleton < MemoryManager >
+{
+ MemoryManager();
+};
+#endif
diff --git a/src/shared/Mthread.cpp b/src/shared/Mthread.cpp
deleted file mode 100644
index fbbeeb5a620..00000000000
--- a/src/shared/Mthread.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- Cross-platform thread handling
- Copyright (C) 2005 Andrew Zabolotny
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "Mthread.h"
-
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE_CC__)
-# define TRINITY_PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE
-#else
-# define TRINITY_PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
-#endif
-
-#if PLATFORM != PLATFORM_WINDOWS
-
-MThread::MThread ()
-{
- tid = 0;
-}
-
-MThread::~MThread ()
-{
- /* Kill thread if this is not the current thread */
- if (tid && (pthread_self () != tid))
- {
- pthread_cancel (tid);
- pthread_join (tid, NULL);
- }
-}
-
-static void *thread_start_routine (void *arg)
-{
- MThread *newthr = (MThread *)arg;
- pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
- newthr->routine (newthr->arg);
- return NULL;
-}
-
-MThread *MThread::Start (void (*routine) (void *arg), void *arg)
-{
- MThread *newthr = new MThread ();
- newthr->routine = routine;
- newthr->arg = arg;
- int rc = pthread_create (&newthr->tid, NULL, thread_start_routine, newthr);
- if (rc)
- {
- newthr->DecRef ();
- return NULL;
- }
-
- return newthr;
-}
-
-pthread_mutexattr_t MMutex::attr;
-int MMutex::attr_refcount = 0;
-
-MMutex::MMutex ()
-{
- if (!attr_refcount++)
- {
- pthread_mutexattr_init (&attr);
- pthread_mutexattr_settype (&attr, TRINITY_PTHREAD_MUTEX_RECURSIVE);
- }
-
- pthread_mutex_init (&mutex, &attr);
-}
-
-MMutex::~MMutex ()
-{
- pthread_mutex_destroy (&mutex);
- if (!--attr_refcount)
- pthread_mutexattr_destroy (&attr);
-}
-
-bool MMutex::Lock ()
-{
- return (pthread_mutex_lock (&mutex) == 0);
-}
-
-bool MMutex::TryLock ()
-{
- return (pthread_mutex_trylock (&mutex) == 0);
-}
-
-void MMutex::Unlock ()
-{
- pthread_mutex_unlock (&mutex);
-}
-
-MMutex *MMutex::Create ()
-{
- return new MMutex ();
-}
-
-#else //windows
-
-MThread::MThread()
-{
- th = NULL;
-}
-
-MThread::~MThread ()
-{
- /* Kill thread if this is not current thread */
- if (th && (GetCurrentThreadId () != id))
- {
- TerminateThread (th, 0);
- WaitForSingleObject (th, INFINITE);
- CloseHandle (th);
- }
-}
-
-bool MThread::SetPriority (ThreadPriority prio)
-{
- int p;
- switch (prio)
- {
- case IDLE: p = THREAD_PRIORITY_IDLE; break;
- case LOWER: p = THREAD_PRIORITY_LOWEST; break;
- case LOW: p = THREAD_PRIORITY_BELOW_NORMAL; break;
- case NORMAL: p = THREAD_PRIORITY_NORMAL; break;
- case HIGH: p = THREAD_PRIORITY_ABOVE_NORMAL; break;
- case HIGHER: p = THREAD_PRIORITY_HIGHEST; break;
- case REALTIME: p = THREAD_PRIORITY_TIME_CRITICAL; break;
- default: p = THREAD_PRIORITY_NORMAL; break;
- }
- return SetThreadPriority (th, p);
-}
-
-static DWORD WINAPI thread_start_routine (void *arg)
-//static void thread_start_routine (void *arg)
-{
- MThread *newthr = (MThread *)arg;
- newthr->id = GetCurrentThreadId ();
- newthr->routine (newthr->arg);
- return 0;
-}
-
-MThread *MThread::Start (void (*routine) (void *arg), void *arg)
-{
- DWORD dwtid;
- MThread *newthr = new MThread ();
- newthr->routine = routine;
- newthr->arg = arg;
- newthr->th = CreateThread (NULL, WIN32_THREAD_STACK_SIZE, thread_start_routine, newthr, 0, &dwtid);
- //newthr->th = (HANDLE)_beginthread(thread_start_routine, 0, newthr);
- if (!newthr->th)
- {
- newthr->DecRef ();
- return NULL;
- }
- return newthr;
-}
-
-MMutex::MMutex ()
-{
- sem = CreateMutex (NULL, FALSE, NULL);
-}
-
-MMutex::~MMutex ()
-{
- CloseHandle (sem);
-}
-
-bool MMutex::Lock ()
-{
- return (WaitForSingleObject (sem, INFINITE) != WAIT_FAILED);
-}
-
-bool MMutex::TryLock ()
-{
- DWORD state = WaitForSingleObject (sem, 0);
- return (state == WAIT_OBJECT_0) && (state != WAIT_ABANDONED);
-}
-
-void MMutex::Unlock ()
-{
- ReleaseMutex (sem);
-}
-
-MMutex *MMutex::Create ()
-{
- MMutex *mutex = new MMutex ();
- if (!mutex->sem)
- {
- mutex->DecRef ();
- return NULL;
- }
- return mutex;
-}
-#endif
-
diff --git a/src/shared/Mthread.h b/src/shared/Mthread.h
deleted file mode 100644
index d0ac6deb43c..00000000000
--- a/src/shared/Mthread.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef MTHREAD_H
-#define MTHREAD_H
-
-#include "Base.h"
-#ifndef WIN32
-#include <pthread.h>
-#else
-#include <windows.h>
-//#include "Process.h"
-#define WIN32_THREAD_STACK_SIZE 0x10000
-#endif
-
-enum ThreadPriority
-{
- IDLE,
- LOWER,
- LOW,
- NORMAL,
- HIGH,
- HIGHER,
- REALTIME
-};
-
-class MThread: public Base
-{
- public:
- static MThread *Start (void (*routine) (void *arg), void *arg);
- MThread ();
- ~MThread ();
- bool SetPriority (ThreadPriority prio);
-
- void (*routine) (void *arg);
- void *arg;
-
- #ifdef WIN32
- HANDLE th;
- ULONG id;
- #else
- pthread_t tid;
- #endif
-
-};
-
-class MMutex : public Base
-{
- public:
-
- #ifdef WIN32
- HANDLE sem;
- #else
- pthread_mutex_t mutex;
- static pthread_mutexattr_t attr;
- static int attr_refcount;
- #endif
- static MMutex *Create ();
- MMutex ();
- virtual ~MMutex ();
- virtual bool Lock ();
- virtual bool TryLock ();
- virtual void Unlock ();
-};
-#endif // MTHREAD_H
-
diff --git a/src/shared/PacketLog.cpp b/src/shared/PacketLog.cpp
index aa9fd2dc348..96c9727e7fa 100644
--- a/src/shared/PacketLog.cpp
+++ b/src/shared/PacketLog.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/PacketLog.h b/src/shared/PacketLog.h
index 30fb7da15b9..49ac72ebc4b 100644
--- a/src/shared/PacketLog.h
+++ b/src/shared/PacketLog.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/ProgressBar.cpp b/src/shared/ProgressBar.cpp
index f5a45b9d862..b72118ad804 100644
--- a/src/shared/ProgressBar.cpp
+++ b/src/shared/ProgressBar.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/ProgressBar.h b/src/shared/ProgressBar.h
index 3f217f228fe..50c5c7d11e5 100644
--- a/src/shared/ProgressBar.h
+++ b/src/shared/ProgressBar.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/ServiceWin32.cpp b/src/shared/ServiceWin32.cpp
index d384884529a..5c68ba31954 100644
--- a/src/shared/ServiceWin32.cpp
+++ b/src/shared/ServiceWin32.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -131,10 +131,10 @@ bool WinServiceUninstall()
serviceName, SERVICE_QUERY_STATUS | DELETE);
if (service)
{
- SERVICE_STATUS serviceStatus;
- if (QueryServiceStatus(service, &serviceStatus))
+ SERVICE_STATUS serviceStatus2;
+ if (QueryServiceStatus(service, &serviceStatus2))
{
- if (serviceStatus.dwCurrentState == SERVICE_STOPPED)
+ if (serviceStatus2.dwCurrentState == SERVICE_STOPPED)
DeleteService(service);
}
CloseServiceHandle(service);
diff --git a/src/shared/ServiceWin32.h b/src/shared/ServiceWin32.h
index d046acdcef4..18a52c396ea 100644
--- a/src/shared/ServiceWin32.h
+++ b/src/shared/ServiceWin32.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/SystemConfig.h b/src/shared/SystemConfig.h
index 6b4471e792d..9d154b863d0 100644
--- a/src/shared/SystemConfig.h
+++ b/src/shared/SystemConfig.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -28,7 +28,7 @@
#include "revision.h"
-#define _PACKAGENAME "TrinityCore "
+#define _PACKAGENAME "TrinityCore2 "
#define _CODENAME "YUME"
#if TRINITY_ENDIAN == TRINITY_BIGENDIAN
diff --git a/src/shared/SystemConfig.h.in b/src/shared/SystemConfig.h.in
new file mode 100644
index 00000000000..ad8df37b5be
--- /dev/null
+++ b/src/shared/SystemConfig.h.in
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 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_SYSTEMCONFIG_H
+#define TRINITY_SYSTEMCONFIG_H
+
+#ifndef _PACKAGENAME
+#define _PACKAGENAME "TrinityCore2 "
+#endif
+
+#include "Platform/Define.h"
+#include "revision.h" //-----here u are ------ _REVISION is the magic key
+
+#ifndef _VERSION
+#if PLATFORM == PLATFORM_WINDOWS
+# define _VERSION(REVD,REVT,REVN,REVH) "0.13.0-DEV" " (" REVD " " REVT " Revision " REVN " - " REVH ")"
+#else
+# define _VERSION(REVD,REVT,REVN,REVH) "@VERSION@" " (" REVD " " REVT " Revision " REVN " - " REVH ")"
+#endif
+#endif
+
+// Format is YYYYMMDDRR where RR is the change in the conf file
+// for that day.
+#ifndef _MANGOSDCONFVERSION
+# define _MANGOSDCONFVERSION 2008022901
+#endif
+#ifndef _REALMDCONFVERSION
+# define _REALMDCONFVERSION 2007062001
+#endif
+
+#if MANGOS_ENDIAN == MANGOS_BIGENDIAN
+# define _ENDIAN_STRING "big-endian"
+#else
+# define _ENDIAN_STRING "little-endian"
+#endif
+
+// The path to config files
+#ifndef SYSCONFDIR
+# define SYSCONFDIR ""
+#endif
+
+#if PLATFORM == PLATFORM_WINDOWS
+# ifdef _WIN64
+# define _ENDIAN_PLATFORM "Win64 (" _ENDIAN_STRING ")"
+# else
+# define _ENDIAN_PLATFORM "Win32 (" _ENDIAN_STRING ")"
+# endif
+# define _MANGOSD_CONFIG SYSCONFDIR"mangosd.conf"
+# define _REALMD_CONFIG SYSCONFDIR"realmd.conf"
+#else
+# define _ENDIAN_PLATFORM "Unix (" _ENDIAN_STRING ")"
+# define _MANGOSD_CONFIG SYSCONFDIR"mangosd.conf"
+# define _REALMD_CONFIG SYSCONFDIR"realmd.conf"
+#endif
+
+
+#define DEFAULT_PLAYER_LIMIT 100
+#define DEFAULT_WORLDSERVER_PORT 8085 //8129
+#define DEFAULT_REALMSERVER_PORT 3724
+#define DEFAULT_SOCKET_SELECT_TIME 10000
+#endif
diff --git a/src/shared/Timer.h b/src/shared/Timer.h
index 81b6bb58465..82f5be161d9 100644
--- a/src/shared/Timer.h
+++ b/src/shared/Timer.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/Util.cpp b/src/shared/Util.cpp
index 26d2275ec2a..767b65e441c 100644
--- a/src/shared/Util.cpp
+++ b/src/shared/Util.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -36,27 +36,27 @@ static MTRandTSS mtRand;
int32 irand (int32 min, int32 max)
{
- return int32 (mtRand.get ().randInt (max - min)) + min;
+ return int32 (mtRand.get ().randInt (max - min)) + min;
}
uint32 urand (uint32 min, uint32 max)
{
- return mtRand.get ().randInt (max - min) + min;
+ return mtRand.get ().randInt (max - min) + min;
}
int32 rand32 ()
{
- return mtRand.get ().randInt ();
+ return mtRand.get ().randInt ();
}
double rand_norm(void)
{
- return mtRand.get ().randExc ();
+ return mtRand.get ().randExc ();
}
double rand_chance (void)
{
- return mtRand.get ().randExc (100.0);
+ return mtRand.get ().randExc (100.0);
}
Tokens StrSplit(const std::string &src, const std::string &sep)
@@ -254,8 +254,9 @@ bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize)
size_t len = utf8::distance(utf8str,utf8str+csize);
if(len > wsize)
{
+ if(wsize > 0)
+ wstr[0] = L'\0';
wsize = 0;
- wstr = L"";
return false;
}
@@ -265,8 +266,9 @@ bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize)
}
catch(std::exception)
{
+ if(wsize > 0)
+ wstr[0] = L'\0';
wsize = 0;
- wstr = L"";
return false;
}
diff --git a/src/shared/Util.h b/src/shared/Util.h
index 98e60f83319..adfbdad620a 100644
--- a/src/shared/Util.h
+++ b/src/shared/Util.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -287,20 +287,20 @@ bool consoleToUtf8(const std::string& conStr,std::string& utf8str);
bool Utf8FitTo(const std::string& str, std::wstring search);
#if PLATFORM == PLATFORM_WINDOWS
-#define UTF8PRINTF(OUT,FRM,RESERR) \
-{ \
- char temp_buf[6000]; \
- va_list ap; \
- va_start(ap, FRM); \
- size_t temp_len = vsnprintf(temp_buf,6000,FRM,ap); \
- va_end(ap); \
- \
- wchar_t wtemp_buf[6000]; \
- size_t wtemp_len = 6000-1; \
+#define UTF8PRINTF(OUT,FRM,RESERR) \
+{ \
+ char temp_buf[32*1024]; \
+ va_list ap; \
+ va_start(ap, FRM); \
+ size_t temp_len = vsnprintf(temp_buf,32*1024,FRM,ap); \
+ va_end(ap); \
+ \
+ wchar_t wtemp_buf[32*1024]; \
+ size_t wtemp_len = 32*1024-1; \
if(!Utf8toWStr(temp_buf,temp_len,wtemp_buf,wtemp_len)) \
- return RESERR; \
+ return RESERR; \
CharToOemBuffW(&wtemp_buf[0],&temp_buf[0],wtemp_len+1);\
- fprintf(OUT,temp_buf); \
+ fprintf(OUT,temp_buf); \
}
#else
#define UTF8PRINTF(OUT,FRM,RESERR) \
@@ -317,3 +317,231 @@ uint32 CreatePIDFile(const std::string& filename);
#endif
+//handler for operations on large flags
+#ifndef _FLAG96
+#define _FLAG96
+
+class flag96
+{
+private:
+ uint32 part[3];
+public:
+ flag96(uint32 p1=0,uint32 p2=0,uint32 p3=0)
+ {
+ part[0]=p1;
+ part[1]=p2;
+ part[2]=p3;
+ }
+
+ inline bool IsEqual(uint32 p1=0, uint32 p2=0, uint32 p3=0) const
+ {
+ return (
+ part[0]==p1 &&
+ part[1]==p2 &&
+ part[2]==p3);
+ };
+
+ inline bool HasFlag(uint32 p1=0, uint32 p2=0, uint32 p3=0) const
+ {
+ return (
+ part[0]&p1 ||
+ part[1]&p2 ||
+ part[2]&p3);
+ };
+
+ inline void Set(uint32 p1=0, uint32 p2=0, uint32 p3=0)
+ {
+ part[0]=p1;
+ part[1]=p2;
+ part[2]=p3;
+ };
+
+ template<class type>
+ inline bool operator < (type & right)
+ {
+ for (uint8 i=3;i>0;i--)
+ {
+ if (part[i-1]<right.part[i-1])
+ return 1;
+ else if (part[i-1]>right.part[i-1])
+ return 0;
+ }
+ return 0;
+ };
+
+ template<class type>
+ inline bool operator < (type & right) const
+ {
+ for (uint8 i=3;i>0;i--)
+ {
+ if (part[i-1]<right.part[i-1])
+ return 1;
+ else if (part[i-1]>right.part[i-1])
+ return 0;
+ }
+ return 0;
+ };
+
+ template<class type>
+ inline bool operator != (type & right)
+ {
+ if (part[0]!=right.part[0]
+ || part[1]!=right.part[1]
+ || part[2]!=right.part[2])
+ return true;
+ return false;
+ }
+
+ template<class type>
+ inline bool operator != (type & right) const
+ {
+ if (part[0]!=right.part[0]
+ || part[1]!=right.part[1]
+ || part[2]!=right.part[2])
+ return true;
+ return false;
+ };
+
+ template<class type>
+ inline bool operator == (type & right)
+ {
+ if (part[0]!=right.part[0]
+ || part[1]!=right.part[1]
+ || part[2]!=right.part[2])
+ return false;
+ return true;
+ };
+
+ template<class type>
+ inline bool operator == (type & right) const
+ {
+ if (part[0]!=right.part[0]
+ || part[1]!=right.part[1]
+ || part[2]!=right.part[2])
+ return false;
+ return true;
+ };
+
+ template<class type>
+ inline void operator = (type & right)
+ {
+ part[0]=right.part[0];
+ part[1]=right.part[1];
+ part[2]=right.part[2];
+ };
+
+ template<class type>
+ inline flag96 operator & (type & right)
+ {
+ flag96 ret(part[0] & right.part[0],part[1] & right.part[1],part[2] & right.part[2]);
+ return
+ ret;
+ };
+ template<class type>
+ inline flag96 operator & (type & right) const
+ {
+ flag96 ret(part[0] & right.part[0],part[1] & right.part[1],part[2] & right.part[2]);
+ return
+ ret;
+ };
+
+ template<class type>
+ inline void operator &= (type & right)
+ {
+ *this=*this & right;
+ };
+
+ template<class type>
+ inline flag96 operator | (type & right)
+ {
+ flag96 ret(part[0] | right.part[0],part[1] | right.part[1],part[2] | right.part[2]);
+ return
+ ret;
+ };
+
+ template<class type>
+ inline flag96 operator | (type & right) const
+ {
+ flag96 ret(part[0] | right.part[0],part[1] | right.part[1],part[2] | right.part[2]);
+ return
+ ret;
+ };
+
+ template<class type>
+ inline void operator |= (type & right)
+ {
+ *this=*this | right;
+ };
+
+ inline void operator ~ ()
+ {
+ part[2]=~part[2];
+ part[1]=~part[1];
+ part[0]=~part[0];
+ };
+
+ template<class type>
+ inline flag96 operator ^ (type & right)
+ {
+ flag96 ret(part[0] ^ right.part[0],part[1] ^ right.part[1],part[2] ^ right.part[2]);
+ return
+ ret;
+ };
+
+ template<class type>
+ inline flag96 operator ^ (type & right) const
+ {
+ flag96 ret(part[0] ^ right.part[0],part[1] ^ right.part[1],part[2] ^ right.part[2]);
+ return
+ ret;
+ };
+
+ template<class type>
+ inline void operator ^= (type & right)
+ {
+ *this=*this^right;
+ };
+
+ inline operator bool() const
+ {
+ return(
+ part[0] != 0 ||
+ part[1] != 0 ||
+ part[2] != 0);
+ };
+
+ inline operator bool()
+ {
+ return(
+ part[0] != 0 ||
+ part[1] != 0 ||
+ part[2] != 0);
+ };
+
+ inline bool operator ! () const
+ {
+ return(
+ part[0] == 0 &&
+ part[1] == 0 &&
+ part[2] == 0);
+ };
+
+ inline bool operator ! ()
+ {
+ return(
+ part[0] == 0 &&
+ part[1] == 0 &&
+ part[2] == 0);
+ };
+
+ inline uint32 & operator[](uint8 el)
+ {
+ return (part[el]);
+ };
+
+ inline const uint32 & operator[](uint8 el) const
+ {
+ return (part[el]);
+ };
+};
+#endif
diff --git a/src/shared/WorldPacket.h b/src/shared/WorldPacket.h
index 8849b790f01..1eb3f12dd86 100644
--- a/src/shared/WorldPacket.h
+++ b/src/shared/WorldPacket.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/BaseModel.cpp b/src/shared/vmap/BaseModel.cpp
index f4bf13bc558..2ffd5672218 100644
--- a/src/shared/vmap/BaseModel.cpp
+++ b/src/shared/vmap/BaseModel.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/BaseModel.h b/src/shared/vmap/BaseModel.h
index 6c17f704692..098e1d9381b 100644
--- a/src/shared/vmap/BaseModel.h
+++ b/src/shared/vmap/BaseModel.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/CoordModelMapping.cpp b/src/shared/vmap/CoordModelMapping.cpp
index 319e7bb8c31..c362101ffb4 100644
--- a/src/shared/vmap/CoordModelMapping.cpp
+++ b/src/shared/vmap/CoordModelMapping.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/CoordModelMapping.h b/src/shared/vmap/CoordModelMapping.h
index cfaa600ee81..7c89f0e8a0f 100644
--- a/src/shared/vmap/CoordModelMapping.h
+++ b/src/shared/vmap/CoordModelMapping.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/DebugCmdLogger.cpp b/src/shared/vmap/DebugCmdLogger.cpp
index 2552a16acc2..de656f4cfc5 100644
--- a/src/shared/vmap/DebugCmdLogger.cpp
+++ b/src/shared/vmap/DebugCmdLogger.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/DebugCmdLogger.h b/src/shared/vmap/DebugCmdLogger.h
index a194d335381..5493ab6f332 100644
--- a/src/shared/vmap/DebugCmdLogger.h
+++ b/src/shared/vmap/DebugCmdLogger.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/IVMapManager.h b/src/shared/vmap/IVMapManager.h
index 01aef4b9d4c..243a15aef73 100644
--- a/src/shared/vmap/IVMapManager.h
+++ b/src/shared/vmap/IVMapManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/Makefile.am b/src/shared/vmap/Makefile.am
new file mode 100644
index 00000000000..483a926c907
--- /dev/null
+++ b/src/shared/vmap/Makefile.am
@@ -0,0 +1,58 @@
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+#
+# Copyright (C) 2008-2009 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
+
+## Process this file with automake to produce Makefile.in
+
+## Sub-directories to parse
+
+## CPP flags for includes, defines, etc.
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared -I$(srcdir)/../../../dep/include/g3dlite
+
+## Build MaNGOS shared library and its parts as convenience library.
+# All libraries will be convenience libraries. Might be changed to shared
+# later.
+noinst_LIBRARIES = libmangosvmaps.a
+
+libmangosvmaps_a_SOURCES = \
+ AABSPTree.h \
+ BaseModel.cpp \
+ BaseModel.h \
+ CoordModelMapping.cpp \
+ CoordModelMapping.h \
+ DebugCmdLogger.cpp \
+ DebugCmdLogger.h \
+ IVMapManager.h \
+ ManagedModelContainer.cpp \
+ ManagedModelContainer.h \
+ ModelContainer.cpp \
+ ModelContainer.h \
+ NodeValueAccess.h \
+ ShortBox.h \
+ ShortVector.h \
+ SubModel.cpp \
+ SubModel.h \
+ TileAssembler.cpp \
+ TileAssembler.h \
+ TreeNode.cpp \
+ TreeNode.h \
+ VMapDefinitions.h \
+ VMapFactory.cpp \
+ VMapFactory.h \
+ VMapManager.cpp \
+ VMapManager.h \
+ VMapTools.h
diff --git a/src/shared/vmap/ManagedModelContainer.cpp b/src/shared/vmap/ManagedModelContainer.cpp
index 1362002bafd..c7bfefe7179 100644
--- a/src/shared/vmap/ManagedModelContainer.cpp
+++ b/src/shared/vmap/ManagedModelContainer.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/ManagedModelContainer.h b/src/shared/vmap/ManagedModelContainer.h
index 33c675d0806..e6862f915c7 100644
--- a/src/shared/vmap/ManagedModelContainer.h
+++ b/src/shared/vmap/ManagedModelContainer.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/ModelContainer.cpp b/src/shared/vmap/ModelContainer.cpp
index 9eb100161d8..4a722d2585b 100644
--- a/src/shared/vmap/ModelContainer.cpp
+++ b/src/shared/vmap/ModelContainer.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/ModelContainer.h b/src/shared/vmap/ModelContainer.h
index 9613bf53d96..abc96261050 100644
--- a/src/shared/vmap/ModelContainer.h
+++ b/src/shared/vmap/ModelContainer.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/NodeValueAccess.h b/src/shared/vmap/NodeValueAccess.h
index e14a6dba676..54fc5ee99b6 100644
--- a/src/shared/vmap/NodeValueAccess.h
+++ b/src/shared/vmap/NodeValueAccess.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/ShortBox.h b/src/shared/vmap/ShortBox.h
index bffca0d806d..0e98677aa9e 100644
--- a/src/shared/vmap/ShortBox.h
+++ b/src/shared/vmap/ShortBox.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/ShortVector.h b/src/shared/vmap/ShortVector.h
index f7dd0f74859..5f0fb7d9fd8 100644
--- a/src/shared/vmap/ShortVector.h
+++ b/src/shared/vmap/ShortVector.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/SubModel.cpp b/src/shared/vmap/SubModel.cpp
index c6022d2ed69..370c80062d6 100644
--- a/src/shared/vmap/SubModel.cpp
+++ b/src/shared/vmap/SubModel.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/SubModel.h b/src/shared/vmap/SubModel.h
index c52dc7f5c51..89ea9b91d7b 100644
--- a/src/shared/vmap/SubModel.h
+++ b/src/shared/vmap/SubModel.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/TileAssembler.cpp b/src/shared/vmap/TileAssembler.cpp
index e6a1a6f448b..64d67205f68 100644
--- a/src/shared/vmap/TileAssembler.cpp
+++ b/src/shared/vmap/TileAssembler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -75,12 +75,12 @@ namespace VMAP
addWorldAreaMapId(0); //Azeroth
addWorldAreaMapId(1); //Kalimdor
addWorldAreaMapId(530); //Expansion01
+ addWorldAreaMapId(571); //Expansion02
}
//=================================================================
std::string getModNameFromModPosName(const std::string& pModPosName)
{
-
size_t spos = pModPosName.find_first_of('#');
std::string modelFileName = pModPosName.substr(0,spos);
return(modelFileName);
@@ -142,7 +142,6 @@ namespace VMAP
//=================================================================
bool TileAssembler::convertWorld()
{
-
#ifdef _ASSEMBLER_DEBUG
# ifdef _DEBUG
::g_df = fopen("../TileAssembler_debug.txt", "wb");
diff --git a/src/shared/vmap/TileAssembler.h b/src/shared/vmap/TileAssembler.h
index a2fe8055fcf..d2183794a9e 100644
--- a/src/shared/vmap/TileAssembler.h
+++ b/src/shared/vmap/TileAssembler.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/TreeNode.cpp b/src/shared/vmap/TreeNode.cpp
index 113199235bf..c884f9b3b1d 100644
--- a/src/shared/vmap/TreeNode.cpp
+++ b/src/shared/vmap/TreeNode.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/TreeNode.h b/src/shared/vmap/TreeNode.h
index d71396487b9..1b9532001e5 100644
--- a/src/shared/vmap/TreeNode.h
+++ b/src/shared/vmap/TreeNode.h
@@ -1,7 +1,7 @@
/*
-* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
-* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+* Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/VMapDefinitions.h b/src/shared/vmap/VMapDefinitions.h
index 0800bfbda88..fd28a91d515 100644
--- a/src/shared/vmap/VMapDefinitions.h
+++ b/src/shared/vmap/VMapDefinitions.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/VMapFactory.cpp b/src/shared/vmap/VMapFactory.cpp
index 2dad2047189..5189f79daba 100644
--- a/src/shared/vmap/VMapFactory.cpp
+++ b/src/shared/vmap/VMapFactory.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/VMapFactory.h b/src/shared/vmap/VMapFactory.h
index 9a4493d8817..f3375d723c1 100644
--- a/src/shared/vmap/VMapFactory.h
+++ b/src/shared/vmap/VMapFactory.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/VMapManager.cpp b/src/shared/vmap/VMapManager.cpp
index 3b93b63086b..f5c2640be70 100644
--- a/src/shared/vmap/VMapManager.cpp
+++ b/src/shared/vmap/VMapManager.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/VMapManager.h b/src/shared/vmap/VMapManager.h
index 8ece6de4652..bfeba3cfe67 100644
--- a/src/shared/vmap/VMapManager.h
+++ b/src/shared/vmap/VMapManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
diff --git a/src/shared/vmap/VMapTools.h b/src/shared/vmap/VMapTools.h
index 4961064d188..3af3a29310d 100644
--- a/src/shared/vmap/VMapTools.h
+++ b/src/shared/vmap/VMapTools.h
@@ -1,7 +1,7 @@
/*
-* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
-* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+* Copyright (C) 2008-2009 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
diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am
new file mode 100644
index 00000000000..81040a49592
--- /dev/null
+++ b/src/tools/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright (C) 2005-2009 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
+
+## Process this file with automake to produce Makefile.in
+
+## Sub-directories to parse
+SUBDIRS = genrevision
+
+## Additional files to include when running 'make dist'
+# Nothing yet.
diff --git a/src/tools/genrevision/Makefile.am b/src/tools/genrevision/Makefile.am
new file mode 100644
index 00000000000..3f60ac14ab2
--- /dev/null
+++ b/src/tools/genrevision/Makefile.am
@@ -0,0 +1,35 @@
+# Copyright (C) 2005-2009 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
+
+## Process this file with automake to produce Makefile.in
+
+## CPP flags for includes, defines, etc.
+AM_CPPFLAGS = -I$(srcdir)
+
+## Build world list daemon as standalone program
+bin_PROGRAMS = genrevision
+genrevision_SOURCES = \
+ genrevision.cpp
+
+## Link world daemon against the shared library
+genrevision_LDADD =
+genrevision_LDFLAGS = -L$(libdir)
+
+## Additional files to include when running 'make dist'
+# Include world daemon configuration
+#EXTRA_DIST =
+
+## Additional files to install
diff --git a/src/trinitycore/CMakeLists.txt b/src/trinitycore/CMakeLists.txt
index 2c7c4544577..7cd012d9f45 100644
--- a/src/trinitycore/CMakeLists.txt
+++ b/src/trinitycore/CMakeLists.txt
@@ -2,14 +2,14 @@
########### next target ###############
SET(trinity-core_SRCS
-CliRunnable.cpp
-CliRunnable.h
-Main.cpp
-Master.cpp
-Master.h
-RASocket.cpp
-RASocket.h
-WorldRunnable.cpp
+CliRunnable.cpp
+CliRunnable.h
+Main.cpp
+Master.cpp
+Master.h
+RASocket.cpp
+RASocket.h
+WorldRunnable.cpp
WorldRunnable.h
)
diff --git a/src/trinitycore/CliRunnable.cpp b/src/trinitycore/CliRunnable.cpp
index 839358e7034..91f37cd1b48 100644
--- a/src/trinitycore/CliRunnable.cpp
+++ b/src/trinitycore/CliRunnable.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -82,19 +82,10 @@ bool ChatHandler::HandleAccountDeleteCommand(const char* args)
}
/// Commands not recommended call from chat, but support anyway
- if(m_session)
- {
- uint32 targetSecurity = accmgr.GetSecurity(account_id);
-
- /// can delete only for account with less security
- /// This is also reject self apply in fact
- if (targetSecurity >= m_session->GetSecurity())
- {
- SendSysMessage (LANG_YOURS_SECURITY_IS_LOW);
- SetSentErrorMessage (true);
- return false;
- }
- }
+ /// can delete only for account with less security
+ /// This is also reject self apply in fact
+ if(HasLowerSecurityAccount (NULL,account_id,true))
+ return false;
AccountOpResult result = accmgr.DeleteAccount(account_id);
switch(result)
@@ -177,12 +168,15 @@ bool ChatHandler::HandleAccountOnlineListCommand(const char* args)
///- Get the list of accounts ID logged to the realm
QueryResult *resultDB = CharacterDatabase.Query("SELECT name,account FROM characters WHERE online > 0");
if (!resultDB)
+ {
+ SendSysMessage(LANG_ACCOUNT_LIST_EMPTY);
return true;
+ }
///- Display the list of account/characters online
- SendSysMessage("=====================================================================");
+ SendSysMessage(LANG_ACCOUNT_LIST_BAR);
SendSysMessage(LANG_ACCOUNT_LIST_HEADER);
- SendSysMessage("=====================================================================");
+ SendSysMessage(LANG_ACCOUNT_LIST_BAR);
///- Circle through accounts
do
@@ -199,7 +193,7 @@ bool ChatHandler::HandleAccountOnlineListCommand(const char* args)
if(resultLogin)
{
Field *fieldsLogin = resultLogin->Fetch();
- PSendSysMessage("|%15s| %20s | %15s |%4d|%5d|",
+ PSendSysMessage(LANG_ACCOUNT_LIST_LINE,
fieldsLogin[0].GetString(),name.c_str(),fieldsLogin[1].GetString(),fieldsLogin[2].GetUInt32(),fieldsLogin[3].GetUInt32());
delete resultLogin;
@@ -211,7 +205,7 @@ bool ChatHandler::HandleAccountOnlineListCommand(const char* args)
delete resultDB;
- SendSysMessage("=====================================================================");
+ SendSysMessage(LANG_ACCOUNT_LIST_BAR);
return true;
}
@@ -259,6 +253,20 @@ bool ChatHandler::HandleAccountCreateCommand(const char* args)
}
/// Set the level of logging
+bool ChatHandler::HandleServerSetLogFileLevelCommand(const char *args)
+{
+ if(!*args)
+ return false;
+
+ char *NewLevel = strtok((char*)args, " ");
+ if (!NewLevel)
+ return false;
+
+ sLog.SetLogFileLevel(NewLevel);
+ return true;
+}
+
+/// Set the level of logging
bool ChatHandler::HandleServerSetLogLevelCommand(const char *args)
{
if(!*args)
@@ -318,7 +326,7 @@ void CliRunnable::run()
char commandbuf[256];
///- Display the list of available CLI functions then beep
- sLog.outString();
+ sLog.outString("");
if(sConfig.GetBoolDefault("BeepAtStart", true))
printf("\a"); // \a = Alert
@@ -373,4 +381,3 @@ void CliRunnable::run()
///- End the database thread
WorldDatabase.ThreadEnd(); // free mySQL thread resources
}
-
diff --git a/src/trinitycore/CliRunnable.h b/src/trinitycore/CliRunnable.h
index ea60ef695bc..20ff58f27ba 100644
--- a/src/trinitycore/CliRunnable.h
+++ b/src/trinitycore/CliRunnable.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -33,4 +33,3 @@ class CliRunnable : public ZThread::Runnable
};
#endif
/// @}
-
diff --git a/src/trinitycore/Main.cpp b/src/trinitycore/Main.cpp
index 4be314d75f3..7b00073026d 100644
--- a/src/trinitycore/Main.cpp
+++ b/src/trinitycore/Main.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -21,8 +21,6 @@
/// \addtogroup Trinityd Trinity Daemon
/// @{
/// \file
-#include "SystemConfig.h"
-#include "revision.h"
#include "Common.h"
#include "Database/DatabaseEnv.h"
@@ -31,18 +29,18 @@
#include "Master.h"
#ifndef _TRINITY_CORE_CONFIG
-# define _TRINITY_CORE_CONFIG "trinitycore.conf"
+# define _TRINITY_CORE_CONFIG "TrinityCore.conf"
#endif //_TRINITY_CORE_CONFIG
// Format is YYYYMMDDRR where RR is the change in the conf file
// for that day.
#ifndef _TRINITY_CORE_CONFVER
-# define _TRINITY_CORE_CONFVER 2008022901
+# define _TRINITY_CORE_CONFVER 2009032201
#endif //_TRINITY_CORE_CONFVER
#ifdef WIN32
#include "ServiceWin32.h"
-char serviceName[] = "Trinityd";
+char serviceName[] = "TrinityCore";
char serviceLongName[] = "Trinity core service";
char serviceDescription[] = "Massive Network Game Object Server";
/*
@@ -64,7 +62,6 @@ uint32 realmID; ///< Id of the realm
void usage(const char *prog)
{
sLog.outString("Usage: \n %s [<options>]\n"
- " --version print version and exit\n\r"
" -c config_file use config_file as configuration file\n\r"
#ifdef WIN32
" Running as service functions:\n\r"
@@ -95,12 +92,6 @@ extern int main(int argc, char **argv)
cfg_file = argv[c];
}
- if( strcmp(argv[c],"--version") == 0)
- {
- printf("%s\n", _FULLVERSION);
- return 0;
- }
-
#ifdef WIN32
////////////
//Services//
@@ -172,4 +163,3 @@ extern int main(int argc, char **argv)
}
/// @}
-
diff --git a/src/trinitycore/Makefile.am b/src/trinitycore/Makefile.am
new file mode 100644
index 00000000000..7e1cd086d3c
--- /dev/null
+++ b/src/trinitycore/Makefile.am
@@ -0,0 +1,62 @@
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+#
+# Copyright (C) 2008-2009 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
+
+## Process this file with automake to produce Makefile.in
+
+## CPP flags for includes, defines, etc.
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir)/../../dep/include -I$(srcdir)/../framework -I$(srcdir)/../shared -I$(srcdir)/../game -I$(srcdir) -DSYSCONFDIR=\"$(sysconfdir)/\"
+
+## Build world list daemon as standalone program
+bin_PROGRAMS = trinity-worldd
+trinity_worldd_SOURCES = \
+ CliRunnable.cpp \
+ CliRunnable.h \
+ Main.cpp \
+ Master.cpp \
+ Master.h \
+ RASocket.cpp \
+ RASocket.h \
+ WorldRunnable.cpp \
+ WorldRunnable.h
+
+## Link world daemon against the shared library
+trinity_worldd_LDADD = ../bindings/scripts/libtrinityscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
+trinity_worldd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/scripts/ -L$(libdir) $(TRINI_LIBS) -export-dynamic
+
+## Additional files to include when running 'make dist'
+# Include world daemon configuration
+EXTRA_DIST = \
+ mangosd.conf.dist
+
+## Additional files to install
+sysconf_DATA = \
+ mangosd.conf.dist
+
+install-data-hook:
+ @list='$(sysconf_DATA)'; for p in $$list; do \
+ dest=`echo $$p | sed -e s/.dist//`; \
+ if test -f $(DESTDIR)$(sysconfdir)/$$dest; then \
+ echo "$@ will not overwrite existing $(DESTDIR)$(sysconfdir)/$$dest"; \
+ else \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest; \
+ fi; \
+ done
+
+clean-local:
+ rm -f $(sysconf_DATA)
diff --git a/src/trinitycore/Master.cpp b/src/trinitycore/Master.cpp
index 8fd5af08800..a478f18daa9 100644
--- a/src/trinitycore/Master.cpp
+++ b/src/trinitycore/Master.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -118,72 +118,74 @@ public:
class RARunnable : public ZThread::Runnable
{
public:
- uint32 numLoops, loopCounter;
-
- RARunnable ()
- {
- uint32 socketSelecttime = sWorld.getConfig (CONFIG_SOCKET_SELECTTIME);
- numLoops = (sConfig.GetIntDefault ("MaxPingTime", 30) * (MINUTE * 1000000 / socketSelecttime));
- loopCounter = 0;
- }
-
- void
- checkping ()
- {
- // ping if need
- if ((++loopCounter) == numLoops)
- {
+ uint32 numLoops, loopCounter;
+
+ RARunnable ()
+ {
+ uint32 socketSelecttime = sWorld.getConfig (CONFIG_SOCKET_SELECTTIME);
+ numLoops = (sConfig.GetIntDefault ("MaxPingTime", 30) * (MINUTE * 1000000 / socketSelecttime));
loopCounter = 0;
- sLog.outDetail ("Ping MySQL to keep connection alive");
- delete WorldDatabase.Query ("SELECT 1 FROM command LIMIT 1");
- delete LoginDatabase.Query ("SELECT 1 FROM realmlist LIMIT 1");
- delete CharacterDatabase.Query ("SELECT 1 FROM bugreport LIMIT 1");
- }
- }
-
- void
- run (void)
- {
- SocketHandler h;
-
- // Launch the RA listener socket
- ListenSocket<RASocket> RAListenSocket (h);
- bool usera = sConfig.GetBoolDefault ("Ra.Enable", false);
-
- if (usera)
- {
- port_t raport = sConfig.GetIntDefault ("Ra.Port", 3443);
- std::string stringip = sConfig.GetStringDefault ("Ra.IP", "0.0.0.0");
- ipaddr_t raip;
- if (!Utility::u2ip (stringip, raip))
- sLog.outError ("Trinity RA can not bind to ip %s", stringip.c_str ());
- else if (RAListenSocket.Bind (raip, raport))
- sLog.outError ("Trinity RA can not bind to port %d on %s", raport, stringip.c_str ());
- else
- {
- h.Add (&RAListenSocket);
+ }
+
+ void checkping ()
+ {
+ // ping if need
+ if ((++loopCounter) == numLoops)
+ {
+ loopCounter = 0;
+ sLog.outDetail ("Ping MySQL to keep connection alive");
+ delete WorldDatabase.Query ("SELECT 1 FROM command LIMIT 1");
+ delete LoginDatabase.Query ("SELECT 1 FROM realmlist LIMIT 1");
+ delete CharacterDatabase.Query ("SELECT 1 FROM bugreport LIMIT 1");
+ }
+ }
- sLog.outString ("Starting Remote access listner on port %d on %s", raport, stringip.c_str ());
- }
- }
+ void run ()
+ {
+ SocketHandler h;
- // Socket Selet time is in microseconds , not miliseconds!!
- uint32 socketSelecttime = sWorld.getConfig (CONFIG_SOCKET_SELECTTIME);
+ // Launch the RA listener socket
+ ListenSocket<RASocket> RAListenSocket (h);
+ bool usera = sConfig.GetBoolDefault ("Ra.Enable", false);
- // if use ra spend time waiting for io, if not use ra ,just sleep
- if (usera)
- while (!World::IsStopped())
+ if (usera)
{
- h.Select (0, socketSelecttime);
- checkping ();
+ port_t raport = sConfig.GetIntDefault ("Ra.Port", 3443);
+ std::string stringip = sConfig.GetStringDefault ("Ra.IP", "0.0.0.0");
+ ipaddr_t raip;
+ if (!Utility::u2ip (stringip, raip))
+ sLog.outError ("MaNGOS RA can not bind to ip %s", stringip.c_str ());
+ else if (RAListenSocket.Bind (raip, raport))
+ sLog.outError ("MaNGOS RA can not bind to port %d on %s", raport, stringip.c_str ());
+ else
+ {
+ h.Add (&RAListenSocket);
+
+ sLog.outString ("Starting Remote access listner on port %d on %s", raport, stringip.c_str ());
+ }
}
- else
- while (!World::IsStopped())
+
+ // Socket Selet time is in microseconds , not miliseconds!!
+ uint32 socketSelecttime = sWorld.getConfig (CONFIG_SOCKET_SELECTTIME);
+
+ // if use ra spend time waiting for io, if not use ra ,just sleep
+ if (usera)
{
- ZThread::Thread::sleep (static_cast<unsigned long> (socketSelecttime / 1000));
- checkping ();
+ while (!World::IsStopped())
+ {
+ h.Select (0, socketSelecttime);
+ checkping ();
+ }
}
- }
+ else
+ {
+ while (!World::IsStopped())
+ {
+ ZThread::Thread::sleep (static_cast<unsigned long> (socketSelecttime / 1000));
+ checkping ();
+ }
+ }
+ }
};
Master::Master()
@@ -200,15 +202,15 @@ int Master::Run()
sLog.outString( "%s (core-daemon)", _FULLVERSION );
sLog.outString( "<Ctrl-C> to stop.\n" );
- sLog.outTitle( " ______ __");
- sLog.outTitle( "/\\__ _\\ __ __/\\ \\__");
- sLog.outTitle( "\\/_/\\ \\/ _ __ /\\_\\ ___ /\\_\\ \\ ,_\\ __ __");
- sLog.outTitle( " \\ \\ \\/\\`'__\\/\\ \\ /' _ `\\/\\ \\ \\ \\/ /\\ \\/\\ \\");
- sLog.outTitle( " \\ \\ \\ \\ \\/ \\ \\ \\/\\ \\/\\ \\ \\ \\ \\ \\_\\ \\ \\_\\ \\");
- sLog.outTitle( " \\ \\_\\ \\_\\ \\ \\_\\ \\_\\ \\_\\ \\_\\ \\__\\\\/`____ \\");
- sLog.outTitle( " \\/_/\\/_/ \\/_/\\/_/\\/_/\\/_/\\/__/ `/___/> \\");
- sLog.outTitle( " C O R E /\\___/");
- sLog.outTitle( "http://TrinityCore.org \\/__/\n");
+ sLog.outString( " ______ __");
+ sLog.outString( "/\\__ _\\ __ __/\\ \\__");
+ sLog.outString( "\\/_/\\ \\/ _ __ /\\_\\ ___ /\\_\\ \\ ,_\\ __ __");
+ sLog.outString( " \\ \\ \\/\\`'__\\/\\ \\ /' _ `\\/\\ \\ \\ \\/ /\\ \\/\\ \\");
+ sLog.outString( " \\ \\ \\ \\ \\/ \\ \\ \\/\\ \\/\\ \\ \\ \\ \\ \\_\\ \\ \\_\\ \\");
+ sLog.outString( " \\ \\_\\ \\_\\ \\ \\_\\ \\_\\ \\_\\ \\_\\ \\__\\\\/`____ \\");
+ sLog.outString( " \\/_/\\/_/ \\/_/\\/_/\\/_/\\/_/\\/__/ `/___/> \\");
+ sLog.outString( " C O R E /\\___/");
+ sLog.outString( "http://TrinityCore.org \\/__/\n");
/// worldd PID file creation
std::string pidfile = sConfig.GetStringDefault("PidFile", "");
@@ -280,7 +282,7 @@ int Master::Run()
sLog.outError("Can't set used processors (hex): %x",curAff);
}
}
- sLog.outString();
+ sLog.outString("");
}
bool Prio = sConfig.GetBoolDefault("ProcessPriority", false);
@@ -292,7 +294,7 @@ int Master::Run()
sLog.outString("TrinityCore process priority class set to HIGH");
else
sLog.outError("ERROR: Can't set Trinityd process priority class.");
- sLog.outString();
+ sLog.outString("");
}
}
#endif
@@ -317,14 +319,14 @@ int Master::Run()
}
///- Launch the world listener socket
- port_t wsport = sWorld.getConfig (CONFIG_PORT_WORLD);
- std::string bind_ip = sConfig.GetStringDefault ("BindIP", "0.0.0.0");
+ port_t wsport = sWorld.getConfig (CONFIG_PORT_WORLD);
+ std::string bind_ip = sConfig.GetStringDefault ("BindIP", "0.0.0.0");
- if (sWorldSocketMgr->StartNetwork (wsport, bind_ip.c_str ()) == -1)
+ if (sWorldSocketMgr->StartNetwork (wsport, bind_ip.c_str ()) == -1)
{
- sLog.outError ("Failed to start network");
- World::StopNow(ERROR_EXIT_CODE);
- // go down and shutdown the server
+ sLog.outError ("Failed to start network");
+ World::StopNow(ERROR_EXIT_CODE);
+ // go down and shutdown the server
}
sWorldSocketMgr->Wait ();
@@ -401,14 +403,15 @@ int Master::Run()
/// Initialize connection to the databases
bool Master::_StartDB()
{
- ///- Get world database info from configuration file
std::string dbstring;
- if(!sConfig.GetString("WorldDatabaseInfo", &dbstring))
+
+ ///- Get world database info from configuration file
+ dbstring = sConfig.GetStringDefault("WorldDatabaseInfo", "");
+ if(dbstring.empty())
{
sLog.outError("Database not specified in configuration file");
return false;
}
- sLog.outDetail("World Database: %s", dbstring.c_str());
///- Initialise the world database
if(!WorldDatabase.Initialize(dbstring.c_str()))
@@ -417,12 +420,13 @@ bool Master::_StartDB()
return false;
}
- if(!sConfig.GetString("CharacterDatabaseInfo", &dbstring))
+ ///- Get character database info from configuration file
+ dbstring = sConfig.GetStringDefault("CharacterDatabaseInfo", "");
+ if(dbstring.empty())
{
sLog.outError("Character Database not specified in configuration file");
return false;
}
- sLog.outDetail("Character Database: %s", dbstring.c_str());
///- Initialise the Character database
if(!CharacterDatabase.Initialize(dbstring.c_str()))
@@ -432,14 +436,14 @@ bool Master::_StartDB()
}
///- Get login database info from configuration file
- if(!sConfig.GetString("LoginDatabaseInfo", &dbstring))
+ dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", "");
+ if(dbstring.empty())
{
sLog.outError("Login database not specified in configuration file");
return false;
}
///- Initialise the login database
- sLog.outDetail("Login Database: %s", dbstring.c_str() );
if(!LoginDatabase.Initialize(dbstring.c_str()))
{
sLog.outError("Cannot connect to login database %s",dbstring.c_str());
@@ -455,6 +459,20 @@ bool Master::_StartDB()
}
sLog.outString("Realm running as realm ID %d", realmID);
+ ///- Initialize the DB logging system
+ if(sConfig.GetBoolDefault("EnableLogDB", false))
+ {
+ // everything successful - set var to enable DB logging once startup finished.
+ sLog.SetLogDBLater(true);
+ sLog.SetLogDB(false);
+ sLog.SetRealmID(realmID);
+ }
+ else
+ {
+ sLog.SetLogDBLater(false);
+ sLog.SetLogDB(false);
+ }
+
///- Clean the database before starting
clearOnlineAccounts();
@@ -463,7 +481,8 @@ bool Master::_StartDB()
sWorld.LoadDBVersion();
- sLog.outString("Using %s", sWorld.GetDBVersion());
+ sLog.outString("Using World DB: %s", sWorld.GetDBVersion());
+ sLog.outString("Using creature EventAI: %s", sWorld.GetCreatureEventAIVersion());
return true;
}
@@ -476,8 +495,10 @@ void Master::clearOnlineAccounts()
"UPDATE account SET online = 0 WHERE online > 0 "
"AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = '%d')",realmID);
-
CharacterDatabase.Execute("UPDATE characters SET online = 0 WHERE online<>0");
+
+ // Battleground instance ids reset at server restart
+ CharacterDatabase.Execute("UPDATE characters SET bgid = 0 WHERE bgid<>0");
}
/// Handle termination signals
@@ -518,4 +539,3 @@ void Master::_UnhookSignals()
signal(SIGBREAK, 0);
#endif
}
-
diff --git a/src/trinitycore/Master.h b/src/trinitycore/Master.h
index 456202594f6..967f497051a 100644
--- a/src/trinitycore/Master.h
+++ b/src/trinitycore/Master.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -50,4 +50,3 @@ class Master
#define sMaster Trinity::Singleton<Master>::Instance()
#endif
/// @}
-
diff --git a/src/trinitycore/RASocket.cpp b/src/trinitycore/RASocket.cpp
index 62a5dbc39c9..370340859d3 100644
--- a/src/trinitycore/RASocket.cpp
+++ b/src/trinitycore/RASocket.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -69,7 +69,7 @@ RASocket::~RASocket()
///- Delete buffer and decrease active admins count
delete [] buff;
- sLog.outRALog("Connection was closed.\n");
+ sLog.outRemote("Connection was closed.\n");
if(stage==OK)
iUsers--;
@@ -79,7 +79,7 @@ RASocket::~RASocket()
void RASocket::OnAccept()
{
std::string ss=GetRemoteAddress();
- sLog.outRALog("Incoming connection from %s.\n",ss.c_str());
+ sLog.outRemote("Incoming connection from %s.\n",ss.c_str());
///- If there is already an active admin, drop the connection
if(iUsers)
dropclient
@@ -97,7 +97,7 @@ void RASocket::OnRead()
unsigned int sz=ibuf.GetLength();
if(iInputLength+sz>=RA_BUFF_SIZE)
{
- sLog.outRALog("Input buffer overflow, possible DOS attack.\n");
+ sLog.outRemote("Input buffer overflow, possible DOS attack.\n");
SetCloseAndDelete();
return;
}
@@ -160,7 +160,7 @@ void RASocket::OnRead()
if(!result)
{
Sendf("-No such user.\r\n");
- sLog.outRALog("User %s does not exist.\n",szLogin.c_str());
+ sLog.outRemote("User %s does not exist.\n",szLogin.c_str());
if(bSecure)SetCloseAndDelete();
}
else
@@ -173,7 +173,7 @@ void RASocket::OnRead()
if(fields[0].GetUInt32()<iMinLevel)
{
Sendf("-Not enough privileges.\r\n");
- sLog.outRALog("User %s has no privilege.\n",szLogin.c_str());
+ sLog.outRemote("User %s has no privilege.\n",szLogin.c_str());
if(bSecure)SetCloseAndDelete();
} else
{
@@ -208,14 +208,14 @@ void RASocket::OnRead()
++iUsers;
Sendf("+Logged in.\r\n");
- sLog.outRALog("User %s has logged in.\n",szLogin.c_str());
+ sLog.outRemote("User %s has logged in.\n",szLogin.c_str());
Sendf("TC>");
}
else
{
///- Else deny access
Sendf("-Wrong pass.\r\n");
- sLog.outRALog("User %s has failed to log in.\n",szLogin.c_str());
+ sLog.outRemote("User %s has failed to log in.\n",szLogin.c_str());
if(bSecure)SetCloseAndDelete();
}
}
@@ -224,7 +224,7 @@ void RASocket::OnRead()
case OK:
if(strlen(buff))
{
- sLog.outRALog("Got '%s' cmd.\n",buff);
+ sLog.outRemote("Got '%s' cmd.\n",buff);
sWorld.QueueCliCommand(&RASocket::zprint , buff);
}
else
@@ -257,4 +257,3 @@ void RASocket::zprint( const char * szText )
#endif
}
-
diff --git a/src/trinitycore/RASocket.h b/src/trinitycore/RASocket.h
index 145afd52c60..8900e689b2c 100644
--- a/src/trinitycore/RASocket.h
+++ b/src/trinitycore/RASocket.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -65,4 +65,3 @@ class RASocket: public TcpSocket
};
#endif
/// @}
-
diff --git a/src/trinitycore/TrinityCore.rc b/src/trinitycore/TrinityCore.rc
index 4e6510c0407..0acad1e4ba2 100644
--- a/src/trinitycore/TrinityCore.rc
+++ b/src/trinitycore/TrinityCore.rc
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 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
diff --git a/src/trinitycore/WorldRunnable.cpp b/src/trinitycore/WorldRunnable.cpp
index 73d99e66061..e49e4ad74b8 100644
--- a/src/trinitycore/WorldRunnable.cpp
+++ b/src/trinitycore/WorldRunnable.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -29,13 +29,19 @@
#include "Timer.h"
#include "ObjectAccessor.h"
#include "MapManager.h"
+#include "BattleGroundMgr.h"
#include "Database/DatabaseEnv.h"
-#if (defined(SHORT_SLEEP) || defined(WIN32))
+#if (defined(WIN32) || defined(SHORT_SLEEP))
#define WORLD_SLEEP_CONST 50
#else
-#define WORLD_SLEEP_CONST 100 //Is this still needed?? [On linux some time ago not working 50ms]
+#define WORLD_SLEEP_CONST 100 //Is this still needed?? [On linux some time ago not working 50ms]
+#endif
+
+#ifdef WIN32
+#include "ServiceWin32.h"
+extern int m_ServiceStatus;
#endif
/// Heartbeat for the World
@@ -43,6 +49,8 @@ void WorldRunnable::run()
{
///- Init new SQL thread for the world database
WorldDatabase.ThreadStart(); // let thread do safe mySQL requests (one connection call enough)
+ CharacterDatabase.ThreadStart();
+ LoginDatabase.ThreadStart();
sWorld.InitResultQueue();
uint32 realCurrTime = 0;
@@ -72,16 +80,25 @@ void WorldRunnable::run()
}
else
prevSleepTime = 0;
+
+ #ifdef WIN32
+ if (m_ServiceStatus == 0) World::StopNow(SHUTDOWN_EXIT_CODE);
+ while (m_ServiceStatus == 2) Sleep(1000);
+ #endif
}
sWorld.KickAll(); // save and kick all players
sWorld.UpdateSessions( 1 ); // real players unload required UpdateSessions call
+ // unload battleground templates before different singletons destroyed
+ sBattleGroundMgr.DeleteAllBattleGrounds();
+
sWorldSocketMgr->StopNetwork();
MapManager::Instance().UnloadAll(); // unload all grids (including locked in memory)
///- End the database thread
WorldDatabase.ThreadEnd(); // free mySQL thread resources
+ CharacterDatabase.ThreadStart();
+ LoginDatabase.ThreadEnd();
}
-
diff --git a/src/trinitycore/WorldRunnable.h b/src/trinitycore/WorldRunnable.h
index b84e5b6a04c..8df3a6a0c89 100644
--- a/src/trinitycore/WorldRunnable.h
+++ b/src/trinitycore/WorldRunnable.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -33,4 +33,3 @@ class WorldRunnable : public ZThread::Runnable
};
#endif
/// @}
-
diff --git a/src/trinitycore/resource.h b/src/trinitycore/resource.h
index fbc730320b4..7dc5cb9ef7b 100644
--- a/src/trinitycore/resource.h
+++ b/src/trinitycore/resource.h
@@ -13,4 +13,3 @@
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
-
diff --git a/src/trinitycore/run-mangosd b/src/trinitycore/run-mangosd
index f307bd9e1ad..4a146804e81 100644
--- a/src/trinitycore/run-mangosd
+++ b/src/trinitycore/run-mangosd
@@ -6,7 +6,7 @@ while :
do
echo "TrinityCore daemon restarted"
echo `date` >> crash.log &
- ./mangosd | tail -n 20 >> crash.log
+ ./mangosd | tail -n 20 >> crash.log
echo " " >> crash.log &
pid=`ps ax | awk '($5 ~ /trinitycore/) { print $1 }'`
wait $pid
diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist
index fcc093e811a..018ddf378b5 100644
--- a/src/trinitycore/trinitycore.conf.dist
+++ b/src/trinitycore/trinitycore.conf.dist
@@ -1,7 +1,7 @@
##########################################
# Trinity Core worldd configuration file #
##########################################
-ConfVersion=2009010301
+ConfVersion=2009032201
###################################################################################################################
# CONNECTIONS AND DIRECTORIES
@@ -25,11 +25,15 @@ ConfVersion=2009010301
# WorldDatabaseInfo
# CharacterDatabaseInfo
# Database connection settings for the world server.
-# Default: hostname;port;username;password;database
-# .;somenumber;username;password;database - use named pipes at Windows
-# Named pipes: mySQL required adding "enable-named-pipe" to [mysqld] section my.ini
-# .;/path/to/unix_socket;username;password;database - use Unix sockets at Unix/Linux
-# Unix sockets: experimental, not tested
+# Default:
+# ---MYSQL---
+# hostname;port;username;password;database
+# .;somenumber;username;password;database - use named pipes at Windows
+# Named pipes: mySQL required adding "enable-named-pipe" to [mysqld] section my.ini
+# .;/path/to/unix_socket;username;password;database - use Unix sockets at Unix/Linux
+# ---PGSQL---
+# hostname;port;username;password;database
+# .;/path/to/unix_socket/DIRECTORY or . for default path;username;password;database - use Unix sockets at Unix/Linux
#
# MaxPingTime
# Settings for maximum database-ping interval (minutes between pings)
@@ -109,7 +113,7 @@ EAIErrorLevel = 2
#
# SocketSelectTime
# Socket select time (in milliseconds)
-# Default: 10000
+# Default: 10000 (10 secs)
#
# GridCleanUpDelay
# Grid clean up delay (in milliseconds)
@@ -127,15 +131,11 @@ EAIErrorLevel = 2
# Player save interval (in milliseconds)
# Default: 900000 (15 min)
#
-# DisconnectToleranceInterval
-# Tolerance for disconnected players before putting in the queue. (in seconds)
-# Default: 0 (disabled)
-#
# vmap.enableLOS
# vmap.enableHeight
# Enable/Disable VMmap support for line of sight and height calculation
-# Default: 1 (true)
-# 0 (false)
+# Default: 0 (disable)
+# 1 (enable)
#
# vmap.ignoreMapIds
# Map id that will be ignored by VMaps
@@ -163,6 +163,15 @@ EAIErrorLevel = 2
# Update realm uptime period in minutes (for save data in 'uptime' table). Must be > 0
# Default: 10 (minutes)
#
+# LogDB.Opt.ClearInterval
+# Time for the WUPDATE_CLEANDB timer that clears the `logs` table of old entries. Must be > 0.
+# Default: 10 (minutes)
+#
+# LogDB.Opt.ClearTime
+# The maximum time in seconds of old `logs` table entries to keep.
+# Default: 1209600 (14 days)
+# 0 - don't clear
+#
# MaxCoreStuckTime
# Periodically check if the process got freezed, if this is the case force crash after the specified
# amount of seconds. Must be > 0. Recommended > 10 secs if you use this.
@@ -188,7 +197,6 @@ GridCleanUpDelay = 300000
MapUpdateInterval = 100
ChangeWeatherInterval = 600000
PlayerSaveInterval = 900000
-DisconnectToleranceInterval = 0
vmap.enableLOS = 0
vmap.enableHeight = 0
vmap.ignoreMapIds = "369"
@@ -196,6 +204,8 @@ vmap.ignoreSpellIds = "7720"
DetectPosCollision = 1
TargetPosRecalculateRange = 1.5
UpdateUptimeInterval = 10
+LogDB.Opt.ClearInterval = 10
+LogDB.Opt.ClearTime = 1209600
MaxCoreStuckTime = 0
AddonChannel = 1
@@ -216,19 +226,19 @@ AddonChannel = 1
#
# LogLevel
# Server console level of logging
-# 0 = Minimum; 1 = Basic&Error; 2 = Detail; 3 = Full/Debug
+# 0 = Minimum; 1 = Basic; 2 = Detail; 3 = Full/Debug
# Default: 3
#
-# LogTime
-# Include time in server console output [hh:mm:ss]
-# Default: 0 (no time)
-# 1 (print time)
-#
# LogFile
# Logfile name
# Default: "Server.log"
# "" - Empty name disable creating log file
#
+# ChatLogFile
+# Log file for chat logs
+# Default: "chat.log"
+# "" - Empty name for disable
+#
# LogTimestamp
# Logfile with timestamp of server start in name
# Default: 0 - no timestamp in name
@@ -236,11 +246,12 @@ AddonChannel = 1
#
# LogFileLevel
# Server file level of logging
-# 0 = Minimum; 1 = Error; 2 = Detail; 3 = Full/Debug
+# 0 = Minimum; 1 = Basic; 2 = Detail; 3 = Full/Debug
# Default: 0
#
-# LogFilter_TransportMoves
+# LogFilter_AchievementUpdates
# LogFilter_CreatureMoves
+# LogFilter_TransportMoves
# LogFilter_VisibilityChanges
# Log filters
# Default: 1 - not include with any log level
@@ -294,23 +305,104 @@ AddonChannel = 1
# "" - Empty name for disable
#
# LogColors
-# Color for messages (format "normal_color details_color debug_color error_color")
+# Color for messages (format "normal basic detail debug")
# Colors: 0 - BLACK, 1 - RED, 2 - GREEN, 3 - BROWN, 4 - BLUE, 5 - MAGENTA, 6 - CYAN, 7 - GREY,
# 8 - YELLOW, 9 - LRED, 10 - LGREEN, 11 - LBLUE, 12 - LMAGENTA, 13 - LCYAN, 14 - WHITE
# Default: "" - none colors
-# Example: "13 7 11 9"
+# Example: "13 11 9 5"
+#
+# EnableLogDB
+# Enable/disable logging to database (LogDatabaseInfo).
+# Default: 0 - disabled
+# 1 - enabled
+#
+# DBLogLevel
+# Log level of DB logging.
+# 0 = Minimum; 1 = Basic; 2 = Detail; 3 = Full/Debug
+# Default: 3
+#
+# LogDB.Char
+# Enable/disable logging character outputs to DB.
+# Default: 0 - off
+# 1 - on
+#
+# LogDB.GM
+# Enable/disable logging GM commands to DB.
+# Default: 0 - off
+# 1 - on
+#
+# LogDB.RA
+# Enable/disable logging remote access events to DB.
+# Default: 0 - off
+# 1 - on
+#
+# LogDB.World
+# Enable/disable logging world packets to DB.
+# Default: 0 - off
+# 1 - on (very heavy)
+#
+# LogDB.Chat
+# Enable/disable logging chat messages to the database.
+# Default: 0 - off
+# 1 - on
+#
+# ChatLogs.Channel
+# Enable logging chatting in custom channels.
+# Default: 0 - off
+# 1 - on
+#
+# ChatLogs.Whisper
+# Enable logging whispers between players.
+# Default: 0 - off
+# 1 - on
+#
+# ChatLogs.Party
+# Enable logging party messages.
+# Default: 0 - off
+# 1 - on
+#
+# ChatLogs.Raid
+# Enable logging raid messages.
+# Default: 0 - off
+# 1 - on
+#
+# ChatLogs.Guild
+# Enable logging guild messages.
+# Default: 0 - off
+# 1 - on
+#
+# ChatLogs.Public
+# Enable logging public chat events (say/yell/emote).
+# Default: 0 - off
+# 1 - on
+#
+# ChatLogs.Addon
+# Enable logging addon messages.
+# Default: 0 - off
+# 1 - on
+#
+# ChatLogs.BattleGround
+# Enable logging battleground chats.
+# Default: 0 - off
+# 1 - on
+#
+# ChatLogTimestamp
+# Chat Logfile with timestamp of server start in name
+# Default: 0 - no timestamp in name
+# 1 - add timestamp in name in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext
#
###################################################################################################################
LogSQL = 1
PidFile = ""
LogLevel = 1
-LogTime = 0
LogFile = "Server.log"
+ChatLogFile = "chat.log"
LogTimestamp = 0
LogFileLevel = 0
-LogFilter_TransportMoves = 1
+LogFilter_AchievementUpdates = 1
LogFilter_CreatureMoves = 1
+LogFilter_TransportMoves = 1
LogFilter_VisibilityChanges = 1
WorldLogFile = ""
DBErrorLogFile = "db_errors.log"
@@ -322,6 +414,23 @@ GmLogTimestamp = 0
GmLogPerAccount = 0
RaLogFile = "ra_commands.log"
LogColors = ""
+EnableLogDB = 0
+DBLogLevel = 1
+LogDB.Char = 0
+LogDB.GM = 0
+LogDB.RA = 0
+LogDB.World = 0
+LogDB.Chat = 0
+ChatLogs.Channel = 0
+ChatLogs.SysChan = 0
+ChatLogs.Whisper = 0
+ChatLogs.Party = 0
+ChatLogs.Raid = 0
+ChatLogs.Guild = 0
+ChatLogs.Public = 0
+ChatLogs.Addon = 0
+ChatLogs.BattleGround = 0
+ChatLogTimestamp = 0
###################################################################################################################
# SERVER SETTINGS
@@ -367,9 +476,9 @@ LogColors = ""
#
# Expansion
# Allow server use content from expansion
-# 2 - check expansion 2 maps existence, and if client support expansion 2 and account have
+# Default: 2 - check expansion 2 maps existence, and if client support expansion 2 and account have
# expansion 2 setting then allow visit expansion 2 maps, allow create new class character)
-# Default: 1 - check expansion 1 maps existence, and if client support expansion 1 and account have
+# 1 - check expansion 1 maps existence, and if client support expansion 1 and account have
# expansion 1 setting then allow visit expansion 1 maps, allow create new races character)
# 0 - not check expansion maps existence, not allow wisit its, not allow create new race or new class
# characters, ignore account expansion setting)
@@ -433,6 +542,18 @@ LogColors = ""
# Default: 10 (client limitation)
# The number must be between 1 and 10
#
+# HeroicCharactersPerRealm
+# Limit numbers of heroic class characters for account at realm
+# Default: 1
+# The number must be between 0 (not allowed) and 10
+#
+# MinLevelForHeroicCharacterCreating
+# Limit creating heroic characters only for account with another character of specific level (ignored for GM accounts)
+# 0 - not require any existed chaarcter
+# 1 - require at least any character existed
+# Default: 55 - default requirement
+#
+#
# SkipCinematics
# Disable in-game script movie at first character's login(allows to prevent buggy intro in case of custom start location coordinates)
# Default: 0 - show intro for each new characrer
@@ -440,14 +561,18 @@ LogColors = ""
# 2 - disable intro show in all cases
#
# MaxPlayerLevel
-# Max level that can be reached by player for experience (in range from 1 to 255).
+# Max level that can be reached by player for experience (in range from 1 to 100).
# Change not recommended
-# Default: 70
+# Default: 80
#
# StartPlayerLevel
# Staring level that have character at creating (in range 1 to MaxPlayerLevel)
# Default: 1
#
+# StartHeroicPlayerLevel
+# Staring level that have character of heroic class at creating (in range 1 to MaxPlayerLevel)
+# Default: 55
+#
# StartPlayerMoney
# Amount of money that new players will start with.
# If you want to start with silver, use for example 100 (100 copper = 1 silver)
@@ -484,34 +609,14 @@ LogColors = ""
#
# AlwaysMaxSkillForLevel
# Players will automatically gain max level dependent (weapon/defense) skill when logging in, leveling up etc.
-# Default: 0 (true)
-# 1 (false)
+# Default: 0 (false)
+# 1 (true)
#
# ActivateWeather
# Activate weather system
# Default: 1 (true)
# 0 (false)
#
-# Battleground.CastDeserter
-# Cast or not Deserter spell at player who leave battleground in progress
-# Default: 1 (true)
-# 0 (false)
-#
-# Battleground.QueueAnnouncer.Enable
-# Enable queue announcer posting to chat
-# Default: 1 (true)
-# 0 (false)
-#
-# Battleground.QueueAnnouncer.PlayerOnly
-# Enable queue announcer posting to chat
-# Default: 0 (false)
-# 1 (true)
-#
-# Battleground.PrematureReward
-# Reward players in case of prematurely finished BG
-# Default: 1 (true)
-# 0 (false)
-#
# CastUnstuck
# Allow cast or not Unstuck spell at .start or client Help option use
# Default: 1 (true)
@@ -533,7 +638,7 @@ LogColors = ""
#
# Instance.UnloadDelay
# Unload the instance map from memory after some time if no players are inside.
-# Default: 1800000 (miliseconds, i.e 30 minutes)
+# Default: 1800000 (miliseconds 30 minutes)
# 0 (instance maps are kept in memory until they are reset)
#
# Quests.LowLevelHideDiff
@@ -566,10 +671,20 @@ LogColors = ""
# Default: 3600 sec (1 hour)
#
# SkillChance.Prospecting
-# For prospecting skillup not possible by default, but can be allowed as custom setting
+# For prospecting skillup impossible by default, but can be allowed as custom setting
+# Default: 0 - no skilups
+# 1 - skilups possible
+#
+# SkillChance.Milling
+# For milling skillup impossible by default, but can be allowed as custom setting
# Default: 0 - no skilups
# 1 - skilups possible
#
+# OffhandCheckAtTalentsReset
+# Talent reset can change offhand weapon restrictions for equip slots.
+# Default: 0 - recheck offhand slot weapon only at zone update
+# 1 - recheck offhand slot weapon at talent reset also
+#
# Event.Announce
# Default: 0 (false)
# 1 (true)
@@ -591,7 +706,7 @@ LogColors = ""
GameType = 1
RealmZone = 1
-Expansion = 1
+Expansion = 2
DBC.Locale = 255
DeclinedNames = 0
StrictPlayerNames = 0
@@ -601,9 +716,12 @@ MaxWhoListReturns = 49
CharactersCreatingDisabled = 0
CharactersPerAccount = 50
CharactersPerRealm = 10
+HeroicCharactersPerRealm = 1
+MinLevelForHeroicCharacterCreating = 55
SkipCinematics = 0
-MaxPlayerLevel = 70
+MaxPlayerLevel = 80
StartPlayerLevel = 1
+StartHeroicPlayerLevel = 55
StartPlayerMoney = 0
MaxHonorPoints = 75000
StartHonorPoints = 0
@@ -614,10 +732,6 @@ DisableWaterBreath = 4
AllFlightPaths = 0
AlwaysMaxSkillForLevel = 0
ActivateWeather = 1
-Battleground.CastDeserter = 1
-Battleground.QueueAnnouncer.Enable = 1
-Battleground.QueueAnnouncer.PlayerOnly = 0
-Battleground.PrematureReward = 1
CastUnstuck = 1
Instance.IgnoreLevel = 0
Instance.IgnoreRaid = 0
@@ -630,6 +744,8 @@ MinPetitionSigns = 9
MaxGroupXPDistance = 74
MailDeliveryDelay = 3600
SkillChance.Prospecting = 0
+SkillChance.Milling = 0
+OffhandCheckAtTalentsReset = 0
Event.Announce = 0
BeepAtStart = 1
Motd = "Welcome to a Trinity Core server."
@@ -847,6 +963,18 @@ Channel.SilentlyGMJoin = 0
# 0 (disable)
# 1 (enable)
#
+# GM.Visible
+# GM visibility at login
+# Default: 2 (last save state)
+# 0 (invisible)
+# 1 (visible)
+#
+# GM.AcceptTickets
+# Is GM accepting tickets from player by default or not.
+# Default: 2 (last save state)
+# 0 (disable)
+# 1 (enable)
+#
# GM.Chat
# GM chat mode at login
# Default: 2 (last save state)
@@ -860,7 +988,7 @@ Channel.SilentlyGMJoin = 0
# 1 (enable)
#
# GM.InGMList
-# Is GM showed in GM list (if visible) in non-GM state (.gmoff)
+# Is GM showed in GM list (if visible) in non-GM state (.gm off)
# Default: 0 (false)
# 1 (true)
#
@@ -875,18 +1003,32 @@ Channel.SilentlyGMJoin = 0
# 0 (not include)
#
# GM.StartLevel
-# GM starting level (1-255)
+# GM starting level (1-100)
# Default: 1
#
+# GM.LowerSecurity
+# Disallow a lower security member to interact with a higher one using commands
+# Default: 0 (disable)
+# 1 (enable)
+#
+# GM.AllowAchievementGain
+# If enabled it allows gaining achievements for GM characters
+# Default: 1 (enable)
+# 0 (disable)
+#
###################################################################################################################
-GM.LoginState = 2
-GM.Chat = 2
-GM.WhisperingTo = 2
-GM.InGMList = 0
-GM.InWhoList = 0
-GM.LogTrade = 1
-GM.StartLevel = 70
+GM.LoginState = 2
+GM.Visible = 2
+GM.AcceptTickets = 2
+GM.Chat = 2
+GM.WhisperingTo = 2
+GM.InGMList = 0
+GM.InWhoList = 0
+GM.LogTrade = 1
+GM.StartLevel = 80
+GM.LowerSecurity = 0
+GM.AllowAchievementGain = 1
###################################################################################################################
# VISIBILITY AND RADIUSES
@@ -900,9 +1042,9 @@ GM.StartLevel = 70
# Visibility.Distance.Creature
# Visibility.Distance.Player
# Visibility distance for different in game object
-# Max limited by active player zone: ~ 333
+# Max limited by active player zone: ~ 166
# Min limit dependent from objects
-# Default: 132 (cell size)
+# Default: 66 (cell size)
# Min limit is max aggro radius (45) * Rate.Creature.Aggro
#
# Visibility.Distance.Object
@@ -928,10 +1070,10 @@ GM.StartLevel = 70
###################################################################################################################
Visibility.GroupMode = 0
-Visibility.Distance.Creature = 132
-Visibility.Distance.Player = 132
-Visibility.Distance.Object = 132
-Visibility.Distance.InFlight = 132
+Visibility.Distance.Creature = 66
+Visibility.Distance.Player = 66
+Visibility.Distance.Object = 66
+Visibility.Distance.InFlight = 66
Visibility.Distance.Grey.Unit = 1
Visibility.Distance.Grey.Object = 10
@@ -942,6 +1084,8 @@ Visibility.Distance.Grey.Object = 10
# Rate.Mana
# Rate.Rage.Income
# Rate.Rage.Loss
+# Rate.RunicPower.Income
+# Rate.RunicPower.Loss
# Rate.Focus
# Rate.Loyalty
# Health and power regeneration and rage income from damage.
@@ -1006,6 +1150,14 @@ Visibility.Distance.Grey.Object = 10
# Reputation Gain rate
# Default: 1
#
+# Rate.Reputation.LowLevel.Kill
+# Reputation Gain form low level kill (grey creture)
+# Default: 1
+#
+# Rate.Reputation.LowLevel.Quest
+# Reputation Gain rate
+# Default: 1
+#
# Rate.InstanceResetTime
# Multiplier for the number of days in between global raid/heroic instance resets.
# Default: 1
@@ -1058,12 +1210,20 @@ Visibility.Distance.Grey.Object = 10
# Default: 1 (enabled)
# 0 (disabled)
#
+# Death.Bones.World
+# Death.Bones.BattlegroundOrArena
+# Enable/disable creating bones instead corpse at resurrection (in normal zones/instacnes, or battleground/arenas)
+# Default: 1 (enabled)
+# 0 (disabled)
+#
###################################################################################################################
Rate.Health = 1
Rate.Mana = 1
Rate.Rage.Income = 1
Rate.Rage.Loss = 1
+Rate.RunicPower.Income = 1
+Rate.RunicPower.Loss = 1
Rate.Focus = 1
Rate.Loyalty = 1
Rate.Skill.Discovery = 1
@@ -1092,6 +1252,8 @@ Rate.Mining.Amount = 1
Rate.Mining.Next = 1
Rate.Talent = 1
Rate.Reputation.Gain = 1
+Rate.Reputation.LowLevel.Kill = 1
+Rate.Reputation.LowLevel.Quest = 1
Rate.InstanceResetTime = 1
SkillGain.Crafting = 1
SkillGain.Defense = 1
@@ -1110,51 +1272,104 @@ DurabilityLossChance.Block = 0.05
Death.SicknessLevel = 11
Death.CorpseReclaimDelay.PvP = 1
Death.CorpseReclaimDelay.PvE = 0
+Death.Bones.World = 1
+Death.Bones.BattlegroundOrArena = 1
+
###################################################################################################################
+# BATTLEGROUND CONFIG
#
-# Rated arena matches config
+# Battleground.CastDeserter
+# Cast Deserter spell at player who leave battleground in progress
+# Default: 1 (enable)
+# 0 (disable)
#
-# MaxRatingDifference: the maximum rating difference between two groups in rated matches
-# Default: 0 (disable, rating difference is discarded)
+# Battleground.QueueAnnouncer.Enable
+# Enable queue announcer posting to chat
+# Default: 0 (disable)
+# 1 (enable)
+#
+# Battleground.QueueAnnouncer.PlayerOnly
+# Enable queue announcer posting to chat
+# Default: 0 (disable)
+# 1 (enable)
#
-# RatingDiscardTimer: after the specified milliseconds has passed,
-# rating information will be discarded when selecting teams for matches
-# also initiates an update by this timer
-# Default: 60000
+# Battleground.InvitationType
+# Set Battleground invitation type
+# Default: 0 (normal - invite as much players to bg as possible, don't bother with ballance)
+# 1 (Experimental - don't allow to invite much more players of one faction)
#
-# AutoDistributePoints: set if arena points should be distributed automatically, or by GM command
-# Default: 0 (disable) (recommended): use gm command or sql query to distribute the points
-# 1 (enable): arena points are distributed automatically
+# Battleground.PrematureFinishTimer
+# The time to end the bg if there are less than MinPlayersPerTeam on one side in milliseconds
+# Default: 300000 (5 minutes)
+# 0 - disable (not recommended)
#
-# AutoDistributeInterval: how often should the distribution take place
-# if automatic distribution is enabled
-# in days
-# Default: 7 (weekly)
+# BattleGround.PremadeGroupWaitForMatch
+# The time in which premade group of 1 faction waits in BG Queue for premade group of other faction
+# Default: 1800000 (30 minutes)
+# 0 - disable (not recommended)
#
###################################################################################################################
-Arena.MaxRatingDifference = 0
-Arena.RatingDiscardTimer = 60000
-Arena.AutoDistributePoints = 0
-Arena.AutoDistributeInterval = 7
+Battleground.CastDeserter = 1
+Battleground.QueueAnnouncer.Enable = 0
+Battleground.QueueAnnouncer.PlayerOnly = 0
+Battleground.InvitationType = 0
+BattleGround.PrematureFinishTimer = 300000
+BattleGround.PremadeGroupWaitForMatch = 1800000
+
###################################################################################################################
+# ARENA CONFIG
+#
+# Arena.MaxRatingDifference
+# The maximum rating difference between two groups in rated matches
+# Default: 150 (enable, recommended)
+# 0 (disable, rating difference is discarded)
+#
+# Arena.RatingDiscardTimer
+# After the specified milliseconds has passed,
+# rating information will be discarded when selecting teams for matches
+# also initiates an update by this timer
+# Default: 600000 (10 minutes, recommended)
+# 0 (disable)
+#
+# Arena.AutoDistributePoints
+# Set if arena points should be distributed automatically, or by GM command
+# Default: 0 (disable) (recommended): use gm command or sql query to distribute the points
+# 1 (enable) arena points are distributed automatically
+#
+# Arena.AutoDistributeInterval
+# How often should the distribution take place
+# If automatic distribution is enabled in days
+# Default: 7 (weekly)
+#
+# Arena.QueueAnnouncer.Enable
+# Enable bg queue announcer posting to chat
+# Default: 0 (disable)
+# 1 (enable)
#
-# Battleground config
+# Arena.ArenaSeason.ID
+# Current area season id show in client
+# Default: 1
#
-# PrematureFinishTimer: the time to end the bg if there are less than minplayersperteam on one side
-# in milliseconds
-# Default: 300000
-# 0 - disable
+# Arena.ArenaSeason.InProgress
+# Current area season state
+# Default: 1 (active)
+# 0 (finished)
#
###################################################################################################################
-BattleGround.PrematureFinishTimer = 300000
+Arena.MaxRatingDifference = 150
+Arena.RatingDiscardTimer = 600000
+Arena.AutoDistributePoints = 0
+Arena.AutoDistributeInterval = 7
+Arena.QueueAnnouncer.Enable = 0
+Arena.ArenaSeason.ID = 1
+Arena.ArenaSeason.InProgress = 1
###################################################################################################################
-#
# NETWORK CONFIG
#
# Network.Threads
@@ -1183,7 +1398,7 @@ Network.TcpNodelay = 1
###################################################################################################################
# AUCTION HOUSE BOT SETTINGS
-#
+#
# AuctionHouseBot.EnableSeller
# Enable/Disable the part of AHBot that puts items up for auction
# Default 0 (disabled)
@@ -1194,7 +1409,7 @@ Network.TcpNodelay = 1
#
# Auction House Bot character data
# AuctionHouseBot.Account is the account number (in realmd->account table) of the player you want to run as the auction bot.
-# AuctionHouseBot.GUID is the GUID (in characters->characters table) of the player you want to run as the auction bot.
+# AuctionHouseBot.GUID is the GUID (in characters->characters table) of the player you want to run as the auction bot.
# Default: 0 (Auction House Bot disabled)
#
# AuctionHouseBot.VendorItems
@@ -1221,7 +1436,7 @@ Network.TcpNodelay = 1
# Default 1
# Bind_Quest_Item
# Default 0
-#
+#
# AuctionHouseBot.ItemsPerCycle
# Number of Items to Add/Remove from the AH during mass operations
# Default 200
diff --git a/src/trinityrealm/AuthCodes.h b/src/trinityrealm/AuthCodes.h
index defa513dede..a85415ba849 100644
--- a/src/trinityrealm/AuthCodes.h
+++ b/src/trinityrealm/AuthCodes.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -68,9 +68,8 @@ enum LoginResult
// we need to stick to 1 version or half of the stuff will work for someone
// others will not and opposite
-// will only support WoW and WoW:TBC 2.4.3 client build 8606...
+// will only support WoW, WoW:TBC and WoW:WotLK 3.0.9 client build 9551...
-#define EXPECTED_TRINITY_CLIENT_BUILD {8606, 0}
+#define EXPECTED_TRINITY_CLIENT_BUILD {9551, 0}
#endif
-
diff --git a/src/trinityrealm/AuthSocket.cpp b/src/trinityrealm/AuthSocket.cpp
index 3dc6b3a5c28..c5c81593737 100644
--- a/src/trinityrealm/AuthSocket.cpp
+++ b/src/trinityrealm/AuthSocket.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -1092,4 +1092,3 @@ Patcher::~Patcher()
for(Patches::iterator i = _patches.begin(); i != _patches.end(); i++ )
delete i->second;
}
-
diff --git a/src/trinityrealm/AuthSocket.h b/src/trinityrealm/AuthSocket.h
index 73aa1b280e2..3cae54c7789 100644
--- a/src/trinityrealm/AuthSocket.h
+++ b/src/trinityrealm/AuthSocket.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -84,4 +84,3 @@ class AuthSocket: public TcpSocket
};
#endif
/// @}
-
diff --git a/src/trinityrealm/CMakeLists.txt b/src/trinityrealm/CMakeLists.txt
index f883259bbf5..a8f5a646924 100644
--- a/src/trinityrealm/CMakeLists.txt
+++ b/src/trinityrealm/CMakeLists.txt
@@ -1,11 +1,11 @@
########### next target ###############
SET(trinity-realm_SRCS
-AuthCodes.h
-AuthSocket.cpp
-AuthSocket.h
-Main.cpp
-RealmList.cpp
+AuthCodes.h
+AuthSocket.cpp
+AuthSocket.h
+Main.cpp
+RealmList.cpp
RealmList.h
)
@@ -16,14 +16,14 @@ add_definitions(
-D_TRINITY_REALM_CONFIG='"${CONF_DIR}/trinityrealm.conf"'
)
IF (DO_MYSQL)
- SET(trinity-realm_LINK_FLAGS "-pthread ${trinity-realm_LINK_FLAGS}")
+ SET(trinity-realm_LINK_FLAGS "-pthread ${trinity-realm_LINK_FLAGS}")
ENDIF(DO_MYSQL)
IF (DO_POSTGRE)
- SET(trinity-realm_LINK_FLAGS "${POSTGRE_LIBS} ${trinity-realm_LINK_FLAGS}")
+ SET(trinity-realm_LINK_FLAGS "${POSTGRE_LIBS} ${trinity-realm_LINK_FLAGS}")
ENDIF(DO_POSTGRE)
IF (CMAKE_SYSTEM_NAME MATCHES "Darwin")
- SET(trinity-realm_LINK_FLAGS "-framework Carbon ${trinity-realm_LINK_FLAGS}")
+ SET(trinity-realm_LINK_FLAGS "-framework Carbon ${trinity-realm_LINK_FLAGS}")
ENDIF (CMAKE_SYSTEM_NAME MATCHES "Darwin")
SET_TARGET_PROPERTIES(trinity-realm PROPERTIES LINK_FLAGS "${trinity-realm_LINK_FLAGS}")
@@ -45,6 +45,7 @@ ${OSX_LIBS}
install(TARGETS trinity-realm DESTINATION bin)
+
########### install files ###############
install(FILES trinityrealm.conf.dist DESTINATION etc)
diff --git a/src/trinityrealm/Main.cpp b/src/trinityrealm/Main.cpp
index 05fd704c10b..65596e35b21 100644
--- a/src/trinityrealm/Main.cpp
+++ b/src/trinityrealm/Main.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -31,7 +31,6 @@
#include "sockets/ListenSocket.h"
#include "AuthSocket.h"
#include "SystemConfig.h"
-#include "revision.h"
#include "Util.h"
// Format is YYYYMMDDRR where RR is the change in the conf file
@@ -41,12 +40,12 @@
#endif
#ifndef _TRINITY_REALM_CONFIG
-# define _TRINITY_REALM_CONFIG "trinityrealm.conf"
+# define _TRINITY_REALM_CONFIG "TrinityRealm.conf"
#endif //_TRINITY_REALM_CONFIG
#ifdef WIN32
#include "ServiceWin32.h"
-char serviceName[] = "realmd";
+char serviceName[] = "TrinityRealm";
char serviceLongName[] = "Trinity realm service";
char serviceDescription[] = "Massive Network Game Object Server";
/*
@@ -58,7 +57,7 @@ char serviceDescription[] = "Massive Network Game Object Server";
int m_ServiceStatus = -1;
#endif
-bool StartDB(std::string &dbstring);
+bool StartDB();
void UnhookSignals();
void HookSignals();
@@ -71,7 +70,6 @@ DatabaseType LoginDatabase; ///< Accessor to the
void usage(const char *prog)
{
sLog.outString("Usage: \n %s [<options>]\n"
- " --version print version and exit\n\r"
" -c config_file use config_file as configuration file\n\r"
#ifdef WIN32
" Running as service functions:\n\r"
@@ -102,12 +100,6 @@ extern int main(int argc, char **argv)
cfg_file = argv[c];
}
- if( strcmp(argv[c],"--version") == 0)
- {
- printf("%s\n", _FULLVERSION);
- return 0;
- }
-
#ifdef WIN32
////////////
//Services//
@@ -187,10 +179,19 @@ extern int main(int argc, char **argv)
}
///- Initialize the database connection
- std::string dbstring;
- if(!StartDB(dbstring))
+ if(!StartDB())
return 1;
+ ///- Initialize the log database
+ if(sConfig.GetBoolDefault("EnableLogDB", false))
+ {
+ // everything successful - set var to enable DB logging once startup finished.
+ sLog.SetLogDBLater(true);
+ sLog.SetLogDB(false);
+ // ensure we've set realm to 0 (realmd realmid)
+ sLog.SetRealmID(0);
+ }
+
///- Get the list of realms for the server
m_realmList.Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20));
if (m_realmList.size() == 0)
@@ -243,7 +244,7 @@ extern int main(int argc, char **argv)
sLog.outError("Can't set used processors (hex): %x", curAff);
}
}
- sLog.outString();
+ sLog.outString("");
}
bool Prio = sConfig.GetBoolDefault("ProcessPriority", false);
@@ -254,7 +255,7 @@ extern int main(int argc, char **argv)
sLog.outString("TrinityRealm process priority class set to HIGH");
else
sLog.outError("ERROR: Can't set realmd process priority class.");
- sLog.outString();
+ sLog.outString("");
}
}
#endif
@@ -263,6 +264,20 @@ extern int main(int argc, char **argv)
uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / 100000));
uint32 loopCounter = 0;
+ // possibly enable db logging; avoid massive startup spam by doing it here.
+ if (sLog.GetLogDBLater())
+ {
+ sLog.outString("Enabling database logging...");
+ sLog.SetLogDBLater(false);
+ // login db needs thread for logging
+ sLog.SetLogDB(true);
+ }
+ else
+ {
+ sLog.SetLogDB(false);
+ sLog.SetLogDBLater(false);
+ }
+
///- Wait for termination signal
while (!stopEvent)
{
@@ -282,6 +297,7 @@ extern int main(int argc, char **argv)
}
///- Wait for the delay thread to exit
+ LoginDatabase.ThreadEnd();
LoginDatabase.HaltDelayThread();
///- Remove signal handling before leaving
@@ -312,20 +328,21 @@ void OnSignal(int s)
}
/// Initialize connection to the database
-bool StartDB(std::string &dbstring)
+bool StartDB()
{
- if(!sConfig.GetString("LoginDatabaseInfo", &dbstring))
+ std::string dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", "");
+ if(dbstring.empty())
{
sLog.outError("Database not specified");
return false;
}
- sLog.outString("Database: %s", dbstring.c_str() );
if(!LoginDatabase.Initialize(dbstring.c_str()))
{
sLog.outError("Cannot connect to database");
return false;
}
+ LoginDatabase.ThreadStart();
return true;
}
@@ -351,4 +368,3 @@ void UnhookSignals()
}
/// @}
-
diff --git a/src/trinityrealm/Makefile.am b/src/trinityrealm/Makefile.am
new file mode 100644
index 00000000000..a14b50c847a
--- /dev/null
+++ b/src/trinityrealm/Makefile.am
@@ -0,0 +1,59 @@
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+#
+# Copyright (C) 2008-2009 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
+
+## Process this file with automake to produce Makefile.in
+
+## CPP flags for includes, defines, etc.
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir)/../../dep/include -I$(srcdir)/../framework -I$(srcdir)/../shared -I$(srcdir) -DSYSCONFDIR=\"$(sysconfdir)/\"
+
+## Build realm list daemon as standalone program
+bin_PROGRAMS = trinity-realmd
+trinity_realmd_SOURCES = \
+ AuthCodes.h \
+ AuthSocket.cpp \
+ AuthSocket.h \
+ Main.cpp \
+ RealmList.cpp \
+ RealmList.h
+
+## Link realm list daemon against the shared library
+trinity_realmd_LDADD = ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la
+trinity_realmd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L$(libdir) $(TRINI_LIBS)
+
+## Additional files to include when running 'make dist'
+# Include realm list daemon configuration
+EXTRA_DIST = \
+ realmd.conf.dist
+
+## Additional files to install
+sysconf_DATA = \
+ realmd.conf.dist
+
+install-data-hook:
+ @list='$(sysconf_DATA)'; for p in $$list; do \
+ dest=`echo $$p | sed -e s/.dist//`; \
+ if test -f $(DESTDIR)$(sysconfdir)/$$dest; then \
+ echo "$@ will not overwrite existing $(DESTDIR)$(sysconfdir)/$$dest"; \
+ else \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest; \
+ fi; \
+ done
+
+clean-local:
+ rm -f $(sysconf_DATA)
diff --git a/src/trinityrealm/RealmList.cpp b/src/trinityrealm/RealmList.cpp
index ca4dc9271b7..6a3d6b47e0f 100644
--- a/src/trinityrealm/RealmList.cpp
+++ b/src/trinityrealm/RealmList.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -100,4 +100,3 @@ void RealmList::UpdateRealms(bool init)
delete result;
}
}
-
diff --git a/src/trinityrealm/RealmList.h b/src/trinityrealm/RealmList.h
index 31690a19eb3..3663b2bd20d 100644
--- a/src/trinityrealm/RealmList.h
+++ b/src/trinityrealm/RealmList.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 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
@@ -30,8 +30,8 @@
/// Storage object for a realm
struct Realm
{
- std::string name;
std::string address;
+ std::string name;
uint8 icon;
uint8 color;
uint8 timezone;
@@ -66,4 +66,3 @@ class RealmList
};
#endif
/// @}
-
diff --git a/src/trinityrealm/TrinityRealm.rc b/src/trinityrealm/TrinityRealm.rc
index 33c7eef719a..bcd37f240c5 100644
--- a/src/trinityrealm/TrinityRealm.rc
+++ b/src/trinityrealm/TrinityRealm.rc
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 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
diff --git a/src/trinityrealm/resource.h b/src/trinityrealm/resource.h
index fbc730320b4..7dc5cb9ef7b 100644
--- a/src/trinityrealm/resource.h
+++ b/src/trinityrealm/resource.h
@@ -13,4 +13,3 @@
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
-
diff --git a/src/trinityrealm/trinityrealm.conf.dist b/src/trinityrealm/trinityrealm.conf.dist
index 72ef1c9012e..363f98ae31c 100644
--- a/src/trinityrealm/trinityrealm.conf.dist
+++ b/src/trinityrealm/trinityrealm.conf.dist
@@ -17,7 +17,7 @@ ConfVersion=2007062001
# LogsDir
# Logs directory setting.
# Important: Logs dir must exists, or all logs be disable
-# Default: "" - no log directory prefix, if used log names isn't absolute path then logs will be
+# Default: "" - no log directory prefix, if used log names isn't absolute path then logs will be
# stored in current directory for run program.
#
# MaxPingTime
@@ -36,14 +36,9 @@ ConfVersion=2007062001
#
# LogLevel
# Server console level of logging
-# 0 = Minimum; 1 = Error; 2 = Detail; 3 = Full/Debug
+# 0 = Minimum; 1 = Basic; 2 = Detail; 3 = Full/Debug
# Default: 0
#
-# LogTime
-# Include time in server console output [hh:mm:ss]
-# Default: 0 (no time)
-# 1 (print time)
-#
# LogFile
# Logfile name
# Default: "realmd.log"
@@ -56,15 +51,25 @@ ConfVersion=2007062001
#
# LogFileLevel
# Server file level of logging
-# 0 = Minimum; 1 = Error; 2 = Detail; 3 = Full/Debug
+# 0 = Minimum; 1 = Basic; 2 = Detail; 3 = Full/Debug
# Default: 0
#
# LogColors
-# Color for messages (format "normal_color details_color debug_color error_color)
+# Color for messages (format "normal basic detail debug")
# Colors: 0 - BLACK, 1 - RED, 2 - GREEN, 3 - BROWN, 4 - BLUE, 5 - MAGENTA, 6 - CYAN, 7 - GREY,
# 8 - YELLOW, 9 - LRED, 10 - LGREEN, 11 - LBLUE, 12 - LMAGENTA, 13 - LCYAN, 14 - WHITE
# Default: "" - none colors
-# "13 7 11 9" - for example :)
+# Example: "13 11 9 5"
+#
+# EnableLogDB
+# Enable/disable logging to database (LogDatabaseInfo).
+# Default: 0 - disabled
+# 1 - enabled
+#
+# DBLogLevel
+# Log level of DB logging.
+# 0 = Minimum; 1 = Basic; 2 = Detail; 3 = Full/Debug
+# Default: 3
#
# UseProcessors
# Used processors mask for multi-processors system (Used only at Windows)
@@ -78,7 +83,7 @@ ConfVersion=2007062001
#
# RealmsStateUpdateDelay
# Realm list Update up delay (updated at realm list request if delay expired).
-# Default: 20
+# Default: 20
# 0 (Disabled)
#
# WrongPass.MaxCount
@@ -103,14 +108,15 @@ RealmServerPort = 3724
BindIP = "0.0.0.0"
PidFile = ""
LogLevel = 0
-LogTime = 0
LogFile = "realmd.log"
LogTimestamp = 0
LogFileLevel = 0
-LogColors = ""
UseProcessors = 0
ProcessPriority = 1
RealmsStateUpdateDelay = 20
WrongPass.MaxCount = 0
WrongPass.BanTime = 600
WrongPass.BanType = 0
+LogColors = ""
+EnableLogDB = 0
+DBLogLevel = 1