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

Port From (https://github.com/TrinityCore/TrinityCore/commit/fe63cd3dbb66f4fda743858db4284a24bc2bd400)
This commit is contained in:
hondacrx
2019-08-17 10:47:55 -04:00
parent bdfea4ecad
commit d3cbe70f56
10 changed files with 155 additions and 158 deletions
+1 -1
View File
@@ -175,8 +175,8 @@ namespace Framework.Constants
public const int MaxCreatureModelIds = 4; public const int MaxCreatureModelIds = 4;
public const int MaxTrainerspellAbilityReqs = 3; public const int MaxTrainerspellAbilityReqs = 3;
public const int CreatureRegenInterval = 2 * Time.InMilliseconds; public const int CreatureRegenInterval = 2 * Time.InMilliseconds;
public const int CreatureNoPathEvadeTime = 5 * Time.InMilliseconds;
public const int PetFocusRegenInterval = 4 * Time.InMilliseconds; public const int PetFocusRegenInterval = 4 * Time.InMilliseconds;
public const int CreatureNoPathEvadeTime = 5 * Time.InMilliseconds;
public const int BoundaryVisualizeCreature = 15425; public const int BoundaryVisualizeCreature = 15425;
public const float BoundaryVisualizeCreatureScale = 0.25f; public const float BoundaryVisualizeCreatureScale = 0.25f;
public const int BoundaryVisualizeStepSize = 1; public const int BoundaryVisualizeStepSize = 1;
@@ -33,6 +33,7 @@ namespace Game.Entities
ObjectGuid m_suppressedTarget; // Stores the creature's "real" target while casting ObjectGuid m_suppressedTarget; // Stores the creature's "real" target while casting
float m_suppressedOrientation; // Stores the creature's "real" orientation while casting float m_suppressedOrientation; // Stores the creature's "real" orientation while casting
long _lastDamagedTime; // Part of Evade mechanics
MultiMap<byte, byte> m_textRepeat = new MultiMap<byte, byte>(); MultiMap<byte, byte> m_textRepeat = new MultiMap<byte, byte>();
public ulong m_PlayerDamageReq; public ulong m_PlayerDamageReq;
+143 -130
View File
@@ -101,10 +101,7 @@ namespace Game.Entities
public void DisappearAndDie() public void DisappearAndDie()
{ {
DestroyForNearbyPlayers(); ForcedDespawn(0);
if (IsAlive())
setDeathState(DeathState.JustDied);
RemoveCorpse(false);
} }
public void SearchFormation() public void SearchFormation()
@@ -121,7 +118,7 @@ namespace Game.Entities
FormationMgr.AddCreatureToGroup(frmdata.leaderGUID, this); FormationMgr.AddCreatureToGroup(frmdata.leaderGUID, this);
} }
public void RemoveCorpse(bool setSpawnTime = true) public void RemoveCorpse(bool setSpawnTime = true, bool destroyForNearbyPlayers = true)
{ {
if (getDeathState() != DeathState.Corpse) if (getDeathState() != DeathState.Corpse)
return; return;
@@ -135,6 +132,9 @@ namespace Game.Entities
if (IsAIEnabled) if (IsAIEnabled)
GetAI().CorpseRemoved(respawnDelay); GetAI().CorpseRemoved(respawnDelay);
if (destroyForNearbyPlayers)
DestroyForNearbyPlayers();
// Should get removed later, just keep "compatibility" with scripts // Should get removed later, just keep "compatibility" with scripts
if (setSpawnTime) if (setSpawnTime)
m_respawnTime = Math.Max(Time.UnixTime + respawnDelay, m_respawnTime); m_respawnTime = Math.Max(Time.UnixTime + respawnDelay, m_respawnTime);
@@ -145,6 +145,21 @@ namespace Game.Entities
float x, y, z, o; float x, y, z, o;
GetRespawnPosition(out x, out y, out z, out o); GetRespawnPosition(out x, out y, out z, out o);
// We were spawned on transport, calculate real position
if (IsSpawnedOnTransport())
{
Position pos = m_movementInfo.transport.pos;
pos.posX = x;
pos.posY = y;
pos.posZ = z;
pos.SetOrientation(o);
ITransport transport = GetDirectTransport();
if (transport != null)
transport.CalculatePassengerPosition(ref x, ref y, ref z, ref o);
}
SetHomePosition(x, y, z, o); SetHomePosition(x, y, z, o);
GetMap().CreatureRelocation(this, x, y, z, o); GetMap().CreatureRelocation(this, x, y, z, o);
} }
@@ -275,6 +290,11 @@ namespace Game.Entities
SetNpcFlags((NPCFlags)(npcFlags & 0xFFFFFFFF)); SetNpcFlags((NPCFlags)(npcFlags & 0xFFFFFFFF));
SetNpcFlags2((NPCFlags2)(npcFlags >> 32)); SetNpcFlags2((NPCFlags2)(npcFlags >> 32));
// if unit is in combat, keep this flag
unitFlags &= ~(uint)UnitFlags.InCombat;
if (IsInCombat())
unitFlags |= (uint)UnitFlags.InCombat;
SetUnitFlags((UnitFlags)unitFlags); SetUnitFlags((UnitFlags)unitFlags);
SetUnitFlags2((UnitFlags2)unitFlags2); SetUnitFlags2((UnitFlags2)unitFlags2);
SetUnitFlags3((UnitFlags3)unitFlags3); SetUnitFlags3((UnitFlags3)unitFlags3);
@@ -283,8 +303,6 @@ namespace Game.Entities
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.StateAnimID), (uint)CliDB.AnimationDataStorage.Count); SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.StateAnimID), (uint)CliDB.AnimationDataStorage.Count);
RemoveUnitFlag(UnitFlags.InCombat);
SetBaseAttackTime(WeaponAttackType.BaseAttack, cInfo.BaseAttackTime); SetBaseAttackTime(WeaponAttackType.BaseAttack, cInfo.BaseAttackTime);
SetBaseAttackTime(WeaponAttackType.OffAttack, cInfo.BaseAttackTime); SetBaseAttackTime(WeaponAttackType.OffAttack, cInfo.BaseAttackTime);
SetBaseAttackTime(WeaponAttackType.RangedAttack, cInfo.RangeAttackTime); SetBaseAttackTime(WeaponAttackType.RangedAttack, cInfo.RangeAttackTime);
@@ -518,13 +536,11 @@ namespace Game.Entities
if (!IsInEvadeMode() && (!bInCombat || IsPolymorphed() || CanNotReachTarget())) // regenerate health if not in combat or if polymorphed if (!IsInEvadeMode() && (!bInCombat || IsPolymorphed() || CanNotReachTarget())) // regenerate health if not in combat or if polymorphed
RegenerateHealth(); RegenerateHealth();
if (HasUnitFlag2(UnitFlags2.RegeneratePower)) if (GetPowerType() == PowerType.Energy)
{ Regenerate(PowerType.Energy);
if (GetPowerType() == PowerType.Energy) else
Regenerate(PowerType.Energy); Regenerate(PowerType.Mana);
else
RegenerateMana();
}
m_regenTimer = SharedConst.CreatureRegenInterval; m_regenTimer = SharedConst.CreatureRegenInterval;
} }
@@ -541,66 +557,14 @@ namespace Game.Entities
} }
void RegenerateMana()
{
int curValue = GetPower(PowerType.Mana);
int maxValue = GetMaxPower(PowerType.Mana);
if (curValue >= maxValue)
return;
int addvalue = 0;
// Combat and any controlled creature
if (IsInCombat() || !GetCharmerOrOwnerGUID().IsEmpty())
{
float ManaIncreaseRate = WorldConfig.GetFloatValue(WorldCfg.RatePowerMana);
addvalue = (int)((27.0f / 5.0f + 17.0f) * ManaIncreaseRate);
}
else
addvalue = maxValue / 3;
// Apply modifiers (if any).
addvalue *= (int)GetTotalAuraMultiplierByMiscValue(AuraType.ModPowerRegenPercent, (int)PowerType.Mana);
addvalue += GetTotalAuraModifierByMiscValue(AuraType.ModPowerRegen, (int)PowerType.Mana) * SharedConst.CreatureRegenInterval / (5 * Time.InMilliseconds);
ModifyPower(PowerType.Mana, addvalue);
}
void RegenerateHealth()
{
if (!isRegeneratingHealth())
return;
ulong curValue = GetHealth();
ulong maxValue = GetMaxHealth();
if (curValue >= maxValue)
return;
long addvalue = 0;
// Not only pet, but any controlled creature
if (!GetCharmerOrOwnerGUID().IsEmpty())
{
float HealthIncreaseRate = WorldConfig.GetFloatValue(WorldCfg.RateHealth);
addvalue = (uint)(0.015f * GetMaxHealth() * HealthIncreaseRate);
}
else
addvalue = (long)maxValue / 3;
// Apply modifiers (if any).
addvalue *= (int)GetTotalAuraMultiplier(AuraType.ModHealthRegenPercent);
addvalue += GetTotalAuraModifier(AuraType.ModRegen) * SharedConst.CreatureRegenInterval / (5 * Time.InMilliseconds);
ModifyHealth(addvalue);
}
public void Regenerate(PowerType power) public void Regenerate(PowerType power)
{ {
int curValue = GetPower(power); int curValue = GetPower(power);
int maxValue = GetMaxPower(power); int maxValue = GetMaxPower(power);
if (!HasUnitFlag2(UnitFlags2.RegeneratePower))
return;
if (curValue >= maxValue) if (curValue >= maxValue)
return; return;
@@ -620,6 +584,19 @@ namespace Game.Entities
addvalue = 20; addvalue = 20;
break; break;
} }
case PowerType.Mana:
{
// Combat and any controlled creature
if (IsInCombat() || GetCharmerOrOwnerGUID().IsEmpty())
{
float ManaIncreaseRate = WorldConfig.GetFloatValue(WorldCfg.RatePowerMana);
addvalue = (27.0f / 5.0f + 17.0f) * ManaIncreaseRate;
}
else
addvalue = maxValue / 3;
break;
}
default: default:
return; return;
} }
@@ -631,6 +608,35 @@ namespace Game.Entities
ModifyPower(power, (int)addvalue); ModifyPower(power, (int)addvalue);
} }
void RegenerateHealth()
{
if (!isRegeneratingHealth())
return;
ulong curValue = GetHealth();
ulong maxValue = GetMaxHealth();
if (curValue >= maxValue)
return;
long addvalue = 0;
// Not only pet, but any controlled creature (and not polymorphed)
if (!GetCharmerOrOwnerGUID().IsEmpty() && !IsPolymorphed())
{
float HealthIncreaseRate = WorldConfig.GetFloatValue(WorldCfg.RateHealth);
addvalue = (uint)(0.015f * GetMaxHealth() * HealthIncreaseRate);
}
else
addvalue = (long)maxValue / 3;
// Apply modifiers (if any).
addvalue *= (int)GetTotalAuraMultiplier(AuraType.ModHealthRegenPercent);
addvalue += GetTotalAuraModifier(AuraType.ModRegen) * SharedConst.CreatureRegenInterval / (5 * Time.InMilliseconds);
ModifyHealth(addvalue);
}
public void DoFleeToGetAssistance() public void DoFleeToGetAssistance()
{ {
if (!GetVictim()) if (!GetVictim())
@@ -770,6 +776,10 @@ namespace Game.Entities
return false; return false;
} }
// Allow players to see those units while dead, do it here (mayby altered by addon auras)
if (cinfo.TypeFlags.HasAnyFlag(CreatureTypeFlags.GhostVisible))
m_serverSideVisibility.SetValue(ServerSideVisibilityType.Ghost, GhostVisibilityType.Alive | GhostVisibilityType.Ghost);
if (!CreateFromProto(guidlow, entry, data, vehId)) if (!CreateFromProto(guidlow, entry, data, vehId))
return false; return false;
@@ -1615,7 +1625,7 @@ namespace Game.Entities
setDeathState(DeathState.Corpse); setDeathState(DeathState.Corpse);
} }
RemoveCorpse(false); RemoveCorpse(false, false);
if (getDeathState() == DeathState.Dead) if (getDeathState() == DeathState.Dead)
{ {
@@ -1672,33 +1682,21 @@ namespace Game.Entities
return; return;
} }
// do it before killing creature
DestroyForNearbyPlayers();
if (IsAlive())
setDeathState(DeathState.JustDied);
bool overrideRespawnTime = true;
if (forceRespawnTimer > TimeSpan.Zero) if (forceRespawnTimer > TimeSpan.Zero)
{ {
if (IsAlive()) SetRespawnTime((uint)forceRespawnTimer.TotalSeconds);
{ overrideRespawnTime = false;
uint respawnDelay = m_respawnDelay;
uint corpseDelay = m_corpseDelay;
m_respawnDelay = (uint)forceRespawnTimer.TotalSeconds;
m_corpseDelay = 0;
setDeathState(DeathState.JustDied);
m_respawnDelay = respawnDelay;
m_corpseDelay = corpseDelay;
}
else
{
m_corpseRemoveTime = Time.UnixTime;
m_respawnTime = Time.UnixTime + (long)forceRespawnTimer.TotalMilliseconds;
}
}
else
{
if (IsAlive())
setDeathState(DeathState.JustDied);
} }
RemoveCorpse(false); // Skip corpse decay time
RemoveCorpse(overrideRespawnTime, false);
} }
public void DespawnOrUnsummon(TimeSpan time, TimeSpan forceRespawnTimer = default(TimeSpan)) { DespawnOrUnsummon((uint)time.TotalMilliseconds, forceRespawnTimer); } public void DespawnOrUnsummon(TimeSpan time, TimeSpan forceRespawnTimer = default(TimeSpan)) { DespawnOrUnsummon((uint)time.TotalMilliseconds, forceRespawnTimer); }
@@ -1979,6 +1977,14 @@ namespace Game.Entities
if (!IsAlive()) if (!IsAlive())
return false; 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 ;) // we don't need help from non-combatant ;)
if (IsCivilian()) if (IsCivilian())
return false; return false;
@@ -2066,22 +2072,41 @@ namespace Game.Entities
if (IsAIEnabled && !GetAI().CanAIAttack(victim)) if (IsAIEnabled && !GetAI().CanAIAttack(victim))
return false; return false;
if (GetMap().IsDungeon()) // we cannot attack in evade mode
return true; if (IsInEvadeMode())
return false;
// if the mob is actively being damaged, do not reset due to distance unless it's a world boss // or if enemy is in evade mode
if (!isWorldBoss()) if (victim.GetTypeId() == TypeId.Unit && victim.ToCreature().IsInEvadeMode())
if (Time.UnixTime - GetLastDamagedTime() <= SharedConst.MaxAggroResetTime) return false;
if (!GetCharmerOrOwnerGUID().IsPlayer())
{
if (GetMap().IsDungeon())
return true; return true;
//Use AttackDistance in distance check if threat radius is lower. This prevents creature bounce in and out of combat every update tick. // don't check distance to home position if recently damaged, this should include taunt auras
float dist = Math.Max(GetAttackDistance(victim), (WorldConfig.GetFloatValue(WorldCfg.ThreatRadius) + m_CombatDistance)); if (!isWorldBoss() && (GetLastDamagedTime() > Global.WorldMgr.GetGameTime() || HasAuraType(AuraType.ModTaunt)))
return true;
}
// Map visibility range, but no more than 2*cell size
float dist = Math.Min(GetMap().GetVisibilityRange(), MapConst.SizeofCells * 2);
Unit unit = GetCharmerOrOwner(); Unit unit = GetCharmerOrOwner();
if (unit != null) if (unit != null)
return victim.IsWithinDist(unit, dist); return victim.IsWithinDist(unit, dist);
else 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.HasAnyFlag(InhabitType.Air))
return victim.IsInDist2d(m_homePosition, dist);
else
return victim.IsInDist(m_homePosition, dist);
}
} }
CreatureAddon GetCreatureAddon() CreatureAddon GetCreatureAddon()
@@ -2242,40 +2267,17 @@ namespace Game.Entities
public void GetRespawnPosition(out float x, out float y, out float z) public void GetRespawnPosition(out float x, out float y, out float z)
{ {
if (m_spawnId != 0) float notUsed;
{ GetRespawnPosition(out x, out y, out z, out notUsed, out notUsed);
CreatureData data = Global.ObjectMgr.GetCreatureData(GetSpawnId());
if (data != null)
{
x = data.posX;
y = data.posY;
z = data.posZ;
return;
}
}
GetPosition(out x, out y, out z);
} }
public void GetRespawnPosition(out float x, out float y, out float z, out float ori) public void GetRespawnPosition(out float x, out float y, out float z, out float ori)
{ {
if (m_spawnId != 0) float notUsed;
{ GetRespawnPosition(out x, out y, out z, out ori, out notUsed);
CreatureData data = Global.ObjectMgr.GetCreatureData(GetSpawnId());
if (data != null)
{
x = data.posX;
y = data.posY;
z = data.posZ;
ori = data.orientation;
return;
}
}
GetPosition(out x, out y, out z, out ori);
} }
public void GetRespawnPosition(out float x, out float y, out float z, out float ori, out float dist) public void GetRespawnPosition(out float x, out float y, out float z, out float ori, out float dist)
{ {
// for npcs on transport, this will return transport offset
if (m_spawnId != 0) if (m_spawnId != 0)
{ {
CreatureData data = Global.ObjectMgr.GetCreatureData(GetSpawnId()); CreatureData data = Global.ObjectMgr.GetCreatureData(GetSpawnId());
@@ -2291,10 +2293,17 @@ namespace Game.Entities
} }
} }
GetPosition(out x, out y, out z, out ori); // 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();
ori = homePos.GetOrientation();
dist = 0; dist = 0;
} }
bool IsSpawnedOnTransport() { return m_creatureData != null && m_creatureData.mapid != GetMapId(); }
public void AllLootRemovedFromCorpse() public void AllLootRemovedFromCorpse()
{ {
if (loot.loot_type != LootType.Skinning && !IsPet() && GetCreatureTemplate().SkinLootId != 0 && hasLootRecipient()) if (loot.loot_type != LootType.Skinning && !IsPet() && GetCreatureTemplate().SkinLootId != 0 && hasLootRecipient())
@@ -3056,6 +3065,10 @@ namespace Game.Entities
public bool IsReputationGainDisabled() { return DisableReputationGain; } public bool IsReputationGainDisabled() { return DisableReputationGain; }
public bool IsDamageEnoughForLootingAndReward() { return m_creatureInfo.FlagsExtra.HasAnyFlag(CreatureFlagsExtra.NoPlayerDamageReq) || m_PlayerDamageReq == 0; } public bool IsDamageEnoughForLootingAndReward() { return m_creatureInfo.FlagsExtra.HasAnyFlag(CreatureFlagsExtra.NoPlayerDamageReq) || m_PlayerDamageReq == 0; }
// Part of Evade mechanics
long GetLastDamagedTime() { return _lastDamagedTime; }
public void SetLastDamagedTime(long val) { _lastDamagedTime = val; }
public void ResetPlayerDamageReq() { m_PlayerDamageReq = (uint)(GetHealth() / 2); } public void ResetPlayerDamageReq() { m_PlayerDamageReq = (uint)(GetHealth() / 2); }
public uint GetOriginalEntry() public uint GetOriginalEntry()
+4 -7
View File
@@ -1047,13 +1047,14 @@ namespace Game.Entities
victim.ModifyHealth(-(int)damage); victim.ModifyHealth(-(int)damage);
if (damagetype == DamageEffectType.Direct || damagetype == DamageEffectType.SpellDirect) if (damagetype == DamageEffectType.Direct || damagetype == DamageEffectType.SpellDirect)
{
victim.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.DirectDamage, spellProto != null ? spellProto.Id : 0); victim.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.DirectDamage, spellProto != null ? spellProto.Id : 0);
victim.UpdateLastDamagedTime(spellProto);
}
if (!victim.IsTypeId(TypeId.Player)) if (!victim.IsTypeId(TypeId.Player))
{ {
// Part of Evade mechanics. DoT's and Thorns / Retribution Aura do not contribute to this
if (damagetype != DamageEffectType.DOT && damage > 0 && !victim.GetOwnerGUID().IsPlayer() && (spellProto == null || !spellProto.HasAura(GetMap().GetDifficultyID(), AuraType.DamageShield)))
victim.ToCreature().SetLastDamagedTime(Global.WorldMgr.GetGameTime() + SharedConst.MaxAggroResetTime);
victim.AddThreat(this, damage, damageSchoolMask, spellProto); victim.AddThreat(this, damage, damageSchoolMask, spellProto);
} }
else // victim is a player else // victim is a player
@@ -3206,9 +3207,5 @@ namespace Game.Entities
} }
return true; return true;
} }
// Part of Evade mechanics
public long GetLastDamagedTime() { return _lastDamagedTime; }
public void SetLastDamagedTime(long val) { _lastDamagedTime = val; }
} }
} }
-1
View File
@@ -65,7 +65,6 @@ namespace Game.Entities
public float m_modMeleeHitChance { get; set; } public float m_modMeleeHitChance { get; set; }
public float m_modRangedHitChance { get; set; } public float m_modRangedHitChance { get; set; }
public float m_modSpellHitChance { get; set; } public float m_modSpellHitChance { get; set; }
long _lastDamagedTime;
bool m_canDualWield; bool m_canDualWield;
public int m_baseSpellCritChance { get; set; } public int m_baseSpellCritChance { get; set; }
public uint m_regenTimer { get; set; } public uint m_regenTimer { get; set; }
-11
View File
@@ -4262,17 +4262,6 @@ namespace Game.Entities
return val; return val;
} }
void UpdateLastDamagedTime(SpellInfo spellProto)
{
if (!IsTypeId(TypeId.Unit) || IsPet())
return;
if (spellProto != null && spellProto.HasAura(Difficulty.None, AuraType.DamageShield))
return;
SetLastDamagedTime(Time.UnixTime);
}
public bool IsHighestExclusiveAura(Aura aura, bool removeOtherAuraApplications = false) public bool IsHighestExclusiveAura(Aura aura, bool removeOtherAuraApplications = false)
{ {
foreach (AuraEffect aurEff in aura.GetAuraEffects()) foreach (AuraEffect aurEff in aura.GetAuraEffects())
+3 -2
View File
@@ -143,8 +143,9 @@ namespace Game
GetPlayer().RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Talk); GetPlayer().RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Talk);
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?
unit.StopMoving(); //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 // If spiritguide, no need for gossip menu, just put player into resurrect queue
if (unit.IsSpiritGuide()) if (unit.IsSpiritGuide())
+1 -1
View File
@@ -438,7 +438,7 @@ namespace Game.PvP
{ {
// Don't save respawn time // Don't save respawn time
creature.SetRespawnTime(0); creature.SetRespawnTime(0);
creature.RemoveCorpse(); creature.DespawnOrUnsummon();
creature.AddObjectToRemoveList(); creature.AddObjectToRemoveList();
} }
+1 -1
View File
@@ -2587,7 +2587,7 @@ namespace Game.Spells
{ {
target.Kill(caster); target.Kill(caster);
if (caster.IsTypeId(TypeId.Unit)) if (caster.IsTypeId(TypeId.Unit))
caster.ToCreature().RemoveCorpse(); caster.ToCreature().DespawnOrUnsummon();
} }
if (!mode.HasAnyFlag(AuraEffectHandleModes.ChangeAmount)) if (!mode.HasAnyFlag(AuraEffectHandleModes.ChangeAmount))
+1 -4
View File
@@ -2956,10 +2956,7 @@ namespace Game.Spells
caster.RewardPlayerAndGroupAtEvent(18388, unitTarget); caster.RewardPlayerAndGroupAtEvent(18388, unitTarget);
Creature target = unitTarget.ToCreature(); Creature target = unitTarget.ToCreature();
if (target != null) if (target != null)
{ target.DespawnOrUnsummon();
target.setDeathState(DeathState.Corpse);
target.RemoveCorpse();
}
} }
break; break;
// Mug Transformation // Mug Transformation