diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bindings/scripts/scripts/world/npcs_special.cpp | 13 | ||||
-rw-r--r-- | src/game/Creature.cpp | 4 | ||||
-rw-r--r-- | src/game/Creature.h | 2 | ||||
-rw-r--r-- | src/game/GroupHandler.cpp | 9 | ||||
-rw-r--r-- | src/game/MovementHandler.cpp | 20 | ||||
-rw-r--r-- | src/game/Opcodes.cpp | 6 | ||||
-rw-r--r-- | src/game/Opcodes.h | 4 | ||||
-rw-r--r-- | src/game/PetHandler.cpp | 6 | ||||
-rw-r--r-- | src/game/Player.cpp | 85 | ||||
-rw-r--r-- | src/game/Player.h | 6 | ||||
-rw-r--r-- | src/game/SharedDefines.h | 2 | ||||
-rw-r--r-- | src/game/Spell.cpp | 64 | ||||
-rw-r--r-- | src/game/Spell.h | 1 | ||||
-rw-r--r-- | src/game/SpellAuraDefines.h | 2 | ||||
-rw-r--r-- | src/game/SpellAuraEffects.cpp | 49 | ||||
-rw-r--r-- | src/game/SpellAuraEffects.h | 1 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 38 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 3 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 1 | ||||
-rw-r--r-- | src/game/StatSystem.cpp | 2 | ||||
-rw-r--r-- | src/game/Totem.cpp | 4 | ||||
-rw-r--r-- | src/game/Totem.h | 2 | ||||
-rw-r--r-- | src/game/Unit.cpp | 216 | ||||
-rw-r--r-- | src/game/Unit.h | 6 | ||||
-rw-r--r-- | src/game/Vehicle.cpp | 48 | ||||
-rw-r--r-- | src/game/WorldSession.cpp | 34 | ||||
-rw-r--r-- | src/game/WorldSession.h | 2 |
27 files changed, 457 insertions, 173 deletions
diff --git a/src/bindings/scripts/scripts/world/npcs_special.cpp b/src/bindings/scripts/scripts/world/npcs_special.cpp index 7908e2989f1..9a2b9b48604 100644 --- a/src/bindings/scripts/scripts/world/npcs_special.cpp +++ b/src/bindings/scripts/scripts/world/npcs_special.cpp @@ -1842,12 +1842,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/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 da0387f8d1b..53d36436142 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/PetHandler.cpp b/src/game/PetHandler.cpp index ee8c02dfb43..1ffe4bc1632 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..8e4bd3052a7 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); + if (armor)
+ {
+ 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); + {
+ 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) @@ -20200,9 +20236,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 +23041,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 +23057,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..b2f1798c36f 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..f1c31d6434c 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..792152ad882 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 { @@ -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 @@ -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 24c2ded7321..79abeac66cb 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 @@ -3880,22 +3880,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) @@ -4576,12 +4561,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: @@ -6603,10 +6585,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) @@ -6639,6 +6620,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..b934b9823df 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 95360052238..422cace994e 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,8 +6566,21 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger // Sacred Shield if (dummySpell->SpellFamilyFlags[1]&0x00080000) { - triggered_spell_id = 58597; - target = this; + 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; } // Righteous Vengeance @@ -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)); - data.append(pVictim->GetPackGUID()); - data.append(GetPackGUID()); - data << uint32(SpellID); - data << uint32(Damage); - data << uint32(OverHeal); - data << uint8(critical ? 1 : 0); - data << uint8(0); // unused in client? + 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);
SendMessageToSet(&data, true); } @@ -10645,6 +10673,14 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo) if (itr->type == spellInfo->Mechanic) 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) { @@ -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) @@ -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..61badc7ef28 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[]); |