aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h4
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp4
-rw-r--r--src/server/game/Entities/Player/Player.cpp1
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp19
-rwxr-xr-xsrc/server/game/Entities/Vehicle/Vehicle.cpp26
-rw-r--r--src/server/game/Entities/Vehicle/Vehicle.h2
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp52
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp5
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp2
-rw-r--r--src/server/scripts/Outland/zone_shadowmoon_valley.cpp11
10 files changed, 83 insertions, 43 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index 2ff5ce27aa0..3b9109a8f38 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -104,8 +104,8 @@ enum SMART_EVENT
SMART_EVENT_REWARD_QUEST = 20, // QuestID(0any)
SMART_EVENT_REACHED_HOME = 21, // NONE
SMART_EVENT_RECEIVE_EMOTE = 22, // EmoteId, CooldownMin, CooldownMax, condition, val1, val2, val3
- SMART_EVENT_HAS_AURA = 23, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 RepeatMin, RepeatMax
- SMART_EVENT_TARGET_BUFFED = 24, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 RepeatMin, RepeatMax
+ SMART_EVENT_HAS_AURA = 23, // Param1 = SpellID, Param2 = Stack amount, Param3/4 RepeatMin, RepeatMax
+ SMART_EVENT_TARGET_BUFFED = 24, // Param1 = SpellID, Param2 = Stack amount, Param3/4 RepeatMin, RepeatMax
SMART_EVENT_RESET = 25, // Called after combat, when the creature respawn and spawn.
SMART_EVENT_IC_LOS = 26, // NoHostile, MaxRnage, CooldownMin, CooldownMax
SMART_EVENT_PASSENGER_BOARDED = 27, // CooldownMin, CooldownMax
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 6f88222bbbc..83cdb52776c 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -1294,8 +1294,8 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint3
if (!UpdateEntry(Entry, team, data))
return false;
- if (vehId && !CreateVehicleKit(vehId, Entry))
- vehId = 0;
+ if (vehId)
+ CreateVehicleKit(vehId, Entry);
return true;
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 195a9118929..6d83ea60dba 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -25689,6 +25689,7 @@ void Player::ActivateSpec(uint8 spec)
ClearComboPointHolders();
ClearAllReactives();
UnsummonAllTotems();
+ ExitVehicle();
RemoveAllControlled();
/*RemoveAllAurasOnDeath();
if (GetPet())
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 9d581fcdce9..d76885591a5 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -12419,6 +12419,9 @@ void Unit::setDeathState(DeathState s)
if (IsNonMeleeSpellCasted(false))
InterruptNonMeleeSpells(false);
+ ExitVehicle(); // Exit vehicle before calling RemoveAllControlled
+ // vehicles use special type of charm that is not removed by the next function
+ // triggering an assert
UnsummonAllTotems();
RemoveAllControlled();
RemoveAllAurasOnDeath();
@@ -16842,7 +16845,10 @@ void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* a
if (Player* player = ToPlayer())
{
if (vehicle->GetBase()->GetTypeId() == TYPEID_PLAYER && player->isInCombat())
+ {
+ vehicle->GetBase()->RemoveAura(const_cast<AuraApplication*>(aurApp));
return;
+ }
}
ASSERT(!m_vehicle);
@@ -16906,7 +16912,7 @@ void Unit::_ExitVehicle(Position const* exitPosition)
Player* player = ToPlayer();
- // If player is on mouted duel and exits the mount should immediatly lose the duel
+ // If the player is on mounted duel and exits the mount, he should immediatly lose the duel
if (player && player->duel && player->duel->isMounted)
player->DuelComplete(DUEL_FLED);
@@ -16934,14 +16940,19 @@ void Unit::_ExitVehicle(Position const* exitPosition)
SendMessageToSet(&data, false);
}
+ float height = pos.GetPositionZ();
+
Movement::MoveSplineInit init(this);
- init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), false);
+
+ // Creatures without inhabit type air should begin falling after exiting the vehicle
+ if (GetTypeId() == TYPEID_UNIT && !CanFly() && height > GetMap()->GetWaterOrGroundLevel(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), &height) + 0.1f)
+ init.SetFall();
+
+ init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), height, false);
init.SetFacing(GetOrientation());
init.SetTransportExit();
init.Launch();
- //GetMotionMaster()->MoveFall(); // Enable this once passenger positions are calculater properly (see above)
-
if (player)
player->ResummonPetTemporaryUnSummonedIfAny();
diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp
index 85215c5302b..fad9115ee3d 100755
--- a/src/server/game/Entities/Vehicle/Vehicle.cpp
+++ b/src/server/game/Entities/Vehicle/Vehicle.cpp
@@ -744,6 +744,31 @@ void Vehicle::RemovePendingEventsForSeat(int8 seatId)
}
}
+/**
+ * @fn void Vehicle::RemovePendingEventsForSeat(uint8 seatId)
+ *
+ * @brief Removes any pending events for given passenger. Executed when vehicle control aura is removed while adding passenger is in progress
+ *
+ * @author Shauren
+ * @date 13-2-2013
+ *
+ * @param passenger Unit that is supposed to enter the vehicle.
+ */
+
+void Vehicle::RemovePendingEventsForPassenger(Unit* passenger)
+{
+ for (PendingJoinEventContainer::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end();)
+ {
+ if ((*itr)->Passenger == passenger)
+ {
+ (*itr)->to_Abort = true;
+ _pendingJoinEvents.erase(itr++);
+ }
+ else
+ ++itr;
+ }
+}
+
VehicleJoinEvent::~VehicleJoinEvent()
{
if (Target)
@@ -769,6 +794,7 @@ bool VehicleJoinEvent::Execute(uint64, uint32)
{
ASSERT(Passenger->IsInWorld());
ASSERT(Target && Target->GetBase()->IsInWorld());
+ ASSERT(Target->GetBase()->HasAuraTypeWithCaster(SPELL_AURA_CONTROL_VEHICLE, Passenger->GetGUID()));
Target->RemovePendingEventsForSeat(Seat->first);
diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h
index 70b821de912..67975490ecc 100644
--- a/src/server/game/Entities/Vehicle/Vehicle.h
+++ b/src/server/game/Entities/Vehicle/Vehicle.h
@@ -71,6 +71,8 @@ class Vehicle : public TransportBase
VehicleSeatEntry const* GetSeatForPassenger(Unit const* passenger) const;
+ void RemovePendingEventsForPassenger(Unit* passenger);
+
protected:
friend class VehicleJoinEvent;
uint32 UsableSeatNum; ///< Number of seats that match VehicleSeatEntry::UsableByPlayer, used for proper display flags
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 08b05b1a7e3..effd2057c68 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -3241,7 +3241,7 @@ void ObjectMgr::LoadPlayerInfo()
uint32 oldMSTime = getMSTime();
std::string tableName = sWorld->getBoolConfig(CONFIG_START_ALL_SPELLS) ? "playercreateinfo_spell_custom" : "playercreateinfo_spell";
- QueryResult result = WorldDatabase.PQuery("SELECT race, class, Spell FROM %s", tableName.c_str());
+ QueryResult result = WorldDatabase.PQuery("SELECT racemask, classmask, Spell FROM %s", tableName.c_str());
if (!result)
{
@@ -3254,41 +3254,43 @@ void ObjectMgr::LoadPlayerInfo()
do
{
Field* fields = result->Fetch();
+ uint32 raceMask = fields[0].GetUInt32();
+ uint32 classMask = fields[1].GetUInt32();
+ uint32 spellId = fields[2].GetUInt32();
- uint32 current_race = fields[0].GetUInt8();
- if (current_race >= MAX_RACES)
+ if (raceMask != 0 && !(raceMask & RACEMASK_ALL_PLAYABLE))
{
- sLog->outError(LOG_FILTER_SQL, "Wrong race %u in `playercreateinfo_spell` table, ignoring.", current_race);
+ sLog->outError(LOG_FILTER_SQL, "Wrong race mask %u in `playercreateinfo_spell` table, ignoring.", raceMask);
continue;
}
- uint32 current_class = fields[1].GetUInt8();
- if (current_class >= MAX_CLASSES)
+ if (classMask != 0 && !(classMask & CLASSMASK_ALL_PLAYABLE))
{
- sLog->outError(LOG_FILTER_SQL, "Wrong class %u in `playercreateinfo_spell` table, ignoring.", current_class);
+ sLog->outError(LOG_FILTER_SQL, "Wrong class mask %u in `playercreateinfo_spell` table, ignoring.", classMask);
continue;
}
- if (!current_race || !current_class)
+ for (uint32 raceIndex = RACE_HUMAN; raceIndex < MAX_RACES; ++raceIndex)
{
- uint32 min_race = current_race ? current_race : 1;
- uint32 max_race = current_race ? current_race + 1 : MAX_RACES;
- uint32 min_class = current_class ? current_class : 1;
- uint32 max_class = current_class ? current_class + 1 : MAX_CLASSES;
- for (uint32 r = min_race; r < max_race; ++r)
- for (uint32 c = min_class; c < max_class; ++c)
- if (PlayerInfo* info = _playerInfo[r][c])
- info->spell.push_back(fields[2].GetUInt32());
- }
- else if (PlayerInfo* info = _playerInfo[current_race][current_class])
- info->spell.push_back(fields[2].GetUInt32());
- else
- {
- sLog->outError(LOG_FILTER_SQL, "Wrong race: %u, class: %u combination in `playercreateinfo_spell` table, ignoring.", current_race, current_class);
- continue;
+ if (raceMask == 0 || ((1 << (raceIndex - 1)) & raceMask))
+ {
+ for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex)
+ {
+ if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
+ {
+ if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
+ {
+ info->spell.push_back(spellId);
+ ++count;
+ }
+ // We need something better here, the check is not accounting for spells used by multiple races/classes but not all of them.
+ // Either split the masks per class, or per race, which kind of kills the point yet.
+ // else if (raceMask != 0 && classMask != 0)
+ // sLog->outError(LOG_FILTER_SQL, "Racemask/classmask (%u/%u) combination was found containing an invalid race/class combination (%u/%u) in `playercreateinfo_spell` (Spell %u), ignoring.", raceMask, classMask, raceIndex, classIndex, spellId);
+ }
+ }
+ }
}
-
- ++count;
}
while (result->NextRow());
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index e3d266eaaa5..24c58a666d1 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -2323,7 +2323,7 @@ void AuraEffect::HandleAuraModPacifyAndSilence(AuraApplication const* aurApp, ui
Unit* target = aurApp->GetTarget();
// Vengeance of the Blue Flight (@todo REMOVE THIS!)
- /// @workaround
+ /// @workaround
if (m_spellInfo->Id == 45839)
{
if (apply)
@@ -2926,6 +2926,9 @@ void AuraEffect::HandleAuraControlVehicle(AuraApplication const* aurApp, uint8 m
}
else
{
+ // Remove pending passengers before exiting vehicle - might cause an Uninstall
+ target->GetVehicleKit()->RemovePendingEventsForPassenger(caster);
+
if (GetId() == 53111) // Devour Humanoid
{
target->Kill(caster);
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
index 8b771f507c2..3d22bac4376 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
@@ -54,7 +54,7 @@ enum Yells
SAY_SYLVANAS_OUTRO_4 = 4
};
-enum Spelsl
+enum Spells
{
SPELL_OVERLORD_BRAND = 69172,
SPELL_OVERLORD_BRAND_HEAL = 69190,
diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
index 5a9fcba8fd4..b8f96e373f3 100644
--- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
+++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
@@ -1891,16 +1891,11 @@ class spell_unlocking_zuluheds_chains : public SpellScriptLoader
{
PrepareSpellScript(spell_unlocking_zuluheds_chains_SpellScript);
- bool Load()
- {
- return GetCaster()->GetTypeId() == TYPEID_PLAYER;
- }
-
void HandleAfterHit()
{
- Player* caster = GetCaster()->ToPlayer();
- if (caster->GetQuestStatus(QUEST_ZULUHED) == QUEST_STATUS_INCOMPLETE)
- caster->KilledMonsterCredit(NPC_KARYNAKU, 0);
+ if (GetCaster()->GetTypeId() == TYPEID_PLAYER)
+ if (Creature* karynaku = GetCaster()->FindNearestCreature(NPC_KARYNAKU, 15.0f))
+ GetCaster()->ToPlayer()->CastedCreatureOrGO(NPC_KARYNAKU, karynaku->GetGUID(), GetSpellInfo()->Id);
}
void Register()