aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/AI/CoreAI/GuardAI.cpp87
-rwxr-xr-xsrc/server/game/AI/CoreAI/GuardAI.h23
-rwxr-xr-xsrc/server/game/AI/CoreAI/PetAI.cpp52
-rwxr-xr-xsrc/server/game/AI/EventAI/CreatureEventAIMgr.cpp21
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp27
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h10
-rwxr-xr-xsrc/server/game/Battlegrounds/Battleground.cpp5
-rwxr-xr-xsrc/server/game/Battlegrounds/Zones/BattlegroundAB.cpp2
-rwxr-xr-xsrc/server/game/Battlegrounds/Zones/BattlegroundSA.cpp11
-rw-r--r--src/server/game/Calendar/CalendarMgr.cpp24
-rwxr-xr-xsrc/server/game/Chat/Commands/Level3.cpp34
-rwxr-xr-xsrc/server/game/DataStores/DBCEnums.h18
-rwxr-xr-xsrc/server/game/Entities/Corpse/Corpse.cpp2
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.cpp6
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.h6
-rwxr-xr-xsrc/server/game/Entities/DynamicObject/DynamicObject.cpp2
-rwxr-xr-xsrc/server/game/Entities/GameObject/GameObject.cpp4
-rwxr-xr-xsrc/server/game/Entities/Item/Container/Bag.cpp2
-rwxr-xr-xsrc/server/game/Entities/Item/Item.cpp8
-rwxr-xr-xsrc/server/game/Entities/Item/ItemPrototype.h9
-rwxr-xr-xsrc/server/game/Entities/Object/Object.h10
-rwxr-xr-xsrc/server/game/Entities/Pet/Pet.cpp2
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp31
-rwxr-xr-xsrc/server/game/Entities/Transport/Transport.cpp35
-rwxr-xr-xsrc/server/game/Entities/Transport/Transport.h2
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp90
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h43
-rwxr-xr-xsrc/server/game/Entities/Vehicle/Vehicle.cpp2
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.cpp93
-rwxr-xr-xsrc/server/game/Handlers/AuthHandler.cpp2
-rwxr-xr-xsrc/server/game/Handlers/CalendarHandler.cpp56
-rwxr-xr-xsrc/server/game/Handlers/ItemHandler.cpp2
-rwxr-xr-xsrc/server/game/Handlers/MiscHandler.cpp87
-rwxr-xr-xsrc/server/game/Handlers/MovementHandler.cpp102
-rwxr-xr-xsrc/server/game/Handlers/PetHandler.cpp6
-rwxr-xr-xsrc/server/game/Handlers/QueryHandler.cpp10
-rwxr-xr-xsrc/server/game/Handlers/SpellHandler.cpp20
-rwxr-xr-xsrc/server/game/Handlers/TradeHandler.cpp2
-rwxr-xr-xsrc/server/game/Loot/LootMgr.cpp15
-rwxr-xr-xsrc/server/game/Movement/MotionMaster.cpp6
-rwxr-xr-xsrc/server/game/Movement/MotionMaster.h4
-rw-r--r--src/server/game/Movement/Spline/MoveSpline.cpp2
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.cpp75
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.h31
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInitArgs.h3
-rw-r--r--src/server/game/Movement/Spline/MovementPacketBuilder.cpp14
-rwxr-xr-xsrc/server/game/Server/Protocol/Opcodes.cpp6
-rwxr-xr-xsrc/server/game/Server/Protocol/Opcodes.h6
-rw-r--r--src/server/game/Server/Protocol/PacketLog.cpp61
-rw-r--r--[-rwxr-xr-x]src/server/game/Server/Protocol/PacketLog.h (renamed from src/server/game/Server/Protocol/WorldLog.h)45
-rwxr-xr-xsrc/server/game/Server/Protocol/WorldLog.cpp114
-rwxr-xr-xsrc/server/game/Server/WorldSession.cpp41
-rwxr-xr-xsrc/server/game/Server/WorldSession.h2
-rwxr-xr-xsrc/server/game/Server/WorldSocket.cpp54
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuraEffects.cpp26
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp7
-rwxr-xr-xsrc/server/game/Spells/SpellEffects.cpp8
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.cpp6
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.h2
-rw-r--r--src/server/scripts/Commands/cs_modify.cpp2
-rw-r--r--src/server/scripts/Commands/cs_wp.cpp6
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockSpire/blackrock_spire.h9
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockSpire/boss_pyroguard_emberseer.cpp39
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockSpire/instance_blackrock_spire.cpp100
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp2
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp2
-rwxr-xr-xsrc/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp7
-rwxr-xr-xsrc/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp4
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp27
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp8
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp6
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp2
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp8
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp4
-rw-r--r--src/server/scripts/Northrend/dragonblight.cpp99
-rw-r--r--src/server/scripts/Northrend/sholazar_basin.cpp125
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp2
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp2
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp6
-rw-r--r--src/server/scripts/Outland/blades_edge_mountains.cpp2
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp93
-rw-r--r--src/server/scripts/Spells/spell_item.cpp2
-rw-r--r--src/server/scripts/World/npcs_special.cpp37
-rw-r--r--src/server/worldserver/worldserver.conf.dist23
88 files changed, 1302 insertions, 799 deletions
diff --git a/src/server/game/AI/CoreAI/GuardAI.cpp b/src/server/game/AI/CoreAI/GuardAI.cpp
index 252bcbabca5..6e2326ca9d5 100755
--- a/src/server/game/AI/CoreAI/GuardAI.cpp
+++ b/src/server/game/AI/CoreAI/GuardAI.cpp
@@ -23,7 +23,7 @@
#include "World.h"
#include "CreatureAIImpl.h"
-int GuardAI::Permissible(const Creature* creature)
+int GuardAI::Permissible(Creature const* creature)
{
if (creature->isGuard())
return PERMIT_BASE_SPECIAL;
@@ -31,7 +31,7 @@ int GuardAI::Permissible(const Creature* creature)
return PERMIT_BASE_NO;
}
-GuardAI::GuardAI(Creature* creature) : ScriptedAI(creature), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
+GuardAI::GuardAI(Creature* creature) : ScriptedAI(creature)
{
}
@@ -40,108 +40,35 @@ bool GuardAI::CanSeeAlways(WorldObject const* obj)
if (!obj->isType(TYPEMASK_UNIT))
return false;
- std::list<HostileReference*> t_list = me->getThreatManager().getThreatList();
- for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
- {
- if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid()))
- if (unit == obj)
- return true;
- }
+ std::list<HostileReference*> threatList = me->getThreatManager().getThreatList();
+ for (std::list<HostileReference*>::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr)
+ if ((*itr)->getUnitGuid() == obj->GetGUID())
+ return true;
return false;
}
-void GuardAI::MoveInLineOfSight(Unit* unit)
-{
- // Ignore Z for flying creatures
- if (!me->CanFly() && me->GetDistanceZ(unit) > CREATURE_Z_ATTACK_RANGE)
- return;
-
- if (!me->getVictim() && me->IsValidAttackTarget(unit) &&
- (unit->IsHostileToPlayers() || me->IsHostileTo(unit)) &&
- unit->isInAccessiblePlaceFor(me))
- {
- float attackRadius = me->GetAttackDistance(unit);
- if (me->IsWithinDistInMap(unit, attackRadius))
- {
- //Need add code to let guard support player
- AttackStart(unit);
- //u->RemoveAurasByType(SPELL_AURA_MOD_STEALTH);
- }
- }
-}
-
void GuardAI::EnterEvadeMode()
{
if (!me->isAlive())
{
- sLog->outStaticDebug("Creature stopped attacking because he is dead [guid=%u]", me->GetGUIDLow());
me->GetMotionMaster()->MoveIdle();
-
- i_state = STATE_NORMAL;
-
- i_victimGuid = 0;
me->CombatStop(true);
me->DeleteThreatList();
return;
}
- Unit* victim = ObjectAccessor::GetUnit(*me, i_victimGuid);
-
- if (!victim)
- {
- sLog->outStaticDebug("Creature stopped attacking because victim does not exist [guid=%u]", me->GetGUIDLow());
- }
- else if (!victim->isAlive())
- {
- sLog->outStaticDebug("Creature stopped attacking because victim is dead [guid=%u]", me->GetGUIDLow());
- }
- else if (victim->HasStealthAura())
- {
- sLog->outStaticDebug("Creature stopped attacking because victim is using stealth [guid=%u]", me->GetGUIDLow());
- }
- else if (victim->isInFlight())
- {
- sLog->outStaticDebug("Creature stopped attacking because victim is flying away [guid=%u]", me->GetGUIDLow());
- }
- else
- {
- sLog->outStaticDebug("Creature stopped attacking because victim outran him [guid=%u]", me->GetGUIDLow());
- }
+ sLog->outDebug(LOG_FILTER_UNITS, "Guard entry: %u enters evade mode.", me->GetEntry());
me->RemoveAllAuras();
me->DeleteThreatList();
- i_victimGuid = 0;
me->CombatStop(true);
- i_state = STATE_NORMAL;
// Remove ChaseMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
me->GetMotionMaster()->MoveTargetedHome();
}
-void GuardAI::UpdateAI(const uint32 /*diff*/)
-{
- // update i_victimGuid if me->getVictim() !=0 and changed
- if (!UpdateVictim())
- return;
-
- Unit* const victim = me->getVictim();
- if (!victim)
- return;
-
- i_victimGuid = victim->GetGUID();
-
- if (me->isAttackReady())
- {
- if (me->IsWithinMeleeRange(victim))
- {
- me->AttackerStateUpdate(victim);
- me->resetAttackTimer();
- }
- }
-}
-
void GuardAI::JustDied(Unit* killer)
{
if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
diff --git a/src/server/game/AI/CoreAI/GuardAI.h b/src/server/game/AI/CoreAI/GuardAI.h
index c80c5a6c343..c8dd9d54921 100755
--- a/src/server/game/AI/CoreAI/GuardAI.h
+++ b/src/server/game/AI/CoreAI/GuardAI.h
@@ -20,34 +20,19 @@
#define TRINITY_GUARDAI_H
#include "ScriptedCreature.h"
-#include "Timer.h"
class Creature;
class GuardAI : public ScriptedAI
{
- enum GuardState
- {
- STATE_NORMAL = 1,
- STATE_LOOK_AT_VICTIM = 2
- };
-
public:
+ explicit GuardAI(Creature* creature);
- explicit GuardAI(Creature* c);
-
- void MoveInLineOfSight(Unit*);
- void EnterEvadeMode();
- void JustDied(Unit*);
+ static int Permissible(Creature const* creature);
bool CanSeeAlways(WorldObject const* obj);
- void UpdateAI(const uint32);
- static int Permissible(const Creature*);
-
- private:
- uint64 i_victimGuid;
- GuardState i_state;
- TimeTracker i_tracker;
+ void EnterEvadeMode();
+ void JustDied(Unit* killer);
};
#endif
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index bcec8d273b9..160b406a6ea 100755
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -153,40 +153,56 @@ void PetAI::UpdateAI(const uint32 diff)
if (spellInfo->IsPositive())
{
- // non combat spells allowed
- // only pet spells have IsNonCombatSpell and not fit this reqs:
- // Consume Shadows, Lesser Invisibility, so ignore checks for its
if (spellInfo->CanBeUsedInCombat())
{
- // allow only spell without spell cost or with spell cost but not duration limit
- int32 duration = spellInfo->GetDuration();
- if ((spellInfo->ManaCost || spellInfo->ManaCostPercentage || spellInfo->ManaPerSecond) && duration > 0)
+ // check spell cooldown
+ if (me->HasSpellCooldown(spellInfo->Id))
continue;
- // allow only spell without cooldown > duration
- int32 cooldown = spellInfo->GetRecoveryTime();
- if (cooldown >= 0 && duration >= 0 && cooldown > duration)
+ // Check if we're in combat or commanded to attack
+ if (!me->isInCombat() && !me->GetCharmInfo()->IsCommandAttack())
continue;
}
Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE, 0);
-
bool spellUsed = false;
- for (std::set<uint64>::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
- {
- Unit* target = ObjectAccessor::GetUnit(*me, *tar);
- //only buff targets that are in combat, unless the spell can only be cast while out of combat
- if (!target)
- continue;
+ // Some spells can target enemy or friendly (DK Ghoul's Leap)
+ // Check for enemy first (pet then owner)
+ Unit* target = me->getAttackerForHelper();
+ if (!target && owner)
+ target = owner->getAttackerForHelper();
- if (spell->CanAutoCast(target))
+ if (target)
+ {
+ if (CanAttack(target) && spell->CanAutoCast(target))
{
targetSpellStore.push_back(std::make_pair(target, spell));
spellUsed = true;
- break;
}
}
+
+ // No enemy, check friendly
+ if (!spellUsed)
+ {
+ for (std::set<uint64>::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
+ {
+ Unit* ally = ObjectAccessor::GetUnit(*me, *tar);
+
+ //only buff targets that are in combat, unless the spell can only be cast while out of combat
+ if (!ally)
+ continue;
+
+ if (spell->CanAutoCast(ally))
+ {
+ targetSpellStore.push_back(std::make_pair(ally, spell));
+ spellUsed = true;
+ break;
+ }
+ }
+ }
+
+ // No valid targets at all
if (!spellUsed)
delete spell;
}
diff --git a/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp b/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp
index 517e55af457..a863f2f89cf 100755
--- a/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp
+++ b/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp
@@ -204,12 +204,17 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
temp.raw.param3 = fields[8].GetInt32();
temp.raw.param4 = fields[9].GetInt32();
+ CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
//Creature does not exist in database
- if (!sObjectMgr->GetCreatureTemplate(temp.creature_id))
+ if (!cInfo)
{
- sLog->outErrorDb("CreatureEventAI: Event %u has script for non-existing creature entry (%u), skipping.", i, temp.creature_id);
+ sLog->outErrorDb("CreatureEventAI: Event %u has script for non-existing creature entry (%u), skipping.", i, creature_id);
continue;
}
+
+ // Only on the first script
+ if (cInfo->AIName != "EventAI" && m_CreatureEventAI_Event_Map[creature_id].empty())
+ sLog->outErrorDb("Creature entry %u has EventAI scripts, but its AIName is not 'EventAI' - possible AI-mismatch?", temp.creature_id);
//No chance of this event occuring
if (temp.event_chance == 0)
@@ -735,18 +740,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
}
while (result->NextRow());
- for (CreatureEventAI_Event_Map::const_iterator itr = m_CreatureEventAI_Event_Map.begin(); itr != m_CreatureEventAI_Event_Map.end(); ++itr)
- {
- if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(itr->first))
- {
- if (cInfo->AIName != "EventAI")
- {
- sLog->outErrorDb("Creature entry %u has EventAI scripts, but its AIName is not 'EventAI', changing to EventAI", itr->first);
- const_cast<CreatureTemplate*>(cInfo)->AIName = "EventAI";
- }
- }
- }
-
sLog->outString(">> Loaded %u CreatureEventAI scripts in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
sLog->outString();
}
diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h
index bfd1c7b9d41..435aa176d4d 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.h
+++ b/src/server/game/AI/SmartScripts/SmartAI.h
@@ -62,6 +62,7 @@ class SmartAI : public CreatureAI
void RemoveEscortState(uint32 uiEscortState) { mEscortState &= ~uiEscortState; }
void SetAutoAttack(bool on) { mCanAutoAttack = on; }
void SetCombatMove(bool on);
+ bool CanCombatMove() { return mCanCombatMove; }
void SetFollow(Unit* target, float dist = 0.0f, float angle = 0.0f, uint32 credit = 0, uint32 end = 0, uint32 creditType = 0);
void SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker);
@@ -224,7 +225,6 @@ class SmartAI : public CreatureAI
bool mCanCombatMove;
bool mForcedPaused;
uint32 mInvincibilityHpLevel;
-
bool AssistPlayerInCombat(Unit* who);
uint32 mDespawnTime;
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 85b117ccd8c..21dc92b25d1 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -789,7 +789,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!IsUnit((*itr)))
continue;
- (*itr)->ToUnit()->RemoveAurasDueToSpell(e.action.removeAura.spell);
+ if (e.action.removeAura.spell == 0)
+ (*itr)->ToUnit()->RemoveAllAuras();
+ else
+ (*itr)->ToUnit()->RemoveAurasDueToSpell(e.action.removeAura.spell);
+
sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_REMOVEAURASFROMSPELL: Unit %u, spell %u",
(*itr)->GetGUIDLow(), e.action.removeAura.spell);
}
@@ -1534,6 +1538,27 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_CALL_SCRIPT_RESET:
OnReset();
break;
+ case SMART_ACTION_SET_RANGED_MOVEMENT:
+ {
+ if (!IsSmart())
+ break;
+
+ float attackDistance = (float)e.action.setRangedMovement.distance;
+ float attackAngle = e.action.setRangedMovement.angle / 180.0f * M_PI;
+
+ ObjectList* targets = GetTargets(e, unit);
+ if (targets)
+ {
+ for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ if (Creature* target = (*itr)->ToCreature())
+ if (IsSmart(target) && target->getVictim())
+ if (CAST_AI(SmartAI, target->AI())->CanCombatMove())
+ target->GetMotionMaster()->MoveChase(target->getVictim(), attackDistance, attackAngle);
+
+ delete targets;
+ }
+ break;
+ }
case SMART_ACTION_CALL_TIMED_ACTIONLIST:
{
if (e.GetTargetType() == SMART_TARGET_NONE)
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index a7149f37480..d529479d9dd 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -709,7 +709,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
return false;
break;
case SMART_ACTION_REMOVEAURASFROMSPELL:
- if (!IsSpellValid(e, e.action.removeAura.spell))
+ if (e.action.removeAura.spell != 0 && !IsSpellValid(e, e.action.removeAura.spell))
return false;
break;
case SMART_ACTION_RANDOM_PHASE:
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index bde7768f036..5b54a4d3048 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -398,7 +398,7 @@ enum SMART_ACTION
SMART_ACTION_FLEE_FOR_ASSIST = 25, // With Emote
SMART_ACTION_CALL_GROUPEVENTHAPPENS = 26, // QuestID
SMART_ACTION_CALL_CASTEDCREATUREORGO = 27, // CreatureId, SpellId
- SMART_ACTION_REMOVEAURASFROMSPELL = 28, // Spellid
+ SMART_ACTION_REMOVEAURASFROMSPELL = 28, // Spellid, 0 removes all auras
SMART_ACTION_FOLLOW = 29, // Distance (0 = default), Angle (0 = default), EndCreatureEntry, credit, creditType (0monsterkill, 1event)
SMART_ACTION_RANDOM_PHASE = 30, // PhaseId1, PhaseId2, PhaseId3...
SMART_ACTION_RANDOM_PHASE_RANGE = 31, // PhaseMin, PhaseMax
@@ -451,7 +451,7 @@ enum SMART_ACTION
SMART_ACTION_OVERRIDE_SCRIPT_BASE_OBJECT = 76, // WARNING: CAN CRASH CORE, do not use if you dont know what you are doing
SMART_ACTION_RESET_SCRIPT_BASE_OBJECT = 77, // none
SMART_ACTION_CALL_SCRIPT_RESET = 78, // none
- // Unused = 79,
+ SMART_ACTION_SET_RANGED_MOVEMENT = 79, // Distance, angle
SMART_ACTION_CALL_TIMED_ACTIONLIST = 80, // ID (overwrites already running actionlist), stop after combat?(0/1), timer update type(0-OOC, 1-IC, 2-ALWAYS)
SMART_ACTION_SET_NPC_FLAG = 81, // Flags
SMART_ACTION_ADD_NPC_FLAG = 82, // Flags
@@ -895,6 +895,12 @@ struct SmartAction
struct
{
+ float distance;
+ float angle;
+ } setRangedMovement;
+
+ struct
+ {
uint32 param1;
uint32 param2;
uint32 param3;
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index 9d5858e1ca4..85bbd2f3b89 100755
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -850,9 +850,8 @@ void Battleground::EndBattleground(uint32 winner)
if (team == winner)
{
// update achievement BEFORE personal rating update
- ArenaTeamMember* member = winner_arena_team->GetMember(player->GetGUID());
- if (member)
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, 1);
+ uint32 rating = player->GetArenaPersonalRating(winner_arena_team->GetSlot());
+ player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1);
winner_arena_team->MemberWon(player, loser_matchmaker_rating, winner_matchmaker_change);
}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
index 52d2cdefd65..d28f5ddfe6a 100755
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
@@ -290,7 +290,7 @@ int32 BattlegroundAB::_GetNodeNameId(uint8 node)
case BG_AB_NODE_LUMBER_MILL:return LANG_BG_AB_NODE_LUMBER_MILL;
case BG_AB_NODE_GOLD_MINE: return LANG_BG_AB_NODE_GOLD_MINE;
default:
- ASSERT(0);
+ ASSERT(false);
}
return 0;
}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
index 977897b8d48..133a0aec560 100755
--- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
@@ -720,8 +720,13 @@ void BattlegroundSA::CaptureGraveyard(BG_SA_Graveyards i, Player* Source)
DelCreature(BG_SA_MAXNPC + i);
GraveyardStatus[i] = Source->GetTeamId();
- WorldSafeLocsEntry const* sg = NULL;
- sg = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]);
+ WorldSafeLocsEntry const* sg = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]);
+ if (!sg)
+ {
+ sLog->outError("BattlegroundSA::CaptureGraveyard: non-existant GY entry: %u", BG_SA_GYEntries[i]);
+ return;
+ }
+
AddSpiritGuide(i + BG_SA_MAXNPC, sg->x, sg->y, sg->z, BG_SA_GYOrientation[i], (GraveyardStatus[i] == TEAM_ALLIANCE? ALLIANCE : HORDE));
uint32 npc = 0;
uint32 flag = 0;
@@ -781,7 +786,7 @@ void BattlegroundSA::CaptureGraveyard(BG_SA_Graveyards i, Player* Source)
SendWarningToAll(LANG_BG_SA_H_GY_SOUTH);
break;
default:
- ASSERT(0);
+ ASSERT(false);
break;
};
}
diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp
index cef68891890..62bc0ab3205 100644
--- a/src/server/game/Calendar/CalendarMgr.cpp
+++ b/src/server/game/Calendar/CalendarMgr.cpp
@@ -95,9 +95,9 @@ CalendarEventIdList const& CalendarMgr::GetPlayerEvents(uint64 guid)
CalendarInvite* CalendarMgr::GetInvite(uint64 inviteId)
{
- CalendarInviteMap::iterator it = _invites.find(inviteId);
- if (it != _invites.end())
- return &(it->second);
+ CalendarInviteMap::iterator itr = _invites.find(inviteId);
+ if (itr != _invites.end())
+ return &(itr->second);
sLog->outError("CalendarMgr::GetInvite: [" UI64FMTD "] not found!", inviteId);
return NULL;
@@ -105,9 +105,9 @@ CalendarInvite* CalendarMgr::GetInvite(uint64 inviteId)
CalendarEvent* CalendarMgr::GetEvent(uint64 eventId)
{
- CalendarEventMap::iterator it = _events.find(eventId);
- if (it != _events.end())
- return &(it->second);
+ CalendarEventMap::iterator itr = _events.find(eventId);
+ if (itr != _events.end())
+ return &(itr->second);
sLog->outError("CalendarMgr::GetEvent: [" UI64FMTD "] not found!", eventId);
return NULL;
@@ -316,11 +316,6 @@ void CalendarMgr::AddAction(CalendarAction const& action)
if (!calendarEvent)
return;
- CalendarInviteIdList const& inviteIds = calendarEvent->GetInviteIdList();
- for (CalendarInviteIdList::const_iterator it = inviteIds.begin(); it != inviteIds.end(); ++it)
- if (uint64 invitee = RemoveInvite(*it))
- SendCalendarEventRemovedAlert(invitee, *calendarEvent);
-
RemoveEvent(eventId);
break;
}
@@ -464,8 +459,6 @@ bool CalendarMgr::RemoveEvent(uint64 eventId)
return false;
}
- _events.erase(itr);
-
bool val = true;
CalendarInviteIdList const& invites = itr->second.GetInviteIdList();
@@ -474,8 +467,13 @@ bool CalendarMgr::RemoveEvent(uint64 eventId)
CalendarInvite* invite = GetInvite(*itrInvites);
if (!invite || !RemovePlayerEvent(invite->GetInvitee(), eventId))
val = false;
+
+ if (uint64 invitee = RemoveInvite(*itrInvites))
+ SendCalendarEventRemovedAlert(invitee, itr->second);
}
+ _events.erase(itr);
+
return val;
}
diff --git a/src/server/game/Chat/Commands/Level3.cpp b/src/server/game/Chat/Commands/Level3.cpp
index 30562bb9662..4b2f1c5e7bb 100755
--- a/src/server/game/Chat/Commands/Level3.cpp
+++ b/src/server/game/Chat/Commands/Level3.cpp
@@ -1144,15 +1144,20 @@ bool ChatHandler::HandleLookupQuestCommand(const char *args)
{
QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
- if (status == QUEST_STATUS_COMPLETE)
+ switch (status)
{
- if (target->GetQuestRewardStatus(qinfo->GetQuestId()))
- statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
- else
+ case QUEST_STATUS_COMPLETE:
statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE);
+ break;
+ case QUEST_STATUS_INCOMPLETE:
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
+ break;
+ case QUEST_STATUS_REWARDED:
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
+ break;
+ default:
+ break;
}
- else if (status == QUEST_STATUS_INCOMPLETE)
- statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
}
if (m_session)
@@ -1187,15 +1192,20 @@ bool ChatHandler::HandleLookupQuestCommand(const char *args)
{
QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
- if (status == QUEST_STATUS_COMPLETE)
+ switch (status)
{
- if (target->GetQuestRewardStatus(qinfo->GetQuestId()))
- statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
- else
+ case QUEST_STATUS_COMPLETE:
statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE);
+ break;
+ case QUEST_STATUS_INCOMPLETE:
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
+ break;
+ case QUEST_STATUS_REWARDED:
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
+ break;
+ default:
+ break;
}
- else if (status == QUEST_STATUS_INCOMPLETE)
- statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
}
if (m_session)
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index 80949effa0c..e73480cb4de 100755
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -245,7 +245,7 @@ enum AreaFlags
AREA_FLAG_CITY = 0x00000200, // only for one zone named "City" (where it located?)
AREA_FLAG_OUTLAND = 0x00000400, // expansion zones? (only Eye of the Storm not have this flag, but have 0x00004000 flag)
AREA_FLAG_SANCTUARY = 0x00000800, // sanctuary area (PvP disabled)
- AREA_FLAG_NEED_FLY = 0x00001000, // Unknown
+ AREA_FLAG_NEED_FLY = 0x00001000, // Respawn alive at the graveyard without corpse
AREA_FLAG_UNUSED1 = 0x00002000, // Unused in 3.3.5a
AREA_FLAG_OUTLAND2 = 0x00004000, // expansion zones? (only Circle of Blood Arena not have this flag, but have 0x00000400 flag)
AREA_FLAG_OUTDOOR_PVP = 0x00008000, // pvp objective area? (Death's Door also has this flag although it's no pvp object area)
@@ -260,7 +260,7 @@ enum AreaFlags
AREA_FLAG_WINTERGRASP = 0x01000000, // Wintergrasp and it's subzones
AREA_FLAG_INSIDE = 0x02000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors
AREA_FLAG_OUTSIDE = 0x04000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors
- AREA_FLAG_WINTERGRASP_2 = 0x08000000, // Same as AREA_FLAG_WINTERGRASP except for The Sunken Ring and Western Bridge.
+ AREA_FLAG_WINTERGRASP_2 = 0x08000000, // Can Hearth And Resurrect From Area
AREA_FLAG_NO_FLY_ZONE = 0x20000000 // Marks zones where you cannot fly
};
@@ -416,16 +416,27 @@ enum SummonPropFlags
enum VehicleSeatFlags
{
+ VEHICLE_SEAT_FLAG_HAS_LOWER_ANIM_FOR_ENTER = 0x00000001,
+ VEHICLE_SEAT_FLAG_HAS_LOWER_ANIM_FOR_RIDE = 0x00000002,
+ VEHICLE_SEAT_FLAG_SHOULD_USE_VEH_SEAT_EXIT_ANIM_ON_VOLUNTARY_EXIT = 0x00000008,
VEHICLE_SEAT_FLAG_HIDE_PASSENGER = 0x00000200, // Passenger is hidden
- VEHICLE_SEAT_FLAG_UNK1 = 0x00000400, // needed for CGCamera__SyncFreeLookFacing
+ VEHICLE_SEAT_FLAG_ALLOW_TURNING = 0x00000400, // needed for CGCamera__SyncFreeLookFacing
VEHICLE_SEAT_FLAG_CAN_CONTROL = 0x00000800, // Lua_UnitInVehicleControlSeat
VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL = 0x00001000, // Can cast spells with SPELL_AURA_MOUNTED from seat (possibly 4.x only, 0 seats on 3.3.5a)
VEHICLE_SEAT_FLAG_UNCONTROLLED = 0x00002000, // can override !& VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT
VEHICLE_SEAT_FLAG_CAN_ATTACK = 0x00004000, // Can attack, cast spells and use items from vehicle
+ VEHICLE_SEAT_FLAG_SHOULD_USE_VEH_SEAT_EXIT_ANIMN_ON_FORCED_EXIT = 0x00008000,
+ VEHICLE_SEAT_FLAG_HAS_VEH_EXIT_ANIM_VOLUNTARY_EXIT = 0x00040000,
+ VEHICLE_SEAT_FLAG_HAS_VEH_EXIT_ANIM_FORCED_EXIT = 0x00080000,
+ VEHICLE_SEAT_FLAG_REC_HAS_VEHICLE_ENTER_ANIM = 0x00400000,
+ VEHICLE_SEAT_FLAG_ENABLE_VEHICLE_ZOOM = 0x01000000,
VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT = 0x02000000, // Lua_CanExitVehicle - can enter and exit at free will
VEHICLE_SEAT_FLAG_CAN_SWITCH = 0x04000000, // Lua_CanSwitchVehicleSeats
+ VEHICLE_SEAT_FLAG_HAS_START_WARITING_FOR_VEH_TRANSITION_ANIM_ENTER = 0x08000000,
+ VEHICLE_SEAT_FLAG_HAS_START_WARITING_FOR_VEH_TRANSITION_ANIM_EXIT = 0x10000000,
VEHICLE_SEAT_FLAG_CAN_CAST = 0x20000000, // Lua_UnitHasVehicleUI
VEHICLE_SEAT_FLAG_UNK2 = 0x40000000, // checked in conjunction with 0x800 in CastSpell2
+ VEHICLE_SEAT_FLAG_ALLOWS_INTERACTION = 0x80000000,
};
enum VehicleSeatFlagsB
@@ -437,6 +448,7 @@ enum VehicleSeatFlagsB
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_2 = 0x00000040,
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_3 = 0x00000100,
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_4 = 0x02000000,
+ VEHICLE_SEAT_FLAG_B_CAN_SWITCH = 0x04000000,
VEHICLE_SEAT_FLAG_B_VEHICLE_PLAYERFRAME_UI = 0x80000000, // Lua_UnitHasVehiclePlayerFrameUI - actually checked for flagsb &~ 0x80000000
};
diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp
index 5b7c40e5494..4613a3554db 100755
--- a/src/server/game/Entities/Corpse/Corpse.cpp
+++ b/src/server/game/Entities/Corpse/Corpse.cpp
@@ -89,7 +89,7 @@ bool Corpse::Create(uint32 guidlow, Player* owner)
WorldObject::_Create(guidlow, HIGHGUID_CORPSE, owner->GetPhaseMask());
- SetFloatValue(OBJECT_FIELD_SCALE_X, 1);
+ SetObjectScale(1);
SetUInt64Value(CORPSE_FIELD_OWNER, owner->GetGUID());
_gridCoord = Trinity::ComputeGridCoord(GetPositionX(), GetPositionY());
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index d120713636d..e8ec686daf5 100755
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -333,7 +333,7 @@ bool Creature::InitEntry(uint32 Entry, uint32 /*team*/, const CreatureData* data
SetSpeed(MOVE_SWIM, 1.0f); // using 1.0 rate
SetSpeed(MOVE_FLIGHT, 1.0f); // using 1.0 rate
- SetFloatValue(OBJECT_FIELD_SCALE_X, cinfo->scale);
+ SetObjectScale(cinfo->scale);
SetFloatValue(UNIT_FIELD_HOVERHEIGHT, cinfo->HoverHeight);
@@ -1668,8 +1668,8 @@ bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo)
if (!spellInfo)
return false;
- // Spells that don't have effectMechanics.
- if (!spellInfo->HasAnyEffectMechanic() && GetCreatureTemplate()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1)))
+ // Creature is immune to main mechanic of the spell
+ if (GetCreatureTemplate()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1)))
return true;
// This check must be done instead of 'if (GetCreatureTemplate()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1)))' for not break
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index f6021a7d7ec..c8ebf1aa13b 100755
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -677,6 +677,11 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
void GetHomePosition(float &x, float &y, float &z, float &ori) { m_homePosition.GetPosition(x, y, z, ori); }
Position GetHomePosition() { return m_homePosition; }
+ void SetTransportHomePosition(float x, float y, float z, float o) { m_transportHomePosition.Relocate(x, y, z, o); }
+ void SetTransportHomePosition(const Position &pos) { m_transportHomePosition.Relocate(pos); }
+ void GetTransportHomePosition(float &x, float &y, float &z, float &ori) { m_transportHomePosition.GetPosition(x, y, z, ori); }
+ Position GetTransportHomePosition() { return m_transportHomePosition; }
+
uint32 GetWaypointPath(){return m_path_id;}
void LoadPath(uint32 pathid) { m_path_id = pathid; }
@@ -750,6 +755,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
uint32 m_originalEntry;
Position m_homePosition;
+ Position m_transportHomePosition;
bool DisableReputationGain;
diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.cpp b/src/server/game/Entities/DynamicObject/DynamicObject.cpp
index abeae0656ee..76d4cb6624b 100755
--- a/src/server/game/Entities/DynamicObject/DynamicObject.cpp
+++ b/src/server/game/Entities/DynamicObject/DynamicObject.cpp
@@ -92,7 +92,7 @@ bool DynamicObject::CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spe
WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetPhaseMask());
SetEntry(spellId);
- SetFloatValue(OBJECT_FIELD_SCALE_X, 1);
+ SetObjectScale(1);
SetUInt64Value(DYNAMICOBJECT_CASTER, caster->GetGUID());
// The lower word of DYNAMICOBJECT_BYTES must be 0x0001. This value means that the visual radius will be overriden
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 10136c5fbd7..5101d01899d 100755
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -206,7 +206,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
UpdateRotationFields(rotation2, rotation3); // GAMEOBJECT_FACING, GAMEOBJECT_ROTATION, GAMEOBJECT_PARENTROTATION+2/3
- SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size);
+ SetObjectScale(goinfo->size);
SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
@@ -1674,7 +1674,7 @@ void GameObject::CastSpell(Unit* target, uint32 spellId)
else
{
trigger->setFaction(14);
- // Set owner guid for target if no owner avalible - needed by trigger auras
+ // Set owner guid for target if no owner available - needed by trigger auras
// - trigger gets despawned and there's no caster avalible (see AuraEffect::TriggerSpell())
trigger->CastSpell(target ? target : trigger, spellInfo, true, 0, 0, target ? target->GetGUID() : 0);
}
diff --git a/src/server/game/Entities/Item/Container/Bag.cpp b/src/server/game/Entities/Item/Container/Bag.cpp
index 4eede93bd37..c4d4adeb6f2 100755
--- a/src/server/game/Entities/Item/Container/Bag.cpp
+++ b/src/server/game/Entities/Item/Container/Bag.cpp
@@ -78,7 +78,7 @@ bool Bag::Create(uint32 guidlow, uint32 itemid, Player const* owner)
Object::_Create(guidlow, 0, HIGHGUID_CONTAINER);
SetEntry(itemid);
- SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
+ SetObjectScale(1.0f);
SetUInt64Value(ITEM_FIELD_OWNER, owner ? owner->GetGUID() : 0);
SetUInt64Value(ITEM_FIELD_CONTAINED, owner ? owner->GetGUID() : 0);
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index f2b893896dc..209fdae8ce6 100755
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -258,7 +258,7 @@ bool Item::Create(uint32 guidlow, uint32 itemid, Player const* owner)
Object::_Create(guidlow, 0, HIGHGUID_ITEM);
SetEntry(itemid);
- SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
+ SetObjectScale(1.0f);
SetUInt64Value(ITEM_FIELD_OWNER, owner ? owner->GetGUID() : 0);
SetUInt64Value(ITEM_FIELD_CONTAINED, owner ? owner->GetGUID() : 0);
@@ -274,7 +274,7 @@ bool Item::Create(uint32 guidlow, uint32 itemid, Player const* owner)
for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
SetSpellCharges(i, itemProto->Spells[i].SpellCharges);
- SetUInt32Value(ITEM_FIELD_DURATION, abs(itemProto->Duration));
+ SetUInt32Value(ITEM_FIELD_DURATION, itemProto->Duration);
SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, 0);
return true;
}
@@ -400,7 +400,7 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, Field* fields, uint32 entr
// Set entry, MUST be before proto check
SetEntry(entry);
- SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
+ SetObjectScale(1.0f);
ItemTemplate const* proto = GetTemplate();
if (!proto)
@@ -420,7 +420,7 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, Field* fields, uint32 entr
// update duration if need, and remove if not need
if ((proto->Duration == 0) != (duration == 0))
{
- SetUInt32Value(ITEM_FIELD_DURATION, abs(proto->Duration));
+ SetUInt32Value(ITEM_FIELD_DURATION, proto->Duration);
need_save = true;
}
diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h
index 2eae7234229..1b5eec7fbaf 100755
--- a/src/server/game/Entities/Item/ItemPrototype.h
+++ b/src/server/game/Entities/Item/ItemPrototype.h
@@ -192,6 +192,12 @@ enum ItemFlagsExtra
ITEM_FLAGS_EXTRA_NEED_ROLL_DISABLED = 0x00000100
};
+enum ItemFlagsCustom
+{
+ ITEM_FLAGS_CU_DURATION_REAL_TIME = 0x0001, // Item duration will tick even if player is offline
+ ITEM_FLAGS_CU_IGNORE_QUEST_STATUS = 0x0002, // No quest status will be checked when this item drops
+};
+
enum BAG_FAMILY_MASK
{
BAG_FAMILY_MASK_NONE = 0x00000000,
@@ -644,7 +650,7 @@ struct ItemTemplate
uint32 GemProperties; // id from GemProperties.dbc
uint32 RequiredDisenchantSkill;
float ArmorDamageModifier;
- int32 Duration; // negative = realtime, positive = ingame time
+ uint32 Duration;
uint32 ItemLimitCategory; // id from ItemLimitCategory.dbc
uint32 HolidayId; // id from Holidays.dbc
uint32 ScriptId;
@@ -652,6 +658,7 @@ struct ItemTemplate
uint32 FoodType;
uint32 MinMoneyLoot;
uint32 MaxMoneyLoot;
+ uint32 FlagsCu;
// helpers
bool CanChangeEquipStateInCombat() const
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 3693f683b24..5a6a5799fee 100755
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -34,11 +34,11 @@
#define CONTACT_DISTANCE 0.5f
#define INTERACTION_DISTANCE 5.0f
#define ATTACK_DISTANCE 5.0f
-#define MAX_VISIBILITY_DISTANCE 500.0f // max distance for visible objects
+#define MAX_VISIBILITY_DISTANCE SIZE_OF_GRIDS // max distance for visible objects
#define SIGHT_RANGE_UNIT 50.0f
-#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents
-#define DEFAULT_VISIBILITY_INSTANCE 120.0f // default visible distance in instances, 120 yards
-#define DEFAULT_VISIBILITY_BGARENAS 180.0f // default visible distance in BG/Arenas, 180 yards
+#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents
+#define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards
+#define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards
#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
#define DEFAULT_COMBAT_REACH 1.5f
@@ -137,6 +137,8 @@ class Object
uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); }
void SetEntry(uint32 entry) { SetUInt32Value(OBJECT_FIELD_ENTRY, entry); }
+ void SetObjectScale(float scale) { SetFloatValue(OBJECT_FIELD_SCALE_X, scale); }
+
TypeID GetTypeId() const { return m_objectTypeId; }
bool isType(uint16 mask) const { return (mask & m_objectType); }
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index f3a736daceb..75deb8b4216 100755
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -870,7 +870,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
else
scale = cFamily->minScale + float(getLevel() - cFamily->minScaleLevel) / cFamily->maxScaleLevel * (cFamily->maxScale - cFamily->minScale);
- SetFloatValue(OBJECT_FIELD_SCALE_X, scale);
+ SetObjectScale(scale);
}
// Resistance
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index f5f336a2402..4cf6d4ad979 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -3153,7 +3153,7 @@ void Player::InitStatsForLevel(bool reapplyMods)
SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f);
// reset size before reapply auras
- SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
+ SetObjectScale(1.0f);
// save base values (bonuses already included in stored stats
for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i)
@@ -10157,7 +10157,8 @@ uint32 Player::GetItemCount(uint32 item, bool inBankAlso, Item* skipItem) const
if (inBankAlso)
{
- for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; ++i)
+ // checking every item from 39 to 74 (including bank bags)
+ for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_BAG_END; ++i)
if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
if (pItem != skipItem && pItem->GetEntry() == item)
count += pItem->GetCount();
@@ -10197,7 +10198,7 @@ uint32 Player::GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipIte
if (Bag* pBag = GetBagByPos(i))
count += pBag->GetItemCountWithLimitCategory(limitCategory, skipItem);
- for (int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; ++i)
+ for (int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_BAG_END; ++i)
if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
if (pItem != skipItem)
if (ItemTemplate const* pProto = pItem->GetTemplate())
@@ -10223,7 +10224,7 @@ Item* Player::GetItemByGuid(uint64 guid) const
if (pItem->GetGUID() == guid)
return pItem;
- for (int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; ++i)
+ for (int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_BAG_END; ++i)
if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
if (pItem->GetGUID() == guid)
return pItem;
@@ -12180,11 +12181,6 @@ Item* Player::StoreNewItem(ItemPosCountVec const& dest, uint32 item, bool update
pItem->SetItemRandomProperties(randomPropertyId);
pItem = StoreItem(dest, pItem, update);
- const ItemTemplate* proto = pItem->GetTemplate();
- for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
- if (proto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE && proto->Spells[i].SpellId > 0) // On obtain trigger
- CastSpell(this, proto->Spells[i].SpellId, true, pItem);
-
if (allowedLooters.size() > 1 && pItem->GetTemplate()->GetMaxStackSize() == 1 && pItem->IsSoulBound())
{
pItem->SetSoulboundTradeable(allowedLooters);
@@ -12290,6 +12286,14 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool
AddEnchantmentDurations(pItem);
AddItemDurations(pItem);
+
+ const ItemTemplate* proto = pItem->GetTemplate();
+ for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
+ if (proto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE && proto->Spells[i].SpellId > 0) // On obtain trigger
+ if (bag == INVENTORY_SLOT_BAG_0 || (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END))
+ if (!HasAura(proto->Spells[i].SpellId))
+ CastSpell(this, proto->Spells[i].SpellId, true, pItem);
+
return pItem;
}
else
@@ -12326,6 +12330,13 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool
pItem2->SetState(ITEM_CHANGED, this);
+ const ItemTemplate* proto = pItem2->GetTemplate();
+ for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
+ if (proto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE && proto->Spells[i].SpellId > 0) // On obtain trigger
+ if (bag == INVENTORY_SLOT_BAG_0 || (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END))
+ if (!HasAura(proto->Spells[i].SpellId))
+ CastSpell(this, proto->Spells[i].SpellId, true, pItem2);
+
return pItem2;
}
}
@@ -13654,7 +13665,7 @@ void Player::UpdateItemDuration(uint32 time, bool realtimeonly)
Item* item = *itr;
++itr; // current element can be erased in UpdateDuration
- if ((realtimeonly && item->GetTemplate()->Duration < 0) || !realtimeonly)
+ if (!realtimeonly || item->GetTemplate()->FlagsCu & ITEM_FLAGS_CU_DURATION_REAL_TIME)
item->UpdateDuration(this, time);
}
}
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index 9578605ac6f..95c6d308626 100755
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -214,7 +214,7 @@ bool Transport::Create(uint32 guidlow, uint32 entry, uint32 mapid, float x, floa
m_goInfo = goinfo;
- SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size);
+ SetObjectScale(goinfo->size);
SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
@@ -656,6 +656,7 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,
o + GetOrientation());
creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation());
+ creature->SetTransportHomePosition(creature->m_movementInfo.t_pos);
if (!creature->IsPositionValid())
{
@@ -698,11 +699,33 @@ void Transport::UpdateNPCPositions()
Creature* npc = *itr;
float x, y, z, o;
- o = GetOrientation() + npc->m_movementInfo.t_pos.m_orientation;
- x = GetPositionX() + (npc->m_movementInfo.t_pos.m_positionX * cos(GetOrientation()) + npc->m_movementInfo.t_pos.m_positionY * sin(GetOrientation() + M_PI));
- y = GetPositionY() + (npc->m_movementInfo.t_pos.m_positionY * cos(GetOrientation()) + npc->m_movementInfo.t_pos.m_positionX * sin(GetOrientation()));
- z = GetPositionZ() + npc->m_movementInfo.t_pos.m_positionZ;
- npc->SetHomePosition(x, y, z, o);
+ npc->m_movementInfo.t_pos.GetPosition(x, y, z, o);
+ CalculatePassengerPosition(x, y, z, o);
GetMap()->CreatureRelocation(npc, x, y, z, o, false);
+ npc->GetTransportHomePosition(x, y, z, o);
+ CalculatePassengerPosition(x, y, z, o);
+ npc->SetHomePosition(x, y, z, o);
}
}
+
+//! This method transforms supplied transport offsets into global coordinates
+void Transport::CalculatePassengerPosition(float& x, float& y, float& z, float& o)
+{
+ float inx = x, iny = y, inz = z, ino = o;
+ o = GetOrientation() + ino;
+ x = GetPositionX() + (inx * cos(GetOrientation()) + iny * sin(GetOrientation() + M_PI));
+ y = GetPositionY() + (iny * cos(GetOrientation()) + inx * sin(GetOrientation()));
+ z = GetPositionZ() + inz;
+}
+
+//! This method transforms supplied global coordinates into local offsets
+void Transport::CalculatePassengerOffset(float& x, float& y, float& z, float& o)
+{
+ o -= GetOrientation();
+ z -= GetPositionZ();
+ y -= GetPositionY(); // y = searchedY * cos(o) + searchedX * sin(o)
+ x -= GetPositionX(); // x = searchedX * cos(o) + searchedY * sin(o + pi)
+ float inx = x, iny = y;
+ y = (iny - inx * tan(GetOrientation())) / (cos(GetOrientation()) - sin(GetOrientation() + M_PI) * tan(GetOrientation()));
+ x = (inx - iny * sin(GetOrientation() + M_PI) / cos(GetOrientation())) / (cos(GetOrientation()) - tan(GetOrientation()) * sin(GetOrientation() + M_PI));
+}
diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h
index 518dcf6359d..4b0c42c9071 100755
--- a/src/server/game/Entities/Transport/Transport.h
+++ b/src/server/game/Entities/Transport/Transport.h
@@ -47,6 +47,8 @@ class Transport : public GameObject
uint32 AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y, float z, float o, uint32 anim=0);
void UpdatePosition(MovementInfo* mi);
void UpdateNPCPositions();
+ void CalculatePassengerPosition(float& x, float& y, float& z, float& o);
+ void CalculatePassengerOffset(float& x, float& y, float& z, float& o);
void BuildStartMovePacket(Map const* targetMap);
void BuildStopMovePacket(Map const* targetMap);
uint32 GetScriptId() const { return ScriptId; }
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index ba481176d23..bb2d057bfaa 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -396,10 +396,25 @@ void Unit::UpdateSplineMovement(uint32 t_diff)
m_movesplineTimer.Reset(POSITION_UPDATE_DELAY);
Movement::Location loc = movespline->ComputePosition();
- if (GetTypeId() == TYPEID_PLAYER)
- ((Player*)this)->UpdatePosition(loc.x,loc.y,loc.z,loc.orientation);
- else
- GetMap()->CreatureRelocation((Creature*)this,loc.x,loc.y,loc.z,loc.orientation);
+ if (HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ {
+ Position& pos = m_movementInfo.t_pos;
+ pos.m_positionX = loc.x;
+ pos.m_positionY = loc.y;
+ pos.m_positionZ = loc.z;
+ pos.m_orientation = loc.orientation;
+ if (Unit* vehicle = GetVehicleBase())
+ {
+ loc.x += vehicle->GetPositionX();
+ loc.y += vehicle->GetPositionY();
+ loc.z += vehicle->GetPositionZMinusOffset();
+ loc.orientation = vehicle->GetOrientation();
+ }
+ else if (Transport* trans = GetTransport())
+ trans->CalculatePassengerPosition(loc.x, loc.y, loc.z, loc.orientation);
+ }
+
+ UpdatePosition(loc.x, loc.y, loc.z, loc.orientation);
}
}
@@ -414,13 +429,13 @@ void Unit::SendMonsterMoveExitVehicle(Position const* newPos)
WorldPacket data(SMSG_MONSTER_MOVE, 1+12+4+1+4+4+4+12+GetPackGUID().size());
data.append(GetPackGUID());
- data << uint8(GetTypeId() == TYPEID_PLAYER ? 1 : 0); // new in 3.1, bool
+ data << uint8(GetTypeId() == TYPEID_PLAYER ? 1 : 0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40)
data << GetPositionX() << GetPositionY() << GetPositionZ();
data << getMSTime();
data << uint8(SPLINETYPE_FACING_ANGLE);
data << float(GetOrientation()); // guess
- data << uint32(SPLINEFLAG_EXIT_VEHICLE);
+ data << uint32(SPLINEFLAG_TRANSPORT_EXIT);
data << uint32(0); // Time in between points
data << uint32(1); // 1 single waypoint
data << newPos->GetPositionX();
@@ -437,7 +452,7 @@ void Unit::SendMonsterMoveTransport(Unit* vehicleOwner)
data.append(GetPackGUID());
data.append(vehicleOwner->GetPackGUID());
data << int8(GetTransSeat());
- data << uint8(0);
+ data << uint8(0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40)
data << GetPositionX() - vehicleOwner->GetPositionX();
data << GetPositionY() - vehicleOwner->GetPositionY();
data << GetPositionZ() - vehicleOwner->GetPositionZ();
@@ -7366,30 +7381,16 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
if (procSpell->SpellIconID != 2019)
return false;
- AuraEffect* aurEffA = NULL;
- AuraEffectList const& auras = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE);
- for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
+ if (Creature* totem = GetMap()->GetCreature(m_SummonSlot[1])) // Fire totem summon slot
{
- SpellInfo const* spell = (*i)->GetSpellInfo();
- if (spell->SpellFamilyName == uint32(SPELLFAMILY_SHAMAN) && spell->SpellFamilyFlags.HasFlag(0, 0x02000000, 0))
+ if (SpellInfo const* totemSpell = sSpellMgr->GetSpellInfo(totem->m_spells[0]))
{
- if ((*i)->GetCasterGUID() != GetGUID())
- continue;
- if (spell->Id == 63283)
- continue;
- aurEffA = (*i);
- break;
+ int32 bp0 = CalculatePctN(totemSpell->Effects[EFFECT_0].CalcValue(), triggerAmount);
+ int32 bp1 = CalculatePctN(totemSpell->Effects[EFFECT_1].CalcValue(), triggerAmount);
+ CastCustomSpell(this, 63283, &bp0, &bp1, NULL, true);
+ return true;
}
}
- if (aurEffA)
- {
- int32 bp0 = 0, bp1 = 0;
- bp0 = CalculatePctN(triggerAmount, aurEffA->GetAmount());
- if (AuraEffect* aurEffB = aurEffA->GetBase()->GetEffect(EFFECT_1))
- bp1 = CalculatePctN(triggerAmount, aurEffB->GetAmount());
- CastCustomSpell(this, 63283, &bp0, &bp1, NULL, true, NULL, triggeredByAura);
- return true;
- }
return false;
}
break;
@@ -7786,17 +7787,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
}
}
}
- // Item - Death Knight T10 Melee 4P Bonus
- if (dummySpell->Id == 70656)
- {
- Player* player = ToPlayer();
- if (!player)
- return false;
-
- for (uint32 i = 0; i < MAX_RUNES; ++i)
- if (player->GetRuneCooldown(i) == 0)
- return false;
- }
break;
}
case SPELLFAMILY_POTION:
@@ -8064,7 +8054,7 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, Sp
*handled = true;
if (victim && victim->HasAura(53601))
{
- int32 bp0 = CalculatePctN(int32(damage / 12), dummySpell->Effects[EFFECT_2]. CalcValue());
+ int32 bp0 = CalculatePctN(int32(damage / 12), dummySpell->Effects[EFFECT_2].CalcValue());
// Item - Paladin T9 Holy 4P Bonus
if (AuraEffect const* aurEff = GetAuraEffect(67191, 0))
AddPctN(bp0, aurEff->GetAmount());
@@ -8724,6 +8714,16 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
trigger_spell_id = 50475;
basepoints0 = CalculatePctN(int32(damage), triggerAmount);
}
+ // Item - Death Knight T10 Melee 4P Bonus
+ else if (auraSpellInfo->Id == 70656)
+ {
+ if (GetTypeId() != TYPEID_PLAYER || getClass() != CLASS_DEATH_KNIGHT)
+ return false;
+
+ for (uint8 i = 0; i < MAX_RUNES; ++i)
+ if (ToPlayer()->GetRuneCooldown(i) == 0)
+ return false;
+ }
break;
}
case SPELLFAMILY_ROGUE:
@@ -10206,7 +10206,7 @@ Unit* Unit::GetFirstControlled() const
// Sequence: charmed, pet, other guardians
Unit* unit = GetCharm();
if (!unit)
- if (uint64 guid = GetUInt64Value(UNIT_FIELD_SUMMON))
+ if (uint64 guid = GetMinionGUID())
unit = ObjectAccessor::GetUnit(*this, guid);
return unit;
@@ -12677,7 +12677,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
{
// Set creature speed rate from CreatureInfo
if (GetTypeId() == TYPEID_UNIT)
- speed *= ToCreature()->GetCreatureTemplate()->speed_walk;
+ speed *= ToCreature()->GetCreatureTemplate()->speed_run; // at this point, MOVE_WALK is never reached
// Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need
// TODO: possible affect only on MOVE_RUN
@@ -12997,8 +12997,7 @@ void Unit::TauntFadeOut(Unit* taunter)
return;
}
- //m_ThreatManager.tauntFadeOut(taunter);
- target = m_ThreatManager.getHostilTarget();
+ target = creature->SelectVictim(); // might have more taunt auras remaining
if (target && target != taunter)
{
@@ -14796,6 +14795,7 @@ void Unit::StopMoving()
return;
Movement::MoveSplineInit init(*this);
+ init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset());
init.SetFacing(GetOrientation());
init.Launch();
}
@@ -17033,7 +17033,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
}
if (IsInMap(caster))
- caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1, target, true, NULL, NULL, origCasterGUID);
+ caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1, target, false, NULL, NULL, origCasterGUID);
else // This can happen during Player::_LoadAuras
{
int32 bp0 = seatId;
@@ -17043,7 +17043,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
else
{
if (IsInMap(caster))
- caster->CastSpell(target, spellEntry, true, NULL, NULL, origCasterGUID);
+ caster->CastSpell(target, spellEntry, false, NULL, NULL, origCasterGUID);
else
Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, NULL, NULL, origCasterGUID);
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index f246f595dec..65a165b40d2 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -737,15 +737,48 @@ enum MovementFlags2
enum SplineFlags
{
- SPLINEFLAG_WALKMODE = 0x00001000,
- SPLINEFLAG_FLYING = 0x00002000,
- SPLINEFLAG_TRANSPORT = 0x00800000,
- SPLINEFLAG_EXIT_VEHICLE = 0x01000000,
+ SPLINEFLAG_NONE = 0x00000000,
+ SPLINEFLAG_FORWARD = 0x00000001,
+ SPLINEFLAG_BACKWARD = 0x00000002,
+ SPLINEFLAG_STRAFE_LEFT = 0x00000004,
+ SPLINEFLAG_STRAFE_RIGHT = 0x00000008,
+ SPLINEFLAG_TURN_LEFT = 0x00000010,
+ SPLINEFLAG_TURN_RIGHT = 0x00000020,
+ SPLINEFLAG_PITCH_UP = 0x00000040,
+ SPLINEFLAG_PITCH_DOWN = 0x00000080,
+ SPLINEFLAG_DONE = 0x00000100,
+ SPLINEFLAG_FALLING = 0x00000200,
+ SPLINEFLAG_NO_SPLINE = 0x00000400,
+ SPLINEFLAG_TRAJECTORY = 0x00000800,
+ SPLINEFLAG_WALK_MODE = 0x00001000,
+ SPLINEFLAG_FLYING = 0x00002000,
+ SPLINEFLAG_KNOCKBACK = 0x00004000,
+ SPLINEFLAG_FINAL_POINT = 0x00008000,
+ SPLINEFLAG_FINAL_TARGET = 0x00010000,
+ SPLINEFLAG_FINAL_FACING = 0x00020000,
+ SPLINEFLAG_CATMULL_ROM = 0x00040000,
+ SPLINEFLAG_CYCLIC = 0x00080000,
+ SPLINEFLAG_ENTER_CYCLE = 0x00100000,
+ SPLINEFLAG_ANIMATION_TIER = 0x00200000,
+ SPLINEFLAG_FROZEN = 0x00400000,
+ SPLINEFLAG_TRANSPORT = 0x00800000,
+ SPLINEFLAG_TRANSPORT_EXIT = 0x01000000,
+ SPLINEFLAG_UNKNOWN7 = 0x02000000,
+ SPLINEFLAG_UNKNOWN8 = 0x04000000,
+ SPLINEFLAG_ORIENTATION_INVERTED = 0x08000000,
+ SPLINEFLAG_USE_PATH_SMOOTHING = 0x10000000,
+ SPLINEFLAG_ANIMATION = 0x20000000,
+ SPLINEFLAG_UNCOMPRESSED_PATH = 0x40000000,
+ SPLINEFLAG_UNKNOWN10 = 0x80000000,
};
enum SplineType
{
- SPLINETYPE_FACING_ANGLE = 4,
+ SPLINETYPE_NORMAL = 0,
+ SPLINETYPE_STOP = 1,
+ SPLINETYPE_FACING_SPOT = 2,
+ SPLINETYPE_FACING_TARGET = 3,
+ SPLINETYPE_FACING_ANGLE = 4,
};
enum UnitTypeMask
diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp
index c297ce1e792..04bcfdcc375 100755
--- a/src/server/game/Entities/Vehicle/Vehicle.cpp
+++ b/src/server/game/Entities/Vehicle/Vehicle.cpp
@@ -338,7 +338,7 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
}
}
- if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_UNK1))
+ if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING))
unit->AddUnitState(UNIT_STATE_ONVEHICLE);
unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 9dea557f650..df6018faf39 100755
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -2111,9 +2111,9 @@ void ObjectMgr::LoadItemTemplates()
// 118 119 120 121 122 123 124 125
"TotemCategory, socketColor_1, socketContent_1, socketColor_2, socketContent_2, socketColor_3, socketContent_3, socketBonus, "
// 126 127 128 129 130 131 132 133
- "GemProperties, RequiredDisenchantSkill, ArmorDamageModifier, Duration, ItemLimitCategory, HolidayId, ScriptName, DisenchantID, "
+ "GemProperties, RequiredDisenchantSkill, ArmorDamageModifier, duration, ItemLimitCategory, HolidayId, ScriptName, DisenchantID, "
// 134 135 136
- "FoodType, minMoneyLoot, maxMoneyLoot FROM item_template");
+ "FoodType, minMoneyLoot, maxMoneyLoot, flagsCustom FROM item_template");
if (!result)
{
@@ -2230,7 +2230,7 @@ void ObjectMgr::LoadItemTemplates()
itemTemplate.GemProperties = fields[126].GetUInt32();
itemTemplate.RequiredDisenchantSkill = uint32(fields[127].GetInt16());
itemTemplate.ArmorDamageModifier = fields[128].GetFloat();
- itemTemplate.Duration = fields[129].GetInt32();
+ itemTemplate.Duration = fields[129].GetUInt32();
itemTemplate.ItemLimitCategory = uint32(fields[130].GetInt16());
itemTemplate.HolidayId = fields[131].GetUInt32();
itemTemplate.ScriptId = sObjectMgr->GetScriptId(fields[132].GetCString());
@@ -2238,6 +2238,7 @@ void ObjectMgr::LoadItemTemplates()
itemTemplate.FoodType = uint32(fields[134].GetUInt8());
itemTemplate.MinMoneyLoot = fields[135].GetUInt32();
itemTemplate.MaxMoneyLoot = fields[136].GetUInt32();
+ itemTemplate.FlagsCu = fields[137].GetUInt32();
// Checks
@@ -2645,6 +2646,12 @@ void ObjectMgr::LoadItemTemplates()
itemTemplate.HolidayId = 0;
}
+ if (itemTemplate.FlagsCu & ITEM_FLAGS_CU_DURATION_REAL_TIME && !itemTemplate.Duration)
+ {
+ sLog->outErrorDb("Item (Entry %u) has flag ITEM_FLAGS_CU_DURATION_REAL_TIME but it does not have duration limit", entry);
+ itemTemplate.FlagsCu &= ~ITEM_FLAGS_CU_DURATION_REAL_TIME;
+ }
+
++count;
}
while (result->NextRow());
@@ -2731,7 +2738,7 @@ void ObjectMgr::LoadItemSetNames()
if (setEntry->itemId[i])
itemSetItems.insert(setEntry->itemId[i]);
}
-
+
// 0 1 2
QueryResult result = WorldDatabase.Query("SELECT `entry`, `name`, `InventoryType` FROM `item_set_names`");
@@ -6247,74 +6254,54 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
switch (guidhigh)
{
case HIGHGUID_ITEM:
- if (_hiItemGuid >= 0xFFFFFFFE)
- {
- sLog->outError("Item guid overflow!! Can't continue, shutting down server. ");
- World::StopNow(ERROR_EXIT_CODE);
- }
+ {
+ ASSERT(_hiItemGuid < 0xFFFFFFFE && "Item guid overflow!");
return _hiItemGuid++;
+ }
case HIGHGUID_UNIT:
- if (_hiCreatureGuid >= 0x00FFFFFE)
- {
- sLog->outError("Creature guid overflow!! Can't continue, shutting down server. ");
- World::StopNow(ERROR_EXIT_CODE);
- }
+ {
+ ASSERT(_hiCreatureGuid < 0x00FFFFFE && "Creature guid overflow!");
return _hiCreatureGuid++;
+ }
case HIGHGUID_PET:
- if (_hiPetGuid >= 0x00FFFFFE)
- {
- sLog->outError("Pet guid overflow!! Can't continue, shutting down server. ");
- World::StopNow(ERROR_EXIT_CODE);
- }
+ {
+ ASSERT(_hiPetGuid < 0x00FFFFFE && "Pet guid overflow!");
return _hiPetGuid++;
+ }
case HIGHGUID_VEHICLE:
- if (_hiVehicleGuid >= 0x00FFFFFF)
- {
- sLog->outError("Vehicle guid overflow!! Can't continue, shutting down server. ");
- World::StopNow(ERROR_EXIT_CODE);
- }
+ {
+ ASSERT(_hiVehicleGuid < 0x00FFFFFF && "Vehicle guid overflow!");
return _hiVehicleGuid++;
+ }
case HIGHGUID_PLAYER:
- if (_hiCharGuid >= 0xFFFFFFFE)
- {
- sLog->outError("Players guid overflow!! Can't continue, shutting down server. ");
- World::StopNow(ERROR_EXIT_CODE);
- }
+ {
+ ASSERT(_hiCharGuid < 0xFFFFFFFE && "Player guid overflow!");
return _hiCharGuid++;
+ }
case HIGHGUID_GAMEOBJECT:
- if (_hiGoGuid >= 0x00FFFFFE)
- {
- sLog->outError("Gameobject guid overflow!! Can't continue, shutting down server. ");
- World::StopNow(ERROR_EXIT_CODE);
- }
+ {
+ ASSERT(_hiGoGuid < 0x00FFFFFE && "Gameobject guid overflow!");
return _hiGoGuid++;
+ }
case HIGHGUID_CORPSE:
- if (_hiCorpseGuid >= 0xFFFFFFFE)
- {
- sLog->outError("Corpse guid overflow!! Can't continue, shutting down server. ");
- World::StopNow(ERROR_EXIT_CODE);
- }
+ {
+ ASSERT(_hiCorpseGuid < 0xFFFFFFFE && "Corpse guid overflow!");
return _hiCorpseGuid++;
+ }
case HIGHGUID_DYNAMICOBJECT:
- if (_hiDoGuid >= 0xFFFFFFFE)
- {
- sLog->outError("DynamicObject guid overflow!! Can't continue, shutting down server. ");
- World::StopNow(ERROR_EXIT_CODE);
- }
+ {
+ ASSERT(_hiDoGuid < 0xFFFFFFFE && "DynamicObject guid overflow!");
return _hiDoGuid++;
+ }
case HIGHGUID_MO_TRANSPORT:
- if (_hiMoTransGuid >= 0xFFFFFFFE)
- {
- sLog->outError("MO Transport guid overflow!! Can't continue, shutting down server. ");
- World::StopNow(ERROR_EXIT_CODE);
- }
+ {
+ ASSERT(_hiMoTransGuid < 0xFFFFFFFE && "MO Transport guid overflow!");
return _hiMoTransGuid++;
+ }
default:
- ASSERT(0);
+ ASSERT(false && "ObjectMgr::GenerateLowGuid - Unknown HIGHGUID type");
+ return 0;
}
-
- ASSERT(0);
- return 0;
}
void ObjectMgr::LoadGameObjectLocales()
diff --git a/src/server/game/Handlers/AuthHandler.cpp b/src/server/game/Handlers/AuthHandler.cpp
index 9a3e756dda3..49027bdf497 100755
--- a/src/server/game/Handlers/AuthHandler.cpp
+++ b/src/server/game/Handlers/AuthHandler.cpp
@@ -31,7 +31,7 @@ void WorldSession::SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos)
if (!shortForm)
{
packet << uint32(queuePos); // Queue position
- packet << uint8(0); // Unk 3.3.0
+ packet << uint8(0); // Realm has a free character migration - bool
}
SendPacket(&packet);
diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp
index d1277d154cc..298c742fc3a 100755
--- a/src/server/game/Handlers/CalendarHandler.cpp
+++ b/src/server/game/Handlers/CalendarHandler.cpp
@@ -20,7 +20,7 @@
----- Opcodes Not Used yet -----
SMSG_CALENDAR_CLEAR_PENDING_ACTION SendCalendarClearPendingAction()
-SMSG_CALENDAR_RAID_LOCKOUT_UPDATED SendCalendarRaidLockoutUpdated(InstanceSave const* save) <--- Structure unknown, using LOCKOUT_ADDED
+SMSG_CALENDAR_RAID_LOCKOUT_UPDATED SendCalendarRaidLockoutUpdated(InstanceSave const* save)
----- Opcodes without Sniffs -----
SMSG_CALENDAR_FILTER_GUILD [ for (... uint32(count) { packguid(???), uint8(???) } ]
@@ -74,7 +74,11 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/)
else
{
sLog->outError("SMSG_CALENDAR_SEND_CALENDAR: No Invite found with id [" UI64FMTD "]", *it);
- data << uint64(0) << uint64(0) << uint8(0) << uint8(0);
+ data << uint64(0);
+ data << uint64(0);
+ data << uint8(0);
+ data << uint8(0);
+ data << uint8(0);
data.appendPackGUID(0);
}
}
@@ -96,8 +100,12 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/)
else
{
sLog->outError("SMSG_CALENDAR_SEND_CALENDAR: No Event found with id [" UI64FMTD "]", *it);
- data << uint64(0) << uint8(0) << uint32(0)
- << uint32(0) << uint32(0) << uint32(0);
+ data << uint64(0);
+ data << uint8(0);
+ data << uint32(0);
+ data << uint32(0);
+ data << uint32(0);
+ data << uint32(0);
data.appendPackGUID(0);
}
}
@@ -835,26 +843,6 @@ void WorldSession::SendCalendarClearPendingAction()
SendPacket(&data);
}
-void WorldSession::SendCalendarRaidLockoutUpdated(InstanceSave const* save)
-{
- if (!save)
- return;
-
- uint64 guid = _player->GetGUID();
- sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_RAID_LOCKOUT_UPDATED [" UI64FMTD
- "] Map: %u, Difficulty %u", guid, save->GetMapId(), save->GetDifficulty());
-
- time_t cur_time = time_t(time(NULL));
-
- WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, 4 + 4 + 4 + 4 + 8);
- data << secsToTimeBitFields(cur_time);
- data << uint32(save->GetMapId());
- data << uint32(save->GetDifficulty());
- data << uint32(save->GetResetTime() - cur_time);
- data << uint64(save->GetInstanceId());
- SendPacket(&data);
-}
-
void WorldSession::SendCalendarCommandResult(CalendarError err, char const* param /*= NULL*/)
{
uint64 guid = _player->GetGUID();
@@ -898,3 +886,23 @@ void WorldSession::SendCalendarRaidLockout(InstanceSave const* save, bool add)
data << uint64(save->GetInstanceId());
SendPacket(&data);
}
+
+void WorldSession::SendCalendarRaidLockoutUpdated(InstanceSave const* save)
+{
+ if (!save)
+ return;
+
+ uint64 guid = _player->GetGUID();
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_RAID_LOCKOUT_UPDATED [" UI64FMTD
+ "] Map: %u, Difficulty %u", guid, save->GetMapId(), save->GetDifficulty());
+
+ time_t cur_time = time_t(time(NULL));
+
+ WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, 4 + 4 + 4 + 4 + 8);
+ data << secsToTimeBitFields(cur_time);
+ data << uint32(save->GetMapId());
+ data << uint32(save->GetDifficulty());
+ data << uint32(0); // Amount of seconds that has changed to the reset time
+ data << uint32(save->GetResetTime() - cur_time);
+ SendPacket(&data);
+}
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index d537fc5b4aa..a569c914be0 100755
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -423,7 +423,7 @@ void WorldSession::HandleItemQuerySingleOpcode(WorldPacket & recv_data)
data << pProto->GemProperties;
data << pProto->RequiredDisenchantSkill;
data << pProto->ArmorDamageModifier;
- data << uint32(abs(pProto->Duration)); // added in 2.4.2.8209, duration (seconds)
+ data << pProto->Duration; // added in 2.4.2.8209, duration (seconds)
data << pProto->ItemLimitCategory; // WotLK, ItemLimitCategory
data << pProto->HolidayId; // Holiday.dbc?
SendPacket(&data);
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 35872f8c63f..11f0857ca2b 100755
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -51,6 +51,7 @@
#include "GameObjectAI.h"
#include "Group.h"
#include "AccountMgr.h"
+#include "Spell.h"
void WorldSession::HandleRepopRequestOpcode(WorldPacket & recv_data)
{
@@ -429,6 +430,10 @@ void WorldSession::HandleLogoutCancelOpcode(WorldPacket & /*recv_data*/)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_LOGOUT_CANCEL Message");
+ // Player have already logged out serverside, too late to cancel
+ if (!GetPlayer())
+ return;
+
LogoutRequest(0);
WorldPacket data(SMSG_LOGOUT_CANCEL_ACK, 0);
@@ -489,7 +494,7 @@ void WorldSession::HandleZoneUpdateOpcode(WorldPacket & recv_data)
uint32 newZone;
recv_data >> newZone;
- sLog->outDetail("WORLD: Recvd ZONE_UPDATE: %u", newZone);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd ZONE_UPDATE: %u", newZone);
// use server size data
uint32 newzone, newarea;
@@ -725,7 +730,7 @@ void WorldSession::HandleBugOpcode(WorldPacket & recv_data)
void WorldSession::HandleReclaimCorpseOpcode(WorldPacket &recv_data)
{
- sLog->outDetail("WORLD: Received CMSG_RECLAIM_CORPSE");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RECLAIM_CORPSE");
uint64 guid;
recv_data >> guid;
@@ -762,7 +767,7 @@ void WorldSession::HandleReclaimCorpseOpcode(WorldPacket &recv_data)
void WorldSession::HandleResurrectResponseOpcode(WorldPacket & recv_data)
{
- sLog->outDetail("WORLD: Received CMSG_RESURRECT_RESPONSE");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RESURRECT_RESPONSE");
uint64 guid;
uint8 status;
@@ -933,7 +938,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recv_data)
void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)
{
- sLog->outDetail("WORLD: Received CMSG_UPDATE_ACCOUNT_DATA");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_UPDATE_ACCOUNT_DATA");
uint32 type, timestamp, decompressedSize;
recv_data >> type >> timestamp >> decompressedSize;
@@ -988,7 +993,7 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)
void WorldSession::HandleRequestAccountData(WorldPacket& recv_data)
{
- sLog->outDetail("WORLD: Received CMSG_REQUEST_ACCOUNT_DATA");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_ACCOUNT_DATA");
uint32 type;
recv_data >> type;
@@ -1067,18 +1072,18 @@ void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data)
void WorldSession::HandleCompleteCinematic(WorldPacket & /*recv_data*/)
{
- sLog->outStaticDebug("WORLD: Player is watching cinema");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_COMPLETE_CINEMATIC");
}
void WorldSession::HandleNextCinematicCamera(WorldPacket & /*recv_data*/)
{
- sLog->outStaticDebug("WORLD: Which movie to play");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_NEXT_CINEMATIC_CAMERA");
}
void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket & recv_data)
{
/* WorldSession::Update(getMSTime());*/
- sLog->outStaticDebug("WORLD: Time Lag/Synchronization Resent/Update");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_MOVE_TIME_SKIPPED");
uint64 guid;
recv_data.readPackGUID(guid);
@@ -1100,7 +1105,7 @@ void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket & recv_data)
void WorldSession::HandleFeatherFallAck(WorldPacket &recv_data)
{
- sLog->outStaticDebug("WORLD: CMSG_MOVE_FEATHER_FALL_ACK");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_MOVE_FEATHER_FALL_ACK");
// no used
recv_data.rfinish(); // prevent warnings spam
@@ -1188,13 +1193,17 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recv_data)
{
uint64 guid;
recv_data >> guid;
- sLog->outStaticDebug("Inspected guid is " UI64FMTD, guid);
+
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_INSPECT");
_player->SetSelection(guid);
Player* player = ObjectAccessor::FindPlayer(guid);
- if (!player) // wrong player
+ if (!player)
+ {
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_INSPECT: No player found from GUID: " UI64FMTD, guid);
return;
+ }
uint32 talent_points = 0x47;
uint32 guid_size = player->GetPackGUID().wpos();
@@ -1225,7 +1234,7 @@ void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recv_data)
if (!player)
{
- sLog->outError("InspectHonorStats: WTF, player not found...");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_INSPECT_HONOR_STATS: No player found from GUID: " UI64FMTD, guid);
return;
}
@@ -1241,10 +1250,6 @@ void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recv_data)
void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data)
{
- // write in client console: worldport 469 452 6454 2536 180 or /console worldport 469 452 6454 2536 180
- // Received opcode CMSG_WORLD_TELEPORT
- // Time is ***, map=469, x=452.000000, y=6454.000000, z=2536.000000, orient=3.141593
-
uint32 time;
uint32 mapid;
float PositionX;
@@ -1259,20 +1264,20 @@ void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data)
recv_data >> PositionZ;
recv_data >> Orientation; // o (3.141593 = 180 degrees)
- //sLog->outDebug("Received opcode CMSG_WORLD_TELEPORT");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_WORLD_TELEPORT");
+
if (GetPlayer()->isInFlight())
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "Player '%s' (GUID: %u) in flight, ignore worldport command.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
return;
}
- sLog->outStaticDebug("Time %u sec, map=%u, x=%f, y=%f, z=%f, orient=%f", time/1000, mapid, PositionX, PositionY, PositionZ, Orientation);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_WORLD_TELEPORT: Player = %s, Time = %u, map = %u, x = %f, y = %f, z = %f, o = %f", GetPlayer()->GetName(), time, mapid, PositionX, PositionY, PositionZ, Orientation);
if (AccountMgr::IsAdminAccount(GetSecurity()))
GetPlayer()->TeleportTo(mapid, PositionX, PositionY, PositionZ, Orientation);
else
SendNotification(LANG_YOU_NOT_HAVE_PERMISSION);
- sLog->outDebug(LOG_FILTER_NETWORKIO, "Received worldport command from player %s", GetPlayer()->GetName());
}
void WorldSession::HandleWhoisOpcode(WorldPacket& recv_data)
@@ -1714,3 +1719,47 @@ void WorldSession::HandleInstanceLockResponse(WorldPacket& recvPacket)
_player->SetPendingBind(0, 0);
}
+
+void WorldSession::HandleUpdateMissileTrajectory(WorldPacket& recvPacket)
+{
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_UPDATE_MISSILE_TRAJECTORY");
+
+ uint64 guid;
+ uint32 spellId;
+ float elevation, speed;
+ float curX, curY, curZ;
+ float targetX, targetY, targetZ;
+ uint8 moveStop;
+
+ recvPacket >> guid >> spellId >> elevation >> speed;
+ recvPacket >> curX >> curY >> curZ;
+ recvPacket >> targetX >> targetY >> targetZ;
+ recvPacket >> moveStop;
+
+ Unit* caster = ObjectAccessor::GetUnit(*_player, guid);
+ Spell* spell = caster ? caster->GetCurrentSpell(CURRENT_GENERIC_SPELL) : NULL;
+ if (!spell || spell->m_spellInfo->Id != spellId || !spell->m_targets.HasDst() || !spell->m_targets.HasSrc())
+ {
+ recvPacket.rfinish();
+ return;
+ }
+
+ Position pos = *spell->m_targets.GetSrcPos();
+ pos.Relocate(curX, curY, curZ);
+ spell->m_targets.ModSrc(pos);
+
+ pos = *spell->m_targets.GetDstPos();
+ pos.Relocate(targetX, targetY, targetZ);
+ spell->m_targets.ModDst(pos);
+
+ spell->m_targets.SetElevation(elevation);
+ spell->m_targets.SetSpeed(speed);
+
+ if (moveStop)
+ {
+ uint32 opcode;
+ recvPacket >> opcode;
+ recvPacket.SetOpcode(opcode);
+ HandleMovementOpcodes(recvPacket);
+ }
+}
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index b3d663e1850..ff9030f04d5 100755
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -64,10 +64,9 @@ void WorldSession::HandleMoveWorldportAckOpcode()
GetPlayer()->m_InstanceValid = true;
Map* oldMap = GetPlayer()->GetMap();
- ASSERT(oldMap);
if (GetPlayer()->IsInWorld())
{
- sLog->outCrash("Player (Name %s) is still in world when teleported from map %u to new map %u", GetPlayer()->GetName(), oldMap->GetId(), loc.GetMapId());
+ sLog->outError("Player (Name %s) is still in world when teleported from map %u to new map %u", GetPlayer()->GetName(), oldMap->GetId(), loc.GetMapId());
oldMap->RemovePlayerFromMap(GetPlayer(), false);
}
@@ -200,8 +199,7 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data)
sLog->outStaticDebug("Guid " UI64FMTD, guid);
sLog->outStaticDebug("Flags %u, time %u", flags, time/IN_MILLISECONDS);
- Unit* mover = _player->m_mover;
- Player* plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL;
+ Player* plMover = _player->m_mover->ToPlayer();
if (!plMover || !plMover->IsBeingTeleportedNear())
return;
@@ -240,33 +238,33 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data)
GetPlayer()->ProcessDelayedOperations();
}
-void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data)
+void WorldSession::HandleMovementOpcodes(WorldPacket & recvData)
{
- uint16 opcode = recv_data.GetOpcode();
+ uint16 opcode = recvData.GetOpcode();
Unit* mover = _player->m_mover;
- ASSERT(mover != NULL); // there must always be a mover
+ ASSERT(mover != NULL); // there must always be a mover
- Player* plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL;
+ Player* plrMover = mover->ToPlayer();
// ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
- if (plMover && plMover->IsBeingTeleported())
+ if (plrMover && plrMover->IsBeingTeleported())
{
- recv_data.rfinish(); // prevent warnings spam
+ recvData.rfinish(); // prevent warnings spam
return;
}
/* extract packet */
uint64 guid;
- recv_data.readPackGUID(guid);
+ recvData.readPackGUID(guid);
MovementInfo movementInfo;
movementInfo.guid = guid;
- ReadMovementInfo(recv_data, &movementInfo);
+ ReadMovementInfo(recvData, &movementInfo);
- recv_data.rfinish(); // prevent warnings spam
+ recvData.rfinish(); // prevent warnings spam
// prevent tampered movement data
if (guid != mover->GetGUID())
@@ -274,7 +272,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data)
if (!movementInfo.pos.IsPositionValid())
{
- recv_data.rfinish(); // prevent warnings spam
+ recvData.rfinish(); // prevent warnings spam
return;
}
@@ -285,28 +283,54 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data)
// (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
if (movementInfo.t_pos.GetPositionX() > 50 || movementInfo.t_pos.GetPositionY() > 50 || movementInfo.t_pos.GetPositionZ() > 50)
{
- recv_data.rfinish(); // prevent warnings spam
+ recvData.rfinish(); // prevent warnings spam
return;
}
if (!Trinity::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.t_pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.t_pos.GetPositionY(),
movementInfo.pos.GetPositionZ() + movementInfo.t_pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.t_pos.GetOrientation()))
{
- recv_data.rfinish(); // prevent warnings spam
+ recvData.rfinish(); // prevent warnings spam
return;
}
// if we boarded a transport, add us to it
- if (plMover && !plMover->GetTransport())
+ if (plrMover)
{
- // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list
- for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
+ if (!plrMover->GetTransport())
+ {
+ // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list
+ for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
+ {
+ if ((*iter)->GetGUID() == movementInfo.t_guid)
+ {
+ plrMover->m_transport = *iter;
+ (*iter)->AddPassenger(plrMover);
+ break;
+ }
+ }
+ }
+ else if (plrMover->GetTransport()->GetGUID() != movementInfo.t_guid)
{
- if ((*iter)->GetGUID() == movementInfo.t_guid)
+ bool foundNewTransport = false;
+ plrMover->m_transport->RemovePassenger(plrMover);
+ for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
+ {
+ if ((*iter)->GetGUID() == movementInfo.t_guid)
+ {
+ foundNewTransport = true;
+ plrMover->m_transport = *iter;
+ (*iter)->AddPassenger(plrMover);
+ break;
+ }
+ }
+
+ if (!foundNewTransport)
{
- plMover->m_transport = (*iter);
- (*iter)->AddPassenger(plMover);
- break;
+ plrMover->m_transport = NULL;
+ movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
+ movementInfo.t_time = 0;
+ movementInfo.t_seat = -1;
}
}
}
@@ -318,29 +342,29 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data)
movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT;
}
}
- else if (plMover && plMover->GetTransport()) // if we were on a transport, leave
+ else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave
{
- plMover->m_transport->RemovePassenger(plMover);
- plMover->m_transport = NULL;
+ plrMover->m_transport->RemovePassenger(plrMover);
+ plrMover->m_transport = NULL;
movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
movementInfo.t_time = 0;
movementInfo.t_seat = -1;
}
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
- if (opcode == MSG_MOVE_FALL_LAND && plMover && !plMover->isInFlight())
- plMover->HandleFall(movementInfo);
+ if (opcode == MSG_MOVE_FALL_LAND && plrMover && !plrMover->isInFlight())
+ plrMover->HandleFall(movementInfo);
- if (plMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plMover->IsInWater())
+ if (plrMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plrMover->IsInWater())
{
// now client not include swimming flag in case jumping under water
- plMover->SetInWater(!plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ()));
+ plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ()));
}
/*----------------------*/
/* process position-change */
- WorldPacket data(opcode, recv_data.size());
+ WorldPacket data(opcode, recvData.size());
movementInfo.time = getMSTime();
movementInfo.guid = mover->GetGUID();
WriteMovementInfo(&data, &movementInfo);
@@ -357,27 +381,25 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data)
mover->UpdatePosition(movementInfo.pos);
- if (plMover) // nothing is charmed, or player charmed
+ if (plrMover) // nothing is charmed, or player charmed
{
- plMover->UpdateFallInformationIfNeed(movementInfo, opcode);
+ plrMover->UpdateFallInformationIfNeed(movementInfo, opcode);
if (movementInfo.pos.GetPositionZ() < -500.0f)
{
- if (!(plMover->InBattleground()
- && plMover->GetBattleground()
- && plMover->GetBattleground()->HandlePlayerUnderMap(_player)))
+ if (!(plrMover->GetBattleground() && plrMover->GetBattleground()->HandlePlayerUnderMap(_player)))
{
// NOTE: this is actually called many times while falling
// even after the player has been teleported away
// TODO: discard movement packets after the player is rooted
- if (plMover->isAlive())
+ if (plrMover->isAlive())
{
- plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
+ plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
// player can be alive if GM/etc
// change the death state to CORPSE to prevent the death timer from
// starting in the next player update
- if (!plMover->isAlive())
- plMover->KillPlayer();
+ if (!plrMover->isAlive())
+ plrMover->KillPlayer();
}
}
}
diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp
index e54bee96b8b..321c0ada247 100755
--- a/src/server/game/Handlers/PetHandler.cpp
+++ b/src/server/game/Handlers/PetHandler.cpp
@@ -339,9 +339,11 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid
if (unit_target2->GetTypeId() == TYPEID_PLAYER)
pet->SendUpdateToPlayer((Player*)unit_target2);
}
+
if (Unit* powner = pet->GetCharmerOrOwner())
if (powner->GetTypeId() == TYPEID_PLAYER)
- pet->SendUpdateToPlayer(powner->ToPlayer());
+ pet->SendUpdateToPlayer(powner->ToPlayer());
+
result = SPELL_CAST_OK;
}
@@ -741,7 +743,7 @@ void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket)
void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
{
- sLog->outDetail("WORLD: CMSG_PET_CAST_SPELL");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_PET_CAST_SPELL");
uint64 guid;
uint8 castCount;
diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
index 628cdbbdd5e..4fb90bed10b 100755
--- a/src/server/game/Handlers/QueryHandler.cpp
+++ b/src/server/game/Handlers/QueryHandler.cpp
@@ -113,7 +113,7 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket & recv_data)
ObjectMgr::GetLocaleString(cl->SubName, loc_idx, SubName);
}
}
- sLog->outDetail("WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), entry);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), entry);
// guess size
WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 100);
data << uint32(entry); // creature entry
@@ -179,7 +179,7 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recv_data)
ObjectMgr::GetLocaleString(gl->CastBarCaption, loc_idx, CastBarCaption);
}
}
- sLog->outDetail("WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name.c_str(), entry);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name.c_str(), entry);
WorldPacket data (SMSG_GAMEOBJECT_QUERY_RESPONSE, 150);
data << uint32(entry);
data << uint32(info->type);
@@ -209,7 +209,7 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recv_data)
void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/)
{
- sLog->outDetail("WORLD: Received MSG_CORPSE_QUERY");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_CORPSE_QUERY");
Corpse* corpse = GetPlayer()->GetCorpse();
@@ -264,7 +264,7 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPacket & recv_data)
uint64 guid;
recv_data >> textID;
- sLog->outDetail("WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID);
recv_data >> guid;
GetPlayer()->SetSelection(guid);
@@ -344,7 +344,7 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPacket & recv_data)
/// Only _static_ data is sent in this packet !!!
void WorldSession::HandlePageTextQueryOpcode(WorldPacket & recv_data)
{
- sLog->outDetail("WORLD: Received CMSG_PAGE_TEXT_QUERY");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_PAGE_TEXT_QUERY");
uint32 pageID;
recv_data >> pageID;
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index b2d52c85467..c02bb43a353 100755
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -99,7 +99,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
return;
}
- sLog->outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, castCount: %u, spellId: %u, Item: %u, glyphIndex: %u, data length = %i", bagIndex, slot, castCount, spellId, pItem->GetEntry(), glyphIndex, (uint32)recvPacket.size());
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, castCount: %u, spellId: %u, Item: %u, glyphIndex: %u, data length = %i", bagIndex, slot, castCount, spellId, pItem->GetEntry(), glyphIndex, (uint32)recvPacket.size());
ItemTemplate const* proto = pItem->GetTemplate();
if (!proto)
@@ -175,7 +175,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
{
- sLog->outDetail("WORLD: CMSG_OPEN_ITEM packet, data length = %i", (uint32)recvPacket.size());
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_OPEN_ITEM packet, data length = %i", (uint32)recvPacket.size());
Player* pUser = _player;
@@ -650,18 +650,30 @@ void WorldSession::HandleUpdateProjectilePosition(WorldPacket& recvPacket)
uint8 castCount;
float x, y, z; // Position of missile hit
- recvPacket.readPackGUID(casterGuid);
+ recvPacket >> casterGuid;
recvPacket >> spellId;
recvPacket >> castCount;
recvPacket >> x;
recvPacket >> y;
recvPacket >> z;
+ Unit* caster = ObjectAccessor::GetUnit(*_player, casterGuid);
+ if (!caster)
+ return;
+
+ Spell* spell = caster->FindCurrentSpellBySpellId(spellId);
+ if (!spell || !spell->m_targets.HasDst())
+ return;
+
+ Position pos = *spell->m_targets.GetDstPos();
+ pos.Relocate(x, y, z);
+ spell->m_targets.ModDst(pos);
+
WorldPacket data(SMSG_SET_PROJECTILE_POSITION, 21);
data << uint64(casterGuid);
data << uint8(castCount);
data << float(x);
data << float(y);
data << float(z);
- SendPacket(&data);
+ caster->SendMessageToSet(&data, true);
}
diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp
index dc26aaa42ca..9d7fa7da396 100755
--- a/src/server/game/Handlers/TradeHandler.cpp
+++ b/src/server/game/Handlers/TradeHandler.cpp
@@ -531,7 +531,7 @@ void WorldSession::HandleBeginTradeOpcode(WorldPacket& /*recvPacket*/)
void WorldSession::SendCancelTrade()
{
- if (m_playerRecentlyLogout)
+ if (PlayerRecentlyLoggedOut() || PlayerLogout())
return;
SendTradeStatus(TRADE_STATUS_TRADE_CANCELED);
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index 75065158ef6..a5ad46c9ec4 100755
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -356,18 +356,9 @@ bool LootItem::AllowedForPlayer(Player const* player) const
if ((pProto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && player->GetTeam() != ALLIANCE)
return false;
- if (needs_quest)
- {
- // Checking quests for quest-only drop (check only quests requirements in this case)
- if (!player->HasQuestForItem(itemid))
- return false;
- }
- else
- {
- // Not quest only drop (check quest starting items for already accepted non-repeatable quests)
- if (pProto->StartQuest && player->GetQuestStatus(pProto->StartQuest) != QUEST_STATUS_NONE && !player->HasQuestForItem(itemid))
- return false;
- }
+ // check quest requirements
+ if (!(pProto->FlagsCu & ITEM_FLAGS_CU_IGNORE_QUEST_STATUS) && ((needs_quest || (pProto->StartQuest && player->GetQuestStatus(pProto->StartQuest) != QUEST_STATUS_NONE)) && !player->HasQuestForItem(itemid)))
+ return false;
return true;
}
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index c0e1eb842ae..bc0570bb73b 100755
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -298,7 +298,7 @@ void MotionMaster::MovePoint(uint32 id, float x, float y, float z)
}
}
-void MotionMaster::MoveLand(uint32 id, Position const& pos, float speed)
+void MotionMaster::MoveLand(uint32 id, Position const& pos)
{
float x, y, z;
pos.GetPosition(x, y, z);
@@ -307,13 +307,12 @@ void MotionMaster::MoveLand(uint32 id, Position const& pos, float speed)
Movement::MoveSplineInit init(*_owner);
init.MoveTo(x,y,z);
- init.SetVelocity(speed);
init.SetAnimation(Movement::ToGround);
init.Launch();
Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE);
}
-void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, float speed)
+void MotionMaster::MoveTakeoff(uint32 id, Position const& pos)
{
float x, y, z;
pos.GetPosition(x, y, z);
@@ -322,7 +321,6 @@ void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, float speed)
Movement::MoveSplineInit init(*_owner);
init.MoveTo(x,y,z);
- init.SetVelocity(speed);
init.SetAnimation(Movement::ToFly);
init.Launch();
Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE);
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index d6144bfcc3a..727f626cdea 100755
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -157,8 +157,8 @@ class MotionMaster //: private std::stack<MovementGenerator *>
void MovePoint(uint32 id, float x, float y, float z);
// These two movement types should only be used with creatures having landing/takeoff animations
- void MoveLand(uint32 id, Position const& pos, float speed);
- void MoveTakeoff(uint32 id, Position const& pos, float speed);
+ void MoveLand(uint32 id, Position const& pos);
+ void MoveTakeoff(uint32 id, Position const& pos);
void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE);
void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ);
diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp
index 91b4ff08250..b1c25aedfd7 100644
--- a/src/server/game/Movement/Spline/MoveSpline.cpp
+++ b/src/server/game/Movement/Spline/MoveSpline.cpp
@@ -203,7 +203,7 @@ bool MoveSplineInitArgs::Validate() const
return false;\
}
CHECK(path.size() > 1);
- CHECK(velocity > 0.f);
+ CHECK(velocity > 0.1f);
CHECK(time_perc >= 0.f && time_perc <= 1.f);
//CHECK(_checkPathBounds());
return true;
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp
index e586cb4f4f9..c5f959e2f1d 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.cpp
+++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp
@@ -20,6 +20,8 @@
#include "MoveSpline.h"
#include "MovementPacketBuilder.h"
#include "Unit.h"
+#include "Transport.h"
+#include "Vehicle.h"
namespace Movement
{
@@ -58,17 +60,25 @@ namespace Movement
{
MoveSpline& move_spline = *unit.movespline;
- Location real_position(unit.GetPositionX(),unit.GetPositionY(),unit.GetPositionZMinusOffset(),unit.GetOrientation());
- // there is a big chane that current position is unknown if current state is not finalized, need compute it
+ bool transport = false;
+ Location real_position(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZMinusOffset(), unit.GetOrientation());
+ if (unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ {
+ transport = true;
+ real_position.x = unit.GetTransOffsetX();
+ real_position.y = unit.GetTransOffsetY();
+ real_position.z = unit.GetTransOffsetZ();
+ real_position.orientation = unit.GetTransOffsetO();
+ }
+
+ // there is a big chance that current position is unknown if current state is not finalized, need compute it
// this also allows calculate spline position and update map position in much greater intervals
if (!move_spline.Finalized())
real_position = move_spline.ComputePosition();
+ // should i do the things that user should do? - no.
if (args.path.empty())
- {
- // should i do the things that user should do?
- MoveTo(real_position);
- }
+ return;
// corrent first vertex
args.path[0] = real_position;
@@ -82,7 +92,7 @@ namespace Movement
moveFlags |= (MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD);
- if (args.velocity == 0.f)
+ if (!args.HasVelocity)
args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags));
if (!args.Validate())
@@ -94,8 +104,20 @@ namespace Movement
unit.m_movementInfo.SetMovementFlags((MovementFlags)moveFlags);
move_spline.Initialize(args);
- WorldPacket data(SMSG_MONSTER_MOVE, 64);
+ WorldPacket data(!transport ? SMSG_MONSTER_MOVE : SMSG_MONSTER_MOVE_TRANSPORT, 64);
data.append(unit.GetPackGUID());
+ if (transport)
+ {
+ if (unit.GetVehicle())
+ data.appendPackGUID(unit.GetVehicleBase()->GetGUID());
+ else if (unit.GetTransport())
+ data.appendPackGUID(unit.GetTransGUID());
+ else
+ data << uint8(0);
+
+ data << int8(unit.GetTransSeat());
+ }
+
PacketBuilder::WriteMonsterMove(move_spline, data);
unit.SendMessageToSet(&data,true);
}
@@ -116,7 +138,44 @@ namespace Movement
void MoveSplineInit::SetFacing(float angle)
{
+ if (unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ {
+ if (Unit* vehicle = unit.GetVehicleBase())
+ angle -= vehicle->GetOrientation();
+ else if (Transport* transport = unit.GetTransport())
+ angle -= transport->GetOrientation();
+ }
+
args.facing.angle = G3D::wrap(angle, 0.f, (float)G3D::twoPi());
args.flags.EnableFacingAngle();
}
+
+ void MoveSplineInit::MoveTo(Vector3 const& dest)
+ {
+ args.path_Idx_offset = 0;
+ args.path.resize(2);
+ TransportPathTransform transform(unit);
+ args.path[1] = transform(dest);
+ }
+
+ Vector3 TransportPathTransform::operator()(Vector3 input)
+ {
+ if (_owner.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ {
+ if (Unit* vehicle = _owner.GetVehicleBase())
+ {
+ input.x -= vehicle->GetPositionX();
+ input.y -= vehicle->GetPositionY();
+ input.z -= vehicle->GetPositionZMinusOffset();
+ }
+ else if (Transport* transport = _owner.GetTransport())
+ {
+ float unused = 0.0f;
+ transport->CalculatePassengerOffset(input.x, input.y, input.z, unused);
+ }
+ }
+
+ return input;
+ }
+
}
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h
index 7ef6cd7a120..786324e3f77 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.h
+++ b/src/server/game/Movement/Spline/MoveSplineInit.h
@@ -33,6 +33,17 @@ namespace Movement
FlyToGround = 3, // 463 = FlyToGround
};
+ // Transforms coordinates from global to transport offsets
+ class TransportPathTransform
+ {
+ public:
+ TransportPathTransform(Unit& owner) : _owner(owner) { }
+ Vector3 operator()(Vector3 input);
+
+ private:
+ Unit& _owner;
+ };
+
/* Initializes and launches spline movement
*/
class MoveSplineInit
@@ -123,14 +134,15 @@ namespace Movement
inline void MoveSplineInit::SetSmooth() { args.flags.EnableCatmullRom();}
inline void MoveSplineInit::SetCyclic() { args.flags.cyclic = true;}
inline void MoveSplineInit::SetFall() { args.flags.EnableFalling();}
- inline void MoveSplineInit::SetVelocity(float vel){ args.velocity = vel;}
+ inline void MoveSplineInit::SetVelocity(float vel) { args.velocity = vel; args.HasVelocity = true; }
inline void MoveSplineInit::SetOrientationInversed() { args.flags.orientationInversed = true;}
inline void MoveSplineInit::SetOrientationFixed(bool enable) { args.flags.orientationFixed = enable;}
inline void MoveSplineInit::MovebyPath(const PointsArray& controls, int32 path_offset)
{
args.path_Idx_offset = path_offset;
- args.path.assign(controls.begin(),controls.end());
+ args.path.resize(controls.size());
+ std::transform(controls.begin(), controls.end(), args.path.begin(), TransportPathTransform(unit));
}
inline void MoveSplineInit::MoveTo(float x, float y, float z)
@@ -139,13 +151,6 @@ namespace Movement
MoveTo(v);
}
- inline void MoveSplineInit::MoveTo(const Vector3& dest)
- {
- args.path_Idx_offset = 0;
- args.path.resize(2);
- args.path[1] = dest;
- }
-
inline void MoveSplineInit::SetParabolic(float amplitude, float time_shift)
{
args.time_perc = time_shift;
@@ -161,9 +166,11 @@ namespace Movement
inline void MoveSplineInit::SetFacing(Vector3 const& spot)
{
- args.facing.f.x = spot.x;
- args.facing.f.y = spot.y;
- args.facing.f.z = spot.z;
+ TransportPathTransform transform(unit);
+ Vector3 finalSpot = transform(spot);
+ args.facing.f.x = finalSpot.x;
+ args.facing.f.y = finalSpot.y;
+ args.facing.f.z = finalSpot.z;
args.flags.EnableFacingPoint();
}
}
diff --git a/src/server/game/Movement/Spline/MoveSplineInitArgs.h b/src/server/game/Movement/Spline/MoveSplineInitArgs.h
index 26fbbdd0fcc..74409c9562b 100644
--- a/src/server/game/Movement/Spline/MoveSplineInitArgs.h
+++ b/src/server/game/Movement/Spline/MoveSplineInitArgs.h
@@ -42,7 +42,7 @@ namespace Movement
struct MoveSplineInitArgs
{
MoveSplineInitArgs(size_t path_capacity = 16) : path_Idx_offset(0),
- velocity(0.f), parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f)
+ velocity(0.f), parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f), HasVelocity(false)
{
path.reserve(path_capacity);
}
@@ -56,6 +56,7 @@ namespace Movement
float time_perc;
uint32 splineId;
float initialOrientation;
+ bool HasVelocity;
/** Returns true to show that the arguments were configured correctly and MoveSpline initialization will succeed. */
bool Validate() const;
diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
index 0260767dbe2..16f06a25058 100644
--- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
+++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
@@ -44,20 +44,8 @@ namespace Movement
void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, WorldPacket& data)
{
MoveSplineFlag splineflags = move_spline.splineflags;
- /*if (unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
- {
- data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT);
- if (unit->GetVehicle())
- data << unit->GetVehicle()->GetBase()->GetPackGUID();
- else if (unit->GetTransport())
- data << unit->GetTransport()->GetPackGUID();
- else
- data << uint64(0);
-
- data << int8(unit->GetTransSeat());
- }*/
- data << uint8(0);
+ data << uint8(0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40)
data << move_spline.spline.getPoint(move_spline.spline.first());
data << move_spline.GetId();
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 517935acbd2..8fb8ea0298b 100755
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -104,7 +104,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x04B*/ { "CMSG_LOGOUT_REQUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLogoutRequestOpcode },
/*0x04C*/ { "SMSG_LOGOUT_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
/*0x04D*/ { "SMSG_LOGOUT_COMPLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x04E*/ { "CMSG_LOGOUT_CANCEL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLogoutCancelOpcode },
+ /*0x04E*/ { "CMSG_LOGOUT_CANCEL", STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, PROCESS_THREADUNSAFE, &WorldSession::HandleLogoutCancelOpcode },
/*0x04F*/ { "SMSG_LOGOUT_CANCEL_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
/*0x050*/ { "CMSG_NAME_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNameQueryOpcode },
/*0x051*/ { "SMSG_NAME_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
@@ -310,7 +310,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x119*/ { "CMSG_IGNORE_TRADE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleIgnoreTradeOpcode },
/*0x11A*/ { "CMSG_ACCEPT_TRADE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptTradeOpcode },
/*0x11B*/ { "CMSG_UNACCEPT_TRADE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnacceptTradeOpcode },
- /*0x11C*/ { "CMSG_CANCEL_TRADE", STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelTradeOpcode},
+ /*0x11C*/ { "CMSG_CANCEL_TRADE", STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelTradeOpcode },
/*0x11D*/ { "CMSG_SET_TRADE_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTradeItemOpcode },
/*0x11E*/ { "CMSG_CLEAR_TRADE_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleClearTradeItemOpcode },
/*0x11F*/ { "CMSG_SET_TRADE_GOLD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTradeGoldOpcode },
@@ -1148,7 +1148,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x45F*/ { "CMSG_CALENDAR_EVENT_INVITE_NOTES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
/*0x460*/ { "SMSG_CALENDAR_EVENT_INVITE_NOTES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
/*0x461*/ { "SMSG_CALENDAR_EVENT_INVITE_NOTES_ALERT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x462*/ { "CMSG_UPDATE_MISSILE_TRAJECTORY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
+ /*0x462*/ { "CMSG_UPDATE_MISSILE_TRAJECTORY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateMissileTrajectory },
/*0x463*/ { "SMSG_UPDATE_ACCOUNT_DATA_COMPLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
/*0x464*/ { "SMSG_TRIGGER_MOVIE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
/*0x465*/ { "CMSG_COMPLETE_MOVIE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index 3c77ced6741..65e7b3597ce 100755
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -1248,8 +1248,8 @@ enum Opcodes
SMSG_CALENDAR_CLEAR_PENDING_ACTION = 0x4BB,
SMSG_EQUIPMENT_SET_LIST = 0x4BC, // equipment manager list?
CMSG_EQUIPMENT_SET_SAVE = 0x4BD,
- CMSG_UPDATE_PROJECTILE_POSITION = 0x4BE, // uint64 caster, uint32 spellId, uint8 castId, vector3 position
- SMSG_SET_PROJECTILE_POSITION = 0x4BF, // uint64 caster, uint8 castId, vector3 position
+ CMSG_UPDATE_PROJECTILE_POSITION = 0x4BE,
+ SMSG_SET_PROJECTILE_POSITION = 0x4BF,
SMSG_TALENTS_INFO = 0x4C0,
CMSG_LEARN_PREVIEW_TALENTS = 0x4C1,
CMSG_LEARN_PREVIEW_TALENTS_PET = 0x4C2,
@@ -1354,7 +1354,7 @@ enum SessionStatus
STATUS_AUTHED = 0, // Player authenticated (_player == NULL, m_playerRecentlyLogout = false or will be reset before handler call, m_GUID have garbage)
STATUS_LOGGEDIN, // Player in game (_player != NULL, m_GUID == _player->GetGUID(), inWorld())
STATUS_TRANSFER, // Player transferring to another map (_player != NULL, m_GUID == _player->GetGUID(), !inWorld())
- STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, // _player!= NULL or _player == NULL && m_playerRecentlyLogout, m_GUID store last _player guid)
+ STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, // _player != NULL or _player == NULL && m_playerRecentlyLogout && m_playerLogout, m_GUID store last _player guid)
STATUS_NEVER, // Opcode not accepted from client (deprecated or server side only)
STATUS_UNHANDLED, // Opcode not handled yet
};
diff --git a/src/server/game/Server/Protocol/PacketLog.cpp b/src/server/game/Server/Protocol/PacketLog.cpp
new file mode 100644
index 00000000000..bede48ace87
--- /dev/null
+++ b/src/server/game/Server/Protocol/PacketLog.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "PacketLog.h"
+#include "Config.h"
+#include "ByteBuffer.h"
+
+PacketLog::PacketLog() : _file(NULL)
+{
+ Initialize();
+}
+
+PacketLog::~PacketLog()
+{
+ if (_file)
+ fclose(_file);
+
+ _file = NULL;
+}
+
+void PacketLog::Initialize()
+{
+ std::string logsDir = ConfigMgr::GetStringDefault("LogsDir", "");
+
+ if (!logsDir.empty())
+ if ((logsDir.at(logsDir.length()-1) != '/') && (logsDir.at(logsDir.length()-1) != '\\'))
+ logsDir.push_back('/');
+
+ std::string logname = ConfigMgr::GetStringDefault("PacketLogFile", "");
+ if (!logname.empty())
+ _file = fopen((logsDir + logname).c_str(), "wb");
+}
+
+void PacketLog::LogPacket(WorldPacket const& packet, Direction direction)
+{
+ ByteBuffer data(4+4+4+1+packet.size());
+ data << int32(packet.GetOpcode());
+ data << int32(packet.size());
+ data << int32(time(NULL));
+ data << uint8(direction);
+
+ for (uint32 i = 0; i < packet.size(); i++)
+ data << const_cast<WorldPacket&>(packet)[i];
+
+ fwrite(data.contents(), 1, data.size(), _file);
+ fflush(_file);
+}
diff --git a/src/server/game/Server/Protocol/WorldLog.h b/src/server/game/Server/Protocol/PacketLog.h
index fb344f195de..b899daae198 100755..100644
--- a/src/server/game/Server/Protocol/WorldLog.h
+++ b/src/server/game/Server/Protocol/PacketLog.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -16,46 +15,36 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/// \addtogroup u2w
-/// @{
-/// \file
-
-#ifndef TRINITY_WORLDLOG_H
-#define TRINITY_WORLDLOG_H
+#ifndef TRINITY_PACKETLOG_H
+#define TRINITY_PACKETLOG_H
#include "Common.h"
#include <ace/Singleton.h>
-#include "Errors.h"
-#include <stdarg.h>
+enum Direction
+{
+ CLIENT_TO_SERVER,
+ SERVER_TO_CLIENT
+};
+
+class WorldPacket;
-/// %Log packets to a file
-class WorldLog
+class PacketLog
{
- friend class ACE_Singleton<WorldLog, ACE_Thread_Mutex>;
+ friend class ACE_Singleton<PacketLog, ACE_Thread_Mutex>;
private:
- WorldLog();
- ~WorldLog();
- WorldLog(const WorldLog &);
- WorldLog& operator=(const WorldLog &);
- ACE_Thread_Mutex Lock;
+ PacketLog();
+ ~PacketLog();
public:
void Initialize();
- /// Is the world logger active?
- bool LogWorld(void) const { return (i_file != NULL); }
- /// %Log to the file
- void outLog(char const* fmt, ...);
- void outTimestampLog(char const* fmt, ...);
+ bool CanLogPacket() const { return (_file != NULL); }
+ void LogPacket(WorldPacket const& packet, Direction direction);
private:
- FILE* i_file;
-
- bool m_dbWorld;
+ FILE* _file;
};
-#define sWorldLog ACE_Singleton<WorldLog, ACE_Thread_Mutex>::instance()
+#define sPacketLog ACE_Singleton<PacketLog, ACE_Thread_Mutex>::instance()
#endif
-/// @}
-
diff --git a/src/server/game/Server/Protocol/WorldLog.cpp b/src/server/game/Server/Protocol/WorldLog.cpp
deleted file mode 100755
index 38b13dff095..00000000000
--- a/src/server/game/Server/Protocol/WorldLog.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/** \file
- \ingroup u2w
-*/
-
-#include "WorldLog.h"
-#include "Config.h"
-#include "Log.h"
-#include "DatabaseWorkerPool.h"
-
-WorldLog::WorldLog() : i_file(NULL)
-{
- Initialize();
-}
-
-WorldLog::~WorldLog()
-{
- if (i_file != NULL)
- fclose(i_file);
-
- i_file = NULL;
-}
-
-/// Open the log file (if specified so in the configuration file)
-void WorldLog::Initialize()
-{
- std::string logsDir = ConfigMgr::GetStringDefault("LogsDir", "");
-
- if (!logsDir.empty())
- {
- if ((logsDir.at(logsDir.length()-1) != '/') && (logsDir.at(logsDir.length()-1) != '\\'))
- logsDir.push_back('/');
- }
-
- std::string logname = ConfigMgr::GetStringDefault("WorldLogFile", "");
- if (!logname.empty())
- {
- i_file = fopen((logsDir+logname).c_str(), "w");
- }
-
- m_dbWorld = ConfigMgr::GetBoolDefault("LogDB.World", false); // can be VERY heavy if enabled
-}
-
-void WorldLog::outTimestampLog(char const* fmt, ...)
-{
- if (LogWorld())
- {
- TRINITY_GUARD(ACE_Thread_Mutex, Lock);
- ASSERT(i_file);
-
- Log::outTimestamp(i_file);
- va_list args;
- va_start(args, fmt);
- vfprintf(i_file, fmt, args);
- //fprintf(i_file, "\n");
- va_end(args);
-
- fflush(i_file);
- }
-
- if (sLog->GetLogDB() && m_dbWorld)
- {
- va_list ap2;
- va_start(ap2, fmt);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, fmt, ap2);
- sLog->outDB(LOG_TYPE_WORLD, nnew_str);
- va_end(ap2);
- }
-}
-
-void WorldLog::outLog(char const* fmt, ...)
-{
- if (LogWorld())
- {
- TRINITY_GUARD(ACE_Thread_Mutex, Lock);
- ASSERT(i_file);
-
- va_list args;
- va_start(args, fmt);
- vfprintf(i_file, fmt, args);
- //fprintf(i_file, "\n");
- va_end(args);
-
- fflush(i_file);
- }
-
- if (sLog->GetLogDB() && m_dbWorld)
- {
- va_list ap2;
- va_start(ap2, fmt);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, fmt, ap2);
- sLog->outDB(LOG_TYPE_WORLD, nnew_str);
- va_end(ap2);
- }
-}
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 88248b7bc55..81ec5495421 100755
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -208,7 +208,7 @@ void WorldSession::QueuePacket(WorldPacket* new_packet)
/// Logging helper for unexpected opcodes
void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char* status, const char *reason)
{
- sLog->outError("SESSION (account: %u, guidlow: %u, char: %s): received unexpected opcode %s (0x%.4X, status: %s) %s",
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION (account: %u, guidlow: %u, char: %s): received unexpected opcode %s (0x%.4X, status: %s) %s",
GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>",
LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode(), status, reason);
}
@@ -216,7 +216,7 @@ void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char* status,
/// Logging helper for unexpected opcodes
void WorldSession::LogUnprocessedTail(WorldPacket* packet)
{
- sLog->outError("SESSION: opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)",
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION: opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)",
LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode(), uint32(packet->rpos()), uint32(packet->wpos()));
packet->print_storage();
}
@@ -290,7 +290,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
// lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
break;
case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT:
- if (!_player && !m_playerRecentlyLogout)
+ if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout
LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT",
"the player has not logged in yet and not recently logout");
else
@@ -323,9 +323,9 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
break;
}
- // single from authed time opcodes send in to after logout time
- // and before other STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes.
- if (packet->GetOpcode() != CMSG_SET_ACTIVE_VOICE_CHANNEL)
+ // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes
+ // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process.
+ if (packet->GetOpcode() == CMSG_CHAR_ENUM)
m_playerRecentlyLogout = false;
sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
@@ -334,7 +334,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
LogUnprocessedTail(packet);
break;
case STATUS_NEVER:
- sLog->outError("SESSION (account: %u, guidlow: %u, char: %s): received not allowed opcode %s (0x%.4X)",
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION (account: %u, guidlow: %u, char: %s): received not allowed opcode %s (0x%.4X)",
GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>",
LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode());
break;
@@ -404,7 +404,7 @@ void WorldSession::LogoutPlayer(bool Save)
if (_player)
{
- if (uint64 lguid = GetPlayer()->GetLootGUID())
+ if (uint64 lguid = _player->GetLootGUID())
DoLootRelease(lguid);
///- If the player just died before logging out, make him appear as a ghost
@@ -518,21 +518,21 @@ void WorldSession::LogoutPlayer(bool Save)
if (_player->GetGroup() && !_player->GetGroup()->isRaidGroup() && m_Socket)
_player->RemoveFromGroup();
- ///- Send update to group and reset stored max enchanting level
+ //! Send update to group and reset stored max enchanting level
if (_player->GetGroup())
{
_player->GetGroup()->SendUpdate();
_player->GetGroup()->ResetMaxEnchantingLevel();
}
- ///- Broadcast a logout message to the player's friends
+ //! Broadcast a logout message to the player's friends
sSocialMgr->SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUIDLow(), true);
sSocialMgr->RemovePlayerSocial(_player->GetGUIDLow());
- // Call script hook before deletion
- sScriptMgr->OnPlayerLogout(GetPlayer());
+ //! Call script hook before deletion
+ sScriptMgr->OnPlayerLogout(_player);
- ///- Remove the player from the world
+ //! Remove the player from the world
// the player may not be in the world when logging out
// e.g if he got disconnected during a transfer to another map
// calls to GetMap in this case may cause crashes
@@ -540,22 +540,19 @@ void WorldSession::LogoutPlayer(bool Save)
sLog->outChar("Account: %d (IP: %s) Logout Character:[%s] (GUID: %u) Level: %d", GetAccountId(), GetRemoteAddress().c_str(), _player->GetName(), _player->GetGUIDLow(), _player->getLevel());
if (Map* _map = _player->FindMap())
_map->RemovePlayerFromMap(_player, true);
- SetPlayer(NULL); // deleted in Remove call
- ///- Send the 'logout complete' packet to the client
+ SetPlayer(NULL); //! Pointer already deleted during RemovePlayerFromMap
+
+ //! Send the 'logout complete' packet to the client
+ //! Client will respond by sending 3x CMSG_CANCEL_TRADE, which we currently dont handle
WorldPacket data(SMSG_LOGOUT_COMPLETE, 0);
SendPacket(&data);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION: Sent SMSG_LOGOUT_COMPLETE Message");
- ///- Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline
- //No SQL injection as AccountId is uint32
-
+ //! Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ACCOUNT_ONLINE);
-
stmt->setUInt32(0, GetAccountId());
-
CharacterDatabase.Execute(stmt);
-
- sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION: Sent SMSG_LOGOUT_COMPLETE Message");
}
m_playerLogout = false;
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index bb54a0ae19e..00d5a8b5a86 100755
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -221,6 +221,7 @@ class WorldSession
bool PlayerLoading() const { return m_playerLoading; }
bool PlayerLogout() const { return m_playerLogout; }
bool PlayerLogoutWithSave() const { return m_playerLogout && m_playerSave; }
+ bool PlayerRecentlyLoggedOut() const { return m_playerRecentlyLogout; }
void SizeError(WorldPacket const& packet, uint32 size) const;
@@ -785,6 +786,7 @@ class WorldSession
void HandleResetInstancesOpcode(WorldPacket& recv_data);
void HandleHearthAndResurrect(WorldPacket& recv_data);
void HandleInstanceLockResponse(WorldPacket& recvPacket);
+ void HandleUpdateMissileTrajectory(WorldPacket& recvPacket);
// Looking for Dungeon/Raid
void HandleLfgSetCommentOpcode(WorldPacket& recv_data);
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index 64137dfe7c7..74e414a43a9 100755
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -42,7 +42,7 @@
#include "WorldSession.h"
#include "WorldSocketMgr.h"
#include "Log.h"
-#include "WorldLog.h"
+#include "PacketLog.h"
#include "ScriptMgr.h"
#include "AccountMgr.h"
@@ -152,7 +152,7 @@ const std::string& WorldSocket::GetRemoteAddress (void) const
return m_Address;
}
-int WorldSocket::SendPacket(const WorldPacket& pct)
+int WorldSocket::SendPacket(WorldPacket const& pct)
{
ACE_GUARD_RETURN (LockType, Guard, m_OutBufferLock, -1);
@@ -160,24 +160,8 @@ int WorldSocket::SendPacket(const WorldPacket& pct)
return -1;
// Dump outgoing packet.
- if (sWorldLog->LogWorld())
- {
- sWorldLog->outTimestampLog ("SERVER:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
- (uint32) get_handle(),
- pct.size(),
- LookupOpcodeName (pct.GetOpcode()),
- pct.GetOpcode());
-
- uint32 p = 0;
- while (p < pct.size())
- {
- for (uint32 j = 0; j < 16 && p < pct.size(); j++)
- sWorldLog->outLog("%.2X ", const_cast<WorldPacket&>(pct)[p++]);
-
- sWorldLog->outLog("\n");
- }
- sWorldLog->outLog("\n");
- }
+ if (sPacketLog->CanLogPacket())
+ sPacketLog->LogPacket(pct, SERVER_TO_CLIENT);
// Create a copy of the original packet; this is to avoid issues if a hook modifies it.
sScriptMgr->OnPacketSend(this, WorldPacket(pct));
@@ -674,7 +658,7 @@ int WorldSocket::schedule_wakeup_output (GuardType& g)
return 0;
}
-int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
+int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
{
ACE_ASSERT (new_pct);
@@ -687,24 +671,8 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
return -1;
// Dump received packet.
- if (sWorldLog->LogWorld())
- {
- sWorldLog->outTimestampLog ("CLIENT:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
- (uint32) get_handle(),
- new_pct->size(),
- LookupOpcodeName (new_pct->GetOpcode()),
- new_pct->GetOpcode());
-
- uint32 p = 0;
- while (p < new_pct->size())
- {
- for (uint32 j = 0; j < 16 && p < new_pct->size(); j++)
- sWorldLog->outLog ("%.2X ", (*new_pct)[p++]);
-
- sWorldLog->outLog ("\n");
- }
- sWorldLog->outLog ("\n");
- }
+ if (sPacketLog->CanLogPacket())
+ sPacketLog->LogPacket(*new_pct, CLIENT_TO_SERVER);
try
{
@@ -955,6 +923,8 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
sha.UpdateBigNumbers (&k, NULL);
sha.Finalize();
+ std::string address = GetRemoteAddress();
+
if (memcmp (sha.GetDigest(), digest, 20))
{
packet.Initialize (SMSG_AUTH_RESPONSE, 1);
@@ -962,13 +932,11 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
SendPacket(packet);
- sLog->outError("WorldSocket::HandleAuthSession: Sent Auth Response (authentification failed).");
+ sLog->outError("WorldSocket::HandleAuthSession: Authentication failed for account: %u ('%s') address: %s", id, account.c_str(), address.c_str());
return -1;
}
- std::string address = GetRemoteAddress();
-
- sLog->outStaticDebug ("WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.",
+ sLog->outStaticDebug("WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.",
account.c_str(),
address.c_str());
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index d28ba9e1e19..05114c8bc07 100755
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -660,19 +660,23 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
}
break;
case SPELL_AURA_PERIODIC_ENERGIZE:
- if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_GENERIC)
+ switch (m_spellInfo->Id)
{
- // Replenishment (0.25% from max)
- // Infinite Replenishment
- if (m_spellInfo->SpellIconID == 3184 && m_spellInfo->SpellVisual[0] == 12495)
- amount = GetBase()->GetUnitOwner()->GetMaxPower(POWER_MANA) * 25 / 10000;
- }
- // Innervate
- else if (m_spellInfo->Id == 29166)
+ case 57669: // Replenishment (0.2% from max)
+ amount = GetBase()->GetUnitOwner()->GetMaxPower(POWER_MANA) * 0.002f;
+ break;
+ case 61782: // Infinite Replenishment
+ amount = GetBase()->GetUnitOwner()->GetMaxPower(POWER_MANA) * 0.0025f;
+ break;
+ case 29166: // Innervate
ApplyPctF(amount, float(GetBase()->GetUnitOwner()->GetCreatePowers(POWER_MANA)) / GetTotalTicks());
- // Owlkin Frenzy
- else if (m_spellInfo->Id == 48391)
+ break;
+ case 48391: // Owlkin Frenzy
ApplyPctU(amount, GetBase()->GetUnitOwner()->GetCreatePowers(POWER_MANA));
+ break;
+ default:
+ break;
+ }
break;
case SPELL_AURA_PERIODIC_HEAL:
if (!caster)
@@ -2421,7 +2425,7 @@ void AuraEffect::HandleAuraCloneCaster(AuraApplication const* aurApp, uint8 mode
// What must be cloned? at least display and scale
target->SetDisplayId(caster->GetDisplayId());
- //target->SetFloatValue(OBJECT_FIELD_SCALE_X, caster->GetFloatValue(OBJECT_FIELD_SCALE_X)); // we need retail info about how scaling is handled (aura maybe?)
+ //target->SetObjectScale(caster->GetFloatValue(OBJECT_FIELD_SCALE_X)); // we need retail info about how scaling is handled (aura maybe?)
target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_MIRROR_IMAGE);
}
else
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index de432229e2c..58a89f75fd3 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -585,9 +585,7 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme
CleanupEffectExecuteData();
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- {
m_destTargets[i] = SpellDestination(*m_caster);
- }
}
Spell::~Spell()
@@ -4837,8 +4835,9 @@ SpellCastResult Spell::CheckCast(bool strict)
if ((m_spellInfo->AttributesCu & SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
return SPELL_FAILED_NOT_INFRONT;
- if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOSInMap(target))
- return SPELL_FAILED_LINE_OF_SIGHT;
+ if (m_caster->GetEntry() != WORLD_TRIGGER) // Ignore LOS for gameobjects casts (wrongly casted by a trigger)
+ if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOSInMap(target))
+ return SPELL_FAILED_LINE_OF_SIGHT;
}
else
{
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 07bea5f980c..17e79501d16 100755
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -3565,7 +3565,7 @@ void Spell::EffectHealMaxHealth(SpellEffIndex /*effIndex*/)
if (!unitTarget || !unitTarget->isAlive())
return;
- int32 addhealth;
+ int32 addhealth = 0;
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN) // Lay on Hands
{
if (m_caster->GetGUID() == unitTarget->GetGUID())
@@ -3582,11 +3582,7 @@ void Spell::EffectHealMaxHealth(SpellEffIndex /*effIndex*/)
else
addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
- if (m_originalCaster)
- {
- uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL);
- m_healing += unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL);
- }
+ m_healing += addhealth;
}
void Spell::EffectInterruptCast(SpellEffIndex effIndex)
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 06e4978eb58..05566bdf712 100755
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -3043,6 +3043,7 @@ void SpellMgr::LoadDbcDataCorrections()
case 61588: // Blazing Harpoon
case 52479: // Gift of the Harvester
case 48246: // Ball of Flame
+ case 36384: // Skartax Purple Beam
spellInfo->MaxAffectedTargets = 1;
break;
case 41376: // Spite
@@ -3084,7 +3085,7 @@ void SpellMgr::LoadDbcDataCorrections()
case 50312: // Unholy Frenzy
spellInfo->MaxAffectedTargets = 15;
break;
- case 33711: //Murmur's Touch
+ case 33711: // Murmur's Touch
case 38794:
spellInfo->MaxAffectedTargets = 1;
spellInfo->EffectTriggerSpell[0] = 33760;
@@ -3238,6 +3239,9 @@ void SpellMgr::LoadDbcDataCorrections()
spellInfo->EffectDieSides[0] = 0; // was 1, that should probably mean seat 0, but instead it's treated as spell 1
spellInfo->EffectBasePoints[0] = 52391; // Ride Vehicle (forces seat 0)
break;
+ case 45602: // Ride Carpet
+ spellInfo->EffectBasePoints[EFFECT_0] = 0; // force seat 0, vehicle doesn't have the required seat flags for "no seat specified (-1)"
+ break;
case 64745: // Item - Death Knight T8 Tank 4P Bonus
case 64936: // Item - Warrior T8 Protection 4P Bonus
spellInfo->EffectBasePoints[0] = 100; // 100% chance of procc'ing, not -10% (chance calculated in PrepareTriggersExecutedOnHit)
diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h
index 521070f7879..dcf3c38fe4f 100755
--- a/src/server/game/Spells/SpellMgr.h
+++ b/src/server/game/Spells/SpellMgr.h
@@ -605,7 +605,7 @@ class SpellMgr
// Accessors (const or static functions)
public:
- // Spell correctess for client using
+ // Spell correctness for client using
static bool IsSpellValid(SpellInfo const* spellInfo, Player* player = NULL, bool msg = true);
// Spell difficulty
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp
index b6feccc10c6..3e04cb48af4 100644
--- a/src/server/scripts/Commands/cs_modify.cpp
+++ b/src/server/scripts/Commands/cs_modify.cpp
@@ -718,7 +718,7 @@ public:
(ChatHandler(player)).PSendSysMessage(LANG_YOURS_SIZE_CHANGED, handler->GetNameLink().c_str(), Scale);
}
- target->SetFloatValue(OBJECT_FIELD_SCALE_X, Scale);
+ target->SetObjectScale(Scale);
return true;
}
diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp
index f29dd8a5069..99ec263b8f9 100644
--- a/src/server/scripts/Commands/cs_wp.cpp
+++ b/src/server/scripts/Commands/cs_wp.cpp
@@ -949,7 +949,7 @@ public:
if (target)
{
wpCreature->SetDisplayId(target->GetDisplayId());
- wpCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5f);
+ wpCreature->SetObjectScale(0.5f);
wpCreature->SetLevel(point > STRONG_MAX_LEVEL ? STRONG_MAX_LEVEL : point);
}
}
@@ -1003,7 +1003,7 @@ public:
if (target)
{
creature->SetDisplayId(target->GetDisplayId());
- creature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5f);
+ creature->SetObjectScale(0.5f);
}
return true;
@@ -1052,7 +1052,7 @@ public:
if (target)
{
creature->SetDisplayId(target->GetDisplayId());
- creature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5f);
+ creature->SetObjectScale(0.5f);
}
return true;
diff --git a/src/server/scripts/EasternKingdoms/BlackrockSpire/blackrock_spire.h b/src/server/scripts/EasternKingdoms/BlackrockSpire/blackrock_spire.h
index beef71ea857..0af2af948d3 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockSpire/blackrock_spire.h
+++ b/src/server/scripts/EasternKingdoms/BlackrockSpire/blackrock_spire.h
@@ -33,7 +33,8 @@ enum Data
DATA_WARCHIEF_REND_BLACKHAND,
DATA_GYTH,
DATA_THE_BEAST,
- DATA_GENERAL_DRAKKISATH
+ DATA_GENERAL_DRAKKISATH,
+ DATA_DRAGONSPIRE_ROOM,
};
enum Npc
{
@@ -51,6 +52,9 @@ enum Npc
NPC_GYTH = 10339,
NPC_THE_BEAST = 10430,
NPC_GENERAL_DRAKKISATH = 10363,
+ NPC_BLACKHAND_DREADWEAVER = 9817,
+ NPC_BLACKHAND_SUMMONER = 9818,
+ NPC_BLACKHAND_VETERAN = 9819,
};
enum AdditionalData
@@ -58,6 +62,9 @@ enum AdditionalData
SPELL_SUMMON_ROOKERY_WHELP = 15745,
MAX_ENCOUNTER = 14,
MAX_DRAGONSPIRE_HALL_RUNES = 7,
+ EVENT_PYROGUARD_EMBERSEER = 4884,
+ AREATRIGGER_ENTER_UBRS = 2046,
+ AREATRIGGER_STADIUM = 2026,
};
enum GameObjects
diff --git a/src/server/scripts/EasternKingdoms/BlackrockSpire/boss_pyroguard_emberseer.cpp b/src/server/scripts/EasternKingdoms/BlackrockSpire/boss_pyroguard_emberseer.cpp
index 411b800cd03..0279f3e2834 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockSpire/boss_pyroguard_emberseer.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockSpire/boss_pyroguard_emberseer.cpp
@@ -20,11 +20,24 @@
#include "ScriptedCreature.h"
#include "blackrock_spire.h"
+enum Text
+{
+ EMOTE_ONE_STACK = 0,
+ EMOTE_TEN_STACK = 1,
+ EMOTE_FREE_OF_BONDS = 2,
+ YELL_FREE_OF_BONDS = 3,
+};
+
enum Spells
{
- SPELL_FIRENOVA = 23462,
- SPELL_FLAMEBUFFET = 23341,
- SPELL_PYROBLAST = 17274,
+ SPELL_ENCAGED_EMBERSEER = 15282, // Self on spawn
+ SPELL_FIRE_SHIELD_TRIGGER = 13377, // Self on spawn missing from 335 dbc
+ SPELL_FREEZE_ANIM = 16245, // Self on event start
+ SPELL_EMBERSEER_GROWING = 16048, // Self on event start
+ SPELL_EMBERSEER_FULL_STRENGTH = 16047, // Emberseer Full Strength
+ SPELL_FIRENOVA = 23462, // Combat
+ SPELL_FLAMEBUFFET = 23341, // Combat
+ SPELL_PYROBLAST = 17274, // Combat
};
enum Events
@@ -51,6 +64,12 @@ public:
void Reset()
{
+ if(instance->GetBossState(DATA_PYROGAURD_EMBERSEER) == IN_PROGRESS)
+ OpenDoors(false);
+ instance->SetBossState(DATA_PYROGAURD_EMBERSEER,NOT_STARTED);
+ // respawn any dead Blackhand Incarcerators
+ DoCast(me, SPELL_ENCAGED_EMBERSEER);
+ //DoCast(me, SPELL_FIRE_SHIELD_TRIGGER);
_Reset();
}
@@ -64,12 +83,26 @@ public:
void JustDied(Unit* /*killer*/)
{
+ instance->SetBossState(DATA_PYROGAURD_EMBERSEER,DONE);
+ OpenDoors(true);
_JustDied();
}
+ void OpenDoors(bool Boss_Killed)
+ {
+ if (GameObject* door1 = me->GetMap()->GetGameObject(instance->GetData64(GO_EMBERSEER_IN)))
+ door1->SetGoState(GO_STATE_ACTIVE);
+ if (GameObject* door2 = me->GetMap()->GetGameObject(instance->GetData64(GO_DOORS)))
+ door2->SetGoState(GO_STATE_ACTIVE);
+ if (Boss_Killed)
+ if (GameObject* door3 = me->GetMap()->GetGameObject(instance->GetData64(GO_EMBERSEER_OUT)))
+ door3->SetGoState(GO_STATE_ACTIVE);
+ }
+
void UpdateAI(uint32 const diff)
{
if (!UpdateVictim())
+
return;
events.Update(diff);
diff --git a/src/server/scripts/EasternKingdoms/BlackrockSpire/instance_blackrock_spire.cpp b/src/server/scripts/EasternKingdoms/BlackrockSpire/instance_blackrock_spire.cpp
index b5b1b34a593..fdb73fe1196 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockSpire/instance_blackrock_spire.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockSpire/instance_blackrock_spire.cpp
@@ -49,6 +49,12 @@ public:
uint64 Gyth;
uint64 TheBeast;
uint64 GeneralDrakkisath;
+ uint64 go_emberseerin;
+ uint64 go_doors;
+ uint64 go_emberseerout;
+ uint64 go_roomrunes[MAX_DRAGONSPIRE_HALL_RUNES];
+ uint8 Runemaxprotectors[MAX_DRAGONSPIRE_HALL_RUNES];
+ uint8 Runeprotectorsdead[MAX_DRAGONSPIRE_HALL_RUNES];
void Initialize()
{
@@ -67,6 +73,9 @@ public:
Gyth = 0;
TheBeast = 0;
GeneralDrakkisath = 0;
+ go_emberseerin = 0;
+ go_doors = 0;
+ go_emberseerout = 0;
}
bool IsEncounterInProgress() const
@@ -125,7 +134,11 @@ public:
case NPC_GENERAL_DRAKKISATH:
GeneralDrakkisath = creature->GetGUID();
break;
- }
+ case NPC_BLACKHAND_DREADWEAVER:
+ case NPC_BLACKHAND_SUMMONER:
+ case NPC_BLACKHAND_VETERAN:
+ break;
+ }
}
void OnGameObjectCreate(GameObject* go)
@@ -135,6 +148,36 @@ public:
case GO_WHELP_SPAWNER:
go->CastSpell(NULL, SPELL_SUMMON_ROOKERY_WHELP);
break;
+ case GO_EMBERSEER_IN:
+ go_emberseerin = go->GetGUID();
+ break;
+ case GO_DOORS:
+ go_doors = go->GetGUID();
+ break;
+ case GO_EMBERSEER_OUT:
+ go_emberseerout = go->GetGUID();
+ break;
+ case GO_ROOM_1_RUNE:
+ go_roomrunes[0] = go->GetGUID();
+ break;
+ case GO_ROOM_2_RUNE:
+ go_roomrunes[1] = go->GetGUID();
+ break;
+ case GO_ROOM_3_RUNE:
+ go_roomrunes[2] = go->GetGUID();
+ break;
+ case GO_ROOM_4_RUNE:
+ go_roomrunes[3] = go->GetGUID();
+ break;
+ case GO_ROOM_5_RUNE:
+ go_roomrunes[4] = go->GetGUID();
+ break;
+ case GO_ROOM_6_RUNE:
+ go_roomrunes[5] = go->GetGUID();
+ break;
+ case GO_ROOM_7_RUNE:
+ go_roomrunes[6] = go->GetGUID();
+ break;
}
}
@@ -167,6 +210,18 @@ public:
return true;
}
+ void ProcessEvent(WorldObject* /*gameObject*/, uint32 eventId)
+ {
+ switch (eventId)
+ {
+ case EVENT_PYROGUARD_EMBERSEER:
+ SetBossState(DATA_PYROGAURD_EMBERSEER,IN_PROGRESS);
+ break;
+ default:
+ break;
+ }
+ }
+
uint64 GetData64(uint32 type)
{
switch (type)
@@ -199,6 +254,26 @@ public:
return TheBeast;
case DATA_GENERAL_DRAKKISATH:
return GeneralDrakkisath;
+ case GO_EMBERSEER_IN:
+ return go_emberseerin;
+ case GO_DOORS:
+ return go_doors;
+ case GO_EMBERSEER_OUT:
+ return go_emberseerout;
+ case GO_ROOM_1_RUNE:
+ return go_roomrunes[0];
+ case GO_ROOM_2_RUNE:
+ return go_roomrunes[1];
+ case GO_ROOM_3_RUNE:
+ return go_roomrunes[2];
+ case GO_ROOM_4_RUNE:
+ return go_roomrunes[3];
+ case GO_ROOM_5_RUNE:
+ return go_roomrunes[4];
+ case GO_ROOM_6_RUNE:
+ return go_roomrunes[5];
+ case GO_ROOM_7_RUNE:
+ return go_roomrunes[6];
}
return 0;
@@ -247,30 +322,7 @@ public:
};
-uint8 ActivatedRunes = 0;
-
-class go_dragonspire_hall_rune : public GameObjectScript
-{
-public:
- go_dragonspire_hall_rune() : GameObjectScript("go_dragonspire_hall_rune") { }
-
- void OnGameObjectStateChanged(GameObject* go, uint32 state)
- {
- if (state == GO_STATE_READY)
- {
- if (++ActivatedRunes == MAX_DRAGONSPIRE_HALL_RUNES)
- {
- if (GameObject* door1 = GetClosestGameObjectWithEntry(go, GO_EMBERSEER_IN, 150.0f))
- door1->SetGoState(GO_STATE_ACTIVE);
- if (GameObject* door2 = GetClosestGameObjectWithEntry(go, GO_DOORS, 150.0f))
- door2->SetGoState(GO_STATE_ACTIVE);
- }
- }
- }
-};
-
void AddSC_instance_blackrock_spire()
{
new instance_blackrock_spire();
- new go_dragonspire_hall_rune;
}
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp
index 783ac6baad1..2bba875ad1f 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp
@@ -185,7 +185,7 @@ public:
pAttumen->GetMotionMaster()->MoveChase(pAttumen->getVictim());
pAttumen->SetTarget(pAttumen->getVictim()->GetGUID());
}
- pAttumen->SetFloatValue(OBJECT_FIELD_SCALE_X, 1);
+ pAttumen->SetObjectScale(1);
}
} else Mount_Timer -= diff;
}
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp
index 9a9f37d165f..a715dbfce9d 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp
@@ -332,7 +332,7 @@ class boss_akilzon : public CreatureScript
CloudGUID = Cloud->GetGUID();
Cloud->SetUnitMovementFlags(MOVEMENTFLAG_DISABLE_GRAVITY);
Cloud->StopMoving();
- Cloud->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
+ Cloud->SetObjectScale(1.0f);
Cloud->setFaction(35);
Cloud->SetMaxHealth(9999999);
Cloud->SetHealth(9999999);
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp
index ce6b3b37ef8..3da74d16dc3 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp
@@ -197,7 +197,7 @@ class boss_thekal : public CreatureScript
if (Resurrect_Timer <= diff)
{
DoCast(me, SPELL_TIGER_FORM);
- me->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.00f);
+ me->SetObjectScale(2.00f);
me->SetStandState(UNIT_STAND_STATE_STAND);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetFullHealth();
diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp
index 328d1ab1cd4..cf3c4274e48 100644
--- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp
@@ -354,7 +354,7 @@ public:
//! HACK: Creature's can't have MOVEMENTFLAG_FLYING
me->AddUnitMovementFlag(MOVEMENTFLAG_FLYING);
me->setFaction(16);
- me->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
+ me->SetObjectScale(1.0f);
DoCast(me, SPELL_FLAME_SPHERE_VISUAL);
DoCast(me, SPELL_FLAME_SPHERE_SPAWN_EFFECT);
DoCast(me, SPELL_FLAME_SPHERE_PERIODIC);
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
index f329b940e1f..e4dcf978574 100755
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
@@ -615,7 +615,7 @@ class mob_frost_sphere : public CreatureScript
me->SetDisplayId(me->GetCreatureTemplate()->Modelid1);
DoCast(SPELL_PERMAFROST_VISUAL);
DoCast(SPELL_PERMAFROST);
- me->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.0f);
+ me->SetObjectScale(2.0f);
break;
}
}
@@ -659,6 +659,11 @@ public:
m_uiTargetGUID = 0;
}
+ bool CanAIAttack(Unit const* victim) const
+ {
+ return victim->GetTypeId() == TYPEID_PLAYER;
+ }
+
void EnterCombat(Unit* who)
{
m_uiTargetGUID = who->GetGUID();
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
index 1d4961eb8b4..2643b8d60c7 100755
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
@@ -439,7 +439,7 @@ class npc_fizzlebang_toc : public CreatureScript
if (Unit* pTrigger = me->SummonCreature(NPC_TRIGGER, ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 4.69494f, TEMPSUMMON_MANUAL_DESPAWN))
{
m_uiTriggerGUID = pTrigger->GetGUID();
- pTrigger->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.0f);
+ pTrigger->SetObjectScale(2.0f);
pTrigger->SetDisplayId(22862);
pTrigger->CastSpell(pTrigger, SPELL_WILFRED_PORTAL, false);
}
@@ -456,7 +456,7 @@ class npc_fizzlebang_toc : public CreatureScript
if (Creature* pPortal = me->SummonCreature(NPC_WILFRED_PORTAL, ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 4.71239f, TEMPSUMMON_MANUAL_DESPAWN))
{
pPortal->SetReactState(REACT_PASSIVE);
- pPortal->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.0f);
+ pPortal->SetObjectScale(2.0f);
pPortal->CastSpell(pPortal, SPELL_WILFRED_PORTAL, false);
m_uiPortalGUID = pPortal->GetGUID();
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
index f086e8dc9cf..ee966256e2b 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
@@ -149,7 +149,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
events.ScheduleEvent(EVENT_SWARMING_SHADOWS, 30500, EVENT_GROUP_NORMAL);
events.ScheduleEvent(EVENT_TWILIGHT_BLOODBOLT, urand(20000, 25000), EVENT_GROUP_NORMAL);
events.ScheduleEvent(EVENT_AIR_PHASE, 124000 + uint32(Is25ManRaid() ? 3000 : 0));
- instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_UNCONTROLLABLE_FRENZY);
+ CleanAuras();
me->SetSpeed(MOVE_FLIGHT, 0.642857f, true);
_offtank = NULL;
_vampires.clear();
@@ -170,6 +170,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
DoZoneInCombat();
Talk(SAY_AGGRO);
instance->SetBossState(DATA_BLOOD_QUEEN_LANA_THEL, IN_PROGRESS);
+ CleanAuras();
DoCast(me, SPELL_SHROUD_OF_SORROW, true);
DoCast(me, SPELL_FRENZIED_BLOODTHIRST_VISUAL, true);
@@ -180,15 +181,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
{
_JustDied();
Talk(SAY_DEATH);
- instance->DoRemoveAurasDueToSpellOnPlayers(ESSENCE_OF_BLOOD_QUEEN);
- instance->DoRemoveAurasDueToSpellOnPlayers(ESSENCE_OF_BLOOD_QUEEN_PLR);
- instance->DoRemoveAurasDueToSpellOnPlayers(FRENZIED_BLOODTHIRST);
- instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_UNCONTROLLABLE_FRENZY);
- instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLOOD_MIRROR_DAMAGE);
- instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLOOD_MIRROR_VISUAL);
- instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLOOD_MIRROR_DUMMY);
- instance->DoRemoveAurasDueToSpellOnPlayers(DELIRIOUS_SLASH);
- instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PACT_OF_THE_DARKFALLEN);
+ CleanAuras();
// Blah, credit the quest
if (_creditBloodQuickening)
{
@@ -207,6 +200,19 @@ class boss_blood_queen_lana_thel : public CreatureScript
}
}
+ void CleanAuras()
+ {
+ instance->DoRemoveAurasDueToSpellOnPlayers(ESSENCE_OF_BLOOD_QUEEN);
+ instance->DoRemoveAurasDueToSpellOnPlayers(ESSENCE_OF_BLOOD_QUEEN_PLR);
+ instance->DoRemoveAurasDueToSpellOnPlayers(FRENZIED_BLOODTHIRST);
+ instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_UNCONTROLLABLE_FRENZY);
+ instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLOOD_MIRROR_DAMAGE);
+ instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLOOD_MIRROR_VISUAL);
+ instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLOOD_MIRROR_DUMMY);
+ instance->DoRemoveAurasDueToSpellOnPlayers(DELIRIOUS_SLASH);
+ instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PACT_OF_THE_DARKFALLEN);
+ }
+
void DoAction(int32 const action)
{
if (action != ACTION_KILL_MINCHAR)
@@ -227,6 +233,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
void EnterEvadeMode()
{
_EnterEvadeMode();
+ CleanAuras();
if (_killMinchar)
{
_killMinchar = false;
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
index afc7c503bee..494be259baa 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
@@ -631,9 +631,7 @@ class npc_high_overlord_saurfang_icc : public CreatureScript
_events.ScheduleEvent(EVENT_OUTRO_HORDE_4, 24000); // cast
_events.ScheduleEvent(EVENT_OUTRO_HORDE_5, 30000); // move
me->SetDisableGravity(false);
- me->SendMovementFlagUpdate();
- me->Relocate(me->GetPositionX(), me->GetPositionY(), 539.2917f);
- me->MonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), 539.2917f, 0.0f);
+ me->GetMotionMaster()->MoveFall();
for (std::list<Creature*>::iterator itr = _guardList.begin(); itr != _guardList.end(); ++itr)
(*itr)->AI()->DoAction(ACTION_DESPAWN);
break;
@@ -838,9 +836,7 @@ class npc_muradin_bronzebeard_icc : public CreatureScript
me->RemoveAurasDueToSpell(SPELL_GRIP_OF_AGONY);
Talk(SAY_OUTRO_ALLIANCE_1);
me->SetDisableGravity(false);
- me->SendMovementFlagUpdate();
- me->Relocate(me->GetPositionX(), me->GetPositionY(), 539.2917f);
- me->MonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), 539.2917f, 0.0f);
+ me->GetMotionMaster()->MoveFall();
for (std::list<Creature*>::iterator itr = _guardList.begin(); itr != _guardList.end(); ++itr)
(*itr)->AI()->DoAction(ACTION_DESPAWN);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
index 6039ace44ab..734639a8b51 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
@@ -167,7 +167,7 @@ class FrostwyrmLandEvent : public BasicEvent
bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/)
{
- _owner.GetMotionMaster()->MoveLand(POINT_FROSTWYRM_LAND, _dest, 8.247422f);
+ _owner.GetMotionMaster()->MoveLand(POINT_FROSTWYRM_LAND, _dest);
return true;
}
@@ -481,7 +481,7 @@ class boss_sindragosa : public CreatureScript
Position pos;
pos.Relocate(me);
pos.m_positionZ += 17.0f;
- me->GetMotionMaster()->MoveTakeoff(POINT_TAKEOFF, pos, 8.30078125f);
+ me->GetMotionMaster()->MoveTakeoff(POINT_TAKEOFF, pos);
events.CancelEventGroup(EVENT_GROUP_LAND_PHASE);
events.ScheduleEvent(EVENT_AIR_PHASE, 110000);
break;
@@ -523,7 +523,7 @@ class boss_sindragosa : public CreatureScript
events.ScheduleEvent(EVENT_FROST_BREATH, urand(10000, 15000), EVENT_GROUP_LAND_PHASE);
events.ScheduleEvent(EVENT_UNCHAINED_MAGIC, urand(12000, 17000), EVENT_GROUP_LAND_PHASE);
events.ScheduleEvent(EVENT_ICY_GRIP, urand(35000, 40000), EVENT_GROUP_LAND_PHASE);
- me->GetMotionMaster()->MoveLand(POINT_LAND_GROUND, SindragosaLandPos, 0.0f);
+ me->GetMotionMaster()->MoveLand(POINT_LAND_GROUND, SindragosaLandPos);
break;
case EVENT_THIRD_PHASE_CHECK:
{
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
index fab9a5f0740..6fd3cd2a294 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
@@ -1926,7 +1926,7 @@ class spell_svalna_revive_champion : public SpellScriptLoader
//pos.m_positionZ = caster->GetBaseMap()->GetHeight(caster->GetPhaseMask(), pos.GetPositionX(), pos.GetPositionY(), caster->GetPositionZ(), true, 50.0f);
//pos.m_positionZ += 0.05f;
caster->SetHomePosition(pos);
- caster->GetMotionMaster()->MoveLand(POINT_LAND, pos, caster->GetSpeed(MOVE_FLIGHT));
+ caster->GetMotionMaster()->MoveLand(POINT_LAND, pos);
}
void Register()
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
index 4d6bfc578ff..0a4fdec7222 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
@@ -299,7 +299,7 @@ public:
for (itr = chained.begin(); itr != chained.end(); ++itr)
{
if (Player* charmed = Unit::GetPlayer(*me, (*itr).first))
- charmed->SetFloatValue(OBJECT_FIELD_SCALE_X, (*itr).second);
+ charmed->SetObjectScale((*itr).second);
}
chained.clear();
@@ -347,7 +347,7 @@ public:
for (itr = chained.begin(); itr != chained.end(); ++itr)
{
if (Player* player = Unit::GetPlayer(*me, (*itr).first))
- player->SetFloatValue(OBJECT_FIELD_SCALE_X, (*itr).second);
+ player->SetObjectScale((*itr).second);
}
chained.clear();
}
@@ -512,7 +512,7 @@ public:
DoCast(target, SPELL_CHAINS_OF_KELTHUZAD);
float scale = target->GetFloatValue(OBJECT_FIELD_SCALE_X);
chained.insert(std::make_pair(target->GetGUID(), scale));
- target->SetFloatValue(OBJECT_FIELD_SCALE_X, scale * 2);
+ target->SetObjectScale(scale * 2);
events.ScheduleEvent(EVENT_CHAINED_SPELL, 2000); //core has 2000ms to set unit flag charm
}
}
@@ -530,7 +530,7 @@ public:
{
if (!player->isCharmed())
{
- player->SetFloatValue(OBJECT_FIELD_SCALE_X, (*itr).second);
+ player->SetObjectScale((*itr).second);
std::map<uint64, float>::iterator next = itr;
++next;
chained.erase(itr);
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
index 29b8f2e7f48..44cd1184098 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
@@ -276,7 +276,7 @@ public:
arthas->CastSpell(me, SPELL_TRANSFORMING_CHANNEL, false);
pos.Relocate(me);
pos.m_positionZ += 8.0f;
- me->GetMotionMaster()->MoveTakeoff(0, pos, 3.30078125f);
+ me->GetMotionMaster()->MoveTakeoff(0, pos);
// spectators flee event
if (instance)
{
@@ -333,7 +333,7 @@ public:
pos.m_positionX = me->GetHomePosition().GetPositionX();
pos.m_positionY = me->GetHomePosition().GetPositionY();
pos.m_positionZ = 90.6065f;
- me->GetMotionMaster()->MoveLand(0, pos, 6.247422f);
+ me->GetMotionMaster()->MoveLand(0, pos);
me->SetDisableGravity(false, true);
me->SetHover(true);
++introPhase;
diff --git a/src/server/scripts/Northrend/dragonblight.cpp b/src/server/scripts/Northrend/dragonblight.cpp
index 4cbe280a9f2..1b339b24549 100644
--- a/src/server/scripts/Northrend/dragonblight.cpp
+++ b/src/server/scripts/Northrend/dragonblight.cpp
@@ -69,7 +69,106 @@ public:
}
};
+/*######
+## Quest Strengthen the Ancients (12096|12092)
+######*/
+
+enum StrengthenAncientsMisc
+{
+ SAY_WALKER_FRIENDLY = 0,
+ SAY_WALKER_ENEMY = 1,
+ SAY_LOTHALOR = 0,
+
+ SPELL_CREATE_ITEM_BARK = 47550,
+ SPELL_CONFUSED = 47044,
+
+ NPC_LOTHALOR = 26321,
+
+ FACTION_WALKER_ENEMY = 14,
+};
+
+class spell_q12096_q12092_dummy : public SpellScriptLoader // Strengthen the Ancients: On Interact Dummy to Woodlands Walker
+{
+public:
+ spell_q12096_q12092_dummy() : SpellScriptLoader("spell_q12096_q12092_dummy") { }
+
+ class spell_q12096_q12092_dummy_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q12096_q12092_dummy_SpellScript);
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ uint32 roll = rand() % 2;
+
+ Creature* tree = GetHitCreature();
+ Player* player = GetCaster()->ToPlayer();
+
+ if (!tree || !player)
+ return;
+
+ tree->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+
+ if (roll == 1) // friendly version
+ {
+ tree->CastSpell(player, SPELL_CREATE_ITEM_BARK);
+ tree->AI()->Talk(SAY_WALKER_FRIENDLY, player->GetGUID());
+ tree->DespawnOrUnsummon(1000);
+ }
+ else if (roll == 0) // enemy version
+ {
+ tree->AI()->Talk(SAY_WALKER_ENEMY, player->GetGUID());
+ tree->setFaction(FACTION_WALKER_ENEMY);
+ tree->Attack(player, true);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_q12096_q12092_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_q12096_q12092_dummy_SpellScript();
+ }
+};
+
+class spell_q12096_q12092_bark : public SpellScriptLoader // Bark of the Walkers
+{
+public:
+ spell_q12096_q12092_bark() : SpellScriptLoader("spell_q12096_q12092_bark") { }
+
+ class spell_q12096_q12092_bark_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q12096_q12092_bark_SpellScript);
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ Creature* lothalor = GetHitCreature();
+ if (!lothalor || lothalor->GetEntry() != NPC_LOTHALOR)
+ return;
+
+ lothalor->AI()->Talk(SAY_LOTHALOR);
+ lothalor->RemoveAura(SPELL_CONFUSED);
+ lothalor->DespawnOrUnsummon(4000);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_q12096_q12092_bark_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_q12096_q12092_bark_SpellScript();
+ }
+};
+
void AddSC_dragonblight()
{
new npc_alexstrasza_wr_gate;
+ new spell_q12096_q12092_dummy;
+ new spell_q12096_q12092_bark;
}
diff --git a/src/server/scripts/Northrend/sholazar_basin.cpp b/src/server/scripts/Northrend/sholazar_basin.cpp
index 93d0182ea08..afab9b90a4a 100644
--- a/src/server/scripts/Northrend/sholazar_basin.cpp
+++ b/src/server/scripts/Northrend/sholazar_basin.cpp
@@ -746,6 +746,130 @@ public:
}
};
+/*######
+## Quest Kick, What Kick? (12589)
+######*/
+
+enum KickWhatKick
+{
+ NPC_LUCKY_WILHELM = 28054,
+ NPC_APPLE = 28053,
+ NPC_DROSTAN = 28328,
+ NPC_CRUNCHY = 28346,
+ NPC_THICKBIRD = 28093,
+
+ SPELL_HIT_APPLE = 51331,
+ SPELL_MISS_APPLE = 51332,
+ SPELL_MISS_BIRD_APPLE = 51366,
+ SPELL_APPLE_FALL = 51371,
+ SPELL_BIRD_FALL = 51369,
+
+ EVENT_MISS = 0,
+ EVENT_HIT = 1,
+ EVENT_MISS_BIRD = 2,
+
+ SAY_WILHELM_MISS = 0,
+ SAY_WILHELM_HIT = 1,
+ SAY_DROSTAN_REPLY_MISS = 0,
+};
+
+class spell_q12589_shoot_rjr : public SpellScriptLoader
+{
+public:
+ spell_q12589_shoot_rjr() : SpellScriptLoader("spell_q12589_shoot_rjr") { }
+
+ class spell_q12589_shoot_rjr_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q12589_shoot_rjr_SpellScript);
+
+ SpellCastResult CheckCast()
+ {
+ if (Unit* target = GetExplTargetUnit())
+ if (target->GetEntry() == NPC_LUCKY_WILHELM)
+ return SPELL_CAST_OK;
+
+ SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_TARGET_WILHELM);
+ return SPELL_FAILED_CUSTOM_ERROR;
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ uint32 roll = urand(1, 100);
+
+ uint8 ev;
+ if (roll <= 50)
+ ev = EVENT_MISS;
+ else if (roll <= 83)
+ ev = EVENT_HIT;
+ else
+ ev = EVENT_MISS_BIRD;
+
+ Unit* shooter = GetCaster();
+ Creature* wilhelm = GetHitUnit()->ToCreature();
+ Creature* apple = shooter->FindNearestCreature(NPC_APPLE, 30);
+ Creature* drostan = shooter->FindNearestCreature(NPC_DROSTAN, 30);
+
+ if (!wilhelm || !apple || !drostan)
+ return;
+
+ switch (ev)
+ {
+ case EVENT_MISS_BIRD:
+ {
+ Creature* crunchy = shooter->FindNearestCreature(NPC_CRUNCHY, 30);
+ Creature* bird = shooter->FindNearestCreature(NPC_THICKBIRD, 30);
+
+ if (!bird || !crunchy)
+ ; // fall to EVENT_MISS
+ else
+ {
+ shooter->CastSpell(bird, SPELL_MISS_BIRD_APPLE);
+ bird->CastSpell(bird, SPELL_BIRD_FALL);
+ wilhelm->AI()->Talk(SAY_WILHELM_MISS);
+ drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS);
+
+ bird->Kill(bird);
+ crunchy->GetMotionMaster()->MovePoint(0, bird->GetPositionX(), bird->GetPositionY(),
+ bird->GetMap()->GetWaterOrGroundLevel(bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ()));
+ // TODO: Make crunchy perform emote eat when he reaches the bird
+
+ break;
+ }
+ }
+ case EVENT_MISS:
+ {
+ shooter->CastSpell(wilhelm, SPELL_MISS_APPLE);
+ wilhelm->AI()->Talk(SAY_WILHELM_MISS);
+ drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS);
+ break;
+ }
+ case EVENT_HIT:
+ {
+ shooter->CastSpell(apple, SPELL_HIT_APPLE);
+ apple->CastSpell(apple, SPELL_APPLE_FALL);
+ wilhelm->AI()->Talk(SAY_WILHELM_HIT);
+ if (Player* player = shooter->ToPlayer())
+ player->KilledMonsterCredit(NPC_APPLE, 0);
+ apple->DespawnOrUnsummon();
+
+ break;
+ }
+ }
+ }
+
+ void Register()
+ {
+ OnCheckCast += SpellCheckCastFn(spell_q12589_shoot_rjr_SpellScript::CheckCast);
+ OnEffectHitTarget += SpellEffectFn(spell_q12589_shoot_rjr_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_q12589_shoot_rjr_SpellScript();
+ }
+};
+
void AddSC_sholazar_basin()
{
new npc_injured_rainspeaker_oracle();
@@ -756,4 +880,5 @@ void AddSC_sholazar_basin()
new npc_adventurous_dwarf();
new npc_jungle_punch_target();
new spell_q12620_the_lifewarden_wrath();
+ new spell_q12589_shoot_rjr();
}
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp
index 206ba3d9455..3937b213e7e 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp
@@ -691,7 +691,7 @@ public:
Creature* Cyclone = me->SummonCreature(CREATURE_CYCLONE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), float(rand()%5), TEMPSUMMON_TIMED_DESPAWN, 15000);
if (Cyclone)
{
- CAST_CRE(Cyclone)->SetFloatValue(OBJECT_FIELD_SCALE_X, 3.0f);
+ CAST_CRE(Cyclone)->SetObjectScale(3.0f);
Cyclone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
Cyclone->setFaction(me->getFaction());
Cyclone->CastSpell(Cyclone, SPELL_CYCLONE_CYCLONE, true);
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
index 77c07f5fe4d..25207073708 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
@@ -409,7 +409,7 @@ class boss_alar : public CreatureScript
if (Summoned)
{
Summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- Summoned->SetFloatValue(OBJECT_FIELD_SCALE_X, Summoned->GetFloatValue(OBJECT_FIELD_SCALE_X)*2.5f);
+ Summoned->SetObjectScale(Summoned->GetFloatValue(OBJECT_FIELD_SCALE_X)*2.5f);
Summoned->SetDisplayId(11686);
Summoned->setFaction(me->getFaction());
Summoned->SetLevel(me->getLevel());
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp
index c0203150789..d202fdd2f44 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp
@@ -140,7 +140,7 @@ class boss_high_astromancer_solarian : public CreatureScript
me->SetArmor(defaultarmor);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetVisible(true);
- me->SetFloatValue(OBJECT_FIELD_SCALE_X, defaultsize);
+ me->SetObjectScale(defaultsize);
me->SetDisplayId(MODEL_HUMAN);
Summons.DespawnAll();
@@ -153,7 +153,7 @@ class boss_high_astromancer_solarian : public CreatureScript
void JustDied(Unit* /*killer*/)
{
- me->SetFloatValue(OBJECT_FIELD_SCALE_X, defaultsize);
+ me->SetObjectScale(defaultsize);
me->SetDisplayId(MODEL_HUMAN);
DoScriptText(SAY_DEATH, me);
if (instance)
@@ -397,7 +397,7 @@ class boss_high_astromancer_solarian : public CreatureScript
DoScriptText(SAY_VOIDB, me);
me->SetArmor(WV_ARMOR);
me->SetDisplayId(MODEL_VOIDWALKER);
- me->SetFloatValue(OBJECT_FIELD_SCALE_X, defaultsize*2.5f);
+ me->SetObjectScale(defaultsize*2.5f);
}
DoMeleeAttackIfReady();
}
diff --git a/src/server/scripts/Outland/blades_edge_mountains.cpp b/src/server/scripts/Outland/blades_edge_mountains.cpp
index cf0955ed89c..4ec1d04b6ad 100644
--- a/src/server/scripts/Outland/blades_edge_mountains.cpp
+++ b/src/server/scripts/Outland/blades_edge_mountains.cpp
@@ -774,7 +774,7 @@ class npc_simon_bunny : public CreatureScript
colorSequence.clear();
playableSequence.clear();
playerSequence.clear();
- me->SetFloatValue(OBJECT_FIELD_SCALE_X, large ? 2.0f : 1.0f);
+ me->SetObjectScale(large ? 2.0f : 1.0f);
std::list<WorldObject*> ClusterList;
Trinity::AllWorldObjectsInRange objects(me, searchDistance);
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 0c879cfb029..e23e21cf2cd 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -2052,9 +2052,9 @@ class spell_gen_defend : public SpellScriptLoader
public:
spell_gen_defend() : SpellScriptLoader("spell_gen_defend") { }
- class spell_gen_defendAuraScript : public AuraScript
+ class spell_gen_defend_AuraScript : public AuraScript
{
- PrepareAuraScript(spell_gen_defendAuraScript);
+ PrepareAuraScript(spell_gen_defend_AuraScript);
bool Validate(SpellInfo const* /*spellEntry*/)
{
@@ -2103,26 +2103,26 @@ class spell_gen_defend : public SpellScriptLoader
// Defend spells casted by NPCs (add visuals)
if (spell->Effects[EFFECT_0].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
{
- AfterEffectApply += AuraEffectApplyFn(spell_gen_defendAuraScript::RefreshVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
- OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
}
// Remove Defend spell from player when he dismounts
if (spell->Effects[EFFECT_2].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
- OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveDummyFromDriver, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
+ OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveDummyFromDriver, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
// Defend spells casted by players (add/remove visuals)
if (spell->Effects[EFFECT_1].ApplyAuraName == SPELL_AURA_DUMMY)
{
- AfterEffectApply += AuraEffectApplyFn(spell_gen_defendAuraScript::RefreshVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
- OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
}
}
};
AuraScript* GetAuraScript() const
{
- return new spell_gen_defendAuraScript();
+ return new spell_gen_defend_AuraScript();
}
};
@@ -2326,9 +2326,9 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader
public:
spell_gen_on_tournament_mount() : SpellScriptLoader("spell_gen_on_tournament_mount") { }
- class spell_gen_on_tournament_mountAuraScript : public AuraScript
+ class spell_gen_on_tournament_mount_AuraScript : public AuraScript
{
- PrepareAuraScript(spell_gen_on_tournament_mountAuraScript);
+ PrepareAuraScript(spell_gen_on_tournament_mount_AuraScript);
uint32 _pennantSpellId;
@@ -2468,14 +2468,14 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader
void Register()
{
- AfterEffectApply += AuraEffectApplyFn(spell_gen_on_tournament_mountAuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
- OnEffectRemove += AuraEffectRemoveFn(spell_gen_on_tournament_mountAuraScript::HandleRemoveEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ AfterEffectApply += AuraEffectApplyFn(spell_gen_on_tournament_mount_AuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ OnEffectRemove += AuraEffectRemoveFn(spell_gen_on_tournament_mount_AuraScript::HandleRemoveEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
AuraScript* GetAuraScript() const
{
- return new spell_gen_on_tournament_mountAuraScript();
+ return new spell_gen_on_tournament_mount_AuraScript();
}
};
@@ -2484,9 +2484,9 @@ class spell_gen_tournament_pennant : public SpellScriptLoader
public:
spell_gen_tournament_pennant() : SpellScriptLoader("spell_gen_tournament_pennant") { }
- class spell_gen_tournament_pennantAuraScript : public AuraScript
+ class spell_gen_tournament_pennant_AuraScript : public AuraScript
{
- PrepareAuraScript(spell_gen_tournament_pennantAuraScript);
+ PrepareAuraScript(spell_gen_tournament_pennant_AuraScript);
bool Load()
{
@@ -2502,13 +2502,13 @@ class spell_gen_tournament_pennant : public SpellScriptLoader
void Register()
{
- OnEffectApply += AuraEffectApplyFn(spell_gen_tournament_pennantAuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ OnEffectApply += AuraEffectApplyFn(spell_gen_tournament_pennant_AuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
AuraScript* GetAuraScript() const
{
- return new spell_gen_tournament_pennantAuraScript();
+ return new spell_gen_tournament_pennant_AuraScript();
}
};
@@ -2688,6 +2688,63 @@ public:
}
};
+class spell_gen_touch_the_nightmare : public SpellScriptLoader
+{
+public:
+ spell_gen_touch_the_nightmare() : SpellScriptLoader("spell_gen_touch_the_nightmare") { }
+
+ class spell_gen_touch_the_nightmare_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_touch_the_nightmare_SpellScript);
+
+ void HandleDamageCalc(SpellEffIndex effIndex)
+ {
+ uint32 bp = GetCaster()->GetMaxHealth() * 0.3f;
+ SetHitDamage(bp);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_gen_touch_the_nightmare_SpellScript::HandleDamageCalc, EFFECT_2, SPELL_EFFECT_SCHOOL_DAMAGE);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_gen_touch_the_nightmare_SpellScript();
+ }
+};
+
+class spell_gen_dream_funnel: public SpellScriptLoader
+{
+public:
+ spell_gen_dream_funnel() : SpellScriptLoader("spell_gen_dream_funnel") { }
+
+ class spell_gen_dream_funnel_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_dream_funnel_AuraScript);
+
+ void HandleEffectCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated)
+ {
+ if (GetCaster())
+ amount = GetCaster()->GetMaxHealth() * 0.05f;
+
+ canBeRecalculated = false;
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_dream_funnel_AuraScript::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_dream_funnel_AuraScript::HandleEffectCalcAmount, EFFECT_2, SPELL_AURA_PERIODIC_DAMAGE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_gen_dream_funnel_AuraScript();
+ }
+};
+
void AddSC_generic_spell_scripts()
{
new spell_gen_absorb0_hitlimit1();
@@ -2742,4 +2799,6 @@ void AddSC_generic_spell_scripts()
new spell_gen_count_pct_from_max_hp("spell_gen_default_count_pct_from_max_hp");
new spell_gen_count_pct_from_max_hp("spell_gen_50pct_count_pct_from_max_hp", 50);
new spell_gen_despawn_self();
+ new spell_gen_touch_the_nightmare();
+ new spell_gen_dream_funnel();
}
diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp
index 09ff5935b6e..4e2eb633662 100644
--- a/src/server/scripts/Spells/spell_item.cpp
+++ b/src/server/scripts/Spells/spell_item.cpp
@@ -1535,7 +1535,7 @@ class spell_item_impale_leviroth : public SpellScriptLoader
void HandleDummy(SpellEffIndex /* effIndex */)
{
if (Unit* target = GetHitCreature())
- if (target->GetEntry() == NPC_LEVIROTH && target->HealthBelowPct(95))
+ if (target->GetEntry() == NPC_LEVIROTH && !target->HealthBelowPct(95))
target->CastSpell(target, SPELL_LEVIROTH_SELF_IMPALE, true);
}
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index ecd1a439a58..57a65423b6f 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -47,6 +47,7 @@ EndContentData */
#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "World.h"
+#include "PetAI.h"
/*########
# npc_air_force_bots
@@ -2100,16 +2101,18 @@ class npc_shadowfiend : public CreatureScript
public:
npc_shadowfiend() : CreatureScript("npc_shadowfiend") { }
- struct npc_shadowfiendAI : public ScriptedAI
+ struct npc_shadowfiendAI : public PetAI
{
- npc_shadowfiendAI(Creature* creature) : ScriptedAI(creature) {}
+ npc_shadowfiendAI(Creature* creature) : PetAI(creature) {}
- void DamageTaken(Unit* /*killer*/, uint32& damage)
+ void JustDied(Unit* killer)
{
if (me->isSummon())
if (Unit* owner = me->ToTempSummon()->GetSummoner())
- if (owner->HasAura(GLYPH_OF_SHADOWFIEND) && damage >= me->GetHealth())
+ if (owner->HasAura(GLYPH_OF_SHADOWFIEND))
owner->CastSpell(owner, GLYPH_OF_SHADOWFIEND_MANA, true);
+
+ PetAI::JustDied(killer);
}
};
@@ -2988,6 +2991,31 @@ public:
};
};
+/*######
+## npc_generic_harpoon_cannon
+######*/
+
+class npc_generic_harpoon_cannon : public CreatureScript
+{
+public:
+ npc_generic_harpoon_cannon() : CreatureScript("npc_generic_harpoon_cannon") { }
+
+ struct npc_generic_harpoon_cannonAI : public ScriptedAI
+ {
+ npc_generic_harpoon_cannonAI(Creature* creature) : ScriptedAI(creature) {}
+
+ void Reset()
+ {
+ me->SetUnitMovementFlags(MOVEMENTFLAG_ROOT);
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_generic_harpoon_cannonAI(creature);
+ }
+};
+
void AddSC_npcs_special()
{
new npc_air_force_bots();
@@ -3020,4 +3048,5 @@ void AddSC_npcs_special()
new npc_earth_elemental();
new npc_firework();
new npc_spring_rabbit();
+ new npc_generic_harpoon_cannon();
}
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 5d837100b0e..b14038c9571 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -483,12 +483,13 @@ LogFileLevel = 0
DebugLogMask = 0
#
-# WorldLogFile
-# Description: Packet logging file for the world server.
-# Example: "World.log" - (Enabled)
+# PacketLogFile
+# Description: Binary packet logging file for the world server.
+# Filename extension must be .bin to be parsable with WowPacketParser.
+# Example: "World.bin" - (Enabled)
# Default: "" - (Disabled)
-WorldLogFile = ""
+PacketLogFile = ""
#
# DBErrorLogFile
@@ -2024,17 +2025,17 @@ Visibility.GroupMode = 1
# Visibility.Distance.Instances
# Visibility.Distance.BGArenas
# Description: Visibility distance to see other players or gameobjects.
-# Visibility on continents on retail ~90 yards. In BG/Arenas ~180.
-# For instances default ~120.
-# Max limited by active player zone: ~ 333
+# Visibility on continents on retail ~90 yards. In BG/Arenas ~533.
+# For instances default ~170.
+# Max limited by grid size: 533.33333
# Min limit is max aggro radius (45) * Rate.Creature.Aggro
# Default: 90 - (Visibility.Distance.Continents)
-# 120 - (Visibility.Distance.Instances)
-# 180 - (Visibility.Distance.BGArenas)
+# 170 - (Visibility.Distance.Instances)
+# 533 - (Visibility.Distance.BGArenas)
Visibility.Distance.Continents = 90
-Visibility.Distance.Instances = 120
-Visibility.Distance.BGArenas = 180
+Visibility.Distance.Instances = 170
+Visibility.Distance.BGArenas = 533
#
# Visibility.Notify.Period.OnContinents