aboutsummaryrefslogtreecommitdiff
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
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.
-rw-r--r--sql/updates/world/2011_02_26_5_world_npc_spellclick_spells.sql68
-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
9 files changed, 179 insertions, 58 deletions
diff --git a/sql/updates/world/2011_02_26_5_world_npc_spellclick_spells.sql b/sql/updates/world/2011_02_26_5_world_npc_spellclick_spells.sql
new file mode 100644
index 00000000000..f19aca71b24
--- /dev/null
+++ b/sql/updates/world/2011_02_26_5_world_npc_spellclick_spells.sql
@@ -0,0 +1,68 @@
+UPDATE `creature_template` SET `npcflag`=`npcflag`|16777216 WHERE `entry` IN (SELECT `npc_entry` FROM `npc_spellclick_spells`);
+
+DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` IN (32640,32633,31861,31862,25743,27661,27258,27755,27756,27692,40725,32286,29929,29602,29709,27626,28851,
+34120,30403,26813,26523,27496,27714,27996,28605,28606,28607,28833,30066,32930,28312,32627,33060,33067,33062,33109,34994,30234,27629,27924,28061,28192,28669,
+28670,28817,28864,2914,29460,29679,29918,30468,30470,35064,30585,30645,33217,33319,33321,33519,33844,33845,39714);
+INSERT INTO `npc_spellclick_spells` (`npc_entry`,`spell_id`,`quest_start`,`quest_start_active`,`quest_end`,`cast_flags`,`aura_required`,`aura_forbidden`,`user_type`) VALUES
+(32640,61424,0,0,0,1,0,0,0), -- Traveler's Tundra Mammoth
+(32633,61424,0,0,0,1,0,0,0), -- Traveler's Tundra Mammoth
+(31861,61466,0,0,0,1,0,0,0), -- Grand Black War Mammoth
+(31862,61466,0,0,0,1,0,0,0), -- Grand Black War Mammoth
+(25743,46260,0,0,0,1,0,0,0), -- Wooly Mammoth Bull
+(27661,48365,0,0,0,1,0,0,0), -- Wintergarde Gryphon
+(27258,48365,0,0,0,1,0,0,0), -- Wintergarde Gryphoworldn
+(27755,49460,0,0,0,1,0,0,0), -- Amber Drake
+(27756,49464,0,0,0,1,0,0,0), -- Ruby Drake
+(27692,49346,0,0,0,1,0,0,0), -- Emerald Drake
+(40725,75953,0,0,0,1,0,0,0), -- X-53 Touring Rocket
+(32286,61666,0,0,0,1,0,0,0), -- Mekgineer's Chopper
+(29929,58961,0,0,0,1,0,0,0), -- Mechano-hog
+(29602,54908,0,0,0,1,0,0,0), -- Icefang
+(29709,55029,0,0,0,1,0,0,0), -- Freed Proto-Drake
+(27626,49138,0,0,0,1,0,0,0), -- Tatjana's Horse
+(28851,52600,0,0,0,1,0,0,0), -- Enraged Mammoth
+(34120,55089,0,0,0,1,0,0,0), -- Brann's Flying Machine
+(30403,56699,0,0,0,1,0,0,0), -- Nergeld
+(26813,47424,0,0,0,1,0,0,0), -- Kor'kron War Rider
+(26523,48296,0,0,0,1,0,0,0), -- Forsaken Blight Spreader
+(27496,48881,0,0,0,1,0,0,0), -- Refurbished Shredder
+(27714,49584,0,0,0,1,0,0,0), -- 7th Legion Chain Gun
+(27996,50343,0,0,0,1,0,0,0), -- Wyrmrest Vanquisher
+(28605,52263,0,0,0,1,0,0,0), -- Havenshire Stallion
+(28606,52263,0,0,0,1,0,0,0), -- Havenshire Mare
+(28607,52263,0,0,0,1,0,0,0), -- Havenshire Colt
+(28833,52447,0,0,0,1,0,0,0), -- Scarlet Cannon
+(30066,56678,0,0,0,1,0,0,0), -- Argent Skytalon
+(28312,60968,0,0,0,1,0,0,0), -- Wintergrasp Siege Engine
+(32627,60968,0,0,0,1,0,0,0), -- Wintergrasp Siege Engine
+(33060,65031,0,0,0,1,0,0,0), -- Salvaged Siege Engine
+(33067,65031,0,0,0,1,0,0,0), -- Salvaged Siege Turret
+(33062,65030,0,0,0,1,0,0,0), -- Salvaged Chopper
+(33109,62309,0,0,0,1,0,0,0), -- Salvaged Demolisher
+(34944,68458,0,0,0,1,0,0,0), -- Keep Cannon
+-- These use a 'proxy' cast. They summon a similar creature with SummonProperties.category = 4
+(30234,56378,0,0,0,1,0,0,0), -- Hover Disk
+(27629,49207,0,0,0,1,0,0,0), -- Wyrmrest Defender
+(27924,50007,0,0,0,1,0,0,0), -- Dragonflayer Harpoon
+(28061,50557,0,0,0,1,0,0,0), -- Wintergarde Gryphon
+(28192,50860,0,0,0,1,0,0,0), -- Archmage Pentarus' Flying Machine
+(28669,52190,0,0,0,1,0,0,0), -- Flying Fiend
+(28670,53173,0,0,0,1,0,0,0), -- Frostblood Vanquisher
+(28817,52462,0,0,0,1,0,0,0), -- Mine Car
+(28864,52589,0,0,0,1,0,0,0), -- Scourge Gryphon
+(29414,18277,0,0,0,1,0,0,0), -- Bone Gryphon
+(29460,54513,0,0,0,1,0,0,0), -- Frigit Proto-Drake
+(29679,54952,0,0,0,1,0,0,0), -- Hyldsmeet Proto-Drake
+(29918,54301,0,0,0,1,0,0,0), -- Warbear Matriarch
+(30468,56795,0,0,0,1,0,0,0), -- Harnessed Icemaw Matriarch
+(30470,56839,0,0,0,1,0,0,0), -- Skybreaker Cloudbuster
+(30564,57401,0,0,0,1,0,0,0), -- Njorndar Proto-Drake
+(30585,57418,0,0,0,1,0,0,0), -- Hammerhead
+(30645,57612,0,0,0,1,0,0,0), -- Water Terror
+(33217,62774,0,0,0,1,0,0,0), -- Stormwind Steed
+(33319,62782,0,0,0,1,0,0,0), -- Darnassian Nightsaber
+(33321,62784,0,0,0,1,0,0,0), -- Darkspear Raptor
+(33519,63163,0,0,0,1,0,0,0), -- Black Knight's Gryphon
+(33844,63791,0,0,0,1,0,0,0), -- Sunreaver Hawkstrider
+(33845,63792,0,0,0,1,0,0,0), -- Quel'dorei Steed
+(39714,74205,0,0,0,1,0,0,0); -- Shooting Mechano-Tank
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;
}
}