diff options
Diffstat (limited to 'src/game')
| -rw-r--r-- | src/game/Creature.cpp | 11 | ||||
| -rw-r--r-- | src/game/Creature.h | 2 | ||||
| -rw-r--r-- | src/game/PetHandler.cpp | 7 | ||||
| -rw-r--r-- | src/game/Player.cpp | 132 | ||||
| -rw-r--r-- | src/game/PossessedAI.cpp | 4 | ||||
| -rw-r--r-- | src/game/SharedDefines.h | 2 | ||||
| -rw-r--r-- | src/game/Spell.cpp | 2 | ||||
| -rw-r--r-- | src/game/SpellAuras.cpp | 8 | ||||
| -rw-r--r-- | src/game/SpellEffects.cpp | 24 | ||||
| -rw-r--r-- | src/game/SpellHandler.cpp | 9 | ||||
| -rw-r--r-- | src/game/Unit.cpp | 37 | ||||
| -rw-r--r-- | src/game/Unit.h | 5 |
12 files changed, 141 insertions, 102 deletions
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 91eb04b07f5..cb6a7640d16 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -147,7 +147,11 @@ Creature::~Creature() delete i_AI; i_AI = NULL; - DeletePossessedAI(); + if (i_AI_possessed) + { + delete i_AI_possessed; + i_AI_possessed = NULL; + } } void Creature::AddToWorld() @@ -562,13 +566,10 @@ void Creature::InitPossessedAI() i_AI->OnPossess(true); } -void Creature::DeletePossessedAI() +void Creature::DisablePossessedAI() { if (!i_AI_possessed) return; - delete i_AI_possessed; - i_AI_possessed = NULL; - // Signal the old AI that it's been re-enabled i_AI->OnPossess(false); } diff --git a/src/game/Creature.h b/src/game/Creature.h index 5d0ca5b5946..da62a9834ca 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -460,7 +460,7 @@ class TRINITY_DLL_SPEC Creature : public Unit bool AIM_Initialize(); void InitPossessedAI(); - void DeletePossessedAI(); + void DisablePossessedAI(); void AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type); CreatureAI* AI() { return isPossessed() && i_AI_possessed ? i_AI_possessed : i_AI; } diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index f95be3a9352..d912f42c22b 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -97,6 +97,13 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) break; case COMMAND_ATTACK: //spellid=1792 //ATTACK { + // Can't attack if owner is pacified + if (_player->HasAuraType(SPELL_AURA_MOD_PACIFY)) + { + //pet->SendPetCastFail(spellid, SPELL_FAILED_PACIFIED); + //TODO: Send proper error message to client + return; + } // only place where pet can be player pet->clearUnitState(UNIT_STAT_FOLLOW); uint64 selguid = _player->GetSelection(); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 11ffba972a3..5b63b87bc6f 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -18700,70 +18700,70 @@ bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const //-------------TRINITY--------------- //*********************************** -void Player::HandleFallDamage(MovementInfo& movementInfo)
-{
- //Players with Feather Fall or low fall time, or physical immunity (charges used) are ignored
- if (!isInFlight() && movementInfo.fallTime > 1100 && !isDead() && !isGameMaster() &&
- !HasAuraType(SPELL_AURA_HOVER) && !HasAuraType(SPELL_AURA_FEATHER_FALL) &&
- !HasAuraType(SPELL_AURA_FLY) && !IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL,true) )
- {
- //Safe fall, fall time reduction
- int32 safe_fall = GetTotalAuraModifier(SPELL_AURA_SAFE_FALL);
- uint32 fall_time = (movementInfo.fallTime > (safe_fall*10)) ? movementInfo.fallTime - (safe_fall*10) : 0;
-
- if(fall_time > 1100) //Prevent damage if fall time < 1100
- {
- //Fall Damage calculation
- float fallperc = float(fall_time)/1100;
- uint32 damage = (uint32)(((fallperc*fallperc -1) / 9 * GetMaxHealth())*sWorld.getRate(RATE_DAMAGE_FALL));
-
- float height = movementInfo.z;
- UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height);
-
- if (damage > 0)
- {
- //Prevent fall damage from being more than the player maximum health
- if (damage > GetMaxHealth())
- damage = GetMaxHealth();
-
- // Gust of Wind
- if (GetDummyAura(43621))
- damage = GetMaxHealth()/2;
-
- EnvironmentalDamage(GetGUID(), DAMAGE_FALL, damage);
- }
-
- //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction
- DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall);
- }
- }
-}
-
-void Player::HandleFallUnderMap()
-{
- if(InBattleGround() && GetBattleGround()
- && GetBattleGround()->HandlePlayerUnderMap(this))
- {
- // do nothing, the handle already did if returned true
- }
- else
- {
- // 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(isAlive())
- {
- EnvironmentalDamage(GetGUID(),DAMAGE_FALL_TO_VOID, GetMaxHealth());
- // change the death state to CORPSE to prevent the death timer from
- // starting in the next player update
- KillPlayer();
- BuildPlayerRepop();
- }
-
- // cancel the death timer here if started
- RepopAtGraveyard();
- }
-}
+void Player::HandleFallDamage(MovementInfo& movementInfo) +{ + //Players with Feather Fall or low fall time, or physical immunity (charges used) are ignored + if (!isInFlight() && movementInfo.fallTime > 1100 && !isDead() && !isGameMaster() && + !HasAuraType(SPELL_AURA_HOVER) && !HasAuraType(SPELL_AURA_FEATHER_FALL) && + !HasAuraType(SPELL_AURA_FLY) && !IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL,true) ) + { + //Safe fall, fall time reduction + int32 safe_fall = GetTotalAuraModifier(SPELL_AURA_SAFE_FALL); + uint32 fall_time = (movementInfo.fallTime > (safe_fall*10)) ? movementInfo.fallTime - (safe_fall*10) : 0; + + if(fall_time > 1100) //Prevent damage if fall time < 1100 + { + //Fall Damage calculation + float fallperc = float(fall_time)/1100; + uint32 damage = (uint32)(((fallperc*fallperc -1) / 9 * GetMaxHealth())*sWorld.getRate(RATE_DAMAGE_FALL)); + + float height = movementInfo.z; + UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height); + + if (damage > 0) + { + //Prevent fall damage from being more than the player maximum health + if (damage > GetMaxHealth()) + damage = GetMaxHealth(); + + // Gust of Wind + if (GetDummyAura(43621)) + damage = GetMaxHealth()/2; + + EnvironmentalDamage(GetGUID(), DAMAGE_FALL, damage); + } + + //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction + DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall); + } + } +} + +void Player::HandleFallUnderMap() +{ + if(InBattleGround() && GetBattleGround() + && GetBattleGround()->HandlePlayerUnderMap(this)) + { + // do nothing, the handle already did if returned true + } + else + { + // 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(isAlive()) + { + EnvironmentalDamage(GetGUID(),DAMAGE_FALL_TO_VOID, GetMaxHealth()); + // change the death state to CORPSE to prevent the death timer from + // starting in the next player update + KillPlayer(); + BuildPlayerRepop(); + } + + // cancel the death timer here if started + RepopAtGraveyard(); + } +} void Player::Possess(Unit *target) { @@ -18936,8 +18936,8 @@ void Player::RemovePossess(bool attack) if(attack) target->AddThreat(this, 1000000.0f); } - // Delete the assigned possessed AI - ((Creature*)target)->DeletePossessedAI(); + // Disable the assigned possessed AI + ((Creature*)target)->DisablePossessedAI(); } } diff --git a/src/game/PossessedAI.cpp b/src/game/PossessedAI.cpp index 6b803303185..8abbb7f2603 100644 --- a/src/game/PossessedAI.cpp +++ b/src/game/PossessedAI.cpp @@ -24,7 +24,7 @@ void PossessedAI::AttackStart(Unit *u)
{
- if( !u )
+ if( !u || i_pet.GetCharmer()->HasAuraType(SPELL_AURA_MOD_PACIFY))
return;
if (i_pet.getVictim() && u != i_pet.getVictim())
@@ -95,7 +95,7 @@ void PossessedAI::UpdateAI(const uint32 diff) _stopAttack(); // i_victimGuid == 0 && i_pet.getVictim() == NULL now
return;
}
- else if(i_pet.IsWithinCombatDist(i_pet.getVictim(), ATTACK_DISTANCE) && i_pet.isAttackReady())
+ else if(i_pet.IsWithinCombatDist(i_pet.getVictim(), ATTACK_DISTANCE) && i_pet.isAttackReady() && !i_pet.GetCharmer()->HasAuraType(SPELL_AURA_MOD_PACIFY))
{
i_pet.AttackerStateUpdate(i_pet.getVictim());
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 37dca1aa656..dc22b3affbc 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -2069,7 +2069,7 @@ enum SummonType SUMMON_TYPE_CRITTER2 = 407, SUMMON_TYPE_CRITTER3 = 307, SUMMON_TYPE_UNKNOWN5 = 409, - SUMMON_TYPE_UNKNOWN2 = 427, + SUMMON_TYPE_POSESSED3 = 427, SUMMON_TYPE_POSESSED2 = 428 }; diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index da6d67a3c6c..59d019800ed 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1533,6 +1533,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap) }break; case TARGET_SCRIPT: case TARGET_SCRIPT_COORDINATES: + case TARGET_UNIT_AREA_SCRIPT: { SpellScriptTarget::const_iterator lower = spellmgr.GetBeginSpellScriptTarget(m_spellInfo->Id); SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(m_spellInfo->Id); @@ -3865,6 +3866,7 @@ uint8 Spell::CanCast(bool strict) { case SUMMON_TYPE_POSESSED: case SUMMON_TYPE_POSESSED2: + case SUMMON_TYPE_POSESSED3: case SUMMON_TYPE_DEMON: case SUMMON_TYPE_SUMMON: { diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 55203554665..35d39a22b27 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -49,7 +49,6 @@ #include "GridNotifiers.h" #include "GridNotifiersImpl.h" #include "CellImpl.h" -#include "TemporarySummon.h" #define NULL_AURA_SLOT 0xFF @@ -2024,13 +2023,6 @@ void Aura::HandleAuraDummy(bool apply, bool Real) m_target->CastSpell(m_target,47287,true,NULL,this); return; } - - // Eye of Kilrogg, unsummon eye when aura is gone - if(GetId() == 126 && caster->GetTypeId() == TYPEID_PLAYER && caster->GetCharm()) - { - ((TemporarySummon*)caster->GetCharm())->UnSummon(); - return; - } } // AT APPLY & REMOVE diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index a492e06f5b1..b3dcc2c5069 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -341,17 +341,17 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) return; break; } - // gruul's shatter
- case 33671:
- {
- // don't damage self and only players
- if(unitTarget->GetGUID() == m_caster->GetGUID() || unitTarget->GetTypeId() != TYPEID_PLAYER)
- return;
-
- float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[0]));
- if(!radius) return;
- float distance = m_caster->GetDistance2d(unitTarget);
- damage = (distance > radius ) ? 0 : (int32)(m_spellInfo->EffectBasePoints[0]*((radius - distance)/radius));
+ // gruul's shatter + case 33671: + { + // don't damage self and only players + if(unitTarget->GetGUID() == m_caster->GetGUID() || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[0])); + if(!radius) return; + float distance = m_caster->GetDistance2d(unitTarget); + damage = (distance > radius ) ? 0 : (int32)(m_spellInfo->EffectBasePoints[0]*((radius - distance)/radius)); }break; } break; @@ -3150,6 +3150,7 @@ void Spell::EffectSummonType(uint32 i) break; case SUMMON_TYPE_POSESSED: case SUMMON_TYPE_POSESSED2: + case SUMMON_TYPE_POSESSED3: EffectSummonPossessed(i); break; case SUMMON_TYPE_WILD: @@ -3174,7 +3175,6 @@ void Spell::EffectSummonType(uint32 i) EffectSummonTotem(i); break; case SUMMON_TYPE_UNKNOWN1: - case SUMMON_TYPE_UNKNOWN2: case SUMMON_TYPE_UNKNOWN3: case SUMMON_TYPE_UNKNOWN4: case SUMMON_TYPE_UNKNOWN5: diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 07d8b18b543..6caab76e061 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -33,6 +33,7 @@ #include "MapManager.h" #include "ScriptCalls.h" #include "Totem.h" +#include "TemporarySummon.h" void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) { @@ -376,6 +377,14 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket) ((Unit*)_player->GetFarsightTarget())->RemoveAurasDueToSpellByCancel(spellId); return; } + else if (spellInfo->Effect[i] == SPELL_EFFECT_SUMMON && + (spellInfo->EffectMiscValueB[i] == SUMMON_TYPE_POSESSED || + spellInfo->EffectMiscValueB[i] == SUMMON_TYPE_POSESSED2 || + spellInfo->EffectMiscValueB[i] == SUMMON_TYPE_POSESSED3)) + { + // Possession is removed in the UnSummon function + ((TemporarySummon*)_player->GetCharm())->UnSummon(); + } } } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 94f647cdd46..bcdd771bcea 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -46,6 +46,7 @@ #include "GridNotifiersImpl.h" #include "CellImpl.h" #include "Path.h" +#include "TemporarySummon.h" #include <math.h> @@ -3418,6 +3419,21 @@ void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id) // channeled spells are interrupted if they are not finished, even if they are delayed if (m_currentSpells[CURRENT_CHANNELED_SPELL] && (!spell_id || m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id==spell_id)) { + // Unsummon any summoned as possessed creatures on channel interrupt + SpellEntry const *spellInfo = m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo; + for (int i = 0; i < 3; i++) + { + if (spellInfo->Effect[i] == SPELL_EFFECT_SUMMON && + (spellInfo->EffectMiscValueB[i] == SUMMON_TYPE_POSESSED || + spellInfo->EffectMiscValueB[i] == SUMMON_TYPE_POSESSED2 || + spellInfo->EffectMiscValueB[i] == SUMMON_TYPE_POSESSED3)) + { + // Possession is removed in the UnSummon function + if (GetCharm()) + ((TemporarySummon*)GetCharm())->UnSummon(); + } + } + if (m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED) m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel(); m_currentSpells[CURRENT_CHANNELED_SPELL]->SetReferencedFromCurrent(false); @@ -9797,7 +9813,7 @@ CharmInfo* Unit::InitCharmInfo(Unit *charm) } CharmInfo::CharmInfo(Unit* unit) -: m_unit(unit), m_CommandState(COMMAND_FOLLOW), m_reactState(REACT_PASSIVE), m_petnumber(0) +: m_unit(unit), m_CommandState(COMMAND_FOLLOW), m_reactState(REACT_PASSIVE), m_petnumber(0), m_barInit(false) { for(int i =0; i<4; ++i) { @@ -9808,6 +9824,9 @@ CharmInfo::CharmInfo(Unit* unit) void CharmInfo::InitPetActionBar() { + if (m_barInit) + return; + // the first 3 SpellOrActions are attack, follow and stay for(uint32 i = 0; i < 3; i++) { @@ -9822,17 +9841,25 @@ void CharmInfo::InitPetActionBar() PetActionBar[i + 3].Type = ACT_DISABLED; PetActionBar[i + 3].SpellOrAction = 0; } + m_barInit = true; } -void CharmInfo::InitEmptyActionBar() +void CharmInfo::InitEmptyActionBar(bool withAttack) { - for(uint32 x = 1; x < 10; ++x) + if (m_barInit) + return; + + for(uint32 x = 0; x < 10; ++x) { PetActionBar[x].Type = ACT_CAST; PetActionBar[x].SpellOrAction = 0; } - PetActionBar[0].Type = ACT_COMMAND; - PetActionBar[0].SpellOrAction = COMMAND_ATTACK; + if (withAttack) + { + PetActionBar[0].Type = ACT_COMMAND; + PetActionBar[0].SpellOrAction = COMMAND_ATTACK; + } + m_barInit = true; } void CharmInfo::InitPossessCreateSpells() diff --git a/src/game/Unit.h b/src/game/Unit.h index cd5770cccd6..5ae34624c96 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -640,7 +640,7 @@ struct CharmSpellEntry typedef std::list<Player*> SharedVisionList; -struct CharmInfo +struct TRINITY_DLL_SPEC CharmInfo { public: explicit CharmInfo(Unit* unit); @@ -657,7 +657,7 @@ struct CharmInfo void InitPossessCreateSpells(); void InitCharmCreateSpells(); void InitPetActionBar(); - void InitEmptyActionBar(); + void InitEmptyActionBar(bool withAttack = true); //return true if successful bool AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate = ACT_DECIDE); void ToggleCreatureAutocast(uint32 spellid, bool apply); @@ -671,6 +671,7 @@ struct CharmInfo CommandStates m_CommandState; ReactStates m_reactState; uint32 m_petnumber; + bool m_barInit; }; // for clearing special attacks |
