diff --git a/data/sql/updates/pending_db_world/rev_1620443413425226200.sql b/data/sql/updates/pending_db_world/rev_1620443413425226200.sql new file mode 100644 index 000000000..46f8d9d9b --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1620443413425226200.sql @@ -0,0 +1,38 @@ +INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1620443413425226200'); + +DROP TABLE IF EXISTS `spellvisual_dbc`; +CREATE TABLE IF NOT EXISTS `spellvisual_dbc` ( + `ID` INT NOT NULL DEFAULT 0, + `PrecastKit` INT NOT NULL DEFAULT 0, + `CastKit` INT NOT NULL DEFAULT 0, + `ImpactKit` INT NOT NULL DEFAULT 0, + `StateKit` INT NOT NULL DEFAULT 0, + `StateDoneKit` INT NOT NULL DEFAULT 0, + `ChannelKit` INT NOT NULL DEFAULT 0, + `HasMissile` INT NOT NULL DEFAULT 0, + `MissileModel` INT NOT NULL DEFAULT 0, + `MissilePathType` INT NOT NULL DEFAULT 0, + `MissileDestinationAttachment` INT NOT NULL DEFAULT 0, + `MissileSound` INT NOT NULL DEFAULT 0, + `AnimEventSoundID` INT NOT NULL DEFAULT 0, + `Flags` INT NOT NULL DEFAULT 0, + `CasterImpactKit` INT NOT NULL DEFAULT 0, + `TargetImpactKit` INT NOT NULL DEFAULT 0, + `MissileAttachment` INT NOT NULL DEFAULT 0, + `MissileFollowGroundHeight` INT NOT NULL DEFAULT 0, + `MissileFollowGroundDropSpeed` INT NOT NULL DEFAULT 0, + `MissileFollowGroundApproach` INT NOT NULL DEFAULT 0, + `MissileFollowGroundFlags` INT NOT NULL DEFAULT 0, + `MissileMotion` INT NOT NULL DEFAULT 0, + `MissileTargetingKit` INT NOT NULL DEFAULT 0, + `InstantAreaKit` INT NOT NULL DEFAULT 0, + `ImpactAreaKit` INT NOT NULL DEFAULT 0, + `PersistentAreaKit` INT NOT NULL DEFAULT 0, + `MissileCastOffsetX` FLOAT NOT NULL DEFAULT 0, + `MissileCastOffsetY` FLOAT NOT NULL DEFAULT 0, + `MissileCastOffsetZ` FLOAT NOT NULL DEFAULT 0, + `MissileImpactOffsetX` FLOAT NOT NULL DEFAULT 0, + `MissileImpactOffsetY` FLOAT NOT NULL DEFAULT 0, + `MissileImpactOffsetZ` FLOAT NOT NULL DEFAULT 0, + PRIMARY KEY (`ID`) +) ENGINE=MyISAM DEFAULT CHARSET=UTF8MB4 COLLATE=utf8mb4_general_ci; diff --git a/data/sql/updates/pending_db_world/rev_1620443572177894000.sql b/data/sql/updates/pending_db_world/rev_1620443572177894000.sql new file mode 100644 index 000000000..3699a1f95 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1620443572177894000.sql @@ -0,0 +1,8 @@ +INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1620443572177894000'); + +DELETE FROM `spell_custom_attr` WHERE `spell_id` IN (60988,55550,42772,59685); +INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES +(60988, 0x00080000), +(55550, 0x00080000), +(42772, 0x00080000), +(59685, 0x00080000); diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 8b232adb8..b92dd02c4 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -144,6 +144,7 @@ DBCStorage sSpellRadiusStore(SpellRadiusfmt); DBCStorage sSpellRangeStore(SpellRangefmt); DBCStorage sSpellRuneCostStore(SpellRuneCostfmt); DBCStorage sSpellShapeshiftStore(SpellShapeshiftfmt); +DBCStorage sSpellVisualStore(SpellVisualfmt); DBCStorage sStableSlotPricesStore(StableSlotPricesfmt); DBCStorage sSummonPropertiesStore(SummonPropertiesfmt); DBCStorage sTalentStore(TalentEntryfmt); @@ -342,6 +343,7 @@ void LoadDBCStores(const std::string& dataPath) LOAD_DBC(sSpellRangeStore, "SpellRange.dbc", "spellrange_dbc"); LOAD_DBC(sSpellRuneCostStore, "SpellRuneCost.dbc", "spellrunecost_dbc"); LOAD_DBC(sSpellShapeshiftStore, "SpellShapeshiftForm.dbc", "spellshapeshiftform_dbc"); + LOAD_DBC(sSpellVisualStore, "SpellVisual.dbc", "spellvisual_dbc"); LOAD_DBC(sStableSlotPricesStore, "StableSlotPrices.dbc", "stableslotprices_dbc"); LOAD_DBC(sSummonPropertiesStore, "SummonProperties.dbc", "summonproperties_dbc"); LOAD_DBC(sTalentStore, "Talent.dbc", "talent_dbc"); diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 67d574ce4..50bf5287e 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -149,6 +149,7 @@ extern DBCStorage sSpellRangeStore; extern DBCStorage sSpellRuneCostStore; extern DBCStorage sSpellShapeshiftStore; extern DBCStorage sSpellStore; +extern DBCStorage sSpellVisualStore; extern DBCStorage sStableSlotPricesStore; extern DBCStorage sSummonPropertiesStore; extern DBCStorage sTalentStore; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 7d1420398..2e4cb0934 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -4313,7 +4313,7 @@ void Spell::SendSpellStart() if (((IsTriggered() && !m_spellInfo->IsAutoRepeatRangedSpell()) || m_triggeredByAuraSpell) && !m_spellInfo->IsChanneled()) castFlags |= CAST_FLAG_PENDING; - if (m_spellInfo->HasAttribute(SPELL_ATTR0_USES_RANGED_SLOT)) + if (m_spellInfo->HasAttribute(SPELL_ATTR0_USES_RANGED_SLOT) || m_spellInfo->HasAttribute(SPELL_ATTR0_CU_NEEDS_AMMO_DATA)) castFlags |= CAST_FLAG_PROJECTILE; if ((m_caster->GetTypeId() == TYPEID_PLAYER || (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->IsPet())) @@ -4369,7 +4369,7 @@ void Spell::SendSpellGo() if (((IsTriggered() && !m_spellInfo->IsAutoRepeatRangedSpell()) || m_triggeredByAuraSpell) && !m_spellInfo->IsChanneled()) castFlags |= CAST_FLAG_PENDING; - if (m_spellInfo->HasAttribute(SPELL_ATTR0_USES_RANGED_SLOT)) + if (m_spellInfo->HasAttribute(SPELL_ATTR0_USES_RANGED_SLOT) || m_spellInfo->HasAttribute(SPELL_ATTR0_CU_NEEDS_AMMO_DATA)) castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual if ((m_caster->GetTypeId() == TYPEID_PLAYER || @@ -4495,6 +4495,8 @@ void Spell::WriteAmmoToPacket(WorldPacket* data) } else { + uint32 nonRangedAmmoDisplayID = 0; + uint32 nonRangedAmmoInventoryType = 0; for (uint8 i = 0; i < 3; ++i) { if (uint32 item_id = m_caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i)) @@ -4518,6 +4520,10 @@ void Spell::WriteAmmoToPacket(WorldPacket* data) ammoDisplayID = 5998; // is this need fixing? ammoInventoryType = INVTYPE_AMMO; break; + default: + nonRangedAmmoDisplayID = itemEntry->DisplayInfoID; + nonRangedAmmoInventoryType = itemEntry->InventoryType; + break; } if (ammoDisplayID) @@ -4526,6 +4532,12 @@ void Spell::WriteAmmoToPacket(WorldPacket* data) } } } + + if (!ammoDisplayID && !ammoInventoryType) + { + ammoDisplayID = nonRangedAmmoDisplayID; + ammoInventoryType = nonRangedAmmoInventoryType; + } } *data << uint32(ammoDisplayID); diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 35a220333..7b7ef6b32 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -181,7 +181,7 @@ enum SpellCustomAttributes SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER = 0x00010000, SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET = 0x00020000, SPELL_ATTR0_CU_ALLOW_INFLIGHT_TARGET = 0x00040000, - SPELL_ATTR0_CU_NONE6 = 0x00080000, // UNUSED + SPELL_ATTR0_CU_NEEDS_AMMO_DATA = 0x00080000, SPELL_ATTR0_CU_BINARY_SPELL = 0x00100000, SPELL_ATTR0_CU_NO_POSITIVE_TAKEN_BONUS = 0x00200000, SPELL_ATTR0_CU_SINGLE_AURA_STACK = 0x00400000, // pussywizard diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 0a86a76e2..16358c0f4 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3280,6 +3280,20 @@ void SpellMgr::LoadSpellCustomAttr() spellInfo->Effects[EFFECT_0].MiscValue = 127; break; } + + if (spellInfo->Speed > 0.0f) + { + if (SpellVisualEntry const* spellVisual = sSpellVisualStore.LookupEntry(spellInfo->SpellVisual[0])) + { + if (spellVisual->HasMissile) + { + if (spellVisual->MissileModel == -4 || spellVisual->MissileModel == -5) + { + spellInfo->AttributesCu |= SPELL_ATTR0_CU_NEEDS_AMMO_DATA; + } + } + } + } spellInfo->_InitializeExplicitTargetMask(); } diff --git a/src/server/shared/DataStores/DBCStructure.h b/src/server/shared/DataStores/DBCStructure.h index d4ea07a19..8445f8ada 100644 --- a/src/server/shared/DataStores/DBCStructure.h +++ b/src/server/shared/DataStores/DBCStructure.h @@ -1780,6 +1780,38 @@ struct SpellItemEnchantmentConditionEntry //uint8 Logic[5] // 25-30 m_logic[5] }; +struct SpellVisualEntry +{ + //uint32 Id; + //uint32 PrecastKit; + //uint32 CastingKit; + //uint32 ImpactKit; + //uint32 StateKit; + //uint32 StateDoneKit; + //uint32 ChannelKit; + uint32 HasMissile; + int32 MissileModel; + //uint32 MissilePathType; + //uint32 MissileDestinationAttachment; + //uint32 MissileSound; + //uint32 AnimEventSoundID; + //uint32 Flags; + //uint32 CasterImpactKit; + //uint32 TargetImpactKit; + //int32 MissileAttachment; + //uint32 MissileFollowGroundHeight; + //uint32 MissileFollowGroundDropSpeed; + //uint32 MissileFollowGroundApprach; + //uint32 MissileFollowGroundFlags; + //uint32 MissileMotionId; + //uint32 MissileTargetingKit; + //uint32 InstantAreaKit; + //uint32 ImpactAreaKit; + //uint32 PersistentAreaKit; + //DBCPosition3D MissileCastOffset; + //DBCPosition3D MissileImpactOffset; +}; + struct StableSlotPricesEntry { uint32 Slot; diff --git a/src/server/shared/DataStores/DBCfmt.h b/src/server/shared/DataStores/DBCfmt.h index 71f685f96..ca257e081 100644 --- a/src/server/shared/DataStores/DBCfmt.h +++ b/src/server/shared/DataStores/DBCfmt.h @@ -97,6 +97,7 @@ char constexpr SpellRadiusfmt[] = "nfff"; char constexpr SpellRangefmt[] = "nffffixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; char constexpr SpellRuneCostfmt[] = "niiii"; char constexpr SpellShapeshiftfmt[] = "nxxxxxxxxxxxxxxxxxxiixiiixxiiiiiiii"; +char constexpr SpellVisualfmt[] = "dxxxxxxiixxxxxxxxxxxxxxxxxxxxxxx"; char constexpr StableSlotPricesfmt[] = "ni"; char constexpr SummonPropertiesfmt[] = "niiiii"; char constexpr TalentEntryfmt[] = "niiiiiiiixxxxixxixxixxx";