Merge
--HG-- branch : trunk
This commit is contained in:
+22
-1
@@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `db_version`;
|
|||||||
CREATE TABLE `db_version` (
|
CREATE TABLE `db_version` (
|
||||||
`version` varchar(120) default NULL,
|
`version` varchar(120) default NULL,
|
||||||
`creature_ai_version` varchar(120) default NULL,
|
`creature_ai_version` varchar(120) default NULL,
|
||||||
`required_7945_01_mangos_quest_template` bit(1) default NULL
|
`required_7980_01_mangos_item_required_target` bit(1) default NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||||
|
|
||||||
--
|
--
|
||||||
@@ -1658,6 +1658,27 @@ LOCK TABLES `item_loot_template` WRITE;
|
|||||||
/*!40000 ALTER TABLE `item_loot_template` ENABLE KEYS */;
|
/*!40000 ALTER TABLE `item_loot_template` ENABLE KEYS */;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `item_required_target`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `item_required_target`;
|
||||||
|
CREATE TABLE `item_required_target` (
|
||||||
|
`entry` mediumint(8) unsigned NOT NULL,
|
||||||
|
`type` tinyint(3) unsigned NOT NULL default '0',
|
||||||
|
`targetEntry` mediumint(8) unsigned NOT NULL default '0',
|
||||||
|
UNIQUE KEY `entry_type_target` (`entry`,`type`,`targetEntry`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dumping data for table `item_required_target`
|
||||||
|
--
|
||||||
|
|
||||||
|
LOCK TABLES `item_required_target` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `item_required_target` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `item_required_target` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table structure for table `item_template`
|
-- Table structure for table `item_template`
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
-- ALTER TABLE db_version CHANGE COLUMN required_7945_01_mangos_quest_template required_7980_01_mangos_item_required_target bit;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `item_required_target`;
|
||||||
|
CREATE TABLE `item_required_target` (
|
||||||
|
`entry` mediumint(8) unsigned NOT NULL,
|
||||||
|
`type` tinyint(3) unsigned NOT NULL default '0',
|
||||||
|
`targetEntry` mediumint(8) unsigned NOT NULL default '0',
|
||||||
|
UNIQUE KEY `entry_type_target` (`entry`,`type`,`targetEntry`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED;
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
replace into creature_questrelation (id,quest) VALUES (28377,12701);
|
||||||
|
replace into creature_involvedrelation (id,quest) VALUES (28377,12701);
|
||||||
|
replace into creature_involvedrelation (id,quest) VALUES (28914,12723);
|
||||||
|
replace into creature_questrelation (id,quest) VALUES (28914,12724);
|
||||||
|
replace into creature_involvedrelation (id,quest) VALUES (28914,12724);
|
||||||
|
replace into creature_questrelation (id,quest) VALUES (28913,12725);
|
||||||
|
replace into creature_involvedrelation (id,quest) VALUES (28912,12725);
|
||||||
|
replace into creature_questrelation (id,quest) VALUES (28912,12727);
|
||||||
|
replace into creature_involvedrelation (id,quest) VALUES (28913,12727);
|
||||||
|
|
||||||
|
|
||||||
|
DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` IN (28833,28887);
|
||||||
|
INSERT INTO `npc_spellclick_spells` (`npc_entry`, `spell_id`, `quest_id`, `quest_status`, `cast_flags`) VALUES
|
||||||
|
(28833, 52447, 12701, 3, 3),
|
||||||
|
(28887, 52447, 12701, 3, 3);
|
||||||
|
|
||||||
|
UPDATE creature_template SET spell1=52435,spell2=52576,spell5=52588,VehicleId=68,speed=0 WHERE entry IN (28833,28887);
|
||||||
|
UPDATE creature_template SET spell1=52211 WHERE entry=28864;
|
||||||
|
|
||||||
|
DELETE FROM `spell_script_target` WHERE entry IN
|
||||||
|
(52576);
|
||||||
|
INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES
|
||||||
|
(52576,1,28834),
|
||||||
|
(52576,1,28886);
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
DELETE FROM `spell_script_target` WHERE `entry` IN (48743);
|
||||||
|
INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES
|
||||||
|
('48743', '1', '26125');
|
||||||
@@ -1590,7 +1590,8 @@ INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES
|
|||||||
(51859, 1, 28525), -- siphon of archerus
|
(51859, 1, 28525), -- siphon of archerus
|
||||||
(51859, 1, 28542),
|
(51859, 1, 28542),
|
||||||
(51859, 1, 28543),
|
(51859, 1, 28543),
|
||||||
(51859, 1, 28544);
|
(51859, 1, 28544),
|
||||||
|
(48743, 1, 26125); -- Death pact
|
||||||
|
|
||||||
update creature_template set minlevel=50,maxlevel=52,minhealth=2215,maxhealth=2317,faction_A=2084,faction_H=2084,mindmg=50,maxdmg=50 where entry=28528; -- ghoul
|
update creature_template set minlevel=50,maxlevel=52,minhealth=2215,maxhealth=2317,faction_A=2084,faction_H=2084,mindmg=50,maxdmg=50 where entry=28528; -- ghoul
|
||||||
|
|
||||||
@@ -1623,6 +1624,33 @@ INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES
|
|||||||
(52479,1,28819),
|
(52479,1,28819),
|
||||||
(52479,1,28822);
|
(52479,1,28822);
|
||||||
|
|
||||||
|
|
||||||
|
replace into creature_questrelation (id,quest) VALUES (28377,12701);
|
||||||
|
replace into creature_involvedrelation (id,quest) VALUES (28377,12701);
|
||||||
|
replace into creature_involvedrelation (id,quest) VALUES (28914,12723);
|
||||||
|
replace into creature_questrelation (id,quest) VALUES (28914,12724);
|
||||||
|
replace into creature_involvedrelation (id,quest) VALUES (28914,12724);
|
||||||
|
replace into creature_questrelation (id,quest) VALUES (28913,12725);
|
||||||
|
replace into creature_involvedrelation (id,quest) VALUES (28912,12725);
|
||||||
|
replace into creature_questrelation (id,quest) VALUES (28912,12727);
|
||||||
|
replace into creature_involvedrelation (id,quest) VALUES (28913,12727);
|
||||||
|
|
||||||
|
-- ship cannon
|
||||||
|
DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` IN (28833,28887);
|
||||||
|
INSERT INTO `npc_spellclick_spells` (`npc_entry`, `spell_id`, `quest_id`, `quest_status`, `cast_flags`) VALUES
|
||||||
|
(28833, 52447, 12701, 3, 3),
|
||||||
|
(28887, 52447, 12701, 3, 3);
|
||||||
|
|
||||||
|
UPDATE creature_template SET spell1=52435,spell2=52576,spell5=52588,VehicleId=68,speed=0 WHERE entry IN (28833,28887);
|
||||||
|
UPDATE creature_template SET spell1=52211 WHERE entry=28864;
|
||||||
|
|
||||||
|
DELETE FROM `spell_script_target` WHERE entry IN
|
||||||
|
(52576);
|
||||||
|
INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES
|
||||||
|
(52576,1,28834),
|
||||||
|
(52576,1,28886);
|
||||||
|
|
||||||
|
|
||||||
-- frostbrood vanquisher
|
-- frostbrood vanquisher
|
||||||
update creature_template set maxhealth = 133525, minhealth = 133525, maxmana = 51360, minmana = 51360, spell1 = 53114, spell2 = 53112, spell3=53110, VehicleId = 156 where entry = 28670;
|
update creature_template set maxhealth = 133525, minhealth = 133525, maxmana = 51360, minmana = 51360, spell1 = 53114, spell2 = 53112, spell3=53110, VehicleId = 156 where entry = 28670;
|
||||||
|
|
||||||
|
|||||||
@@ -598,6 +598,7 @@ CreatureAI* GetAI_npc_ros_dark_rider(Creature *_Creature)
|
|||||||
return new npc_ros_dark_riderAI(_Creature);
|
return new npc_ros_dark_riderAI(_Creature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// correct way: 52312 52314 52555 ...
|
||||||
struct TRINITY_DLL_DECL npc_dkc1_gothikAI : public ScriptedAI
|
struct TRINITY_DLL_DECL npc_dkc1_gothikAI : public ScriptedAI
|
||||||
{
|
{
|
||||||
npc_dkc1_gothikAI(Creature *c) : ScriptedAI(c) {}
|
npc_dkc1_gothikAI(Creature *c) : ScriptedAI(c) {}
|
||||||
@@ -628,6 +629,8 @@ CreatureAI* GetAI_npc_dkc1_gothik(Creature *_Creature)
|
|||||||
return new npc_dkc1_gothikAI(_Creature);
|
return new npc_dkc1_gothikAI(_Creature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// npc 28912 quest 17217 boss 29001 go 191092
|
||||||
|
|
||||||
void AddSC_the_scarlet_enclave()
|
void AddSC_the_scarlet_enclave()
|
||||||
{
|
{
|
||||||
Script *newscript;
|
Script *newscript;
|
||||||
|
|||||||
@@ -447,6 +447,7 @@ ChatCommand * ChatHandler::getCommandTable()
|
|||||||
{ "gameobject_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameObjectScriptsCommand, "", NULL },
|
{ "gameobject_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameObjectScriptsCommand, "", NULL },
|
||||||
{ "item_enchantment_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemEnchantementsCommand, "", NULL },
|
{ "item_enchantment_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemEnchantementsCommand, "", NULL },
|
||||||
{ "item_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL },
|
{ "item_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL },
|
||||||
|
{ "item_required_target", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemRequiredTragetCommand, "", NULL },
|
||||||
{ "locales_achievement_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesAchievementRewardCommand,"", NULL },
|
{ "locales_achievement_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesAchievementRewardCommand,"", NULL },
|
||||||
{ "locales_creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesCreatureCommand, "", NULL },
|
{ "locales_creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesCreatureCommand, "", NULL },
|
||||||
{ "locales_gameobject", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesGameobjectCommand, "", NULL },
|
{ "locales_gameobject", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesGameobjectCommand, "", NULL },
|
||||||
|
|||||||
@@ -359,6 +359,7 @@ class ChatHandler
|
|||||||
bool HandleReloadGOQuestRelationsCommand(const char* args);
|
bool HandleReloadGOQuestRelationsCommand(const char* args);
|
||||||
bool HandleReloadGOQuestInvRelationsCommand(const char* args);
|
bool HandleReloadGOQuestInvRelationsCommand(const char* args);
|
||||||
bool HandleReloadItemEnchantementsCommand(const char* args);
|
bool HandleReloadItemEnchantementsCommand(const char* args);
|
||||||
|
bool HandleReloadItemRequiredTragetCommand(const char* args);
|
||||||
bool HandleReloadLocalesAchievementRewardCommand(const char* args);
|
bool HandleReloadLocalesAchievementRewardCommand(const char* args);
|
||||||
bool HandleReloadLocalesCreatureCommand(const char* args);
|
bool HandleReloadLocalesCreatureCommand(const char* args);
|
||||||
bool HandleReloadLocalesGameobjectCommand(const char* args);
|
bool HandleReloadLocalesGameobjectCommand(const char* args);
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ bool ChatHandler::HandleDebugSendSpellFailCommand(const char* args)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
char* px = strtok((char*)args, " ");
|
char* px = strtok((char*)args, " ");
|
||||||
if(!px)
|
if (!px)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint8 failnum = (uint8)atoi(px);
|
uint8 failnum = (uint8)atoi(px);
|
||||||
@@ -56,14 +56,13 @@ bool ChatHandler::HandleDebugSendSpellFailCommand(const char* args)
|
|||||||
char* p2 = strtok(NULL, " ");
|
char* p2 = strtok(NULL, " ");
|
||||||
uint8 failarg2 = p2 ? (uint8)atoi(p2) : 0;
|
uint8 failarg2 = p2 ? (uint8)atoi(p2) : 0;
|
||||||
|
|
||||||
|
|
||||||
WorldPacket data(SMSG_CAST_FAILED, 5);
|
WorldPacket data(SMSG_CAST_FAILED, 5);
|
||||||
data << uint8(0);
|
data << uint8(0);
|
||||||
data << uint32(133);
|
data << uint32(133);
|
||||||
data << uint8(failnum);
|
data << uint8(failnum);
|
||||||
if(p1 || p2)
|
if (p1 || p2)
|
||||||
data << uint32(failarg1);
|
data << uint32(failarg1);
|
||||||
if(p2)
|
if (p2)
|
||||||
data << uint32(failarg2);
|
data << uint32(failarg2);
|
||||||
|
|
||||||
m_session->SendPacket(&data);
|
m_session->SendPacket(&data);
|
||||||
|
|||||||
@@ -776,6 +776,23 @@ bool Item::IsFitToSpellRequirements(SpellEntry const* spellInfo) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Item::IsTargetValidForItemUse(Unit* pUnitTarget)
|
||||||
|
{
|
||||||
|
ItemRequiredTargetMapBounds bounds = objmgr.GetItemRequiredTargetMapBounds(GetProto()->ItemId);
|
||||||
|
|
||||||
|
if (bounds.first == bounds.second)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!pUnitTarget)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for(ItemRequiredTargetMap::const_iterator itr = bounds.first; itr != bounds.second; ++itr)
|
||||||
|
if(itr->second.IsFitToRequirements(pUnitTarget))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges)
|
void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges)
|
||||||
{
|
{
|
||||||
// Better lost small time at check in comparison lost time at item save to DB.
|
// Better lost small time at check in comparison lost time at item save to DB.
|
||||||
@@ -982,3 +999,16 @@ bool Item::IsBindedNotWith( Player const* player ) const
|
|||||||
return objmgr.GetPlayerAccountIdByGUID(GetOwnerGUID()) != player->GetSession()->GetAccountId();
|
return objmgr.GetPlayerAccountIdByGUID(GetOwnerGUID()) != player->GetSession()->GetAccountId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ItemRequiredTarget::IsFitToRequirements( Unit* pUnitTarget ) const
|
||||||
|
{
|
||||||
|
switch(m_uiType)
|
||||||
|
{
|
||||||
|
case ITEM_TARGET_TYPE_CREATURE:
|
||||||
|
return pUnitTarget->isAlive();
|
||||||
|
case ITEM_TARGET_TYPE_DEAD:
|
||||||
|
return !pUnitTarget->isAlive();
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
struct SpellEntry;
|
struct SpellEntry;
|
||||||
class Bag;
|
class Bag;
|
||||||
class QueryResult;
|
class QueryResult;
|
||||||
|
class Unit;
|
||||||
|
|
||||||
struct ItemSetEffect
|
struct ItemSetEffect
|
||||||
{
|
{
|
||||||
@@ -197,6 +198,24 @@ enum ItemUpdateState
|
|||||||
ITEM_REMOVED = 3
|
ITEM_REMOVED = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ItemRequiredTargetType
|
||||||
|
{
|
||||||
|
ITEM_TARGET_TYPE_CREATURE = 1,
|
||||||
|
ITEM_TARGET_TYPE_DEAD = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_ITEM_REQ_TARGET_TYPE 2
|
||||||
|
|
||||||
|
struct ItemRequiredTarget
|
||||||
|
{
|
||||||
|
ItemRequiredTarget(ItemRequiredTargetType uiType, uint32 uiTargetEntry) : m_uiType(uiType), m_uiTargetEntry(uiTargetEntry) {}
|
||||||
|
ItemRequiredTargetType m_uiType;
|
||||||
|
uint32 m_uiTargetEntry;
|
||||||
|
|
||||||
|
// helpers
|
||||||
|
bool IsFitToRequirements(Unit* pUnitTarget) const;
|
||||||
|
};
|
||||||
|
|
||||||
bool ItemCanGoIntoBag(ItemPrototype const *proto, ItemPrototype const *pBagProto);
|
bool ItemCanGoIntoBag(ItemPrototype const *proto, ItemPrototype const *pBagProto);
|
||||||
|
|
||||||
class TRINITY_DLL_SPEC Item : public Object
|
class TRINITY_DLL_SPEC Item : public Object
|
||||||
@@ -232,6 +251,7 @@ class TRINITY_DLL_SPEC Item : public Object
|
|||||||
bool IsInTrade() const { return mb_in_trade; }
|
bool IsInTrade() const { return mb_in_trade; }
|
||||||
|
|
||||||
bool IsFitToSpellRequirements(SpellEntry const* spellInfo) const;
|
bool IsFitToSpellRequirements(SpellEntry const* spellInfo) const;
|
||||||
|
bool IsTargetValidForItemUse(Unit* pUnitTarget);
|
||||||
bool IsLimitedToAnotherMapOrZone( uint32 cur_mapId, uint32 cur_zoneId) const;
|
bool IsLimitedToAnotherMapOrZone( uint32 cur_mapId, uint32 cur_zoneId) const;
|
||||||
bool GemsFitSockets() const;
|
bool GemsFitSockets() const;
|
||||||
|
|
||||||
@@ -296,6 +316,7 @@ class TRINITY_DLL_SPEC Item : public Object
|
|||||||
bool IsWeaponVellum() const { return GetProto()->IsWeaponVellum(); }
|
bool IsWeaponVellum() const { return GetProto()->IsWeaponVellum(); }
|
||||||
bool IsArmorVellum() const { return GetProto()->IsArmorVellum(); }
|
bool IsArmorVellum() const { return GetProto()->IsArmorVellum(); }
|
||||||
bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); }
|
bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8 m_slot;
|
uint8 m_slot;
|
||||||
Bag *m_container;
|
Bag *m_container;
|
||||||
|
|||||||
+1
-1
@@ -1524,7 +1524,7 @@ bool ChatHandler::HandleModifyASpeedCommand(const char* args)
|
|||||||
|
|
||||||
float ASpeed = (float)atof((char*)args);
|
float ASpeed = (float)atof((char*)args);
|
||||||
|
|
||||||
if (ASpeed > 10 || ASpeed < 0.1)
|
if (ASpeed > 50 || ASpeed < 0)
|
||||||
{
|
{
|
||||||
SendSysMessage(LANG_BAD_VALUE);
|
SendSysMessage(LANG_BAD_VALUE);
|
||||||
SetSentErrorMessage(true);
|
SetSentErrorMessage(true);
|
||||||
|
|||||||
@@ -668,6 +668,7 @@ bool ChatHandler::HandleReloadAllItemCommand(const char*)
|
|||||||
{
|
{
|
||||||
HandleReloadPageTextsCommand("a");
|
HandleReloadPageTextsCommand("a");
|
||||||
HandleReloadItemEnchantementsCommand("a");
|
HandleReloadItemEnchantementsCommand("a");
|
||||||
|
HandleReloadItemRequiredTragetCommand("a");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1107,6 +1108,14 @@ bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ChatHandler::HandleReloadItemRequiredTragetCommand(const char*)
|
||||||
|
{
|
||||||
|
sLog.outString( "Re-Loading Item Required Targets Table..." );
|
||||||
|
objmgr.LoadItemRequiredTarget();
|
||||||
|
SendGlobalSysMessage("DB table `item_required_target` reloaded.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
|
bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
|
||||||
{
|
{
|
||||||
if(sWorld.IsScriptScheduled())
|
if(sWorld.IsScriptScheduled())
|
||||||
|
|||||||
@@ -2117,6 +2117,106 @@ void ObjectMgr::LoadItemPrototypes()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectMgr::LoadItemRequiredTarget()
|
||||||
|
{
|
||||||
|
m_ItemRequiredTarget.clear(); // needed for reload case
|
||||||
|
|
||||||
|
uint32 count = 0;
|
||||||
|
|
||||||
|
QueryResult *result = WorldDatabase.Query("SELECT entry,type,targetEntry FROM item_required_target");
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
barGoLink bar(1);
|
||||||
|
|
||||||
|
bar.step();
|
||||||
|
|
||||||
|
sLog.outString();
|
||||||
|
sLog.outErrorDb(">> Loaded 0 ItemRequiredTarget. DB table `item_required_target` is empty.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
barGoLink bar(result->GetRowCount());
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Field *fields = result->Fetch();
|
||||||
|
bar.step();
|
||||||
|
|
||||||
|
uint32 uiItemId = fields[0].GetUInt32();
|
||||||
|
uint32 uiType = fields[1].GetUInt32();
|
||||||
|
uint32 uiTargetEntry = fields[2].GetUInt32();
|
||||||
|
|
||||||
|
ItemPrototype const* pItemProto = sItemStorage.LookupEntry<ItemPrototype>(uiItemId);
|
||||||
|
|
||||||
|
if (!pItemProto)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("Table `item_required_target`: Entry %u listed for TargetEntry %u does not exist in `item_template`.",uiItemId,uiTargetEntry);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bIsItemSpellValid = false;
|
||||||
|
|
||||||
|
for(int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
|
||||||
|
{
|
||||||
|
if (SpellEntry const* pSpellInfo = sSpellStore.LookupEntry(pItemProto->Spells[i].SpellId))
|
||||||
|
{
|
||||||
|
if (pItemProto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_USE ||
|
||||||
|
pItemProto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE)
|
||||||
|
{
|
||||||
|
SpellScriptTarget::const_iterator lower = spellmgr.GetBeginSpellScriptTarget(pSpellInfo->Id);
|
||||||
|
SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(pSpellInfo->Id);
|
||||||
|
|
||||||
|
if (lower != upper)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (pSpellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_TARGET_ENEMY ||
|
||||||
|
pSpellInfo->EffectImplicitTargetB[i] == TARGET_UNIT_TARGET_ENEMY ||
|
||||||
|
pSpellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_TARGET_ANY ||
|
||||||
|
pSpellInfo->EffectImplicitTargetB[i] == TARGET_UNIT_TARGET_ANY)
|
||||||
|
{
|
||||||
|
bIsItemSpellValid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bIsItemSpellValid)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("Table `item_required_target`: Spell used by item %u does not have implicit target TARGET_CHAIN_DAMAGE(6), TARGET_DUELVSPLAYER(25), already listed in `spell_script_target` or doesn't have item spelltrigger.",uiItemId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!uiType || uiType > MAX_ITEM_REQ_TARGET_TYPE)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("Table `item_required_target`: Type %u for TargetEntry %u is incorrect.",uiType,uiTargetEntry);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!uiTargetEntry)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("Table `item_required_target`: TargetEntry == 0 for Type (%u).",uiType);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sCreatureStorage.LookupEntry<CreatureInfo>(uiTargetEntry))
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("Table `item_required_target`: creature template entry %u does not exist.",uiTargetEntry);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ItemRequiredTarget.insert(ItemRequiredTargetMap::value_type(uiItemId,ItemRequiredTarget(ItemRequiredTargetType(uiType),uiTargetEntry)));
|
||||||
|
|
||||||
|
++count;
|
||||||
|
} while (result->NextRow());
|
||||||
|
|
||||||
|
delete result;
|
||||||
|
|
||||||
|
sLog.outString();
|
||||||
|
sLog.outString(">> Loaded %u Item required targets", count);
|
||||||
|
}
|
||||||
|
|
||||||
void ObjectMgr::LoadPetLevelInfo()
|
void ObjectMgr::LoadPetLevelInfo()
|
||||||
{
|
{
|
||||||
// Loading levels data
|
// Loading levels data
|
||||||
@@ -6367,6 +6467,9 @@ void ObjectMgr::LoadNPCSpellClickSpells()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!(cInfo->npcflag & UNIT_NPC_FLAG_SPELLCLICK))
|
||||||
|
const_cast<CreatureInfo*>(cInfo)->npcflag |= UNIT_NPC_FLAG_SPELLCLICK;
|
||||||
|
|
||||||
uint32 spellid = fields[1].GetUInt32();
|
uint32 spellid = fields[1].GetUInt32();
|
||||||
SpellEntry const *spellinfo = sSpellStore.LookupEntry(spellid);
|
SpellEntry const *spellinfo = sSpellStore.LookupEntry(spellid);
|
||||||
if (!spellinfo)
|
if (!spellinfo)
|
||||||
|
|||||||
@@ -160,6 +160,8 @@ typedef UNORDERED_MAP<uint32,NpcOptionLocale> NpcOptionLocaleMap;
|
|||||||
typedef UNORDERED_MAP<uint32,PointOfInterestLocale> PointOfInterestLocaleMap;
|
typedef UNORDERED_MAP<uint32,PointOfInterestLocale> PointOfInterestLocaleMap;
|
||||||
|
|
||||||
typedef std::multimap<uint32,uint32> QuestRelations;
|
typedef std::multimap<uint32,uint32> QuestRelations;
|
||||||
|
typedef std::multimap<uint32,ItemRequiredTarget> ItemRequiredTargetMap;
|
||||||
|
typedef std::pair<ItemRequiredTargetMap::const_iterator, ItemRequiredTargetMap::const_iterator> ItemRequiredTargetMapBounds;
|
||||||
|
|
||||||
struct PetLevelInfo
|
struct PetLevelInfo
|
||||||
{
|
{
|
||||||
@@ -534,6 +536,7 @@ class ObjectMgr
|
|||||||
void LoadGameobjects();
|
void LoadGameobjects();
|
||||||
void LoadGameobjectRespawnTimes();
|
void LoadGameobjectRespawnTimes();
|
||||||
void LoadItemPrototypes();
|
void LoadItemPrototypes();
|
||||||
|
void LoadItemRequiredTarget();
|
||||||
void LoadItemLocales();
|
void LoadItemLocales();
|
||||||
void LoadQuestLocales();
|
void LoadQuestLocales();
|
||||||
void LoadNpcTextLocales();
|
void LoadNpcTextLocales();
|
||||||
@@ -805,6 +808,12 @@ class ObjectMgr
|
|||||||
uint32 GetScriptId(const char *name);
|
uint32 GetScriptId(const char *name);
|
||||||
|
|
||||||
int GetOrNewIndexForLocale(LocaleConstant loc);
|
int GetOrNewIndexForLocale(LocaleConstant loc);
|
||||||
|
|
||||||
|
ItemRequiredTargetMapBounds GetItemRequiredTargetMapBounds(uint32 uiItemEntry) const
|
||||||
|
{
|
||||||
|
return ItemRequiredTargetMapBounds(m_ItemRequiredTarget.lower_bound(uiItemEntry),m_ItemRequiredTarget.upper_bound(uiItemEntry));
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// first free id for selected id type
|
// first free id for selected id type
|
||||||
@@ -867,6 +876,8 @@ class ObjectMgr
|
|||||||
|
|
||||||
ScriptNameMap m_scriptNames;
|
ScriptNameMap m_scriptNames;
|
||||||
|
|
||||||
|
ItemRequiredTargetMap m_ItemRequiredTarget;
|
||||||
|
|
||||||
typedef std::vector<LocaleConstant> LocalForIndex;
|
typedef std::vector<LocaleConstant> LocalForIndex;
|
||||||
LocalForIndex m_LocalForIndex;
|
LocalForIndex m_LocalForIndex;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -459,12 +459,12 @@ void Pet::setDeathState(DeathState s) // overwrite virtual
|
|||||||
if(!mapEntry || (mapEntry->map_type != MAP_ARENA && mapEntry->map_type != MAP_BATTLEGROUND))
|
if(!mapEntry || (mapEntry->map_type != MAP_ARENA && mapEntry->map_type != MAP_BATTLEGROUND))
|
||||||
ModifyPower(POWER_HAPPINESS, -HAPPINESS_LEVEL_SIZE);
|
ModifyPower(POWER_HAPPINESS, -HAPPINESS_LEVEL_SIZE);
|
||||||
|
|
||||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
//SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(getDeathState()==ALIVE)
|
else if(getDeathState()==ALIVE)
|
||||||
{
|
{
|
||||||
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
//RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||||
CastPetAuras(true);
|
CastPetAuras(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-13
@@ -286,19 +286,7 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(pet->isPossessed())
|
if(pet->isPossessed())
|
||||||
{
|
Spell::SendCastResult(GetPlayer(),spellInfo,0,result);
|
||||||
WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
|
|
||||||
data << uint8(0) << uint32(spellid) << uint8(result);
|
|
||||||
switch (result)
|
|
||||||
{
|
|
||||||
case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
|
|
||||||
data << uint32(spellInfo->RequiresSpellFocus);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
SendPacket(&data);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
pet->SendPetCastFail(spellid, result);
|
pet->SendPetCastFail(spellid, result);
|
||||||
|
|
||||||
|
|||||||
@@ -17437,6 +17437,10 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
|
|||||||
// stop combat at start taxi flight if any
|
// stop combat at start taxi flight if any
|
||||||
CombatStop();
|
CombatStop();
|
||||||
|
|
||||||
|
StopCastingCharm();
|
||||||
|
StopCastingBindSight();
|
||||||
|
ExitVehicle();
|
||||||
|
|
||||||
// stop trade (client cancel trade at taxi map open but cheating tools can be used for reopen it)
|
// stop trade (client cancel trade at taxi map open but cheating tools can be used for reopen it)
|
||||||
TradeCancel(true);
|
TradeCancel(true);
|
||||||
|
|
||||||
|
|||||||
+25
-17
@@ -3125,18 +3125,26 @@ void Spell::SendCastResult(SpellCastResult result)
|
|||||||
if(((Player*)m_caster)->GetSession()->PlayerLoading()) // don't send cast results at loading time
|
if(((Player*)m_caster)->GetSession()->PlayerLoading()) // don't send cast results at loading time
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
SendCastResult((Player*)m_caster,m_spellInfo,m_cast_count,result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Spell::SendCastResult(Player* caster, SpellEntry const* spellInfo, uint8 cast_count, SpellCastResult result)
|
||||||
|
{
|
||||||
|
if(result == SPELL_CAST_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
|
WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
|
||||||
data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
|
data << uint8(cast_count); // single cast or multi 2.3 (0/1)
|
||||||
data << uint32(m_spellInfo->Id);
|
data << uint32(spellInfo->Id);
|
||||||
data << uint8(result); // problem
|
data << uint8(result); // problem
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
|
case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
|
||||||
data << uint32(m_spellInfo->RequiresSpellFocus);
|
data << uint32(spellInfo->RequiresSpellFocus);
|
||||||
break;
|
break;
|
||||||
case SPELL_FAILED_REQUIRES_AREA:
|
case SPELL_FAILED_REQUIRES_AREA:
|
||||||
// hardcode areas limitation case
|
// hardcode areas limitation case
|
||||||
switch(m_spellInfo->Id)
|
switch(spellInfo->Id)
|
||||||
{
|
{
|
||||||
case 41617: // Cenarion Mana Salve
|
case 41617: // Cenarion Mana Salve
|
||||||
case 41619: // Cenarion Healing Salve
|
case 41619: // Cenarion Healing Salve
|
||||||
@@ -3155,26 +3163,26 @@ void Spell::SendCastResult(SpellCastResult result)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SPELL_FAILED_TOTEMS:
|
case SPELL_FAILED_TOTEMS:
|
||||||
if(m_spellInfo->Totem[0])
|
if(spellInfo->Totem[0])
|
||||||
data << uint32(m_spellInfo->Totem[0]);
|
data << uint32(spellInfo->Totem[0]);
|
||||||
if(m_spellInfo->Totem[1])
|
if(spellInfo->Totem[1])
|
||||||
data << uint32(m_spellInfo->Totem[1]);
|
data << uint32(spellInfo->Totem[1]);
|
||||||
break;
|
break;
|
||||||
case SPELL_FAILED_TOTEM_CATEGORY:
|
case SPELL_FAILED_TOTEM_CATEGORY:
|
||||||
if(m_spellInfo->TotemCategory[0])
|
if(spellInfo->TotemCategory[0])
|
||||||
data << uint32(m_spellInfo->TotemCategory[0]);
|
data << uint32(spellInfo->TotemCategory[0]);
|
||||||
if(m_spellInfo->TotemCategory[1])
|
if(spellInfo->TotemCategory[1])
|
||||||
data << uint32(m_spellInfo->TotemCategory[1]);
|
data << uint32(spellInfo->TotemCategory[1]);
|
||||||
break;
|
break;
|
||||||
case SPELL_FAILED_EQUIPPED_ITEM_CLASS:
|
case SPELL_FAILED_EQUIPPED_ITEM_CLASS:
|
||||||
data << uint32(m_spellInfo->EquippedItemClass);
|
data << uint32(spellInfo->EquippedItemClass);
|
||||||
data << uint32(m_spellInfo->EquippedItemSubClassMask);
|
data << uint32(spellInfo->EquippedItemSubClassMask);
|
||||||
//data << uint32(m_spellInfo->EquippedItemInventoryTypeMask);
|
//data << uint32(spellInfo->EquippedItemInventoryTypeMask);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
((Player*)m_caster)->GetSession()->SendPacket(&data);
|
caster->GetSession()->SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::SendSpellStart()
|
void Spell::SendSpellStart()
|
||||||
@@ -4821,7 +4829,7 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||||||
|
|
||||||
SpellCastResult Spell::CheckPetCast(Unit* target)
|
SpellCastResult Spell::CheckPetCast(Unit* target)
|
||||||
{
|
{
|
||||||
if(!m_caster->isAlive())
|
if(!m_caster->isAlive() && !(m_spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_DEAD))
|
||||||
return SPELL_FAILED_CASTER_DEAD;
|
return SPELL_FAILED_CASTER_DEAD;
|
||||||
|
|
||||||
if(m_caster->hasUnitState(UNIT_STAT_CASTING) && !m_IsTriggeredSpell) //prevent spellcast interruption by another spellcast
|
if(m_caster->hasUnitState(UNIT_STAT_CASTING) && !m_IsTriggeredSpell) //prevent spellcast interruption by another spellcast
|
||||||
|
|||||||
@@ -423,6 +423,7 @@ class Spell
|
|||||||
void CheckSrc() { if(!m_targets.HasSrc()) m_targets.setSrc(m_caster); }
|
void CheckSrc() { if(!m_targets.HasSrc()) m_targets.setSrc(m_caster); }
|
||||||
void CheckDst() { if(!m_targets.HasDst()) m_targets.setDestination(m_caster); }
|
void CheckDst() { if(!m_targets.HasDst()) m_targets.setDestination(m_caster); }
|
||||||
|
|
||||||
|
static void SendCastResult(Player* caster, SpellEntry const* spellInfo, uint8 cast_count, SpellCastResult result);
|
||||||
void SendCastResult(SpellCastResult result);
|
void SendCastResult(SpellCastResult result);
|
||||||
void SendSpellStart();
|
void SendSpellStart();
|
||||||
void SendSpellGo();
|
void SendSpellGo();
|
||||||
|
|||||||
@@ -3879,10 +3879,9 @@ void AuraEffect::HandleAuraModDisarm(bool apply, bool Real, bool /*changeAmount*
|
|||||||
AuraType type = AuraType(GetAuraName());
|
AuraType type = AuraType(GetAuraName());
|
||||||
|
|
||||||
//Prevent handling aura twice
|
//Prevent handling aura twice
|
||||||
if(apply && m_target->GetAurasByType(type).size()>1)
|
if(apply ? m_target->GetAurasByType(type).size() > 1 : m_target->HasAuraType(type))
|
||||||
return;
|
|
||||||
if(!apply && m_target->HasAuraType(type))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint32 field, flag, slot;
|
uint32 field, flag, slot;
|
||||||
WeaponAttackType attType;
|
WeaponAttackType attType;
|
||||||
switch (type)
|
switch (type)
|
||||||
@@ -3905,6 +3904,8 @@ void AuraEffect::HandleAuraModDisarm(bool apply, bool Real, bool /*changeAmount*
|
|||||||
slot=EQUIPMENT_SLOT_RANGED;
|
slot=EQUIPMENT_SLOT_RANGED;
|
||||||
attType=RANGED_ATTACK;
|
attType=RANGED_ATTACK;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if(apply)
|
if(apply)
|
||||||
m_target->SetFlag(field, flag);
|
m_target->SetFlag(field, flag);
|
||||||
@@ -3913,10 +3914,8 @@ void AuraEffect::HandleAuraModDisarm(bool apply, bool Real, bool /*changeAmount*
|
|||||||
|
|
||||||
if (m_target->GetTypeId() == TYPEID_PLAYER)
|
if (m_target->GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
Item *pItem = ((Player*)m_target)->GetItemByPos( INVENTORY_SLOT_BAG_0, slot );
|
if(Item *pItem = ((Player*)m_target)->GetItemByPos( INVENTORY_SLOT_BAG_0, slot ))
|
||||||
if(!pItem )
|
((Player*)m_target)->_ApplyItemMods(pItem, slot, !apply);
|
||||||
return;
|
|
||||||
((Player*)m_target)->_ApplyItemMods(pItem, slot, !apply);
|
|
||||||
}
|
}
|
||||||
else if (((Creature*)m_target)->GetCurrentEquipmentId())
|
else if (((Creature*)m_target)->GetCurrentEquipmentId())
|
||||||
m_target->UpdateDamagePhysical(attType);
|
m_target->UpdateDamagePhysical(attType);
|
||||||
|
|||||||
@@ -3393,10 +3393,8 @@ void Spell::EffectSummonType(uint32 i)
|
|||||||
vehicle->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
|
vehicle->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
|
||||||
|
|
||||||
if(damage)
|
if(damage)
|
||||||
{
|
|
||||||
m_caster->CastSpell(vehicle, damage, true);
|
m_caster->CastSpell(vehicle, damage, true);
|
||||||
m_caster->EnterVehicle(vehicle);
|
m_caster->EnterVehicle(vehicle);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5135,6 +5133,15 @@ void Spell::EffectScriptEffect(uint32 effIndex)
|
|||||||
{
|
{
|
||||||
switch(m_spellInfo->Id)
|
switch(m_spellInfo->Id)
|
||||||
{
|
{
|
||||||
|
// Heart of the Pheonix
|
||||||
|
case 55709:
|
||||||
|
{
|
||||||
|
int pct = 100;
|
||||||
|
if (unitTarget->GetTypeId()==TYPEID_UNIT && ((Creature*)unitTarget)->isPet())
|
||||||
|
if (Unit* owner = ((Creature*)unitTarget)->GetOwner())
|
||||||
|
owner->CastCustomSpell(unitTarget, 54114, &pct, NULL, NULL, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Chimera Shot
|
// Chimera Shot
|
||||||
case 53209:
|
case 53209:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -123,9 +123,29 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SpellCastTargets targets;
|
SpellCastTargets targets;
|
||||||
if(!targets.read(&recvPacket, pUser))
|
if (!targets.read(&recvPacket, pUser))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
targets.Update(pUser);
|
||||||
|
|
||||||
|
if (!pItem->IsTargetValidForItemUse(targets.getUnitTarget()))
|
||||||
|
{
|
||||||
|
// free greay item aftre use faul
|
||||||
|
pUser->SendEquipError(EQUIP_ERR_NONE, pItem, NULL);
|
||||||
|
|
||||||
|
// send spell error
|
||||||
|
if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid))
|
||||||
|
{
|
||||||
|
// for implicit area/coord target spells
|
||||||
|
if(!targets.getUnitTarget())
|
||||||
|
Spell::SendCastResult(_player,spellInfo,cast_count,SPELL_FAILED_NO_VALID_TARGETS);
|
||||||
|
// for explicit target spells
|
||||||
|
else
|
||||||
|
Spell::SendCastResult(_player,spellInfo,cast_count,SPELL_FAILED_BAD_TARGETS);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state.
|
//Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state.
|
||||||
if(!Script->ItemUse(pUser,pItem,targets))
|
if(!Script->ItemUse(pUser,pItem,targets))
|
||||||
{
|
{
|
||||||
@@ -313,6 +333,12 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Client is resending autoshot cast opcode when other spell is casted during shoot rotation
|
||||||
|
// Skip it to prevent "interrupt" message
|
||||||
|
if (IsAutoRepeatRangedSpell(spellInfo) && _player->m_currentSpells[CURRENT_AUTOREPEAT_SPELL]
|
||||||
|
&& _player->m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo == spellInfo)
|
||||||
|
return;
|
||||||
|
|
||||||
// can't use our own spells when we're in possession of another unit,
|
// can't use our own spells when we're in possession of another unit,
|
||||||
if(_player->isPossessing())
|
if(_player->isPossessing())
|
||||||
return;
|
return;
|
||||||
|
|||||||
+12
-7
@@ -2341,7 +2341,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (found)
|
if (found)
|
||||||
pVictim->CastCustomSpell(pVictim, 44413, &spell_dmg, NULL, NULL, false);
|
pVictim->CastCustomSpell(pVictim, 44413, &spell_dmg, NULL, NULL, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3383,7 +3383,7 @@ void Unit::_UpdateSpells( uint32 time )
|
|||||||
void Unit::_UpdateAutoRepeatSpell()
|
void Unit::_UpdateAutoRepeatSpell()
|
||||||
{
|
{
|
||||||
//check "realtime" interrupts
|
//check "realtime" interrupts
|
||||||
if ( (GetTypeId() == TYPEID_PLAYER && ((Player*)this)->isMoving()) || IsNonMeleeSpellCasted(false,false,true) )
|
if ( (GetTypeId() == TYPEID_PLAYER && ((Player*)this)->isMoving()) || IsNonMeleeSpellCasted(false,false,true,m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id == SPELL_ID_AUTOSHOT) )
|
||||||
{
|
{
|
||||||
// cancel wand shoot
|
// cancel wand shoot
|
||||||
if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != SPELL_ID_AUTOSHOT)
|
if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != SPELL_ID_AUTOSHOT)
|
||||||
@@ -3515,7 +3515,7 @@ void Unit::InterruptSpell(uint32 spellType, bool withDelayed, bool withInstant)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Unit::IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled, bool skipAutorepeat) const
|
bool Unit::IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled, bool skipAutorepeat, bool isAutoshoot) const
|
||||||
{
|
{
|
||||||
// We don't do loop here to explicitly show that melee spell is excluded.
|
// We don't do loop here to explicitly show that melee spell is excluded.
|
||||||
// Maybe later some special spells will be excluded too.
|
// Maybe later some special spells will be excluded too.
|
||||||
@@ -3524,12 +3524,14 @@ bool Unit::IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled, bool skip
|
|||||||
if ( m_currentSpells[CURRENT_GENERIC_SPELL] &&
|
if ( m_currentSpells[CURRENT_GENERIC_SPELL] &&
|
||||||
(m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_FINISHED) &&
|
(m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_FINISHED) &&
|
||||||
(withDelayed || m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_DELAYED) )
|
(withDelayed || m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_DELAYED) )
|
||||||
return(true);
|
if (!isAutoshoot || !(m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_NOT_RESET_AUTOSHOT))
|
||||||
|
return(true);
|
||||||
|
|
||||||
// channeled spells may be delayed, but they are still considered casted
|
// channeled spells may be delayed, but they are still considered casted
|
||||||
else if ( !skipChanneled && m_currentSpells[CURRENT_CHANNELED_SPELL] &&
|
else if ( !skipChanneled && m_currentSpells[CURRENT_CHANNELED_SPELL] &&
|
||||||
(m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED) )
|
(m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED) )
|
||||||
return(true);
|
if (!isAutoshoot || !(m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_NOT_RESET_AUTOSHOT))
|
||||||
|
return(true);
|
||||||
|
|
||||||
// autorepeat spells may be finished or delayed, but they are still considered casted
|
// autorepeat spells may be finished or delayed, but they are still considered casted
|
||||||
else if ( !skipAutorepeat && m_currentSpells[CURRENT_AUTOREPEAT_SPELL] )
|
else if ( !skipAutorepeat && m_currentSpells[CURRENT_AUTOREPEAT_SPELL] )
|
||||||
@@ -11000,7 +11002,11 @@ int32 Unit::CalculateSpellDamage(SpellEntry const* spellProto, uint8 effect_inde
|
|||||||
|
|
||||||
if(!basePointsPerLevel && (spellProto->Attributes & SPELL_ATTR_LEVEL_DAMAGE_CALCULATION && spellProto->spellLevel) &&
|
if(!basePointsPerLevel && (spellProto->Attributes & SPELL_ATTR_LEVEL_DAMAGE_CALCULATION && spellProto->spellLevel) &&
|
||||||
spellProto->Effect[effect_index] != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE &&
|
spellProto->Effect[effect_index] != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE &&
|
||||||
spellProto->Effect[effect_index] != SPELL_EFFECT_KNOCK_BACK)
|
spellProto->Effect[effect_index] != SPELL_EFFECT_KNOCK_BACK &&
|
||||||
|
spellProto->EffectApplyAuraName[effect_index] != SPELL_AURA_MOD_SPEED_ALWAYS &&
|
||||||
|
spellProto->EffectApplyAuraName[effect_index] != SPELL_AURA_MOD_SPEED_NOT_STACK &&
|
||||||
|
spellProto->EffectApplyAuraName[effect_index] != SPELL_AURA_MOD_INCREASE_SPEED &&
|
||||||
|
spellProto->EffectApplyAuraName[effect_index] != SPELL_AURA_MOD_DECREASE_SPEED)
|
||||||
//there are many more: slow speed, -healing pct
|
//there are many more: slow speed, -healing pct
|
||||||
//value = int32(value*0.25f*exp(getLevel()*(70-spellProto->spellLevel)/1000.0f));
|
//value = int32(value*0.25f*exp(getLevel()*(70-spellProto->spellLevel)/1000.0f));
|
||||||
value = int32(value * (int32)getLevel() / (int32)(spellProto->spellLevel ? spellProto->spellLevel : 1));
|
value = int32(value * (int32)getLevel() / (int32)(spellProto->spellLevel ? spellProto->spellLevel : 1));
|
||||||
@@ -13618,7 +13624,6 @@ void Unit::SetCharmedBy(Unit* charmer, CharmType type)
|
|||||||
if(GetTypeId() == TYPEID_UNIT)
|
if(GetTypeId() == TYPEID_UNIT)
|
||||||
{
|
{
|
||||||
((Creature*)this)->AI()->OnCharmed(true);
|
((Creature*)this)->AI()->OnCharmed(true);
|
||||||
GetMotionMaster()->Clear(false);
|
|
||||||
GetMotionMaster()->MoveIdle();
|
GetMotionMaster()->MoveIdle();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
+1
-1
@@ -1441,7 +1441,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
|||||||
// set withDelayed to true to account delayed spells as casted
|
// set withDelayed to true to account delayed spells as casted
|
||||||
// delayed+channeled spells are always accounted as casted
|
// delayed+channeled spells are always accounted as casted
|
||||||
// we can skip channeled or delayed checks using flags
|
// we can skip channeled or delayed checks using flags
|
||||||
bool IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled = false, bool skipAutorepeat = false) const;
|
bool IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled = false, bool skipAutorepeat = false, bool isAutoshoot = false) const;
|
||||||
|
|
||||||
// set withDelayed to true to interrupt delayed spells too
|
// set withDelayed to true to interrupt delayed spells too
|
||||||
// delayed+channeled spells are always interrupted
|
// delayed+channeled spells are always interrupted
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "WorldPacket.h"
|
#include "WorldPacket.h"
|
||||||
|
|
||||||
#include "Chat.h"
|
|
||||||
#include "CreatureAI.h"
|
#include "CreatureAI.h"
|
||||||
#include "ZoneScript.h"
|
#include "ZoneScript.h"
|
||||||
|
|
||||||
@@ -85,6 +84,11 @@ void Vehicle::setDeathState(DeathState s) // overwrite vir
|
|||||||
}
|
}
|
||||||
RemoveAllPassengers();
|
RemoveAllPassengers();
|
||||||
}
|
}
|
||||||
|
else if(s == JUST_ALIVED)
|
||||||
|
{
|
||||||
|
if(m_usableSeatNum)
|
||||||
|
SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||||
|
}
|
||||||
Creature::setDeathState(s);
|
Creature::setDeathState(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,13 +248,9 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId)
|
|||||||
GetPositionZ() + unit->m_movementInfo.t_z,
|
GetPositionZ() + unit->m_movementInfo.t_z,
|
||||||
GetOrientation());
|
GetOrientation());
|
||||||
|
|
||||||
unit->GetMotionMaster()->MoveIdle(MOTION_SLOT_IDLE);
|
|
||||||
|
|
||||||
WorldPacket data;
|
WorldPacket data;
|
||||||
if(unit->GetTypeId() == TYPEID_PLAYER)
|
if(unit->GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
//ChatHandler(player).PSendSysMessage("Enter seat %u %u", veSeat->m_ID, seat->first);
|
|
||||||
|
|
||||||
if(seat->first == 0 && seat->second.seatInfo->IsUsable()) // not right
|
if(seat->first == 0 && seat->second.seatInfo->IsUsable()) // not right
|
||||||
SetCharmedBy(unit, CHARM_TYPE_VEHICLE);
|
SetCharmedBy(unit, CHARM_TYPE_VEHICLE);
|
||||||
|
|
||||||
|
|||||||
@@ -1252,6 +1252,9 @@ void World::SetInitialWorldSettings()
|
|||||||
sLog.outString( "Loading SpellsScriptTarget...");
|
sLog.outString( "Loading SpellsScriptTarget...");
|
||||||
spellmgr.LoadSpellScriptTarget(); // must be after LoadCreatureTemplates and LoadGameobjectInfo
|
spellmgr.LoadSpellScriptTarget(); // must be after LoadCreatureTemplates and LoadGameobjectInfo
|
||||||
|
|
||||||
|
sLog.outString( "Loading ItemRequiredTarget...");
|
||||||
|
objmgr.LoadItemRequiredTarget();
|
||||||
|
|
||||||
sLog.outString( "Loading Creature Reputation OnKill Data..." );
|
sLog.outString( "Loading Creature Reputation OnKill Data..." );
|
||||||
objmgr.LoadReputationOnKill();
|
objmgr.LoadReputationOnKill();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user