diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.h | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 1 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 19 | ||||
-rwxr-xr-x | src/server/game/Entities/Vehicle/Vehicle.cpp | 26 | ||||
-rw-r--r-- | src/server/game/Entities/Vehicle/Vehicle.h | 2 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 52 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 5 | ||||
-rw-r--r-- | src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp | 2 | ||||
-rw-r--r-- | src/server/scripts/Outland/zone_shadowmoon_valley.cpp | 11 |
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() |