diff options
author | Machiavelli <machiavelli.trinity@gmail.com> | 2011-02-26 23:00:09 +0100 |
---|---|---|
committer | Machiavelli <machiavelli.trinity@gmail.com> | 2011-02-26 23:00:09 +0100 |
commit | 3ac80ee3a48223f25a2a633130de177ffcd5df11 (patch) | |
tree | 885d5e001fa05e16a2c0683c0e39cb102aa6e353 /src | |
parent | 8497fb27e9ff104e99818fbe2c85eccf25e7931d (diff) |
Core/Vehicles: Correct usage of npc_spellclick_spells instead of blatant hacks for vehicle entry.
Note: This may break a few vehicles, but only due to the absence of proper, non-hackish data.
Diffstat (limited to 'src')
-rwxr-xr-x | src/server/game/Entities/Unit/Unit.cpp | 45 | ||||
-rwxr-xr-x | src/server/game/Entities/Unit/Unit.h | 1 | ||||
-rwxr-xr-x | src/server/game/Entities/Vehicle/Vehicle.cpp | 10 | ||||
-rwxr-xr-x | src/server/game/Globals/ObjectMgr.cpp | 64 | ||||
-rwxr-xr-x | src/server/game/Globals/ObjectMgr.h | 2 | ||||
-rwxr-xr-x | src/server/game/Miscellaneous/SharedDefines.h | 9 | ||||
-rwxr-xr-x | src/server/game/Server/Protocol/Handlers/SpellHandler.cpp | 21 | ||||
-rwxr-xr-x | src/server/game/Spells/SpellEffects.cpp | 17 |
8 files changed, 111 insertions, 58 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 9cc92c7e7d4..ef7c19c9cae 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -16456,6 +16456,51 @@ bool Unit::CheckPlayerCondition(Player* pPlayer) } } +bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) +{ + bool success = false; + uint32 spellClickEntry = GetTypeId() == TYPEID_UNIT ? GetEntry() : GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); + SpellClickInfoMapBounds clickPair = sObjectMgr->GetSpellClickInfoMapBounds(spellClickEntry); + for (SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr) + { + if (itr->second.IsFitToRequirements(clicker, this)) + { + Unit *caster = (itr->second.castFlags & NPC_CLICK_CAST_CASTER_CLICKER) ? clicker : this; + Unit *target = (itr->second.castFlags & NPC_CLICK_CAST_TARGET_CLICKER) ? clicker : this; + uint64 origCasterGUID = (itr->second.castFlags & NPC_CLICK_CAST_ORIG_CASTER_OWNER) ? GetOwnerGUID() : clicker->GetGUID(); + + SpellEntry const* spellEntry = sSpellStore.LookupEntry(itr->second.spellId); + // if(!spellEntry) should be checked at npc_spellclick load + + if (seatId > -1) + { + uint8 i = 0; + bool valid = false; + while (i < MAX_SPELL_EFFECTS && !valid) + if (spellEntry->EffectApplyAuraName[i] == SPELL_AURA_CONTROL_VEHICLE) + valid = true; + + if (!valid) + { + sLog->outErrorDb("Spell %u specified in npc_spellclick_spells is not a valid vehicle enter aura!", itr->second.spellId); + return false; + } + + caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1, target, true, NULL, NULL, origCasterGUID); + } + else + caster->CastSpell(target, spellEntry, true, NULL, NULL, origCasterGUID); + + success = true; + } + } + + if (this->ToCreature()) + this->ToCreature()->AI()->DoAction(EVENT_SPELLCLICK); + + return success; +} + void Unit::EnterVehicle(Vehicle *vehicle, int8 seatId, AuraApplication const * aurApp) { if (!isAlive() || GetVehicleKit() == vehicle || vehicle->GetBase()->IsOnVehicle(this)) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index cb35ee7bafd..3d7b9d6979d 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -2057,6 +2057,7 @@ class Unit : public WorldObject bool m_ControlledByPlayer; bool CheckPlayerCondition(Player* pPlayer); + bool HandleSpellClick(Unit* clicker, int8 seatId = -1); void EnterVehicle(Unit *base, int8 seatId = -1, AuraApplication const * aurApp = NULL) { EnterVehicle(base->GetVehicleKit(), seatId, aurApp); } void EnterVehicle(Vehicle *vehicle, int8 seatId = -1, AuraApplication const * aurApp = NULL); void ExitVehicle(Position const* exitPosition = NULL); diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index e22fe9668e4..d3244cafad1 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -282,7 +282,14 @@ void Vehicle::InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 typ if (minion) accessory->AddUnitTypeMask(UNIT_MASK_ACCESSORY); - accessory->EnterVehicle(this, seatId); + + if (!me->HandleSpellClick(accessory, seatId)) + { + sLog->outErrorDb("Vehicle entry %u in vehicle_accessory does not have a valid record in npc_spellclick_spells! Calling default EnterVehicle()", + me->GetTypeId() == TYPEID_UNIT ? me->GetEntry() : me->GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID)); + accessory->EnterVehicle(this, seatId); + } + // This is not good, we have to send update twice accessory->SendMovementFlagUpdate(); @@ -358,6 +365,7 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId) if (!me->SetCharmedBy(unit, CHARM_TYPE_VEHICLE)) ASSERT(false); + // hack: should be done by aura system if (VehicleScalingInfo const *scalingInfo = sObjectMgr->GetVehicleScalingInfo(m_vehicleInfo->m_ID)) { Player *plr = unit->ToPlayer(); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 3bb103ffe92..815f1cbc770 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -195,49 +195,57 @@ LanguageDesc const* GetLanguageDescByID(uint32 lang) return NULL; } -bool SpellClickInfo::IsFitToRequirements(Player const* player, Creature const * clickNpc) const +bool SpellClickInfo::IsFitToRequirements(Unit const* clicker, Unit const* clickee) const { - if (questStart) + Player const* playerClicker = NULL; + if (playerClicker = clicker->ToPlayer()) { - // not in expected required quest state - if (!player || ((!questStartCanActive || !player->IsActiveQuest(questStart)) && !player->GetQuestRewardStatus(questStart))) - return false; - } + if (questStart) + { + // not in expected required quest state + if (((!questStartCanActive || !playerClicker->IsActiveQuest(questStart)) && !playerClicker->GetQuestRewardStatus(questStart))) + return false; + } - if (questEnd) - { - // not in expected forbidden quest state - if (!player || player->GetQuestRewardStatus(questEnd)) - return false; + if (questEnd) + { + // not in expected forbidden quest state + if (playerClicker->GetQuestRewardStatus(questEnd)) + return false; + } } if (auraRequired) - if (!player->HasAura(auraRequired)) + if (!clicker->HasAura(auraRequired)) return false; if (auraForbidden) - if (player->HasAura(auraForbidden)) + if (clicker->HasAura(auraForbidden)) return false; Unit const * summoner = NULL; // Check summoners for party - if (clickNpc->isSummon()) - summoner = clickNpc->ToTempSummon()->GetSummoner(); + if (clickee->isSummon()) + summoner = clickee->ToTempSummon()->GetSummoner(); if (!summoner) - summoner = clickNpc; + summoner = clickee; + if (!playerClicker) + return true; + + // This only applies to players switch (userType) { case SPELL_CLICK_USER_FRIEND: - if (!player->IsFriendlyTo(summoner)) + if (!playerClicker->IsFriendlyTo(summoner)) return false; break; case SPELL_CLICK_USER_RAID: - if (!player->IsInRaidWith(summoner)) + if (!playerClicker->IsInRaidWith(summoner)) return false; break; case SPELL_CLICK_USER_PARTY: - if (!player->IsInPartyWith(summoner)) + if (!playerClicker->IsInPartyWith(summoner)) return false; break; default: @@ -2749,12 +2757,12 @@ void ObjectMgr::LoadVehicleAccessories() { Field *fields = result->Fetch(); - uint32 uiEntry = fields[0].GetUInt32(); - uint32 uiAccessory = fields[1].GetUInt32(); - int8 uiSeat = int8(fields[2].GetInt16()); - bool bMinion = fields[3].GetBool(); - uint8 uiSummonType = fields[4].GetUInt8(); - uint32 uiSummonTimer = fields[5].GetUInt32(); + uint32 uiEntry = fields[0].GetUInt32(); + uint32 uiAccessory = fields[1].GetUInt32(); + int8 uiSeat = int8(fields[2].GetInt16()); + bool bMinion = fields[3].GetBool(); + uint8 uiSummonType = fields[4].GetUInt8(); + uint32 uiSummonTimer= fields[5].GetUInt32(); if (!sCreatureStorage.LookupEntry<CreatureInfo>(uiEntry)) { @@ -7622,9 +7630,6 @@ void ObjectMgr::LoadNPCSpellClickSpells() continue; } - if (!(cInfo->npcflag & UNIT_NPC_FLAG_SPELLCLICK)) - const_cast<CreatureInfo*>(cInfo)->npcflag |= UNIT_NPC_FLAG_SPELLCLICK; - uint32 spellid = fields[1].GetUInt32(); SpellEntry const *spellinfo = sSpellStore.LookupEntry(spellid); if (!spellinfo) @@ -7696,9 +7701,6 @@ void ObjectMgr::LoadNPCSpellClickSpells() info.userType = SpellClickUserTypes(userType); mSpellClickInfoMap.insert(SpellClickInfoMap::value_type(npc_entry, info)); - // mark creature template as spell clickable - const_cast<CreatureInfo*>(cInfo)->npcflag |= UNIT_NPC_FLAG_SPELLCLICK; - ++count; } while (result->NextRow()); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 085a6f901fd..2a588c40f61 100755 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -335,7 +335,7 @@ struct SpellClickInfo SpellClickUserTypes userType; // helpers - bool IsFitToRequirements(Player const* player, Creature const * clickNpc) const; + bool IsFitToRequirements(Unit const* clicker, Unit const * clickee) const; }; typedef std::multimap<uint32, SpellClickInfo> SpellClickInfoMap; diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index d8d120f527d..fade7de99bf 100755 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -553,9 +553,12 @@ enum SpellClickUserTypes SPELL_CLICK_USER_MAX = 4 }; -#define NPC_CLICK_CAST_CASTER_PLAYER 0x01 -#define NPC_CLICK_CAST_TARGET_PLAYER 0x02 -#define NPC_CLICK_CAST_ORIG_CASTER_OWNER 0x04 +enum SpellClickCastFlags +{ + NPC_CLICK_CAST_CASTER_CLICKER = 0x01, + NPC_CLICK_CAST_TARGET_CLICKER = 0x02, + NPC_CLICK_CAST_ORIG_CASTER_OWNER = 0x04, +}; enum SheathTypes { diff --git a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp index 864c5aa5146..82ab80172b7 100755 --- a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp @@ -559,25 +559,8 @@ void WorldSession::HandleSpellClick(WorldPacket & recv_data) if (!unit->IsInWorld()) return; - SpellClickInfoMapBounds clickPair = sObjectMgr->GetSpellClickInfoMapBounds(unit->GetEntry()); - for (SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr) - { - if (itr->second.IsFitToRequirements(_player, unit)) - { - Unit *caster = (itr->second.castFlags & NPC_CLICK_CAST_CASTER_PLAYER) ? (Unit*)_player : (Unit*)unit; - Unit *target = (itr->second.castFlags & NPC_CLICK_CAST_TARGET_PLAYER) ? (Unit*)_player : (Unit*)unit; - uint64 origCasterGUID = (itr->second.castFlags & NPC_CLICK_CAST_ORIG_CASTER_OWNER) ? unit->GetOwnerGUID() : 0; - caster->CastSpell(target, itr->second.spellId, true, NULL, NULL, origCasterGUID); - } - } - - if (unit->IsVehicle()) - { - if (unit->CheckPlayerCondition(_player)) - _player->EnterVehicle(unit); - } - - unit->AI()->DoAction(EVENT_SPELLCLICK); + if (!unit->HandleSpellClick(_player)) + sLog->outErrorDb("Missing npc_spellclick_spells data for creature %u", unit->GetEntry()); } void WorldSession::HandleMirrrorImageDataRequest(WorldPacket & recv_data) diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index dc1c1f78b12..727a6194bb1 100755 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3129,7 +3129,7 @@ void Spell::EffectSummonType(SpellEffIndex effIndex) { float x, y, z; m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE); - summon = m_caster->GetMap()->SummonCreature(entry, pos, properties, duration, m_caster); + summon = m_originalCaster->GetMap()->SummonCreature(entry, pos, properties, duration, m_caster); if (!summon || !summon->IsVehicle()) return; @@ -3137,10 +3137,21 @@ void Spell::EffectSummonType(SpellEffIndex effIndex) { SpellEntry const *spellProto = sSpellStore.LookupEntry(SpellMgr::CalculateSpellEffectAmount(m_spellInfo, effIndex)); if (spellProto) - m_caster->CastSpell(summon, spellProto, true); + { + m_originalCaster->CastSpell(summon, spellProto, true); + return; + } } - m_caster->EnterVehicle(summon->GetVehicleKit()); + // Hard coded enter vehicle spell + m_originalCaster->CastSpell(summon, 46598, true); + + summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); + uint32 faction = properties->Faction; + if (!faction) + faction = m_originalCaster->getFaction(); + + summon->setFaction(faction); break; } } |