diff options
Diffstat (limited to 'src')
27 files changed, 349 insertions, 209 deletions
diff --git a/src/bindings/interface/ScriptMgr.cpp b/src/bindings/interface/ScriptMgr.cpp index c5d4652d5e6..397bfd2bb70 100644 --- a/src/bindings/interface/ScriptMgr.cpp +++ b/src/bindings/interface/ScriptMgr.cpp @@ -26,11 +26,8 @@ #include "Map.h" #include "ObjectMgr.h" -//uint8 loglevel = 0; -int nrscripts; +int num_sc_scripts; Script *m_scripts[MAX_SCRIPTS]; -InstanceDataScript* m_instance_scripts[MAX_INSTANCE_SCRIPTS]; -int num_inst_scripts; // -- Scripts to be added -- extern void AddSC_default(); @@ -39,26 +36,18 @@ extern void AddSC_default(); TRINITY_DLL_EXPORT void ScriptsFree() { // Free resources before library unload - for(int i=0;i<nrscripts;i++) + for(int i = 0; i < num_sc_scripts; i++) delete m_scripts[i]; - for(int i=0;i<num_inst_scripts;i++) - delete m_instance_scripts[i]; - - nrscripts = 0; - num_inst_scripts = 0; + num_sc_scripts = 0; } TRINITY_DLL_EXPORT void ScriptsInit(char const* cfg_file = "trinitycore.conf") { - nrscripts = 0; - num_inst_scripts = 0; + num_sc_scripts = 0; for(int i=0;i<MAX_SCRIPTS;i++) - { - m_scripts[i]=NULL; - m_instance_scripts[i]=NULL; - } + m_scripts[i]=NULL; // -- Inicialize the Scripts to be Added -- AddSC_default(); @@ -78,6 +67,19 @@ Script* GetScriptByName(std::string Name) return NULL; } +//********************************* +//*** Functions used internally *** + +void Script::RegisterSelf() +{ + int id = GetScriptId(Name.c_str()); + if(id) + { + m_scripts[id] = this; + ++num_sc_scripts; + } +} + //******************************** //*** Functions to be Exported *** @@ -86,6 +88,7 @@ char const* ScriptsVersion() { return "Default Trinity scripting library"; } + TRINITY_DLL_EXPORT bool GossipHello ( Player * player, Creature *_Creature ) { @@ -121,6 +124,34 @@ bool GossipSelectWithCode( Player *player, Creature *_Creature, uint32 sender, u } TRINITY_DLL_EXPORT +bool GOSelect( Player *player, GameObject *_GO, uint32 sender, uint32 action ) +{ + if(!_GO) + return false; + debug_log("TSCR: Gossip selection, sender: %d, action: %d",sender, action); + + Script *tmpscript = m_scripts[_GO->GetGOInfo()->ScriptId]; + if(!tmpscript || !tmpscript->pGOSelect) return false; + + player->PlayerTalkClass->ClearMenus(); + return tmpscript->pGOSelect(player,_GO,sender,action); +} + +TRINITY_DLL_EXPORT +bool GOSelectWithCode( Player *player, GameObject *_GO, uint32 sender, uint32 action, const char* sCode ) +{ + if(!_GO) + return false; + debug_log("TSCR: Gossip selection, sender: %d, action: %d",sender, action); + + Script *tmpscript = m_scripts[_GO->GetGOInfo()->ScriptId]; + if(!tmpscript || !tmpscript->pGOSelectWithCode) return false; + + player->PlayerTalkClass->ClearMenus(); + return tmpscript->pGOSelectWithCode(player,_GO,sender,action,sCode); +} + +TRINITY_DLL_EXPORT bool QuestAccept( Player *player, Creature *_Creature, Quest const *_Quest ) { Script *tmpscript = m_scripts[_Creature->GetScriptId()]; @@ -266,7 +297,7 @@ bool ReceiveEmote( Player *player, Creature *_Creature, uint32 emote ) return tmpscript->pReceiveEmote(player, _Creature, emote); } -/*TRINITY_DLL_EXPORT +TRINITY_DLL_EXPORT InstanceData* CreateInstanceData(Map *map) { if (!map->IsDungeon()) return NULL; @@ -277,47 +308,3 @@ InstanceData* CreateInstanceData(Map *map) return tmpscript->GetInstanceData(map); } -void ScriptedAI::UpdateAI(const uint32) -{ - //Check if we have a current target - if( m_creature->isAlive() && m_creature->SelectHostilTarget() && m_creature->getVictim()) - { - //If we are within range melee the target - if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) - { - if( m_creature->isAttackReady() ) - { - m_creature->AttackerStateUpdate(m_creature->getVictim()); - m_creature->resetAttackTimer(); - } - } - } -} - -void ScriptedAI::EnterEvadeMode() -{ - if( m_creature->isAlive() ) - DoGoHome(); -} - -void ScriptedAI::DoStartAttack(Unit* victim) -{ - if( m_creature->Attack(victim, true) ) - m_creature->GetMotionMaster()->MoveChase(victim); -} - -void ScriptedAI::DoStopAttack() -{ - if( m_creature->getVictim() != NULL ) - { - m_creature->AttackStop(); - } -} - -void ScriptedAI::DoGoHome() -{ - if( !m_creature->getVictim() && m_creature->isAlive() ) - m_creature->GetMotionMaster()->MoveTargetedHome(); -} -*/ - diff --git a/src/bindings/interface/ScriptMgr.h b/src/bindings/interface/ScriptMgr.h index a5e5f478d03..56ad4c2b87b 100644 --- a/src/bindings/interface/ScriptMgr.h +++ b/src/bindings/interface/ScriptMgr.h @@ -35,12 +35,11 @@ class SpellCastTargets; class Map; #define MAX_SCRIPTS 1000 -#define MAX_INSTANCE_SCRIPTS 1000 struct Script { Script() : - pGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGossipSelectWithCode(NULL), + pGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGossipSelectWithCode(NULL), pGOSelect(NULL), pGOSelectWithCode(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) @@ -49,26 +48,30 @@ struct Script std::string Name; // -- Quest/gossip Methods to be scripted -- - bool (*pGossipHello )(Player *player, Creature *_Creature); - bool (*pQuestAccept )(Player *player, Creature *_Creature, Quest const*_Quest ); - bool (*pGossipSelect )(Player *player, Creature *_Creature, uint32 sender, uint32 action ); - bool (*pGossipSelectWithCode)(Player *player, Creature *_Creature, uint32 sender, uint32 action, const char* sCode ); - bool (*pQuestSelect )(Player *player, Creature *_Creature, Quest const*_Quest ); - bool (*pQuestComplete )(Player *player, Creature *_Creature, Quest const*_Quest ); - uint32 (*pNPCDialogStatus )(Player *player, Creature *_Creature ); - uint32 (*pGODialogStatus )(Player *player, GameObject * _GO ); - bool (*pChooseReward )(Player *player, Creature *_Creature, Quest const*_Quest, uint32 opt ); - bool (*pItemHello )(Player *player, Item *_Item, Quest const*_Quest ); - bool (*pGOHello )(Player *player, GameObject *_GO ); - bool (*pAreaTrigger )(Player *player, AreaTriggerEntry* at); - bool (*pItemQuestAccept )(Player *player, Item *_Item, Quest const*_Quest ); - bool (*pGOQuestAccept )(Player *player, GameObject *_GO, Quest const*_Quest ); - bool (*pGOChooseReward )(Player *player, GameObject *_GO, Quest const*_Quest, uint32 opt ); - bool (*pReceiveEmote )(Player *player, Creature *_Creature, uint32 emote ); - bool (*pItemUse )(Player *player, Item* _Item, SpellCastTargets const& targets); - - CreatureAI* (*GetAI)(Creature *_Creature); - // ----------------------------------------- + bool (*pGossipHello )(Player*, Creature*); + bool (*pQuestAccept )(Player*, Creature*, Quest const*); + bool (*pGossipSelect )(Player*, Creature*, uint32, uint32); + bool (*pGossipSelectWithCode)(Player*, Creature*, uint32, uint32, const char*); + bool (*pGOSelect )(Player*, GameObject*, uint32, uint32); + bool (*pGOSelectWithCode )(Player*, GameObject*, uint32, uint32, const char*); + bool (*pQuestSelect )(Player*, Creature*, Quest const*); + bool (*pQuestComplete )(Player*, Creature*, Quest const*); + uint32 (*pNPCDialogStatus )(Player*, Creature*); + uint32 (*pGODialogStatus )(Player*, GameObject*); + bool (*pChooseReward )(Player*, Creature*, Quest const*, uint32); + bool (*pItemHello )(Player*, Item*, Quest const*); + bool (*pGOHello )(Player*, GameObject*); + bool (*pAreaTrigger )(Player*, AreaTriggerEntry*); + bool (*pItemQuestAccept )(Player*, Item*, Quest const*); + bool (*pGOQuestAccept )(Player*, GameObject*, Quest const*); + bool (*pGOChooseReward )(Player*, GameObject*, Quest const*, uint32); + bool (*pReceiveEmote )(Player*, Creature*, uint32); + bool (*pItemUse )(Player*, Item*, SpellCastTargets const&); + + CreatureAI* (*GetAI)(Creature*); + InstanceData* (*GetInstanceData)(Map*); + + void RegisterSelf(); }; @@ -81,11 +84,6 @@ class InstanceDataScript InstanceData* (*GetInstanceData)(Map *_Map); }; -extern int nrscripts; -extern Script *m_scripts[MAX_SCRIPTS]; -extern InstanceDataScript *m_instance_scripts[MAX_INSTANCE_SCRIPTS]; -extern int num_inst_scripts; - #define VISIBLE_RANGE (50.0f) struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI diff --git a/src/bindings/interface/Scripts/sc_default.cpp b/src/bindings/interface/Scripts/sc_default.cpp index 56ec01c4205..e0b431ae5bc 100644 --- a/src/bindings/interface/Scripts/sc_default.cpp +++ b/src/bindings/interface/Scripts/sc_default.cpp @@ -35,6 +35,16 @@ bool GossipSelectWithCode_default( Player* /*player*/, Creature* /*_Creature*/, return false; } +bool GOSelect_default(Player* /*player*/, GameObject* /*_GO*/, uint32 /*sender*/, uint32 /*action*/) +{ + return false; +} + +bool GOSelectWithCode_default(Player* /*player*/, GameObject* /*_GO*/, uint32 /*sender*/, uint32 /*action*/, const char* /*sCode*/) +{ + return false; +} + bool QuestAccept_default(Player* /*player*/, Creature* /*_Creature*/, Quest const* /*_Quest*/ ) { return false; @@ -105,6 +115,8 @@ void AddSC_default() newscript->pQuestAccept = &QuestAccept_default; newscript->pGossipSelect = &GossipSelect_default; newscript->pGossipSelectWithCode = &GossipSelectWithCode_default; + newscript->pGOSelect = &GOSelect_default; + newscript->pGOSelectWithCode = &GOSelectWithCode_default; newscript->pQuestSelect = &QuestSelect_default; newscript->pQuestComplete = &QuestComplete_default; newscript->pNPCDialogStatus = &NPCDialogStatus_default; @@ -117,6 +129,6 @@ void AddSC_default() newscript->pGOQuestAccept = &GOQuestAccept_default; newscript->pGOChooseReward = &GOChooseReward_default; - m_scripts[nrscripts++] = newscript; + newscript->RegisterSelf(); } diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp index 52e6f2e363c..ec4b070a087 100644 --- a/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp +++ b/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp @@ -299,6 +299,7 @@ struct TRINITY_DLL_DECL boss_moroesAI : public ScriptedAI if (target && target->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinMeleeRange(target)) { DoCast(target, SPELL_BLIND); + Blind_Timer = 40000; } else 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 044e62cff86..92e1991e50a 100644 --- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp +++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp @@ -644,7 +644,7 @@ void boss_kalecgosAI::UpdateAI(const uint32 diff) } } -bool GOkalocegos_teleporter(Player *player, GameObject* _GO) +bool GOkalecgos_teleporter(Player *player, GameObject* _GO) { if(player->HasAura(AURA_SPECTRAL_EXHAUSTION)) player->GetSession()->SendNotification(GO_FAILED); @@ -687,7 +687,7 @@ void AddSC_boss_kalecgos() newscript->RegisterSelf(); newscript = new Script; - newscript->Name="kalocegos_teleporter"; - newscript->pGOHello = &GOkalocegos_teleporter; + newscript->Name="kalecgos_teleporter"; + newscript->pGOHello = &GOkalecgos_teleporter; newscript->RegisterSelf(); } 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 a0bd75cb156..066fffa3467 100644 --- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp +++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp @@ -293,9 +293,9 @@ bool GOHello_go_orb_of_the_blue_flight(Player *plr, GameObject* go) } //AI for Kalecgos -struct TRINITY_DLL_DECL boss_kalecgosKJAI : public ScriptedAI +struct TRINITY_DLL_DECL boss_kalecgos_kjAI : public ScriptedAI { - boss_kalecgosKJAI(Creature* c) : ScriptedAI(c){ + boss_kalecgos_kjAI(Creature* c) : ScriptedAI(c){ pInstance = ((ScriptedInstance*)c->GetInstanceData()); } @@ -402,9 +402,9 @@ struct TRINITY_DLL_DECL boss_kalecgosKJAI : public ScriptedAI } }; -CreatureAI* GetAI_boss_kalecgosKJ(Creature *_Creature) +CreatureAI* GetAI_boss_kalecgos_kj(Creature *_Creature) { - return new boss_kalecgosKJAI (_Creature); + return new boss_kalecgos_kjAI (_Creature); } //AI for Kil'jaeden @@ -649,8 +649,8 @@ struct TRINITY_DLL_DECL boss_kiljaedenAI : public Scripted_NoMovementAI break; case TIMER_ORBS_EMPOWER: //Phase 3 if(Phase == PHASE_SACRIFICE){ - if(Kalec)((boss_kalecgosKJAI*)Kalec->AI())->EmpowerOrb(true); - }else if(Kalec)((boss_kalecgosKJAI*)Kalec->AI())->EmpowerOrb(false); + if(Kalec)((boss_kalecgos_kjAI*)Kalec->AI())->EmpowerOrb(true); + }else if(Kalec)((boss_kalecgos_kjAI*)Kalec->AI())->EmpowerOrb(false); Timer[TIMER_ORBS_EMPOWER]= (Phase == PHASE_SACRIFICE) ? 45000 : 35000; OrbActivated = true; TimerIsDeactiveted[TIMER_ORBS_EMPOWER] = true; @@ -749,7 +749,7 @@ struct TRINITY_DLL_DECL mob_kiljaeden_controllerAI : public Scripted_NoMovementA void Reset(){ Phase = PHASE_DECEIVERS; - if(KalecKJ)((boss_kalecgosKJAI*)KalecKJ->AI())->ResetOrbs(); + if(KalecKJ)((boss_kalecgos_kjAI*)KalecKJ->AI())->ResetOrbs(); DeceiverDeathCount = 0; SummonedDeceivers = false; KiljaedenDeath = false; @@ -1270,8 +1270,8 @@ void AddSC_boss_kiljaeden() newscript->RegisterSelf(); newscript = new Script; - newscript->GetAI = &GetAI_boss_kalecgosKJ; - newscript->Name = "boss_kalecgosKJ"; + newscript->GetAI = &GetAI_boss_kalecgos_kj; + newscript->Name = "boss_kalecgos_kj"; newscript->RegisterSelf(); newscript = new Script; 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 597103b62cf..72c062c865a 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 @@ -202,7 +202,7 @@ struct TRINITY_DLL_DECL instance_sunwell_plateau : public ScriptedInstance case DATA_BRUTALLUS_EVENT: Encounters[1] = data; break; case DATA_FELMYST_EVENT: if(data == DONE) - HandleGameObject(FireBarrier, 1); + HandleGameObject(FireBarrier, OPEN); Encounters[2] = data; break; case DATA_EREDAR_TWINS_EVENT: Encounters[3] = data; break; case DATA_MURU_EVENT: 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 ae2c48742d6..a8168615a5e 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 @@ -297,6 +297,7 @@ struct TRINITY_DLL_DECL boss_skeramAI : public ScriptedAI } Invisible = true; } + }; CreatureAI* GetAI_boss_skeram(Creature *_Creature) diff --git a/src/framework/Platform/Define.h b/src/framework/Platform/Define.h index 35be370d65b..57c5b1b59cd 100644 --- a/src/framework/Platform/Define.h +++ b/src/framework/Platform/Define.h @@ -64,10 +64,18 @@ # endif //__APPLE_CC__ && BIG_ENDIAN # if defined(__APPLE_CC__) # define TRINITY_SCRIPT_EXT ".dylib" -# define TRINITY_SCRIPT_NAME "../lib/libtrinityscript" +# if defined(DO_SCRIPTS) +# define TRINITY_SCRIPT_NAME "../lib/libtrinityscript" +# else +# define TRINITY_SCRIPT_NAME "../lib/libtrinityinterface" +# endif // DO_SCRIPTS # else # define TRINITY_SCRIPT_EXT ".so" -# define TRINITY_SCRIPT_NAME "libtrinityscript" +# if defined(DO_SCRIPTS) +# define TRINITY_SCRIPT_NAME "libtrinityscript" +# else +# define TRINITY_SCRIPT_NAME "libtrinityinterface" +# endif // DO_SCRIPTS # endif //__APPLE_CC__ # define TRINITY_PATH_MAX PATH_MAX #endif //PLATFORM @@ -129,6 +137,8 @@ typedef uint32 DWORD; typedef uint64 OBJECT_HANDLE; +#define MAP_BASED_RAND_GEN + #define MaNGOS Trinity #define MANGOS_DLL_DECL TRINITY_DLL_DECL #define MANGOS_DLL_SPEC TRINITY_DLL_SPEC diff --git a/src/game/BattleGroundHandler.cpp b/src/game/BattleGroundHandler.cpp index 8464dc2e7e4..903f7888813 100644 --- a/src/game/BattleGroundHandler.cpp +++ b/src/game/BattleGroundHandler.cpp @@ -467,6 +467,9 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data ) _player->SetBattleGroundId(bg->GetInstanceID(), bgTypeId); // set the destination team _player->SetBGTeam(team); + // clear AFK + if(_player->isAFK()) + _player->ToggleAFK(); // bg->HandleBeforeTeleportToBattleGround(_player); sBattleGroundMgr.SendToBattleGround(_player, instanceId, bgTypeId); // add only in HandleMoveWorldPortAck() diff --git a/src/game/BattleGroundWS.cpp b/src/game/BattleGroundWS.cpp index 76ecde6527b..84da0cc9b65 100644 --- a/src/game/BattleGroundWS.cpp +++ b/src/game/BattleGroundWS.cpp @@ -87,6 +87,7 @@ void BattleGroundWS::Update(uint32 diff) { m_FlagsDropTimer[BG_TEAM_ALLIANCE] = 0; RespawnFlagAfterDrop(ALLIANCE); + m_BothFlagsKept = false; } } if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_WAIT_RESPAWN) @@ -107,8 +108,40 @@ void BattleGroundWS::Update(uint32 diff) { m_FlagsDropTimer[BG_TEAM_HORDE] = 0; RespawnFlagAfterDrop(HORDE); + m_BothFlagsKept = false; } } + if(m_BothFlagsKept) + { + m_FlagSpellForceTimer += diff; + if(m_FlagDebuffState == 0 && m_FlagSpellForceTimer >= 600000) //10 minutes + { + if(Player * plr = objmgr.GetPlayer(m_FlagKeepers[0])) + plr->CastSpell(plr,WS_SPELL_FOCUSED_ASSAULT,true); + if(Player * plr = objmgr.GetPlayer(m_FlagKeepers[1])) + plr->CastSpell(plr,WS_SPELL_FOCUSED_ASSAULT,true); + m_FlagDebuffState = 1; + } + else if(m_FlagDebuffState == 1 && m_FlagSpellForceTimer >= 900000) //15 minutes + { + if(Player * plr = objmgr.GetPlayer(m_FlagKeepers[0])) + { + plr->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT); + plr->CastSpell(plr,WS_SPELL_BRUTAL_ASSAULT,true); + } + if(Player * plr = objmgr.GetPlayer(m_FlagKeepers[1])) + { + plr->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT); + plr->CastSpell(plr,WS_SPELL_BRUTAL_ASSAULT,true); + } + m_FlagDebuffState = 2; + } + } + else + { + m_FlagSpellForceTimer = 0; //reset timer. + m_FlagDebuffState = 0; + } } } @@ -169,6 +202,7 @@ void BattleGroundWS::RespawnFlag(uint32 Team, bool captured) SendMessageToAll(LANG_BG_WS_F_PLACED, CHAT_MSG_BG_SYSTEM_NEUTRAL); PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED); // flag respawned sound... } + m_BothFlagsKept = false; } void BattleGroundWS::RespawnFlagAfterDrop(uint32 team) @@ -197,6 +231,7 @@ void BattleGroundWS::RespawnFlagAfterDrop(uint32 team) sLog.outError("unknown droped flag bg, guid: %u",GUID_LOPART(GetDroppedFlagGUID(team))); SetDroppedFlagGUID(0,team); + m_BothFlagsKept = false; } void BattleGroundWS::EventPlayerCapturedFlag(Player *Source) @@ -216,6 +251,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); + if(m_FlagDebuffState == 1) + Source->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT); + if(m_FlagDebuffState == 2) + Source->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT); if (GetTeamScore(ALLIANCE) < BG_WS_MAX_TEAM_SCORE) AddPoint(ALLIANCE, 1); PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE); @@ -230,6 +269,10 @@ 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); + if(m_FlagDebuffState == 1) + Source->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT); + if(m_FlagDebuffState == 2) + Source->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT); if (GetTeamScore(HORDE) < BG_WS_MAX_TEAM_SCORE) AddPoint(HORDE, 1); PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE); @@ -312,6 +355,10 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player *Source) { SetHordeFlagPicker(0); Source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG); + if(m_FlagDebuffState == 1) + Source->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT); + if(m_FlagDebuffState == 2) + Source->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT); m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_GROUND; Source->CastSpell(Source, BG_WS_SPELL_WARSONG_FLAG_DROPPED, true); set = true; @@ -325,6 +372,10 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player *Source) { SetAllianceFlagPicker(0); Source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG); + if(m_FlagDebuffState == 1) + Source->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT); + if(m_FlagDebuffState == 2) + Source->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT); m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_GROUND; Source->CastSpell(Source, BG_WS_SPELL_SILVERWING_FLAG_DROPPED, true); set = true; @@ -373,6 +424,8 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER); UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 1); Source->CastSpell(Source, BG_WS_SPELL_SILVERWING_FLAG, true); + if(m_FlagState[1] == BG_WS_FLAG_STATE_ON_PLAYER) + m_BothFlagsKept = true; } //horde flag picked up from base @@ -389,6 +442,8 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER); UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 1); Source->CastSpell(Source, BG_WS_SPELL_WARSONG_FLAG, true); + if(m_FlagState[0] == BG_WS_FLAG_STATE_ON_PLAYER) + m_BothFlagsKept = true; } //Alliance flag on ground(not in base) (returned or picked up again from ground!) @@ -403,6 +458,7 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY); PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED); UpdatePlayerScore(Source, SCORE_FLAG_RETURNS, 1); + m_BothFlagsKept = false; } else { @@ -414,6 +470,10 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target Source->CastSpell(Source, BG_WS_SPELL_SILVERWING_FLAG, true); m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_PLAYER; UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER); + if(m_FlagDebuffState == 1) + Source->CastSpell(Source,WS_SPELL_FOCUSED_ASSAULT,true); + if(m_FlagDebuffState == 2) + Source->CastSpell(Source,WS_SPELL_BRUTAL_ASSAULT,true); UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 1); } //called in HandleGameObjectUseOpcode: @@ -432,6 +492,7 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY); PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED); UpdatePlayerScore(Source, SCORE_FLAG_RETURNS, 1); + m_BothFlagsKept = false; } else { @@ -443,6 +504,10 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target Source->CastSpell(Source, BG_WS_SPELL_WARSONG_FLAG, true); m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_PLAYER; UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER); + if(m_FlagDebuffState == 1) + Source->CastSpell(Source,WS_SPELL_FOCUSED_ASSAULT,true); + if(m_FlagDebuffState == 2) + Source->CastSpell(Source,WS_SPELL_BRUTAL_ASSAULT,true); UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 1); } //called in HandleGameObjectUseOpcode: diff --git a/src/game/BattleGroundWS.h b/src/game/BattleGroundWS.h index 906bccfe6ab..7395c3a5bb9 100644 --- a/src/game/BattleGroundWS.h +++ b/src/game/BattleGroundWS.h @@ -130,6 +130,12 @@ enum BG_WS_CreatureTypes BG_CREATURES_MAX_WS = 2 }; +enum BG_WS_CarrierDebuffs +{ + WS_SPELL_FOCUSED_ASSAULT = 46392, + WS_SPELL_BRUTAL_ASSAULT = 46393 +}; + class BattleGroundWGScore : public BattleGroundScore { public: @@ -206,6 +212,9 @@ class BattleGroundWS : public BattleGround uint32 m_ReputationCapture; uint32 m_HonorWinKills; uint32 m_HonorEndKills; + int32 m_FlagSpellForceTimer; + bool m_BothFlagsKept; + uint8 m_FlagDebuffState; // 0 - no debuffs, 1 - focused assault, 2 - brutal assault }; #endif diff --git a/src/game/ConfusedMovementGenerator.cpp b/src/game/ConfusedMovementGenerator.cpp index da383cc8a07..cc64a6ae31f 100644 --- a/src/game/ConfusedMovementGenerator.cpp +++ b/src/game/ConfusedMovementGenerator.cpp @@ -24,6 +24,11 @@ #include "ConfusedMovementGenerator.h" #include "DestinationHolderImp.h" +#ifdef MAP_BASED_RAND_GEN +#define rand_norm() unit.rand_norm() +#define urand(a,b) unit.urand(a,b) +#endif + template<class T> void ConfusedMovementGenerator<T>::Initialize(T &unit) diff --git a/src/game/Map.h b/src/game/Map.h index c69fe5f7345..241a836d249 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -33,6 +33,7 @@ #include "SharedDefines.h" #include "GameSystem/GridRefManager.h" #include "MapRefManager.h" +#include "mersennetwister/MersenneTwister.h" #include <bitset> #include <list> @@ -410,11 +411,18 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj template<class NOTIFIER> void VisitAll(const float &x, const float &y, float radius, NOTIFIER ¬ifier); template<class NOTIFIER> void VisitWorld(const float &x, const float &y, float radius, NOTIFIER ¬ifier); template<class NOTIFIER> void VisitGrid(const float &x, const float &y, float radius, NOTIFIER ¬ifier); + CreatureGroupHolderType CreatureGroupHolder; + +#ifdef MAP_BASED_RAND_GEN + MTRand mtRand; + int32 irand(int32 min, int32 max) { return int32 (mtRand.randInt(max - min)) + min; } + uint32 urand(uint32 min, uint32 max) { return mtRand.randInt(max - min) + min; } + int32 rand32() { return mtRand.randInt(); } + double rand_norm() { return mtRand.randExc(); } + double rand_chance() { return mtRand.randExc(100.0); } +#endif 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); diff --git a/src/game/Object.h b/src/game/Object.h index 2a79d2c22cb..699cdca6b7f 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -548,6 +548,14 @@ class TRINITY_DLL_SPEC WorldObject : public Object template<class NOTIFIER> void VisitNearbyWorldObject(const float &radius, NOTIFIER ¬ifier) const { GetMap()->VisitWorld(GetPositionX(), GetPositionY(), radius, notifier); } bool IsTempWorldObject; +#ifdef MAP_BASED_RAND_GEN + int32 irand(int32 min, int32 max) const { return int32 (GetMap()->mtRand.randInt(max - min)) + min; } + uint32 urand(uint32 min, uint32 max) const { return GetMap()->mtRand.randInt(max - min) + min; } + int32 rand32() const { return GetMap()->mtRand.randInt(); } + double rand_norm() const { return GetMap()->mtRand.randExc(); } + double rand_chance() const { return GetMap()->mtRand.randExc(100.0); } +#endif + protected: explicit WorldObject(); std::string m_name; diff --git a/src/game/OutdoorPvPSI.cpp b/src/game/OutdoorPvPSI.cpp index f9f04f676ff..c1f47db49c7 100644 --- a/src/game/OutdoorPvPSI.cpp +++ b/src/game/OutdoorPvPSI.cpp @@ -188,7 +188,10 @@ bool OutdoorPvPSI::HandleDropFlag(Player *plr, uint32 spellId) GameObject * go = new GameObject; Map * map = MapManager::Instance().GetMap(plr->GetMapId(), plr); if(!map) - return true; + { + delete go; + return true; + } 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/PetHandler.cpp b/src/game/PetHandler.cpp index 459055383cf..348af684411 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -30,6 +30,7 @@ #include "CreatureAI.h" #include "Util.h" #include "Pet.h" +#include "World.h" void WorldSession::HandlePetAction( WorldPacket & recv_data ) { @@ -122,9 +123,14 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid return; // Not let attack through obstructions - //if(!pet->IsWithinLOSInMap(TargetUnit)) - // return; + if(sWorld.getConfig(CONFIG_PET_LOS)) + { + + if(!pet->IsWithinLOSInMap(TargetUnit)) + return; + } + pet->clearUnitState(UNIT_STAT_FOLLOW); // This is true if pet has no target or has target but targets differs. if(pet->getVictim() != TargetUnit) diff --git a/src/game/RandomMovementGenerator.cpp b/src/game/RandomMovementGenerator.cpp index 93e10ad6115..46a3b6086db 100644 --- a/src/game/RandomMovementGenerator.cpp +++ b/src/game/RandomMovementGenerator.cpp @@ -41,6 +41,10 @@ RandomMovementGenerator<Creature>::GetDestination(float &x, float &y, float &z) return true; } +#ifdef MAP_BASED_RAND_GEN +#define rand_norm() creature.rand_norm() +#endif + template<> void RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index bcca1f2c873..88085bd99fe 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1734,7 +1734,7 @@ void Spell::SetTargetMap(uint32 i, uint32 cur) break; case TARGET_UNIT_CASTER_FISHING: { - AddUnitTarget(m_caster, i); + //AddUnitTarget(m_caster, i); float min_dis = GetSpellMinRange(m_spellInfo, true); float max_dis = GetSpellMaxRange(m_spellInfo, true); float dis = rand_norm() * (max_dis - min_dis) + min_dis; @@ -3018,6 +3018,10 @@ void Spell::finish(bool ok) if (m_caster->GetTypeId() == TYPEID_PLAYER) ((Player*)m_caster)->RemoveSpellMods(this); + // Okay to remove extra attacks + if(IsSpellHaveEffect(m_spellInfo, SPELL_EFFECT_ADD_EXTRA_ATTACKS)) + m_caster->m_extraAttacks = 0; + // Heal caster for all health leech from all targets if (m_healthLeech) m_caster->DealHeal(m_caster, uint32(m_healthLeech), m_spellInfo); @@ -3385,7 +3389,7 @@ void Spell::SendLogExecute() data.append(unit->GetPackGUID()); else data << uint8(0); - data << uint32(0); // count? + data << uint32(m_caster->m_extraAttacks); break; case SPELL_EFFECT_INTERRUPT_CAST: if(Unit *unit = m_targets.getUnitTarget()) @@ -4597,20 +4601,7 @@ SpellCastResult Spell::CheckCast(bool strict) case SPELL_EFFECT_LEAP: case SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER: { - 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 - float fz = MapManager::Instance().GetBaseMap(m_caster->GetMapId())->GetHeight(fx,fy,m_caster->GetPositionZ(),true); - if(fz <= INVALID_HEIGHT) // note: this also will prevent use effect in instances without vmaps height enabled - return SPELL_FAILED_TRY_AGAIN; - - float caster_pos_z = m_caster->GetPositionZ(); - // Control the caster to not climb or drop when +-fz > 8 - if(!(fz<=caster_pos_z+8 && fz>=caster_pos_z-8)) - return SPELL_FAILED_TRY_AGAIN; - - // not allow use this effect at battleground until battleground start + //Do not allow to cast it before BG starts. if(m_caster->GetTypeId()==TYPEID_PLAYER) if(BattleGround const *bg = ((Player*)m_caster)->GetBattleGround()) if(bg->GetStatus() != STATUS_IN_PROGRESS) diff --git a/src/game/Spell.h b/src/game/Spell.h index ef0e3266b4e..7d9163f4a0b 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -643,6 +643,14 @@ class Spell uint32 m_customAttr; bool m_skipCheck; uint32 m_effectMask; + +#ifdef MAP_BASED_RAND_GEN + int32 irand(int32 min, int32 max) { return int32 (m_caster->GetMap()->mtRand.randInt(max - min)) + min; } + uint32 urand(uint32 min, uint32 max) { return m_caster->GetMap()->mtRand.randInt(max - min) + min; } + int32 rand32() { return m_caster->GetMap()->mtRand.randInt(); } + double rand_norm() { return m_caster->GetMap()->mtRand.randExc(); } + double rand_chance() { return m_caster->GetMap()->mtRand.randExc(100.0); } +#endif }; namespace Trinity diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 12008b94ddb..b5f0fe6ef47 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -5746,7 +5746,20 @@ void Spell::EffectAddExtraAttacks(uint32 /*i*/) if( unitTarget->m_extraAttacks ) return; + Unit *victim = unitTarget->getVictim(); + + // attack prevented + // fixme, some attacks may not target current victim, this is right now not handled + if (!victim || !unitTarget->IsWithinMeleeRange(victim) || !unitTarget->HasInArc( 2*M_PI/3, victim )) + return; + + // Only for proc/log informations unitTarget->m_extraAttacks = damage; + // Need to send log before attack is made + SendLogExecute(); + m_needSpellLog = false; + + unitTarget->AttackerStateUpdate(victim, BASE_ATTACK, true); } void Spell::EffectParry(uint32 /*i*/) @@ -5770,47 +5783,47 @@ void Spell::EffectMomentMove(uint32 i) return; uint32 mapid = m_caster->GetMapId(); - 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]; - unitTarget->GetPosition(fx[0], fy[0], fz[0]); - - float orientation = unitTarget->GetOrientation(), itr_i, step = dis / 10.0, fx2, fy2, fz2, ground, floor; - int itr_j = 1, last_valid = 0; - bool hit = false; - - for (itr_i = step; itr_i <= dis; itr_i += step) - { - fx[itr_j] = fx[0] + itr_i * cos(orientation); - fy[itr_j] = fy[0] + itr_i * sin(orientation); - ground = MapManager::Instance().GetMap(mapid, unitTarget)->GetHeight(fx[itr_j], fy[itr_j], MAX_HEIGHT, true); - floor = MapManager::Instance().GetMap(mapid, unitTarget)->GetHeight(fx[itr_j], fy[itr_j], fz[last_valid], true); - fz[itr_j] = fabs(ground - fz[last_valid]) <= fabs(floor - fz[last_valid]) ? ground : floor; - if (fabs(fz[itr_j] - fz[0]) <= 6.0) - { - if (VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(mapid, fx[last_valid], fy[last_valid], fz[last_valid] + 0.5, fx[itr_j], fy[itr_j], fz[itr_j] + 0.5, fx2, fy2, fz2, -0.5)) - { - hit = true; - fx[itr_j] = fx2 - 0.6 * cos(orientation); - fy[itr_j] = fy2 - 0.6 * sin(orientation); - ground = MapManager::Instance().GetMap(mapid, unitTarget)->GetHeight(fx[itr_j], fy[itr_j], MAX_HEIGHT, true); - floor = MapManager::Instance().GetMap(mapid, unitTarget)->GetHeight(fx[itr_j], fy[itr_j], fz[last_valid], true); - float tempz = fabs(ground - fz[last_valid]) <= fabs(floor - fz[last_valid]) ? ground : floor; - fz[itr_j] = fabs(tempz - fz[last_valid]) <= fabs(fz2 - fz[last_valid]) ? tempz : fz2; - break; - } - else - last_valid = itr_j; - } - itr_j++; - } - if (hit == false) - itr_j = last_valid; - - unitTarget->NearTeleportTo(fx[itr_j], fy[itr_j], fz[itr_j] + 0.07531, orientation, unitTarget==m_caster); + float dist = m_caster->GetSpellRadiusForTarget(unitTarget, sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + float x,y,z; + float destx,desty,destz,ground,floor; + float orientation = unitTarget->GetOrientation(), step = dist/10.0f; + + unitTarget->GetPosition(x,y,z); + destx = x + dist * cos(orientation); + desty = y + dist * sin(orientation); + ground = unitTarget->GetMap()->GetHeight(destx,desty,MAX_HEIGHT,true); + floor = unitTarget->GetMap()->GetHeight(destx,desty,z, true); + destz = fabs(ground - z) <= fabs(floor - z) ? ground:floor; + + bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(mapid,x,y,z+0.5f,destx,desty,destz+0.5f,destx,desty,destz,-0.5f); + + if(col) // We had a collision! + { + destx -= 0.6 * cos(orientation); + desty -= 0.6 * sin(orientation); + dist = sqrt((x-destx)*(x-destx) + (y-desty)*(y-desty)); + step = dist/10.0f; + } + + int j = 0; + for(j; j<10 ;j++) + { + if(fabs(z - destz) > 6) + { + destx -= step * cos(orientation); + desty -= step * sin(orientation); + ground = unitTarget->GetMap()->GetHeight(destx,desty,MAX_HEIGHT,true); + floor = unitTarget->GetMap()->GetHeight(destx,desty,z, true); + destz = fabs(ground - z) <= fabs(floor - z) ? ground:floor; + }else + break; + } + if(j == 9) + { + return; + } + unitTarget->NearTeleportTo(destx, desty, destz + 0.07531, orientation, unitTarget==m_caster); - delete [] fx; delete [] fy; delete [] fz; } void Spell::EffectReputation(uint32 i) diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 0d39c6cf336..14aa7ea3787 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -354,22 +354,20 @@ SpellSpecific GetSpellSpecific(uint32 spellId) 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: + case 8118: // Strength + case 8099: // Stamina + case 8112: // Spirit + case 8096: // Intellect + case 8115: // Agility + case 8091: // Armor return SPELL_SCROLL; + case 12880: // Enrage (Enrage) + case 57518: // Enrage (Wrecking Crew) + case 12292: // Death Wish + return SPELL_WARRIOR_ENRAGE; } - break; } + break; } case SPELLFAMILY_MAGE: { @@ -514,6 +512,7 @@ bool IsSingleFromSpellSpecificPerTarget(uint32 spellSpec1,uint32 spellSpec2) case SPELL_FOOD: case SPELL_CHARM: case SPELL_SCROLL: + case SPELL_WARRIOR_ENRAGE: case SPELL_MAGE_ARCANE_BRILLANCE: return spellSpec1==spellSpec2; case SPELL_BATTLE_ELIXIR: @@ -3368,7 +3367,7 @@ void SpellMgr::LoadSpellCustomAttr() case 42005: // Bloodboil case 38296: // Spitfire Totem case 37676: // Insidious Whisper - case 46009: // Negative Energy + case 46008: // Negative Energy case 45641: // Fire Bloom case 55665: // Life Drain - Sapphiron (H) case 28796: // Poison Bolt Volly - Faerlina diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index c3174a05e7c..13973e25120 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -139,7 +139,8 @@ enum SpellSpecific SPELL_PRESENCE = 21, SPELL_CHARM = 22, SPELL_SCROLL = 23, - SPELL_MAGE_ARCANE_BRILLANCE = 24 + SPELL_MAGE_ARCANE_BRILLANCE = 24, + SPELL_WARRIOR_ENRAGE = 25, }; #define SPELL_LINKED_MAX_SPELLS 200000 diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 21f34d49ac3..9fce2306774 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -2369,23 +2369,10 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex else return; // ignore ranged case - uint32 extraAttacks = m_extraAttacks; - // melee attack spell casted at main hand attack only if (attType == BASE_ATTACK && m_currentSpells[CURRENT_MELEE_SPELL]) { m_currentSpells[CURRENT_MELEE_SPELL]->cast(); - - // not recent extra attack only at any non extra attack (melee spell case) - if(!extra && extraAttacks) - { - while(m_extraAttacks) - { - AttackerStateUpdate(pVictim, BASE_ATTACK, true); - if(m_extraAttacks > 0) - --m_extraAttacks; - } - } return; } @@ -2411,16 +2398,6 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex //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) - { - while(m_extraAttacks) - { - AttackerStateUpdate(pVictim, BASE_ATTACK, true); - if(m_extraAttacks > 0) - --m_extraAttacks; - } - } } MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit *pVictim, WeaponAttackType attType) const @@ -2494,7 +2471,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack dodge_chance -= int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType)*100); // Modify dodge chance by attacker SPELL_AURA_MOD_COMBAT_RESULT_CHANCE - dodge_chance+= GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE); + dodge_chance+= GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE)*100; dodge_chance = int32 (float (dodge_chance) * GetTotalAuraMultiplier(SPELL_AURA_MOD_ENEMY_DODGE)); tmp = dodge_chance; @@ -6863,7 +6840,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig basepoints0 = triggerAmount; Item* castItem = triggeredByAura->GetParentAura()->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER - ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetParentAura()->GetCastItemGUID()) : NULL; + ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetParentAura()->GetCastItemGUID()) : NULL; // Try handle unknown trigger spells if (sSpellStore.LookupEntry(trigger_spell_id)==NULL) @@ -7365,6 +7342,30 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig return false; } + // check if triggering spell can stack with current target's auras (if not - don't proc) + // don't check if + // aura is passive (talent's aura) + // trigger_spell_id's aura is already active (allow to refresh triggered auras) + // trigger_spell_id's triggeredByAura is already active (for example shaman's shields) + + // This is disabled because: + // TODO: we need better rules here. Enrage should not overwrite death wish, but it should overwrite Wrecking Crew + // Check if triggered spell is aura spell to reduce unnecessary check + /* + AuraMap::iterator i,next; + uint32 aura_id = 0; + for (i = m_Auras.begin(); i != m_Auras.end(); i = next) + { + next = i; + ++next; + if (!(*i).second) continue; + aura_id = (*i).second->GetSpellProto()->Id; + if ( IsPassiveSpell(aura_id) || aura_id == trigger_spell_id || aura_id == triggeredByAura->GetSpellProto()->Id ) continue; + if (spellmgr.IsNoStackSpellDueToSpell(trigger_spell_id, (*i).second->GetSpellProto()->Id, ((*i).second->GetCasterGUID() == GetGUID()))) + return false; + } + */ + // not allow proc extra attack spell at extra attack if( m_extraAttacks && IsSpellHaveEffect(triggerEntry, SPELL_EFFECT_ADD_EXTRA_ATTACKS) ) return false; diff --git a/src/game/World.cpp b/src/game/World.cpp index ad6e54a64cf..1c3200f8351 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1064,7 +1064,7 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_MAX_WHO] = sConfig.GetIntDefault("MaxWhoListReturns", 49); - + m_configs[CONFIG_PET_LOS] = sConfig.GetBoolDefault("vmap.petLOS", false); 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); diff --git a/src/game/World.h b/src/game/World.h index 2c0889e0e9f..92fe74f9b81 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -141,9 +141,9 @@ enum WorldConfigs CONFIG_GM_IN_GM_LIST, CONFIG_GM_IN_WHO_LIST, CONFIG_GM_LOG_TRADE, + CONFIG_START_GM_LEVEL, CONFIG_ALLOW_GM_GROUP, CONFIG_ALLOW_GM_FRIEND, - CONFIG_START_GM_LEVEL, CONFIG_GM_LOWER_SECURITY, CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS, CONFIG_GROUP_VISIBILITY, @@ -230,6 +230,7 @@ enum WorldConfigs CONFIG_INTERVAL_LOG_UPDATE, CONFIG_MIN_LOG_UPDATE, CONFIG_ENABLE_SINFO_LOGIN, + CONFIG_PET_LOS, CONFIG_OFFHAND_CHECK_AT_TALENTS_RESET, CONFIG_CHATLOG_CHANNEL, CONFIG_CHATLOG_WHISPER, diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist index 25f716a77a9..510ffb9d6d2 100644 --- a/src/trinitycore/trinitycore.conf.dist +++ b/src/trinitycore/trinitycore.conf.dist @@ -146,7 +146,12 @@ EAIErrorLevel = 2 # vmap.ignoreSpellIds # These spells are ignored for LoS calculation # List of ids with delimiter ',' -# +# +# vmap.petLOS +# Check LOS for pets, to avoid them going through walls etc. +# Default: 0 (disable, less CPU usage) +# 1 (enable, each pet attack command will check for LOS) +# # DetectPosCollision # Check final move position, summon position, etc for visible collision with other objects or # wall (wall only if vmaps are enabled) @@ -201,6 +206,7 @@ vmap.enableLOS = 0 vmap.enableHeight = 0 vmap.ignoreMapIds = "369" vmap.ignoreSpellIds = "7720" +vmap.petLOS = 0 DetectPosCollision = 1 TargetPosRecalculateRange = 1.5 UpdateUptimeInterval = 10 |
