mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-17 21:50:50 -04:00
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.
This commit is contained in:
@@ -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
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user