aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp2
-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/PetHandler.cpp10
-rw-r--r--src/game/Spell.cpp6
-rw-r--r--src/game/SpellEffects.cpp13
-rw-r--r--src/game/Unit.cpp25
-rw-r--r--src/game/World.cpp2
-rw-r--r--src/game/World.h1
-rw-r--r--src/trinitycore/trinitycore.conf.dist8
11 files changed, 114 insertions, 30 deletions
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/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/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/Spell.cpp b/src/game/Spell.cpp
index bcca1f2c873..14f5a1d3319 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -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())
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 12008b94ddb..29d06ba4d20 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*/)
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 401a3f6beb5..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;
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 827d9157792..92fe74f9b81 100644
--- a/src/game/World.h
+++ b/src/game/World.h
@@ -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