aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bindings/scripts/scripts/world/npcs_special.cpp13
-rw-r--r--src/game/Creature.cpp4
-rw-r--r--src/game/Creature.h2
-rw-r--r--src/game/Group.cpp4
-rw-r--r--src/game/GroupHandler.cpp9
-rw-r--r--src/game/MovementHandler.cpp20
-rw-r--r--src/game/Opcodes.cpp6
-rw-r--r--src/game/Opcodes.h4
-rw-r--r--src/game/Pet.cpp5
-rw-r--r--src/game/PetHandler.cpp6
-rw-r--r--src/game/Player.cpp89
-rw-r--r--src/game/Player.h6
-rw-r--r--src/game/SharedDefines.h2
-rw-r--r--src/game/Spell.cpp64
-rw-r--r--src/game/Spell.h1
-rw-r--r--src/game/SpellAuraDefines.h2
-rw-r--r--src/game/SpellAuraEffects.cpp55
-rw-r--r--src/game/SpellAuraEffects.h1
-rw-r--r--src/game/SpellEffects.cpp38
-rw-r--r--src/game/SpellMgr.cpp3
-rw-r--r--src/game/SpellMgr.h1
-rw-r--r--src/game/StatSystem.cpp2
-rw-r--r--src/game/Totem.cpp4
-rw-r--r--src/game/Totem.h2
-rw-r--r--src/game/Unit.cpp206
-rw-r--r--src/game/Unit.h6
-rw-r--r--src/game/Vehicle.cpp48
-rw-r--r--src/game/WorldSession.cpp34
-rw-r--r--src/game/WorldSession.h2
29 files changed, 463 insertions, 176 deletions
diff --git a/src/bindings/scripts/scripts/world/npcs_special.cpp b/src/bindings/scripts/scripts/world/npcs_special.cpp
index 375848da9e8..3b712af1320 100644
--- a/src/bindings/scripts/scripts/world/npcs_special.cpp
+++ b/src/bindings/scripts/scripts/world/npcs_special.cpp
@@ -1835,12 +1835,13 @@ struct TRINITY_DLL_DECL npc_ebon_gargoyleAI : CasterAI
me->SetReactState(REACT_PASSIVE);
// Fly Away
- me->AddUnitMovementFlag(MOVEMENTFLAG_FLY_MODE);
- me->SetSpeed(MOVE_FLIGHT, 0.25f, true);
- me->SetSpeed(MOVE_RUN, 0.25f, true);
- float x = me->GetPositionX() + 10 * cos(me->GetOrientation());
- float y = me->GetPositionY() + 10 * sin(me->GetOrientation());
- float z = me->GetPositionZ() + 25;
+ me->AddUnitMovementFlag(MOVEMENTFLAG_FLY_MODE|MOVEMENTFLAG_ASCEND|MOVEMENTFLAG_FLYING);
+ me->SetSpeed(MOVE_FLIGHT, 0.75f, true);
+ me->SetSpeed(MOVE_RUN, 0.75f, true);
+ float x = me->GetPositionX() + 20 * cos(me->GetOrientation());
+ float y = me->GetPositionY() + 20 * sin(me->GetOrientation());
+ float z = me->GetPositionZ() + 40;
+ me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MovePoint(0, x, y, z);
// Despawn as soon as possible
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 0a74b64d320..384eec4ebdb 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -1598,12 +1598,12 @@ bool Creature::IsImmunedToSpell(SpellEntry const* spellInfo)
return Unit::IsImmunedToSpell(spellInfo);
}
-bool Creature::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const
+bool Creature::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index, bool checkMechanic) const
{
if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->EffectMechanic[index] - 1)))
return true;
- return Unit::IsImmunedToSpellEffect(spellInfo, index);
+ return Unit::IsImmunedToSpellEffect(spellInfo, index, checkMechanic);
}
SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim)
diff --git a/src/game/Creature.h b/src/game/Creature.h
index 6bad39de566..cd9f30f703a 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -448,7 +448,7 @@ class TRINITY_DLL_SPEC Creature : public Unit, public GridObject<Creature>
bool canCreatureAttack(Unit const *pVictim, bool force = true) const;
bool IsImmunedToSpell(SpellEntry const* spellInfo);
// redefine Unit::IsImmunedToSpell
- bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const;
+ bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index, bool checkMechanic) const;
// redefine Unit::IsImmunedToSpellEffect
bool isElite() const
{
diff --git a/src/game/Group.cpp b/src/game/Group.cpp
index a1585acd41b..b2db3ed46a2 100644
--- a/src/game/Group.cpp
+++ b/src/game/Group.cpp
@@ -1499,7 +1499,9 @@ void Group::SetDungeonDifficulty(Difficulty difficulty)
continue;
player->SetDungeonDifficulty(difficulty);
player->SendDungeonDifficulty(true);
- //send player to recall positio nis a dungeon (to avoid an exploit)
+ // Send player to recall position is a dungeon (to avoid an exploit)
+ if (sMapStore.LookupEntry(player->GetMap()->IsDungeon()))
+ player->TeleportTo(player->m_recallMap, player->m_recallX, player->m_recallY, player->m_recallZ, player->m_recallO);
}
}
diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp
index c074d275614..2864800c53c 100644
--- a/src/game/GroupHandler.cpp
+++ b/src/game/GroupHandler.cpp
@@ -31,6 +31,7 @@
#include "SocialMgr.h"
#include "Util.h"
#include "SpellAuras.h"
+#include "Vehicle.h"
class Aura;
@@ -775,6 +776,14 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
*data << (uint16) 0;
}
+ if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
+ {
+ if(player->GetVehicle()){
+ Vehicle* vv=player->GetVehicle();
+ *data << (uint32) vv->GetVehicleInfo()->m_seatID[player->m_movementInfo.t_seat];
+ }
+ }
+
if (mask & GROUP_UPDATE_FLAG_PET_AURAS)
{
if(pet)
diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp
index d4388f3c7a4..def605bc8c7 100644
--- a/src/game/MovementHandler.cpp
+++ b/src/game/MovementHandler.cpp
@@ -307,7 +307,11 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
}
if (!mover->GetTransport() && !mover->GetVehicle())
- movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT;
+ {
+ GameObject *go = mover->GetMap()->GetGameObject(movementInfo.t_guid);
+ if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT)
+ movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT;
+ }
}
else if (plMover && plMover->GetTransport()) // if we were on a transport, leave
{
@@ -354,6 +358,20 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
plMover->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
plMover->UpdateFallInformationIfNeed(movementInfo, opcode);
+ // If on vehicle, update carried players
+ if (Vehicle *vehicle=plMover->GetVehicleKit())
+ {
+ if (plMover->IsVehicle())
+ {
+ for (int i=0; i < 8; ++i)
+ {
+ if (Unit *passenger = vehicle->GetPassenger(i))
+ if (passenger != NULL && passenger->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)passenger)->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
+ }
+ }
+ }
+
if (movementInfo.z < -500.0f)
{
if (plMover->InBattleGround()
diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp
index 6dc88c9d37a..eda7c7f7173 100644
--- a/src/game/Opcodes.cpp
+++ b/src/game/Opcodes.cpp
@@ -1219,9 +1219,9 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x4A4*/ { "CMSG_QUERY_VEHICLE_STATUS", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4A5*/ { "UMSG_UNKNOWN_1189", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4A6*/ { "SMSG_UNKNOWN_1190", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4A7*/ { "SMSG_UNKNOWN_1191", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4A8*/ { "CMSG_UNKNOWN_1192", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x4A9*/ { "CMSG_EJECT_PASSENGER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4A7*/ { "SMSG_PLAYER_VEHICLE_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4A8*/ { "CMSG_PLAYER_VEHICLE_ENTER", STATUS_LOGGEDIN, &WorldSession::HandleEnterPlayerVehicle },
+ /*0x4A9*/ { "CMSG_EJECT_PASSENGER", STATUS_LOGGEDIN, &WorldSession::HandleEjectPasenger },
/*0x4AA*/ { "SMSG_PET_GUIDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4AB*/ { "SMSG_CLIENTCACHE_VERSION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4AC*/ { "UMSG_UNKNOWN_1196", STATUS_NEVER, &WorldSession::Handle_NULL },
diff --git a/src/game/Opcodes.h b/src/game/Opcodes.h
index 007e17f1687..78da3483b57 100644
--- a/src/game/Opcodes.h
+++ b/src/game/Opcodes.h
@@ -1227,8 +1227,8 @@ enum Opcodes
CMSG_QUERY_VEHICLE_STATUS = 0x4A4, // not found
UMSG_UNKNOWN_1189 = 0x4A5, // not found, old SMSG_PET_GUIDS
SMSG_UNKNOWN_1190 = 0x4A6, // smsg unk, "You can't do that yet"
- SMSG_UNKNOWN_1191 = 0x4A7, // smsg guid+uint32 (vehicle)
- CMSG_UNKNOWN_1192 = 0x4A8, // cmsg uint64
+ SMSG_PLAYER_VEHICLE_DATA = 0x4A7, // smsg guid+uint32 (vehicle)
+ CMSG_PLAYER_VEHICLE_ENTER = 0x4A8, // cmsg uint64
CMSG_EJECT_PASSENGER = 0x4A9, // cmsg uint64
SMSG_PET_GUIDS = 0x4AA, // shifted+5
SMSG_CLIENTCACHE_VERSION = 0x4AB, // shifted+5
diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
index e9b1a2d0eac..261eca21701 100644
--- a/src/game/Pet.cpp
+++ b/src/game/Pet.cpp
@@ -498,7 +498,10 @@ void Pet::setDeathState(DeathState s) // overwrite virtual
void Pet::Update(uint32 diff)
{
- if(m_removed) // pet already removed, just wait in remove queue, no updates
+ if (m_removed) // pet already removed, just wait in remove queue, no updates
+ return;
+
+ if (m_loading)
return;
switch( m_deathState )
diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp
index ee8c02dfb43..edd3a9d4f2b 100644
--- a/src/game/PetHandler.cpp
+++ b/src/game/PetHandler.cpp
@@ -224,8 +224,6 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
case ACT_ENABLED: // 0xC1 spell
{
Unit* unit_target = NULL;
- if (((Creature*)pet)->GetGlobalCooldown() > 0)
- return;
if(guid2)
unit_target = ObjectAccessor::GetUnit(*_player,guid2);
@@ -238,6 +236,10 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
return;
}
+ if (spellInfo->StartRecoveryCategory > 0)
+ if (((Creature*)pet)->GetGlobalCooldown() > 0)
+ return;
+
for (uint32 i = 0; i < 3; ++i)
{
if(spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_AREA_ENEMY_SRC || spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_AREA_ENEMY_DST || spellInfo->EffectImplicitTargetA[i] == TARGET_DEST_DYNOBJ_ENEMY)
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 94d4387f8e7..732ec29ff0b 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -1323,6 +1323,14 @@ void Player::Update( uint32 p_time )
m_zoneUpdateTimer -= p_time;
}
+ if (m_timeSyncTimer > 0)
+ {
+ if(p_time >= m_timeSyncTimer)
+ SendTimeSync();
+ else
+ m_timeSyncTimer -= p_time;
+ }
+
if (isAlive())
{
m_regenTimer += p_time;
@@ -3981,6 +3989,7 @@ void Player::InitVisibleBits()
updateVisualBits.SetBit(PLAYER_BYTES_3);
updateVisualBits.SetBit(PLAYER_DUEL_TEAM);
updateVisualBits.SetBit(PLAYER_GUILD_TIMESTAMP);
+ updateVisualBits.SetBit(UNIT_NPC_FLAGS);
// PLAYER_QUEST_LOG_x also visible bit on official (but only on party/raid)...
for (uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i += 4)
@@ -5862,13 +5871,16 @@ void Player::SendActionButtons(uint32 state) const
WorldPacket data(SMSG_ACTION_BUTTONS, 1+(MAX_ACTION_BUTTONS*4));
data << uint8(state); // can be 0, 1, 2
- for (uint16 button = 0; button < MAX_ACTION_BUTTONS; ++button)
+ if (state != 2)
{
- ActionButtonList::const_iterator itr = m_actionButtons.find(button);
- if (itr != m_actionButtons.end() && itr->second.uState != ACTIONBUTTON_DELETED)
- data << uint32(itr->second.packedData);
- else
- data << uint32(0);
+ for (uint16 button = 0; button < MAX_ACTION_BUTTONS; ++button)
+ {
+ ActionButtonList::const_iterator itr = m_actionButtons.find(button);
+ if (itr != m_actionButtons.end() && itr->second.uState != ACTIONBUTTON_DELETED)
+ data << uint32(itr->second.packedData);
+ else
+ data << uint32(0);
+ }
}
GetSession()->SendPacket(&data);
@@ -7126,12 +7138,29 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl
if (uint32 ssvarmor = ssv->getArmorMod(proto->ScalingStatValue))
armor = ssvarmor;
}
- // Add armor bonus from ArmorDamageModifier if > 0
- if (proto->ArmorDamageModifier > 0)
- armor += uint32(proto->ArmorDamageModifier);
if (armor)
- HandleStatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(armor), apply);
+ {
+ UnitModifierType modType = TOTAL_VALUE;
+ if (proto->Class == ITEM_CLASS_ARMOR)
+ {
+ switch (proto->SubClass)
+ {
+ case ITEM_SUBCLASS_ARMOR_CLOTH:
+ case ITEM_SUBCLASS_ARMOR_LEATHER:
+ case ITEM_SUBCLASS_ARMOR_MAIL:
+ case ITEM_SUBCLASS_ARMOR_PLATE:
+ case ITEM_SUBCLASS_ARMOR_SHIELD:
+ modType = BASE_VALUE;
+ break;
+ }
+ }
+ HandleStatModifier(UNIT_MOD_ARMOR, modType, float(armor), apply);
+ }
+
+ // Add armor bonus from ArmorDamageModifier if > 0
+ if (proto->ArmorDamageModifier > 0)
+ HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(proto->ArmorDamageModifier), apply);
if (proto->Block)
HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(proto->Block), apply);
@@ -7291,7 +7320,14 @@ void Player::_ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType att
}
if (!item->IsBroken()&&item->IsFitToSpellRequirements(aura->GetSpellProto()))
+ {
HandleStatModifier(unitMod, unitModType, float(aura->GetAmount()),apply);
+
+ if (unitModType == TOTAL_PCT)
+ ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT,aura->GetAmount()/100.0f,apply);
+ else
+ ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,aura->GetAmount(),apply);
+ }
}
void Player::ApplyItemEquipSpell(Item *item, bool apply, bool form_change)
@@ -17016,15 +17052,11 @@ void Player::SaveToDB()
sLog.outDebug("The value of player %s at save: ", m_name.c_str());
outDebugValues();
- CharacterDatabase.BeginTransaction();
-
- CharacterDatabase.PExecute("DELETE FROM characters WHERE guid = '%u'",GetGUIDLow());
-
std::string sql_name = m_name;
CharacterDatabase.escape_string(sql_name);
std::ostringstream ss;
- ss << "INSERT INTO characters (guid,account,name,race,class,gender,level,xp,money,playerBytes,playerBytes2,playerFlags,"
+ ss << "REPLACE INTO characters (guid,account,name,race,class,gender,level,xp,money,playerBytes,playerBytes2,playerFlags,"
"map, instance_id, dungeon_difficulty, position_x, position_y, position_z, orientation, data, "
"taximask, online, cinematic, "
"totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, "
@@ -17116,6 +17148,8 @@ void Player::SaveToDB()
ss << uint32(m_activeSpec);
ss << ")";
+ CharacterDatabase.BeginTransaction();
+
CharacterDatabase.Execute( ss.str().c_str() );
if (m_mailsUpdated) //save mails only when needed
@@ -20200,9 +20234,8 @@ void Player::SendInitialPacketsAfterAddToMap()
GetZoneAndAreaId(newzone,newarea);
UpdateZone(newzone,newarea); // also call SendInitWorldStates();
- WorldPacket data(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement
- data << uint32(0x00000000); // on blizz it increments periodically
- GetSession()->SendPacket(&data);
+ ResetTimeSync();
+ SendTimeSync();
CastSpell(this, SPELL_LOGINEFFECT_836, true); // LOGINEFFECT
@@ -23006,8 +23039,8 @@ void Player::ActivateSpec(uint8 spec)
m_usedTalentCount = spentTalents;
InitTalentForLevel();
- _SaveSpells();
-
+ // Let client clear his current Actions
+ SendActionButtons(2);
m_actionButtons.clear();
if (QueryResult *result = CharacterDatabase.PQuery("SELECT button,action,type FROM character_action WHERE guid = '%u' AND spec = '%u' ORDER BY button", GetGUIDLow(), m_activeSpec))
_LoadActions(result, false);
@@ -23022,6 +23055,22 @@ void Player::ActivateSpec(uint8 spec)
SetPower(pw, 0);
}
+void Player::ResetTimeSync()
+{
+ m_timeSyncCount = 0;
+ m_timeSyncTimer = 0;
+}
+
+void Player::SendTimeSync()
+{
+ WorldPacket data(SMSG_TIME_SYNC_REQ, 4);
+ data << uint32(m_timeSyncCount++);
+ GetSession()->SendPacket(&data);
+
+ // Send another opcode in 10s again
+ m_timeSyncTimer = 10000;
+}
+
void Player::SetReputation(uint32 factionentry, uint32 value)
{
GetReputationMgr().SetReputation(sFactionStore.LookupEntry(factionentry),value);
diff --git a/src/game/Player.h b/src/game/Player.h
index cac6e889345..1067105d227 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -2437,6 +2437,9 @@ Spell * m_spellModTakingSpell;
EnchantDurationList m_enchantDuration;
ItemDurationList m_itemDuration;
+ void ResetTimeSync();
+ void SendTimeSync();
+
uint64 m_resurrectGUID;
uint32 m_resurrectMap;
float m_resurrectX, m_resurrectY, m_resurrectZ;
@@ -2572,6 +2575,9 @@ Spell * m_spellModTakingSpell;
SpellCooldowns m_spellCooldowns;
uint32 m_ChampioningFaction;
+
+ uint32 m_timeSyncCount;
+ uint32 m_timeSyncTimer;
};
void AddItemsSetItem(Player*player,Item *item);
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index afccf854ee0..e80239b3574 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -678,7 +678,7 @@ enum SpellEffects
SPELL_EFFECT_KILL_CREDIT = 90,
SPELL_EFFECT_THREAT_ALL = 91,
SPELL_EFFECT_ENCHANT_HELD_ITEM = 92,
- SPELL_EFFECT_SUMMON_PHANTASM = 93, //unused
+ SPELL_EFFECT_FORCE_DESELECT = 93,
SPELL_EFFECT_SELF_RESURRECT = 94,
SPELL_EFFECT_SKINNING = 95,
SPELL_EFFECT_CHARGE = 96,
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index a6f47e63a3c..d0c7c7d549a 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -1208,6 +1208,16 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
if (canEffectTrigger && missInfo != SPELL_MISS_REFLECT)
caster->ProcDamageAndSpell(unit, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell);
+
+ // Failed Pickpocket, reveal rogue
+ if (missInfo == SPELL_MISS_RESIST
+ && m_customAttr & SPELL_ATTR_CU_PICKPOCKET
+ && unitTarget->GetTypeId() == TYPEID_UNIT)
+ {
+ m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK);
+ if (((Creature*)unitTarget)->IsAIEnabled)
+ ((Creature*)unitTarget)->AI()->AttackStart(m_caster);
+ }
}
if(m_caster && !m_caster->IsFriendlyTo(unit) && !IsPositiveSpell(m_spellInfo->Id))
@@ -1421,7 +1431,7 @@ void Spell::DoTriggersOnSpellHit(Unit *unit)
// Cast Avenging Wrath Marker
m_caster->CastSpell(unit,61987, true, m_CastItem);
}
- else
+ else if (sSpellStore.LookupEntry(m_preCastSpell))
m_caster->CastSpell(unit,m_preCastSpell, true, m_CastItem);
}
@@ -4114,14 +4124,14 @@ SpellCastResult Spell::CheckRuneCost(uint32 runeCostID)
if(src->NoRuneCost())
return SPELL_CAST_OK;
- // Freezing Fog makes Howling Blast cost no runes
- if (m_caster->HasAura(59052) && m_spellInfo->SpellFamilyFlags[1] & 0x2)
- return SPELL_CAST_OK;
-
int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
for (uint32 i = 0; i < RUNE_DEATH; ++i)
+ {
runeCost[i] = src->RuneCost[i];
+ if(Player* modOwner = m_caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
+ }
runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
@@ -4441,6 +4451,39 @@ SpellCastResult Spell::CheckCast(bool strict)
if (target->hasUnitState(UNIT_STAT_UNATTACKABLE))
return SPELL_FAILED_BAD_TARGETS;
+ if(!m_IsTriggeredSpell && (target->HasAuraType(SPELL_AURA_MOD_STEALTH)
+ || target->m_invisibilityMask) && !m_caster->canSeeOrDetect(target, true))
+ return SPELL_FAILED_BAD_TARGETS;
+
+ if (m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ // Not allow banish not self target
+ if (m_spellInfo->Mechanic == MECHANIC_BANISH)
+ if (target->GetTypeId() == TYPEID_UNIT &&
+ !((Player*)m_caster)->isAllowedToLoot((Creature*)target))
+ return SPELL_FAILED_CANT_CAST_ON_TAPPED;
+
+ if (m_customAttr & SPELL_ATTR_CU_PICKPOCKET)
+ {
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ return SPELL_FAILED_BAD_TARGETS;
+ else if ((target->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD) == 0)
+ return SPELL_FAILED_TARGET_NO_POCKETS;
+ }
+
+ // Not allow disarm unarmed player
+ if (m_spellInfo->Mechanic == MECHANIC_DISARM)
+ {
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(!((Player*)target)->GetWeaponForAttack(BASE_ATTACK) || !((Player*)target)->IsUseEquipedWeapon(true))
+ return SPELL_FAILED_TARGET_NO_WEAPONS;
+ }
+ else if (!target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID))
+ return SPELL_FAILED_TARGET_NO_WEAPONS;
+ }
+ }
+
if(!m_IsTriggeredSpell && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOSInMap(target))
return SPELL_FAILED_LINE_OF_SIGHT;
@@ -4995,17 +5038,6 @@ SpellCastResult Spell::CheckCast(bool strict)
}
break;
}
- // Not used for summon?
- case SPELL_EFFECT_SUMMON_PHANTASM:
- {
- if(m_caster->GetPetGUID())
- return SPELL_FAILED_ALREADY_HAVE_SUMMON;
-
- if(m_caster->GetCharmGUID())
- return SPELL_FAILED_ALREADY_HAVE_CHARM;
-
- break;
- }
case SPELL_EFFECT_SUMMON_PET:
{
if(m_caster->GetPetGUID()) //let warlock do a replacement summon
diff --git a/src/game/Spell.h b/src/game/Spell.h
index 04f3984ed91..bda7ebbfaa3 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -322,6 +322,7 @@ class Spell
void EffectFeedPet(uint32 i);
void EffectDismissPet(uint32 i);
void EffectReputation(uint32 i);
+ void EffectForceDeselect(uint32 i);
void EffectSelfResurrect(uint32 i);
void EffectSkinning(uint32 i);
void EffectCharge(uint32 i);
diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h
index 3a3942e9840..9a79dafe1d9 100644
--- a/src/game/SpellAuraDefines.h
+++ b/src/game/SpellAuraDefines.h
@@ -287,7 +287,7 @@ enum AuraType
SPELL_AURA_MOD_EXPERTISE = 240,
SPELL_AURA_FORCE_MOVE_FORWARD = 241,
SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING = 242,
- SPELL_AURA_243 = 243,
+ SPELL_AURA_MOD_FACTION = 243,
SPELL_AURA_COMPREHEND_LANGUAGE = 244,
SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL = 245,
SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK = 246,
diff --git a/src/game/SpellAuraEffects.cpp b/src/game/SpellAuraEffects.cpp
index 1492d586943..d9efa1771ed 100644
--- a/src/game/SpellAuraEffects.cpp
+++ b/src/game/SpellAuraEffects.cpp
@@ -298,7 +298,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleAuraModExpertise, //240 SPELL_AURA_MOD_EXPERTISE
&AuraEffect::HandleForceMoveForward, //241 SPELL_AURA_FORCE_MOVE_FORWARD Forces the player to move forward
&AuraEffect::HandleNULL, //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING - 2 test spells: 44183 and 44182
- &AuraEffect::HandleNULL, //243 faction reaction override spells
+ &AuraEffect::HandleAuraModFaction, //243 SPELL_AURA_MOD_FACTION
&AuraEffect::HandleComprehendLanguage, //244 SPELL_AURA_COMPREHEND_LANGUAGE
&AuraEffect::HandleNoImmediateEffect, //245 SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL
&AuraEffect::HandleNoImmediateEffect, //246 SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK implemented in Spell::EffectApplyAura
@@ -2288,6 +2288,7 @@ void AuraEffect::HandleShapeshiftBoosts(Unit * target, bool apply) const
break;
case FORM_MOONKIN:
spellId = 24905;
+ spellId2 = 69366;
break;
case FORM_FLIGHT:
spellId = 33948;
@@ -3470,7 +3471,7 @@ void AuraEffect::HandleAuraMounted(AuraApplication const * aurApp, uint8 mode, b
if(GetSpellProto()->Effect[i] == SPELL_EFFECT_SUMMON
&& GetSpellProto()->EffectMiscValue[i] == GetMiscValue())
display_id = 0;
- target->Mount(display_id);
+ target->Mount(display_id,ci->VehicleId);
}
else
{
@@ -4755,7 +4756,7 @@ void AuraEffect::HandleAuraModWeaponCritPercent(AuraApplication const * aurApp,
return;
for (int i = 0; i < MAX_ATTACK; ++i)
- if(Item* pItem = ((Player*)target)->GetWeaponForAttack(WeaponAttackType(i)))
+ if(Item* pItem = ((Player*)target)->GetWeaponForAttack(WeaponAttackType(i), true))
((Player*)target)->_ApplyWeaponDependentAuraCritMod(pItem,WeaponAttackType(i),this,apply);
// mods must be applied base at equipped weapon class and subclass comparison
@@ -5076,7 +5077,7 @@ void AuraEffect::HandleModDamageDone(AuraApplication const * aurApp, uint8 mode,
if(target->GetTypeId() == TYPEID_PLAYER)
{
for (int i = 0; i < MAX_ATTACK; ++i)
- if(Item* pItem = ((Player*)target)->GetWeaponForAttack(WeaponAttackType(i)))
+ if(Item* pItem = ((Player*)target)->GetWeaponForAttack(WeaponAttackType(i), true))
((Player*)target)->_ApplyWeaponDependentAuraDamageMod(pItem,WeaponAttackType(i),this,apply);
}
@@ -5097,19 +5098,19 @@ void AuraEffect::HandleModDamageDone(AuraApplication const * aurApp, uint8 mode,
target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(GetAmount()), apply);
target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(GetAmount()), apply);
target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(GetAmount()), apply);
+
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(GetAmount() > 0)
+ target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,GetAmount(),apply);
+ else
+ target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG,GetAmount(),apply);
+ }
}
else
{
// done in Player::_ApplyWeaponDependentAuraMods
}
-
- if(target->GetTypeId() == TYPEID_PLAYER)
- {
- if(GetAmount() > 0)
- target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,GetAmount(),apply);
- else
- target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG,GetAmount(),apply);
- }
}
// Skip non magic case for speedup
@@ -5163,7 +5164,7 @@ void AuraEffect::HandleModDamagePercentDone(AuraApplication const * aurApp, uint
if(target->GetTypeId() == TYPEID_PLAYER)
{
for (int i = 0; i < MAX_ATTACK; ++i)
- if(Item* pItem = ((Player*)target)->GetWeaponForAttack(WeaponAttackType(i)))
+ if(Item* pItem = ((Player*)target)->GetWeaponForAttack(WeaponAttackType(i), true))
((Player*)target)->_ApplyWeaponDependentAuraDamageMod(pItem,WeaponAttackType(i),this,apply);
}
@@ -5184,14 +5185,14 @@ void AuraEffect::HandleModDamagePercentDone(AuraApplication const * aurApp, uint
target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(GetAmount()), apply);
target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(GetAmount()), apply);
target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(GetAmount()), apply);
+ // For show in client
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT,GetAmount()/100.0f,apply);
}
else
{
// done in Player::_ApplyWeaponDependentAuraMods
}
- // For show in client
- if(target->GetTypeId() == TYPEID_PLAYER)
- target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT,GetAmount()/100.0f,apply);
}
// Skip non magic case for speedup
@@ -5996,6 +5997,28 @@ void AuraEffect::HandleAuraEmpathy(AuraApplication const * aurApp, uint8 mode, b
target->ApplyModUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO, apply);
}
+void AuraEffect::HandleAuraModFaction(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(apply)
+ {
+ target->setFaction(GetMiscValue());
+ if(target->GetTypeId()==TYPEID_PLAYER)
+ target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+ }
+ else
+ {
+ target->RestoreFaction();
+ if(target->GetTypeId()==TYPEID_PLAYER)
+ target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+ }
+}
+
+
void AuraEffect::HandleComprehendLanguage(AuraApplication const * aurApp, uint8 mode, bool apply) const
{
if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
diff --git a/src/game/SpellAuraEffects.h b/src/game/SpellAuraEffects.h
index 75e061da5fe..3adf009e388 100644
--- a/src/game/SpellAuraEffects.h
+++ b/src/game/SpellAuraEffects.h
@@ -255,6 +255,7 @@ class TRINITY_DLL_SPEC AuraEffect
void HandleBindSight(AuraApplication const * aurApp, uint8 mode, bool apply) const;
void HandleForceReaction(AuraApplication const * aurApp, uint8 mode, bool apply) const;
void HandleAuraEmpathy(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModFaction(AuraApplication const * aurApp, uint8 mode, bool apply) const;
void HandleComprehendLanguage(AuraApplication const * aurApp, uint8 mode, bool apply) const;
void HandleAuraConvertRune(AuraApplication const * aurApp, uint8 mode, bool apply) const;
void HandleAuraLinked(AuraApplication const * aurApp, uint8 mode, bool apply) const;
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 47e47d1f119..2a7a45bfbee 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -159,7 +159,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectKillCreditPersonal, // 90 SPELL_EFFECT_KILL_CREDIT Kill credit but only for single person
&Spell::EffectUnused, // 91 SPELL_EFFECT_THREAT_ALL one spell: zzOLDBrainwash
&Spell::EffectEnchantHeldItem, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM
- &Spell::EffectUnused, // 93 SPELL_EFFECT_SUMMON_PHANTASM
+ &Spell::EffectForceDeselect, // 93 SPELL_EFFECT_FORCE_DESELECT
&Spell::EffectSelfResurrect, // 94 SPELL_EFFECT_SELF_RESURRECT
&Spell::EffectSkinning, // 95 SPELL_EFFECT_SKINNING
&Spell::EffectCharge, // 96 SPELL_EFFECT_CHARGE
@@ -3884,22 +3884,7 @@ void Spell::EffectPickPocket(uint32 /*i*/)
// victim have to be alive and humanoid or undead
if (unitTarget->isAlive() && (unitTarget->GetCreatureTypeMask() &CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD) != 0)
- {
- int32 chance = 10 + int32(m_caster->getLevel()) - int32(unitTarget->getLevel());
-
- if (chance > irand(0, 19))
- {
- // Stealing successful
- //sLog.outDebug("Sending loot from pickpocket");
- ((Player*)m_caster)->SendLoot(unitTarget->GetGUID(),LOOT_PICKPOCKETING);
- }
- else
- {
- // Reveal action + get attack
- m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK);
- m_caster->CombatStart(unitTarget);
- }
- }
+ ((Player*)m_caster)->SendLoot(unitTarget->GetGUID(),LOOT_PICKPOCKETING);
}
void Spell::EffectAddFarsight(uint32 i)
@@ -4580,12 +4565,9 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
}
case SPELLFAMILY_HUNTER:
{
- // Kill Shot
+ // Kill Shot - bonus damage from Ranged Attack Power
if(m_spellInfo->SpellFamilyFlags[1] & 0x800000)
- {
- // Increase Weapon Damage by 200% (or Weapon Damage + Weapon Damage)
- spell_bonus += m_caster->CalculateDamage(RANGED_ATTACK, false, true);
- }
+ spell_bonus += int32(0.4f*m_caster->GetTotalAttackPowerValue(RANGED_ATTACK));
break;
}
case SPELLFAMILY_DEATHKNIGHT:
@@ -6607,10 +6589,9 @@ void Spell::EffectLeapForward(uint32 i)
destz = fabs(ground - z) <= fabs(floor - z) ? ground:floor;
} else break;
}
- if (j == 9)
- return;
- unitTarget->NearTeleportTo(destx, desty, destz + 0.07531, orientation, unitTarget==m_caster);
+ if(j < 10)
+ unitTarget->NearTeleportTo(destx, desty, destz + 0.07531, orientation, unitTarget==m_caster);
}
void Spell::EffectReputation(uint32 i)
@@ -6643,6 +6624,13 @@ void Spell::EffectQuestComplete(uint32 i)
_player->AreaExploredOrEventHappens(quest_id);
}
+void Spell::EffectForceDeselect(uint32 i)
+{
+ WorldPacket data(SMSG_CLEAR_TARGET, 8);
+ data << uint64(m_caster->GetGUID());
+ m_caster->SendMessageToSet(&data, true);
+}
+
void Spell::EffectSelfResurrect(uint32 i)
{
if(!unitTarget || unitTarget->isAlive())
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index d39b47a925d..35ccabd1c60 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -3542,6 +3542,9 @@ void SpellMgr::LoadSpellCustomAttr()
mSpellCustomAttr[i] |= SPELL_ATTR_CU_CHARGE;
count++;
break;
+ case SPELL_EFFECT_PICKPOCKET:
+ mSpellCustomAttr[i] |= SPELL_ATTR_CU_PICKPOCKET;
+ break;
case SPELL_EFFECT_TRIGGER_SPELL:
if (IsPositionTarget(spellInfo->EffectImplicitTargetA[j]) ||
spellInfo->Targets & (TARGET_FLAG_SOURCE_LOCATION|TARGET_FLAG_DEST_LOCATION))
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index a31c4c5434c..6f865ef30dc 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -825,6 +825,7 @@ inline bool IsProfessionSkill(uint32 skill)
#define SPELL_ATTR_CU_LINK_HIT 0x00000800
#define SPELL_ATTR_CU_LINK_AURA 0x00001000
#define SPELL_ATTR_CU_LINK_REMOVE 0x00002000
+#define SPELL_ATTR_CU_PICKPOCKET 0x00004000
#define SPELL_ATTR_CU_EXCLUDE_SELF 0x00008000
#define SPELL_ATTR_CU_NEGATIVE_EFF0 0x00010000
#define SPELL_ATTR_CU_NEGATIVE_EFF1 0x00020000
diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp
index f5d8bf636f2..0a4f1472ff8 100644
--- a/src/game/StatSystem.cpp
+++ b/src/game/StatSystem.cpp
@@ -397,7 +397,7 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
UpdateDamagePhysical(BASE_ATTACK);
if(CanDualWield() && haveOffhandWeapon()) //allow update offhand damage only if player knows DualWield Spec and has equipped offhand weapon
UpdateDamagePhysical(OFF_ATTACK);
- if(getClass() == CLASS_SHAMAN) // mental quickness
+ if(getClass() == CLASS_SHAMAN || getClass() == CLASS_PALADIN) // mental quickness
UpdateSpellDamageAndHealingBonus();
if(pet && pet->IsPetGhoul()) // At ranged attack change for hunter pet
diff --git a/src/game/Totem.cpp b/src/game/Totem.cpp
index 282dc7678cb..a6e30ca09ae 100644
--- a/src/game/Totem.cpp
+++ b/src/game/Totem.cpp
@@ -145,7 +145,7 @@ void Totem::UnSummon()
AddObjectToRemoveList();
}
-bool Totem::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const
+bool Totem::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index, bool checkMechanic) const
{
// TODO: possibly all negative auras immune?
if(GetEntry() == 5925)
@@ -160,5 +160,5 @@ bool Totem::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) co
default:
break;
}
- return Creature::IsImmunedToSpellEffect(spellInfo, index);
+ return Creature::IsImmunedToSpellEffect(spellInfo, index, checkMechanic);
}
diff --git a/src/game/Totem.h b/src/game/Totem.h
index 6dbd699f1d2..535e39a58dd 100644
--- a/src/game/Totem.h
+++ b/src/game/Totem.h
@@ -54,7 +54,7 @@ class Totem : public Minion
void UpdateAttackPowerAndDamage(bool /*ranged*/ ) {}
void UpdateDamagePhysical(WeaponAttackType /*attType*/) {}
- bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const;
+ bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index, bool checkMechanic) const;
protected:
TotemType m_type;
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index b09e414e4ff..3e918396c0e 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -602,6 +602,42 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
pVictim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TAKE_DAMAGE, spellProto ? spellProto->Id : 0);
}
+
+ // Rage from Damage made (only from direct weapon damage)
+ if (cleanDamage && damagetype==DIRECT_DAMAGE && this != pVictim && getPowerType() == POWER_RAGE)
+ {
+ uint32 weaponSpeedHitFactor;
+ uint32 rage_damage = damage + cleanDamage->absorbed_damage;
+
+ switch(cleanDamage->attackType)
+ {
+ case BASE_ATTACK:
+ {
+ if (cleanDamage->hitOutCome == MELEE_HIT_CRIT)
+ weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 7);
+ else
+ weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 3.5f);
+
+ RewardRage(rage_damage, weaponSpeedHitFactor, true);
+
+ break;
+ }
+ case OFF_ATTACK:
+ {
+ if (cleanDamage->hitOutCome == MELEE_HIT_CRIT)
+ weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 3.5f);
+ else
+ weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 1.75f);
+
+ RewardRage(rage_damage, weaponSpeedHitFactor, true);
+
+ break;
+ }
+ case RANGED_ATTACK:
+ break;
+ }
+ }
+
if (!damage)
{
// Rage from absorbed damage
@@ -651,41 +687,6 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
duel_hasEnded = true;
}
- // Rage from Damage made (only from direct weapon damage)
- if (cleanDamage && damagetype==DIRECT_DAMAGE && this != pVictim && getPowerType() == POWER_RAGE)
- {
- uint32 weaponSpeedHitFactor;
- uint32 rage_damage = damage + cleanDamage->absorbed_damage;
-
- switch(cleanDamage->attackType)
- {
- case BASE_ATTACK:
- {
- if (cleanDamage->hitOutCome == MELEE_HIT_CRIT)
- weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 7);
- else
- weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 3.5f);
-
- RewardRage(rage_damage, weaponSpeedHitFactor, true);
-
- break;
- }
- case OFF_ATTACK:
- {
- if (cleanDamage->hitOutCome == MELEE_HIT_CRIT)
- weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 3.5f);
- else
- weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 1.75f);
-
- RewardRage(rage_damage, weaponSpeedHitFactor, true);
-
- break;
- }
- case RANGED_ATTACK:
- break;
- }
- }
-
if (GetTypeId() == TYPEID_PLAYER && this != pVictim)
{
Player *killer = ((Player*)this);
@@ -1849,6 +1850,14 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
RemainingDamage -= int32(currentAbsorb * pVictim->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
continue;
}
+ // Moonkin Form passive
+ if (spellProto->Id == 69366)
+ {
+ //reduces all damage taken while Stunned
+ if (unitflag & UNIT_FLAG_STUNNED)
+ RemainingDamage -= RemainingDamage * currentAbsorb / 100;
+ continue;
+ }
break;
}
case SPELLFAMILY_ROGUE:
@@ -6557,7 +6566,20 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
// Sacred Shield
if (dummySpell->SpellFamilyFlags[1]&0x00080000)
{
- triggered_spell_id = 58597;
+ if (procFlag & PROC_FLAG_TAKEN_POSITIVE_MAGIC_SPELL)
+ {
+ if (procSpell->SpellFamilyName == SPELLFAMILY_PALADIN
+ && (procSpell->SpellFamilyFlags[0] & 0x40000000))
+ {
+ basepoints0 = int32(float(damage)/12.0f);
+ CastCustomSpell(this,66922,&basepoints0,NULL,NULL,true,0,triggeredByAura, pVictim->GetGUID());
+ return true;
+ }
+ else
+ return false;
+ }
+ else
+ triggered_spell_id = 58597;
target = this;
break;
}
@@ -8556,11 +8578,14 @@ bool Unit::IsHostileTo(Unit const* unit) const
//= PvP states
// Green/Blue (can't attack)
- if(pTester->GetTeam()==pTarget->GetTeam())
- return false;
+ if (!pTester->HasAuraType(SPELL_AURA_MOD_FACTION) && !pTarget->HasAuraType(SPELL_AURA_MOD_FACTION))
+ {
+ if(pTester->GetTeam()==pTarget->GetTeam())
+ return false;
- // Red (can attack) if true, Blue/Yellow (can't attack) in another case
- return pTester->IsPvP() && pTarget->IsPvP();
+ // Red (can attack) if true, Blue/Yellow (can't attack) in another case
+ return pTester->IsPvP() && pTarget->IsPvP();
+ }
}
// faction base cases
@@ -8573,7 +8598,7 @@ bool Unit::IsHostileTo(Unit const* unit) const
return true;
// PvC forced reaction and reputation case
- if(tester->GetTypeId() == TYPEID_PLAYER)
+ if(tester->GetTypeId() == TYPEID_PLAYER && !tester->HasAuraType(SPELL_AURA_MOD_FACTION))
{
// forced reaction
if(target_faction->faction)
@@ -8588,7 +8613,7 @@ bool Unit::IsHostileTo(Unit const* unit) const
}
}
// CvP forced reaction and reputation case
- else if(target->GetTypeId() == TYPEID_PLAYER)
+ else if(target->GetTypeId() == TYPEID_PLAYER && !target->HasAuraType(SPELL_AURA_MOD_FACTION))
{
// forced reaction
if(tester_faction->faction)
@@ -8668,11 +8693,14 @@ bool Unit::IsFriendlyTo(Unit const* unit) const
//= PvP states
// Green/Blue (non-attackable)
- if(pTester->GetTeam()==pTarget->GetTeam())
- return true;
+ if (!pTester->HasAuraType(SPELL_AURA_MOD_FACTION) && !pTarget->HasAuraType(SPELL_AURA_MOD_FACTION))
+ {
+ if(pTester->GetTeam()==pTarget->GetTeam())
+ return true;
- // Blue (friendly/non-attackable) if not PVP, or Yellow/Red in another case (attackable)
- return !pTarget->IsPvP();
+ // Blue (friendly/non-attackable) if not PVP, or Yellow/Red in another case (attackable)
+ return !pTarget->IsPvP();
+ }
}
// faction base cases
@@ -8685,7 +8713,7 @@ bool Unit::IsFriendlyTo(Unit const* unit) const
return false;
// PvC forced reaction and reputation case
- if (tester->GetTypeId() == TYPEID_PLAYER)
+ if (tester->GetTypeId() == TYPEID_PLAYER && !tester->HasAuraType(SPELL_AURA_MOD_FACTION))
{
// forced reaction
if (target_faction->faction)
@@ -8700,7 +8728,7 @@ bool Unit::IsFriendlyTo(Unit const* unit) const
}
}
// CvP forced reaction and reputation case
- else if (target->GetTypeId() == TYPEID_PLAYER)
+ else if (target->GetTypeId() == TYPEID_PLAYER && !target->HasAuraType(SPELL_AURA_MOD_FACTION))
{
// forced reaction
if (tester_faction->faction)
@@ -9547,14 +9575,14 @@ void Unit::UnsummonAllTotems()
void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, uint32 OverHeal, bool critical)
{
// we guess size
- WorldPacket data(SMSG_SPELLHEALLOG, (8+8+4+4+1));
+ WorldPacket data(SMSG_SPELLHEALLOG, (8+8+4+4+4+4+1));
data.append(pVictim->GetPackGUID());
data.append(GetPackGUID());
data << uint32(SpellID);
data << uint32(Damage);
data << uint32(OverHeal);
+ data << uint32(0); // Absorb amount
data << uint8(critical ? 1 : 0);
- data << uint8(0); // unused in client?
SendMessageToSet(&data, true);
}
@@ -10646,6 +10674,14 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo)
return true;
}
+ for (int i=0;i<3;++i)
+ {
+ // State/effect immunities applied by aura expect full spell immunity
+ // However function also check for mechanic, so ignore that for now
+ if (IsImmunedToSpellEffect(spellInfo, i, false))
+ return true;
+ }
+
if (spellInfo->Id != 42292 && spellInfo->Id !=59752)
{
SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
@@ -10659,7 +10695,7 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo)
return false;
}
-bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const
+bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index, bool checkMechanic) const
{
if (!spellInfo)
return false;
@@ -10670,12 +10706,15 @@ bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) con
if (itr->type == effect)
return true;
- if (uint32 mechanic = spellInfo->EffectMechanic[index])
+ if (checkMechanic)
{
- SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
- for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
- if (itr->type == spellInfo->EffectMechanic[index])
- return true;
+ if (uint32 mechanic = spellInfo->EffectMechanic[index])
+ {
+ SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
+ for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
+ if (itr->type == spellInfo->EffectMechanic[index])
+ return true;
+ }
}
if (uint32 aura = spellInfo->EffectApplyAuraName[index])
@@ -11061,7 +11100,7 @@ float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM, const SpellEntry * s
return uint32((WeaponSpeed * PPM) / 600.0f); // result is chance in percents (probability = Speed_in_sec * (PPM / 60))
}
-void Unit::Mount(uint32 mount)
+void Unit::Mount(uint32 mount, uint32 VehicleId)
{
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNT);
@@ -11083,6 +11122,27 @@ void Unit::Mount(uint32 mount)
else
((Player*)this)->UnsummonPetTemporaryIfAny();
}
+
+ if(VehicleId !=0)
+ {
+ if(VehicleEntry const *ve = sVehicleStore.LookupEntry(VehicleId))
+ {
+
+ if (CreateVehicleKit(VehicleId))
+ {
+ GetVehicleKit()->Reset();
+
+ // Send others that we now have a vehicle
+ WorldPacket data( SMSG_PLAYER_VEHICLE_DATA, GetPackGUID().size()+4);
+ data.appendPackGUID(GetGUID());
+ data << uint32(VehicleId);
+ SendMessageToSet( &data,true );
+
+ data.Initialize(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
+ ((Player*)this)->GetSession()->SendPacket( &data );
+ }
+ }
+ }
}
}
@@ -11110,6 +11170,16 @@ void Unit::Unmount()
else
((Player*)this)->ResummonPetTemporaryUnSummonedIfAny();
}
+ if(GetTypeId()==TYPEID_PLAYER && GetVehicleKit())
+ {
+ // Send other players that we are no longer a vehicle
+ WorldPacket data( SMSG_PLAYER_VEHICLE_DATA, 8+4 );
+ data.appendPackGUID(GetGUID());
+ data << uint32(0);
+ ((Player*)this)->SendMessageToSet(&data, true);
+ // Remove vehicle class from player
+ RemoveVehicleKit();
+ }
}
void Unit::SetInCombatWith(Unit* enemy)
@@ -11455,9 +11525,9 @@ bool Unit::canDetectStealthOf(Unit const* target, float distance) const
return true;
//Visible distance based on stealth value (stealth rank 4 300MOD, 10.5 - 3 = 7.5)
- float visibleDistance = 10.5f - target->GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH) / 100.0f;
+ float visibleDistance = 7.5f;
//Visible distance is modified by -Level Diff (every level diff = 1.0f in visible distance)
- visibleDistance += int32(getLevelForTarget(target)) - int32(target->getLevelForTarget(this));
+ visibleDistance += float(getLevelForTarget(target)) - target->GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH)/5.0f;
//-Stealth Mod(positive like Master of Deception) and Stealth Detection(negative like paranoia)
//based on wowwiki every 5 mod we have 1 more level diff in calculation
visibleDistance += (float)(GetTotalAuraModifier(SPELL_AURA_MOD_DETECT) - target->GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH_LEVEL)) / 5.0f;
@@ -12195,7 +12265,7 @@ void Unit::ModSpellCastTime(SpellEntry const* spellProto, int32 & castTime, Spel
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CASTING_TIME, castTime, spell);
- if (!(spellProto->Attributes & (SPELL_ATTR_UNK4|SPELL_ATTR_TRADESPELL)) && spellProto->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && spellProto->SpellFamilyName)
+ if (!(spellProto->Attributes & (SPELL_ATTR_UNK4|SPELL_ATTR_TRADESPELL)) && spellProto->SpellFamilyName)
castTime = int32(float(castTime) * GetFloatValue(UNIT_MOD_CAST_SPEED));
else
{
@@ -14918,6 +14988,22 @@ bool Unit::CreateVehicleKit(uint32 id)
return true;
}
+void Unit::RemoveVehicleKit()
+{
+ if (!m_vehicleKit)
+ return;
+
+ m_vehicleKit->Uninstall();
+ delete m_vehicleKit;
+
+ m_vehicleKit = NULL;
+
+ m_updateFlag &= ~UPDATEFLAG_VEHICLE;
+ m_unitTypeMask &= ~UNIT_MASK_VEHICLE;
+ RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
+}
+
Unit *Unit::GetVehicleBase() const
{
return m_vehicle ? m_vehicle->GetBase() : NULL;
diff --git a/src/game/Unit.h b/src/game/Unit.h
index dba30f176f5..3c558c225a7 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -631,6 +631,7 @@ enum NPCFlags
UNIT_NPC_FLAG_STABLEMASTER = 0x00400000, // 100%
UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // cause client to send 997 opcode
UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // cause client to send 1015 opcode (spell click), dynamic, set at loading and don't must be set in DB
+ UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000, // players with mounts that have vehicle data should have it set
UNIT_NPC_FLAG_GUARD = 0x10000000, // custom flag for guards
UNIT_NPC_FLAG_OUTDOORPVP = 0x20000000, // custom flag for outdoor pvp creatures
};
@@ -1272,7 +1273,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
bool IsMounted() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT ); }
uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); }
- void Mount(uint32 mount);
+ void Mount(uint32 mount, uint32 vehicleId=0);
void Unmount();
uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
@@ -1817,7 +1818,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
// redefined in Creature
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask);
bool IsImmunedToDamage(SpellEntry const* spellInfo);
- virtual bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const;
+ virtual bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index, bool checkMechanic=true) const;
// redefined in Creature
uint32 CalcNotIgnoreDamageRedunction( uint32 damage, SpellSchoolMask damageSchoolMask);
uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType=MAX_ATTACK);
@@ -1913,6 +1914,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
bool IsAIEnabled, NeedChangeAI;
MovementInfo m_movementInfo;
bool CreateVehicleKit(uint32 id);
+ void RemoveVehicleKit();
Vehicle *GetVehicleKit()const { return m_vehicleKit; }
Vehicle *GetVehicle() const { return m_vehicle; }
bool IsOnVehicle(const Unit *unit) const { return m_vehicle && m_vehicle == unit->GetVehicleKit(); }
diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp
index 567630a048e..a4a09389552 100644
--- a/src/game/Vehicle.cpp
+++ b/src/game/Vehicle.cpp
@@ -151,9 +151,18 @@ void Vehicle::Die()
void Vehicle::Reset()
{
sLog.outDebug("Vehicle::Reset");
- InstallAllAccessories();
if(m_usableSeatNum)
- me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ {
+ if (me->GetTypeId() == TYPEID_PLAYER)
+ {
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
+ }
+ else
+ {
+ InstallAllAccessories();
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ }
+ }
}
void Vehicle::RemoveAllPassengers()
@@ -275,7 +284,12 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId)
assert(m_usableSeatNum);
--m_usableSeatNum;
if(!m_usableSeatNum)
- me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ {
+ if (me->GetTypeId() == TYPEID_PLAYER)
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
+ else
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ }
}
if(seat->second.seatInfo->m_flags && !(seat->second.seatInfo->m_flags & 0x400))
@@ -292,21 +306,24 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId)
unit->m_movementInfo.t_time = 0; // 1 for player
unit->m_movementInfo.t_seat = seat->first;
- if(unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.seatInfo->m_flags & 0x800) // not right
+ if(me->GetTypeId() == TYPEID_UNIT
+ && unit->GetTypeId() == TYPEID_PLAYER
+ && seat->first == 0 && seat->second.seatInfo->m_flags & 0x800) // not right
if (!me->SetCharmedBy(unit, CHARM_TYPE_VEHICLE))
assert(false);
- if(me->GetTypeId() == TYPEID_UNIT)
+ if(me->IsInWorld())
{
- if(me->IsInWorld())
+ unit->SendMonsterMoveTransport(me);
+
+ if(me->GetTypeId() == TYPEID_UNIT)
{
- unit->SendMonsterMoveTransport(me);
+ if(((Creature*)me)->IsAIEnabled)
+ ((Creature*)me)->AI()->PassengerBoarded(unit, seat->first, true);
+
// move self = move all passengers
me->GetMap()->CreatureRelocation((Creature*)me, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
}
-
- if(((Creature*)me)->IsAIEnabled)
- ((Creature*)me)->AI()->PassengerBoarded(unit, seat->first, true);
}
//if(unit->GetTypeId() == TYPEID_PLAYER)
@@ -334,7 +351,12 @@ void Vehicle::RemovePassenger(Unit *unit)
if(seat->second.seatInfo->IsUsable())
{
if(!m_usableSeatNum)
- me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ {
+ if (me->GetTypeId() == TYPEID_PLAYER)
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
+ else
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ }
++m_usableSeatNum;
}
@@ -342,7 +364,9 @@ void Vehicle::RemovePassenger(Unit *unit)
//SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
- if(unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.seatInfo->m_flags & 0x800)
+ if(me->GetTypeId() == TYPEID_UNIT
+ && unit->GetTypeId() == TYPEID_PLAYER
+ && seat->first == 0 && seat->second.seatInfo->m_flags & 0x800)
me->RemoveCharmedBy(unit);
if(me->GetTypeId() == TYPEID_UNIT && ((Creature*)me)->IsAIEnabled)
diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp
index 569c8fade62..d442d4c359e 100644
--- a/src/game/WorldSession.cpp
+++ b/src/game/WorldSession.cpp
@@ -30,6 +30,7 @@
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Player.h"
+#include "Vehicle.h"
#include "ObjectMgr.h"
#include "Group.h"
#include "Guild.h"
@@ -937,6 +938,39 @@ void WorldSession::SendAddonsInfo()
SendPacket(&data);
}
+
+void WorldSession::HandleEnterPlayerVehicle(WorldPacket &data)
+{
+ // Read guid
+ uint64 guid;
+ data >> guid;
+
+ if(Player* pl=ObjectAccessor::FindPlayer(guid))
+ {
+ if (!pl->GetVehicleKit())
+ return;
+ if (!pl->IsInRaidWith(_player))
+ return;
+ if(!pl->IsWithinDistInMap(_player,INTERACTION_DISTANCE))
+ return;
+ _player->EnterVehicle(pl);
+ }
+}
+
+void WorldSession::HandleEjectPasenger(WorldPacket &data)
+{
+ if(data.GetOpcode()==CMSG_EJECT_PASSENGER)
+ {
+ if(Vehicle* Vv= _player->GetVehicleKit())
+ {
+ uint64 guid;
+ data >> guid;
+ if(Player* Pl=ObjectAccessor::FindPlayer(guid))
+ Pl->ExitVehicle();
+ }
+ }
+ }
+
void WorldSession::SetPlayer( Player *plr )
{
_player = plr;
diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h
index 7e81a3d338f..93c5529eddb 100644
--- a/src/game/WorldSession.h
+++ b/src/game/WorldSession.h
@@ -748,6 +748,8 @@ class TRINITY_DLL_SPEC WorldSession
bool HandleOnItemOpen(Item *pItem);
bool HandleOnGoClick(GameObject *pGameObject);
void HandleOnCreatureKill(Creature *pCreature);
+ void HandleEjectPasenger(WorldPacket &data);
+ void HandleEnterPlayerVehicle(WorldPacket &data);
private:
// private trade methods
void moveItems(Item* myItems[], Item* hisItems[]);