aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMachiavelli <machiavelli.trinity@gmail.com>2011-02-26 23:00:09 +0100
committerMachiavelli <machiavelli.trinity@gmail.com>2011-02-26 23:00:09 +0100
commit3ac80ee3a48223f25a2a633130de177ffcd5df11 (patch)
tree885d5e001fa05e16a2c0683c0e39cb102aa6e353 /src
parent8497fb27e9ff104e99818fbe2c85eccf25e7931d (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-xsrc/server/game/Entities/Unit/Unit.cpp45
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h1
-rwxr-xr-xsrc/server/game/Entities/Vehicle/Vehicle.cpp10
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.cpp64
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.h2
-rwxr-xr-xsrc/server/game/Miscellaneous/SharedDefines.h9
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/SpellHandler.cpp21
-rwxr-xr-xsrc/server/game/Spells/SpellEffects.cpp17
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;
}
}