Core/Creatures: Various fixes for creatures, regarding combat conditions, despawning, and few others (#18998)

* Made some changes to kiting mechanics, simplified code and made taunt auras prolong combat no matter the distance from the spawn
Unified some creature despawning code, removed some brutal direct calls in scripts
Don't play death anim on forced despawn
Removed some redundant visibility changes on creature despawn
Fixed possible problem with pet initializing template info from difficulty greater than normal
Properly keep UNIT_FLAG_IN_COMBAT on UpdateEntry call
Moved RegenerateMana function to general Regenerate(Power) function
Fixed increased health regeneration from polymorph for pets
Implemented CREATURE_TYPE_FLAG_GHOST_VISIBLE, those creatures will be properly seen when player is dead also
Removed hackfix from Gaeriyan and Franclorn Forgewright, fixed properly
Simplified ForcedRespawnTime code in ForcedDespawn
Do not allow to assist unit while evading or when enemy is evading
Do not allow to attack other units when evading or when the unit is evading
Corrected distance checking code before creature is allowed to evade, should fix some common problems
Properly return summon position for summoned creatures as their respawn position
Properly stop all moving units on gossip hello, no matter their npc flags

(cherrypicked from e1f14215d86fc9f0cd041f0e87bf0a689c086329)
This commit is contained in:
xinef1
2019-07-21 21:06:54 +02:00
committed by Shauren
parent a68911472e
commit fe63cd3dbb
34 changed files with 233 additions and 197 deletions
@@ -0,0 +1,13 @@
-- Franclorn Forgewright
SET @ENTRY := 8888;
UPDATE `creature_template` SET `npcflag`=`npcflag`&~0x8000 WHERE `entry`=@ENTRY;
-- Gaeriyan
SET @ENTRY := 9299;
UPDATE `creature_template` SET `npcflag`=`npcflag`&~0x8000 WHERE `entry`=@ENTRY;
UPDATE `creature_template_addon` SET `auras`='10848' WHERE `entry`=@ENTRY;
-- Shroud of Death Spell
DELETE FROM `spell_script_names` WHERE spell_id=10848;
INSERT INTO `spell_script_names` VALUES(10848, 'spell_gen_shroud_of_death');
+130 -65
View File
@@ -178,7 +178,8 @@ _pickpocketLootRestore(0), m_corpseRemoveTime(0), m_respawnTime(0),
m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_boundaryCheckTime(2500), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE),
m_defaultMovementType(IDLE_MOTION_TYPE), m_spawnId(UI64LIT(0)), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false),
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_cannotReachTarget(false), m_cannotReachTimer(0), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
m_originalEntry(0), m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_waypointID(0), m_path_id(0), m_formation(nullptr), m_focusSpell(nullptr), m_focusDelay(0), m_shouldReacquireTarget(false), m_suppressedOrientation(0.0f)
m_originalEntry(0), m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_waypointID(0), m_path_id(0), m_formation(nullptr), m_focusSpell(nullptr), m_focusDelay(0), m_shouldReacquireTarget(false), m_suppressedOrientation(0.0f),
_lastDamagedTime(0)
{
m_regenTimer = CREATURE_REGEN_INTERVAL;
@@ -244,12 +245,7 @@ void Creature::RemoveFromWorld()
void Creature::DisappearAndDie()
{
DestroyForNearbyPlayers();
//SetVisibility(VISIBILITY_OFF);
//ObjectAccessor::UpdateObjectVisibility(this);
if (IsAlive())
setDeathState(JUST_DIED);
RemoveCorpse(false);
ForcedDespawn(0);
}
void Creature::SearchFormation()
@@ -266,7 +262,7 @@ void Creature::SearchFormation()
sFormationMgr->AddCreatureToGroup(frmdata->second->leaderGUID, this);
}
void Creature::RemoveCorpse(bool setSpawnTime)
void Creature::RemoveCorpse(bool setSpawnTime, bool destroyForNearbyPlayers)
{
if (getDeathState() != CORPSE)
return;
@@ -280,6 +276,9 @@ void Creature::RemoveCorpse(bool setSpawnTime)
if (IsAIEnabled)
AI()->CorpseRemoved(respawnDelay);
if (destroyForNearbyPlayers)
DestroyForNearbyPlayers();
// Should get removed later, just keep "compatibility" with scripts
if (setSpawnTime)
m_respawnTime = std::max<time_t>(time(NULL) + respawnDelay, m_respawnTime);
@@ -290,6 +289,20 @@ void Creature::RemoveCorpse(bool setSpawnTime)
float x, y, z, o;
GetRespawnPosition(x, y, z, &o);
// We were spawned on transport, calculate real position
if (IsSpawnedOnTransport())
{
Position& pos = m_movementInfo.transport.pos;
pos.m_positionX = x;
pos.m_positionY = y;
pos.m_positionZ = z;
pos.SetOrientation(o);
if (TransportBase* transport = GetDirectTransport())
transport->CalculatePassengerPosition(x, y, z, &o);
}
SetHomePosition(x, y, z, o);
GetMap()->CreatureRelocation(this, x, y, z, o);
}
@@ -426,6 +439,11 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/,
SetNpcFlags(NPCFlags(npcFlags & 0xFFFFFFFF));
SetNpcFlags2(NPCFlags2(npcFlags >> 32));
// if unit is in combat, keep this flag
unitFlags &= ~UNIT_FLAG_IN_COMBAT;
if (IsInCombat())
unitFlags |= UNIT_FLAG_IN_COMBAT;
SetUnitFlags(UnitFlags(unitFlags));
SetUnitFlags2(UnitFlags2(unitFlags2));
SetUnitFlags3(UnitFlags3(unitFlags3));
@@ -434,8 +452,6 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/,
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::StateAnimID), sAnimationDataStore.GetNumRows());
RemoveUnitFlag(UNIT_FLAG_IN_COMBAT);
SetBaseAttackTime(BASE_ATTACK, cInfo->BaseAttackTime);
SetBaseAttackTime(OFF_ATTACK, cInfo->BaseAttackTime);
SetBaseAttackTime(RANGED_ATTACK, cInfo->RangeAttackTime);
@@ -680,13 +696,11 @@ void Creature::Update(uint32 diff)
if (!IsInEvadeMode() && (!bInCombat || IsPolymorphed() || CanNotReachTarget())) // regenerate health if not in combat or if polymorphed
RegenerateHealth();
if (HasUnitFlag2(UNIT_FLAG2_REGENERATE_POWER))
{
if (GetPowerType() == POWER_ENERGY)
Regenerate(POWER_ENERGY);
else
RegenerateMana();
}
if (GetPowerType() == POWER_ENERGY)
Regenerate(POWER_ENERGY);
else
Regenerate(POWER_MANA);
m_regenTimer = CREATURE_REGEN_INTERVAL;
}
@@ -706,32 +720,57 @@ void Creature::Update(uint32 diff)
sScriptMgr->OnCreatureUpdate(this, diff);
}
void Creature::RegenerateMana()
void Creature::Regenerate(Powers power)
{
uint32 curValue = GetPower(POWER_MANA);
uint32 maxValue = GetMaxPower(POWER_MANA);
uint32 curValue = GetPower(power);
uint32 maxValue = GetMaxPower(power);
if (!HasUnitFlag2(UNIT_FLAG2_REGENERATE_POWER))
return;
if (curValue >= maxValue)
return;
uint32 addvalue = 0;
float addvalue = 0.0f;
// Combat and any controlled creature
if (IsInCombat() || !GetCharmerOrOwnerGUID().IsEmpty())
switch (power)
{
float ManaIncreaseRate = sWorld->getRate(RATE_POWER_MANA);
addvalue = uint32((27.0f / 5.0f + 17.0f) * ManaIncreaseRate);
case POWER_FOCUS:
{
// For hunter pets.
addvalue = 24 * sWorld->getRate(RATE_POWER_FOCUS);
break;
}
case POWER_ENERGY:
{
// For deathknight's ghoul.
addvalue = 20;
break;
}
case POWER_MANA:
{
// Combat and any controlled creature
if (IsInCombat() || GetCharmerOrOwnerGUID().IsEmpty())
{
float ManaIncreaseRate = sWorld->getRate(RATE_POWER_MANA);
addvalue = uint32((27.0f / 5.0f + 17.0f) * ManaIncreaseRate);
}
else
addvalue = maxValue / 3;
break;
}
default:
return;
}
else
addvalue = maxValue / 3;
// Apply modifiers (if any).
addvalue *= GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, POWER_MANA);
addvalue *= GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, power);
addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) * CREATURE_REGEN_INTERVAL / (5 * IN_MILLISECONDS);
addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, power) * (IsHunterPet() ? PET_FOCUS_REGEN_INTERVAL : CREATURE_REGEN_INTERVAL) / (5 * IN_MILLISECONDS);
ModifyPower(POWER_MANA, addvalue);
ModifyPower(power, int32(addvalue));
}
void Creature::RegenerateHealth()
@@ -747,8 +786,8 @@ void Creature::RegenerateHealth()
uint32 addvalue = 0;
// Not only pet, but any controlled creature
if (!GetCharmerOrOwnerGUID().IsEmpty())
// Not only pet, but any controlled creature (and not polymorphed)
if (!GetCharmerOrOwnerGUID().IsEmpty() && !IsPolymorphed())
{
float HealthIncreaseRate = sWorld->getRate(RATE_HEALTH);
@@ -891,6 +930,10 @@ bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 entry, float
return false;
}
// Allow players to see those units while dead, do it here (mayby altered by addon auras)
if (cinfo->type_flags & CREATURE_TYPE_FLAG_GHOST_VISIBLE)
m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE | GHOST_VISIBILITY_GHOST);
if (!CreateFromProto(guidlow, entry, data, vehId))
return false;
@@ -1833,7 +1876,7 @@ void Creature::Respawn(bool force)
setDeathState(CORPSE);
}
RemoveCorpse(false);
RemoveCorpse(false, false);
if (getDeathState() == DEAD)
{
@@ -1891,29 +1934,21 @@ void Creature::ForcedDespawn(uint32 timeMSToDespawn, Seconds const& forceRespawn
return;
}
// do it before killing creature
DestroyForNearbyPlayers();
if (IsAlive())
setDeathState(JUST_DIED);
bool overrideRespawnTime = true;
if (forceRespawnTimer > Seconds::zero())
{
if (IsAlive())
{
uint32 respawnDelay = m_respawnDelay;
uint32 corpseDelay = m_corpseDelay;
m_respawnDelay = forceRespawnTimer.count();
m_corpseDelay = 0;
setDeathState(JUST_DIED);
m_respawnDelay = respawnDelay;
m_corpseDelay = corpseDelay;
}
else
{
m_corpseRemoveTime = time(NULL);
m_respawnTime = time(NULL) + forceRespawnTimer.count();
}
SetRespawnTime(forceRespawnTimer.count());
overrideRespawnTime = false;
}
else
if (IsAlive())
setDeathState(JUST_DIED);
RemoveCorpse(false);
// Skip corpse decay time
RemoveCorpse(overrideRespawnTime, false);
}
void Creature::DespawnOrUnsummon(uint32 msTimeToDespawn /*= 0*/, Seconds const& forceRespawnTimer /*= 0*/)
@@ -2198,6 +2233,14 @@ bool Creature::CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction /
if (!IsAlive())
return false;
// we cannot assist in evade mode
if (IsInEvadeMode())
return false;
// or if enemy is in evade mode
if (enemy->GetTypeId() == TYPEID_UNIT && enemy->ToCreature()->IsInEvadeMode())
return false;
// we don't need help from non-combatant ;)
if (IsCivilian())
return false;
@@ -2291,21 +2334,40 @@ bool Creature::CanCreatureAttack(Unit const* victim, bool /*force*/) const
if (IsAIEnabled && !AI()->CanAIAttack(victim))
return false;
if (GetMap()->IsDungeon())
return true;
// we cannot attack in evade mode
if (IsInEvadeMode())
return false;
// if the mob is actively being damaged, do not reset due to distance unless it's a world boss
if (!isWorldBoss())
if (time(NULL) - GetLastDamagedTime() <= MAX_AGGRO_RESET_TIME)
// or if enemy is in evade mode
if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode())
return false;
if (!GetCharmerOrOwnerGUID().IsPlayer())
{
if (GetMap()->IsDungeon())
return true;
//Use AttackDistance in distance check if threat radius is lower. This prevents creature bounce in and out of combat every update tick.
float dist = std::max(GetAttackDistance(victim), sWorld->getFloatConfig(CONFIG_THREAT_RADIUS)) + m_CombatDistance;
// don't check distance to home position if recently damaged, this should include taunt auras
if (!isWorldBoss() && (GetLastDamagedTime() > sWorld->GetGameTime() || HasAuraType(SPELL_AURA_MOD_TAUNT)))
return true;
}
// Map visibility range, but no more than 2*cell size
float dist = std::min<float>(GetMap()->GetVisibilityRange(), SIZE_OF_GRID_CELL * 2);
if (Unit* unit = GetCharmerOrOwner())
return victim->IsWithinDist(unit, dist);
else
return victim->IsInDist(&m_homePosition, dist);
{
// include sizes for huge npcs
dist += GetObjectSize() + victim->GetObjectSize();
// to prevent creatures in air ignore attacks because distance is already too high...
if (GetCreatureTemplate()->InhabitType & INHABIT_AIR)
return victim->IsInDist2d(&m_homePosition, dist);
else
return victim->IsInDist(&m_homePosition, dist);
}
}
CreatureAddon const* Creature::GetCreatureAddon() const
@@ -2468,6 +2530,7 @@ time_t Creature::GetRespawnTimeEx() const
void Creature::GetRespawnPosition(float &x, float &y, float &z, float* ori, float* dist) const
{
// for npcs on transport, this will return transport offset
if (m_spawnId)
{
if (CreatureData const* data = sObjectMgr->GetCreatureData(GetSpawnId()))
@@ -2484,11 +2547,13 @@ void Creature::GetRespawnPosition(float &x, float &y, float &z, float* ori, floa
}
}
x = GetPositionX();
y = GetPositionY();
z = GetPositionZ();
// changed this from current position to home position, fixes world summons with infinite duration (wg npcs for example)
Position homePos = GetHomePosition();
x = homePos.GetPositionX();
y = homePos.GetPositionY();
z = homePos.GetPositionZ();
if (ori)
*ori = GetOrientation();
*ori = homePos.GetOrientation();
if (dist)
*dist = 0;
}
+8 -3
View File
@@ -88,7 +88,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
ObjectGuid::LowType GetSpawnId() const { return m_spawnId; }
void Update(uint32 time) override; // overwrited Unit::Update
void GetRespawnPosition(float &x, float &y, float &z, float* ori = nullptr, float* dist =nullptr) const;
void GetRespawnPosition(float &x, float &y, float &z, float* ori = nullptr, float* dist = nullptr) const;
bool IsSpawnedOnTransport() const { return m_creatureData && m_creatureData->mapid != GetMapId(); }
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
uint32 GetCorpseDelay() const { return m_corpseDelay; }
@@ -240,7 +241,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
MovementGeneratorType GetDefaultMovementType() const { return m_defaultMovementType; }
void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; }
void RemoveCorpse(bool setSpawnTime = true);
void RemoveCorpse(bool setSpawnTime = true, bool destroyForNearbyPlayers = true);
void DespawnOrUnsummon(uint32 msTimeToDespawn = 0, Seconds const& forceRespawnTime = Seconds(0));
void DespawnOrUnsummon(Milliseconds const& time, Seconds const& forceRespawnTime = Seconds(0)) { DespawnOrUnsummon(uint32(time.count()), forceRespawnTime); }
@@ -334,6 +335,10 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
bool IsFocusing(Spell const* focusSpell = nullptr, bool withDelay = false);
void ReleaseFocus(Spell const* focusSpell = nullptr, bool withDelay = true);
// Part of Evade mechanics
time_t GetLastDamagedTime() const { return _lastDamagedTime; }
void SetLastDamagedTime(time_t val) { _lastDamagedTime = val; }
CreatureTextRepeatIds GetTextRepeatGroup(uint8 textGroup);
void SetTextRepeatId(uint8 textGroup, uint8 id);
void ClearTextRepeatGroup(uint8 textGroup);
@@ -365,7 +370,6 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
uint32 m_combatPulseDelay; // (secs) how often the creature puts the entire zone in combat (only works in dungeons)
ReactStates m_reactState; // for AI, not charmInfo
void RegenerateMana();
void RegenerateHealth();
void Regenerate(Powers power);
MovementGeneratorType m_defaultMovementType;
@@ -415,6 +419,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
ObjectGuid m_suppressedTarget; // Stores the creature's "real" target while casting
float m_suppressedOrientation; // Stores the creature's "real" orientation while casting
time_t _lastDamagedTime; // Part of Evade mechanics
CreatureTextRepeatGroup m_textRepeat;
};
@@ -286,6 +286,7 @@ enum CreatureFlagsExtra
CREATURE_FLAG_EXTRA_GUARD | CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING | CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ | CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK)
const uint32 CREATURE_REGEN_INTERVAL = 2 * IN_MILLISECONDS;
const uint32 PET_FOCUS_REGEN_INTERVAL = 4 * IN_MILLISECONDS;
const uint32 CREATURE_NOPATH_EVADE_TIME = 5 * IN_MILLISECONDS;
const uint8 MAX_KILL_CREDIT = 2;
-36
View File
@@ -633,42 +633,6 @@ void Pet::Update(uint32 diff)
Creature::Update(diff);
}
void Creature::Regenerate(Powers power)
{
uint32 curValue = GetPower(power);
uint32 maxValue = GetMaxPower(power);
if (curValue >= maxValue)
return;
float addvalue = 0.0f;
switch (power)
{
case POWER_FOCUS:
{
// For hunter pets.
addvalue = 24 * sWorld->getRate(RATE_POWER_FOCUS);
break;
}
case POWER_ENERGY:
{
// For deathknight's ghoul.
addvalue = 20;
break;
}
default:
return;
}
// Apply modifiers (if any).
addvalue *= GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, power);
addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, power) * (IsHunterPet() ? PET_FOCUS_REGEN_INTERVAL : CREATURE_REGEN_INTERVAL) / (5 * IN_MILLISECONDS);
ModifyPower(power, int32(addvalue));
}
void Pet::Remove(PetSaveMode mode, bool returnreagent)
{
GetOwner()->RemovePet(this, mode, returnreagent);
-1
View File
@@ -22,7 +22,6 @@
#include "PetDefines.h"
#include "TemporarySummon.h"
#define PET_FOCUS_REGEN_INTERVAL 4 * IN_MILLISECONDS
#define HAPPINESS_LEVEL_SIZE 333000
struct PetSpell
+7 -15
View File
@@ -291,7 +291,7 @@ Unit::Unit(bool isWorldObject) :
m_removedAurasCount(0), i_motionMaster(new MotionMaster(this)), m_regenTimer(0), m_ThreatManager(this),
m_vehicle(NULL), m_vehicleKit(NULL), m_unitTypeMask(UNIT_MASK_NONE),
m_HostileRefManager(this), _aiAnimKitId(0), _movementAnimKitId(0), _meleeAnimKitId(0),
_lastDamagedTime(0), _spellHistory(new SpellHistory(this))
_spellHistory(new SpellHistory(this))
{
m_objectType |= TYPEMASK_UNIT;
m_objectTypeId = TYPEID_UNIT;
@@ -877,13 +877,16 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
victim->ModifyHealth(-(int32)damage);
if (damagetype == DIRECT_DAMAGE || damagetype == SPELL_DIRECT_DAMAGE)
{
victim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DIRECT_DAMAGE, spellProto ? spellProto->Id : 0);
victim->UpdateLastDamagedTime(spellProto);
}
if (victim->GetTypeId() != TYPEID_PLAYER)
{
// Part of Evade mechanics. DoT's and Thorns / Retribution Aura do not contribute to this
if (damagetype != DOT && damage > 0 && !victim->GetOwnerGUID().IsPlayer() && (!spellProto || !spellProto->HasAura(GetMap()->GetDifficultyID(), SPELL_AURA_DAMAGE_SHIELD)))
victim->ToCreature()->SetLastDamagedTime(sWorld->GetGameTime() + MAX_AGGRO_RESET_TIME);
victim->AddThreat(this, float(damage), damageSchoolMask, spellProto);
}
else // victim is a player
{
// random durability for items (HIT TAKEN)
@@ -13914,17 +13917,6 @@ int32 Unit::GetHighestExclusiveSameEffectSpellGroupValue(AuraEffect const* aurEf
return val;
}
void Unit::UpdateLastDamagedTime(SpellInfo const* spellProto)
{
if (GetTypeId() != TYPEID_UNIT || IsPet())
return;
if (spellProto && spellProto->HasAura(DIFFICULTY_NONE, SPELL_AURA_DAMAGE_SHIELD))
return;
SetLastDamagedTime(time(NULL));
}
bool Unit::IsHighestExclusiveAura(Aura const* aura, bool removeOtherAuraApplications /*= false*/)
{
for (AuraEffect* aurEff : aura->GetAuraEffects())
-7
View File
@@ -1991,11 +1991,6 @@ class TC_GAME_API Unit : public WorldObject
// Movement info
Movement::MoveSpline * movespline;
// Part of Evade mechanics
time_t GetLastDamagedTime() const { return _lastDamagedTime; }
void UpdateLastDamagedTime(SpellInfo const* spellProto);
void SetLastDamagedTime(time_t val) { _lastDamagedTime = val; }
int32 GetHighestExclusiveSameEffectSpellGroupValue(AuraEffect const* aurEff, AuraType auraType, bool checkMiscValue = false, int32 miscValue = 0) const;
bool IsHighestExclusiveAura(Aura const* aura, bool removeOtherAuraApplications = false);
@@ -2146,8 +2141,6 @@ class TC_GAME_API Unit : public WorldObject
uint16 _movementAnimKitId;
uint16 _meleeAnimKitId;
time_t _lastDamagedTime; // Part of Evade mechanics
SpellHistory* _spellHistory;
};
+2 -1
View File
@@ -168,7 +168,8 @@ void WorldSession::HandleGossipHelloOpcode(WorldPackets::NPC::Hello& packet)
//if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
// GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
if (unit->IsArmorer() || unit->IsCivilian() || unit->IsQuestGiver() || unit->IsServiceProvider() || unit->IsGuard())
// and if he has pure gossip or is banker and moves or is tabard designer?
//if (unit->IsArmorer() || unit->IsCivilian() || unit->IsQuestGiver() || unit->IsServiceProvider() || unit->IsGuard())
unit->StopMoving();
// If spiritguide, no need for gossip menu, just put player into resurrect queue
+1 -1
View File
@@ -172,7 +172,7 @@ bool OPvPCapturePoint::DelCreature(uint32 type)
++itr;
// Don't save respawn time
c->SetRespawnTime(0);
c->RemoveCorpse();
c->DespawnOrUnsummon();
c->AddObjectToRemoveList();
}
@@ -2943,7 +2943,7 @@ void AuraEffect::HandleAuraControlVehicle(AuraApplication const* aurApp, uint8 m
{
target->Kill(caster);
if (caster->GetTypeId() == TYPEID_UNIT)
caster->ToCreature()->RemoveCorpse();
caster->ToCreature()->DespawnOrUnsummon();
}
if (!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT))
+1 -4
View File
@@ -3188,10 +3188,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
{
caster->RewardPlayerAndGroupAtEvent(18388, unitTarget);
if (Creature* target = unitTarget->ToCreature())
{
target->setDeathState(CORPSE);
target->RemoveCorpse();
}
target->DespawnOrUnsummon();
}
break;
// Mug Transformation
+1 -2
View File
@@ -98,8 +98,7 @@ public:
return false;
}
creatureTarget->setDeathState(JUST_DIED);
creatureTarget->RemoveCorpse();
creatureTarget->DespawnOrUnsummon();
creatureTarget->SetHealth(0); // just for nice GM-mode view
pet->SetCreatorGUID(player->GetGUID());
@@ -196,10 +196,7 @@ public:
{
if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
{
if (summon->IsAlive())
summon->DisappearAndDie();
else
summon->RemoveCorpse();
summon->DespawnOrUnsummon();
}
}
}
@@ -480,8 +480,7 @@ public:
}
else
{
me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
me->RemoveCorpse();
me->DespawnOrUnsummon();
}
}
void EnterCombat(Unit* /*who*/) override { }
@@ -499,9 +499,7 @@ public:
me->SummonCreature(NPC_DEAD, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
}
(*i)->SetVisible(false);
(*i)->setDeathState(JUST_DIED);
if ((*i)->getDeathState() == CORPSE)
(*i)->RemoveCorpse();
(*i)->DespawnOrUnsummon();
}
}
};
@@ -1174,8 +1174,7 @@ public:
uiTimer = 5000;
break;
case 3:
me->KillSelf();
me->RemoveCorpse();
me->DespawnOrUnsummon();
break;
}
} else uiTimer -=diff;
@@ -228,8 +228,7 @@ class instance_uldaman : public InstanceMapScript
Creature* target = instance->GetCreature(*i);
if (!target || target->isDead() || target->getFaction() != 14)
continue;
target->setDeathState(JUST_DIED);
target->RemoveCorpse();
target->DespawnOrUnsummon();
}
// Vault Walkers
@@ -238,8 +237,7 @@ class instance_uldaman : public InstanceMapScript
Creature* target = instance->GetCreature(*i);
if (!target || target->isDead() || target->getFaction() != 14)
continue;
target->setDeathState(JUST_DIED);
target->RemoveCorpse();
target->DespawnOrUnsummon();
}
// Earthen Guardians
@@ -248,8 +246,7 @@ class instance_uldaman : public InstanceMapScript
Creature* target = instance->GetCreature(*i);
if (!target || target->isDead() || target->getFaction() != 14)
continue;
target->setDeathState(JUST_DIED);
target->RemoveCorpse();
target->DespawnOrUnsummon();
}
}
@@ -240,8 +240,7 @@ public:
Creature* boss = ObjectAccessor::GetCreature(*me, AnetheronGUID);
if (!boss || boss->isDead())
{
me->setDeathState(JUST_DIED);
me->RemoveCorpse();
me->DespawnOrUnsummon();
return;
}
}
@@ -249,8 +249,7 @@ public:
Creature* boss = ObjectAccessor::GetCreature(*me, AzgalorGUID);
if (!boss || boss->isDead())
{
me->setDeathState(JUST_DIED);
me->RemoveCorpse();
me->DespawnOrUnsummon();
return;
}
}
@@ -577,8 +577,7 @@ public:
{
if ((faction == 0 && LastOverronPos == 17) || (faction == 1 && LastOverronPos == 21))
{
me->setDeathState(DEAD);
me->RemoveCorpse();
me->DespawnOrUnsummon();
}
}
}
@@ -677,8 +676,7 @@ public:
me->SetEmoteState(EMOTE_ONESHOT_ATTACK_UNARMED);
if ((faction == 0 && LastOverronPos == 17) || (faction == 1 && LastOverronPos == 21))
{
me->setDeathState(DEAD);
me->RemoveCorpse();
me->DespawnOrUnsummon();
}
}
}
@@ -207,8 +207,7 @@ public:
//if we reach this it means event was running but at some point reset.
if (instance->GetData(TYPE_MEDIVH) == NOT_STARTED)
{
me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
me->RemoveCorpse();
me->DespawnOrUnsummon();
me->Respawn();
return;
}
@@ -128,7 +128,7 @@ class boss_skeram : public CreatureScript
if (!me->IsSummon())
Talk(SAY_DEATH);
else
me->RemoveCorpse();
me->DespawnOrUnsummon();
}
void EnterCombat(Unit* /*who*/) override
@@ -936,7 +936,7 @@ public:
void npc_qiraj_war_spawn::npc_qiraj_war_spawnAI::JustDied(Unit* /*slayer*/)
{
me->RemoveCorpse();
me->DespawnOrUnsummon();
if (!MobGUID)
return;
@@ -276,7 +276,7 @@ struct boss_four_horsemen_baseAI : public BossAI
{
if (Creature* cBoss = getHorsemanHandle(boss))
{
cBoss->DespawnOrUnsummon(0);
cBoss->DespawnOrUnsummon();
cBoss->SetRespawnTime(15);
}
else
@@ -248,7 +248,7 @@ class npc_iron_roots : public CreatureScript
target->RemoveAurasDueToSpell(SPELL_ROOTS_FREYA);
}
me->RemoveCorpse(false);
me->DespawnOrUnsummon();
}
private:
@@ -172,8 +172,7 @@ public:
{
if (Creature* mob = ObjectAccessor::GetCreature(*me, beams[i]))
{
mob->setDeathState(DEAD);
mob->RemoveCorpse();
mob->DespawnOrUnsummon();
}
}
}
@@ -805,9 +805,9 @@ public:
if (!Vashj || !Vashj->IsAlive() || ENSURE_AI(boss_lady_vashj::boss_lady_vashjAI, Vashj->ToCreature()->AI())->Phase != 3)
{
// remove
me->setDeathState(DEAD);
me->RemoveCorpse();
me->setFaction(35);
me->DespawnOrUnsummon();
return;
}
CheckTimer = 1000;
@@ -179,11 +179,7 @@ class boss_warchief_kargath_bladefist : public CreatureScript
{
Creature* creature = ObjectAccessor::GetCreature(*me, *itr);
if (creature && creature->IsAlive())
{
creature->GetMotionMaster()->Clear(true);
me->DealDamage(creature, creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
creature->RemoveCorpse();
}
creature->DespawnOrUnsummon();
}
adds.clear();
@@ -191,11 +187,7 @@ class boss_warchief_kargath_bladefist : public CreatureScript
{
Creature* creature = ObjectAccessor::GetCreature(*me, *itr);
if (creature && creature->IsAlive())
{
creature->GetMotionMaster()->Clear(true);
me->DealDamage(creature, creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
creature->RemoveCorpse();
}
creature->DespawnOrUnsummon();
}
assassins.clear();
}
@@ -196,8 +196,8 @@ class npc_ragin_flames : public CreatureScript
if (instance->GetData(DATA_NETHERMANCER_SEPRETHREA) != IN_PROGRESS)
{
//remove
me->setDeathState(JUST_DIED);
me->RemoveCorpse();
me->DespawnOrUnsummon();
return;
}
Check_Timer = 1000;
} else Check_Timer -= diff;
@@ -232,8 +232,8 @@ class npc_nether_wraith : public CreatureScript
{
if (Die_Timer <= diff)
{
me->setDeathState(JUST_DIED);
me->RemoveCorpse();
me->DespawnOrUnsummon();
return;
}
else
Die_Timer -= diff;
@@ -123,11 +123,7 @@ public:
return;
if (id == 0)
{
me->setDeathState(JUST_DIED);
me->RemoveCorpse();
me->SetHealth(0);
}
me->DespawnOrUnsummon(1);
}
void SpellHit(Unit* caster, const SpellInfo* spell) override
@@ -155,7 +151,8 @@ public:
EnterEvadeMode();
me->AddUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
IsNihil = true;
}else
}
else
AttackStart(caster);
}
}
@@ -384,7 +384,6 @@ public:
FlyTimer = 10000;
me->SetDisableGravity(false);
me->SetVisible(true);
}
void SpellHit(Unit* caster, const SpellInfo* spell) override
@@ -428,10 +427,8 @@ public:
PlayerGUID.Clear();
}
me->SetVisible(false);
me->SetDisableGravity(false);
me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
me->RemoveCorpse();
me->DespawnOrUnsummon(1);
}
}
@@ -1197,7 +1194,7 @@ public:
void JustDied(Unit* /*killer*/) override
{
me->RemoveCorpse();
me->DespawnOrUnsummon();
if (Creature* LordIllidan = (ObjectAccessor::GetCreature(*me, LordIllidanGUID)))
ENSURE_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, LordIllidan->AI())->LiveCounter();
}
@@ -4426,6 +4426,42 @@ class spell_gen_pony_mount_check : public SpellScriptLoader
}
};
class spell_gen_shroud_of_death : public SpellScriptLoader
{
public:
spell_gen_shroud_of_death() : SpellScriptLoader("spell_gen_shroud_of_death") { }
class spell_gen_shroud_of_death_AuraScript : public AuraScript
{
PrepareAuraScript(spell_gen_shroud_of_death_AuraScript);
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
PreventDefaultAction();
GetUnitOwner()->m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST);
GetUnitOwner()->m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST);
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
PreventDefaultAction();
GetUnitOwner()->m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE);
GetUnitOwner()->m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE);
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_gen_shroud_of_death_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_gen_shroud_of_death_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_gen_shroud_of_death_AuraScript();
}
};
// 169869 - Transformation Sickness
class spell_gen_decimatus_transformation_sickness : public SpellScriptLoader
{
@@ -4752,6 +4788,7 @@ void AddSC_generic_spell_scripts()
new spell_gen_landmine_knockback_achievement();
new spell_gen_clear_debuffs();
new spell_gen_pony_mount_check();
new spell_gen_shroud_of_death();
new spell_gen_decimatus_transformation_sickness();
new spell_gen_anetheron_summon_towering_infernal();
new spell_gen_mark_of_kazrogal_hellfire();