aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bindings/interface/ScriptMgr.cpp109
-rw-r--r--src/bindings/interface/ScriptMgr.h52
-rw-r--r--src/bindings/interface/Scripts/sc_default.cpp14
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp1
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp18
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_skeram.cpp1
-rw-r--r--src/framework/Platform/Define.h14
-rw-r--r--src/game/BattleGroundHandler.cpp3
-rw-r--r--src/game/BattleGroundWS.cpp65
-rw-r--r--src/game/BattleGroundWS.h9
-rw-r--r--src/game/ConfusedMovementGenerator.cpp5
-rw-r--r--src/game/Map.h14
-rw-r--r--src/game/Object.h8
-rw-r--r--src/game/OutdoorPvPSI.cpp5
-rw-r--r--src/game/PetHandler.cpp10
-rw-r--r--src/game/RandomMovementGenerator.cpp4
-rw-r--r--src/game/Spell.cpp23
-rw-r--r--src/game/Spell.h8
-rw-r--r--src/game/SpellEffects.cpp93
-rw-r--r--src/game/SpellMgr.cpp27
-rw-r--r--src/game/SpellMgr.h3
-rw-r--r--src/game/Unit.cpp51
-rw-r--r--src/game/World.cpp2
-rw-r--r--src/game/World.h3
-rw-r--r--src/trinitycore/trinitycore.conf.dist8
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 &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;
+
+#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 &notifier) 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