mirror of
https://github.com/mangosfour/server.git
synced 2025-12-17 16:37:00 +00:00
Merge remote branch 'origin/master' into 330
This commit is contained in:
commit
33cd1a0aca
32 changed files with 659 additions and 293 deletions
|
|
@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
|
|||
`version` varchar(120) default NULL,
|
||||
`creature_ai_version` varchar(120) default NULL,
|
||||
`cache_id` int(10) default '0',
|
||||
`required_9045_02_mangos_spell_chain` bit(1) default NULL
|
||||
`required_9074_01_mangos_command` bit(1) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||
|
||||
--
|
||||
|
|
@ -743,7 +743,7 @@ INSERT INTO `command` VALUES
|
|||
('server restart cancel',3,'Syntax: .server restart cancel\r\n\r\nCancel the restart/shutdown timer if any.'),
|
||||
('server set loglevel',4,'Syntax: .server set loglevel #level\r\n\r\nSet server log level (0 - errors only, 1 - basic, 2 - detail, 3 - debug).'),
|
||||
('server set motd',3,'Syntax: .server set motd $MOTD\r\n\r\nSet server Message of the day.'),
|
||||
('server shutdown',3,'Syntax: .server shutdown #delay [#exist_code]\r\n\r\nShut the server down after #delay seconds. Use #exist_code or 0 as program exist code.'),
|
||||
('server shutdown',3,'Syntax: .server shutdown #delay [#exit_code]\r\n\r\nShut the server down after #delay seconds. Use #exit_code or 0 as program exit code.'),
|
||||
('server shutdown cancel',3,'Syntax: .server shutdown cancel\r\n\r\nCancel the restart/shutdown timer if any.'),
|
||||
('setskill',3,'Syntax: .setskill #skill #level [#max]\r\n\r\nSet a skill of id #skill with a current skill value of #level and a maximum value of #max (or equal current maximum if not provide) for the selected character. If no character is selected, you learn the skill.'),
|
||||
('showarea',3,'Syntax: .showarea #areaid\r\n\r\nReveal the area of #areaid to the selected character. If no character is selected, reveal this area to you.'),
|
||||
|
|
@ -15271,6 +15271,13 @@ INSERT INTO spell_chain VALUES
|
|||
(10301,10300,7294,5,0),
|
||||
(27150,10301,7294,6,0),
|
||||
(54043,27150,7294,7,0),
|
||||
/*Righteous Vengeance*/
|
||||
(53380,0,53380,1,0),
|
||||
(53381,53380,53380,2,0),
|
||||
(53382,53381,53380,3,0),
|
||||
/*The Art of War*/
|
||||
(53486,0,53486,1,0),
|
||||
(53488,53486,53486,2,0),
|
||||
/*------------------
|
||||
-- (185) Cooking
|
||||
------------------*/
|
||||
|
|
@ -18209,6 +18216,7 @@ INSERT INTO `spell_proc_event` VALUES
|
|||
(45243, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(45244, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(45354, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
|
||||
(45355, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
|
||||
(45481, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
|
||||
(45482, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
|
||||
(45483, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
|
||||
|
|
@ -18367,12 +18375,9 @@ INSERT INTO `spell_proc_event` VALUES
|
|||
(53259, 0x00000000, 9, 0x00000800, 0x00800001, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53260, 0x00000000, 9, 0x00000800, 0x00800001, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53290, 0x00000000, 9, 0x00000800, 0x00000001, 0x00000200, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53380, 0x00000000, 10, 0x00800000, 0x00020000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53381, 0x00000000, 10, 0x00800000, 0x00020000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53382, 0x00000000, 10, 0x00800000, 0x00020000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53380, 0x00000000, 10, 0x00800000, 0x00028000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53397, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53486, 0x00000000, 10, 0x00800000, 0x00028000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53488, 0x00000000, 10, 0x00800000, 0x00028000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53486, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53501, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53502, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53503, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
|
|
@ -18457,7 +18462,7 @@ INSERT INTO `spell_proc_event` VALUES
|
|||
(58386, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0),
|
||||
(58442, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 15),
|
||||
(58444, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 5),
|
||||
(58597, 0x00000000, 10, 0x40000000, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0.000000, 100.000000,0),
|
||||
(58597, 0x00000000, 10, 0x40000000, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0.000000, 100.000000,6),
|
||||
(58616, 0x00000000, 15, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(58620, 0x00000000, 15, 0x00000000, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(58626, 0x00000000, 15, 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
|
|
@ -18535,7 +18540,10 @@ INSERT INTO `spell_proc_event` VALUES
|
|||
(65661, 0x00000000, 15, 0x00400011, 0x00020004, 0x00000000, 0x00000010, 0x00000001, 0.000000, 100.000000,0),
|
||||
(64127, 0x00000000, 6, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(67353, 0x00000000, 7, 0x00008000, 0x00100500, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(67667, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45);
|
||||
(67667, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
|
||||
(67672, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 50),
|
||||
(67702, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
|
||||
(67771, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45);
|
||||
|
||||
/*!40000 ALTER TABLE `spell_proc_event` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
|
|
|||
8
sql/updates/9064_01_mangos_spell_proc_event.sql
Normal file
8
sql/updates/9064_01_mangos_spell_proc_event.sql
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_9045_02_mangos_spell_chain required_9064_01_mangos_spell_proc_event bit;
|
||||
|
||||
DELETE FROM spell_proc_event WHERE entry IN (45355,67672,67702,67771);
|
||||
INSERT INTO spell_proc_event VALUES
|
||||
(45355, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
|
||||
(67672, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 50),
|
||||
(67702, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
|
||||
(67771, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45);
|
||||
10
sql/updates/9068_01_mangos_spell_proc_event.sql
Normal file
10
sql/updates/9068_01_mangos_spell_proc_event.sql
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_9064_01_mangos_spell_proc_event required_9068_01_mangos_spell_proc_event bit;
|
||||
|
||||
DELETE FROM spell_proc_event WHERE entry IN (53380,53381,53382);
|
||||
INSERT INTO spell_proc_event VALUES
|
||||
(53380, 0x00000000, 10, 0x00800000, 0x00028000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0);
|
||||
|
||||
|
||||
DELETE FROM spell_proc_event WHERE entry IN (53486,53488);
|
||||
INSERT INTO spell_proc_event VALUES
|
||||
(53486, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0);
|
||||
14
sql/updates/9068_02_mangos_spell_chain.sql
Normal file
14
sql/updates/9068_02_mangos_spell_chain.sql
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_9068_01_mangos_spell_proc_event required_9068_02_mangos_spell_chain bit;
|
||||
|
||||
/*Righteous Vengeance*/
|
||||
DELETE FROM spell_chain WHERE first_spell = 53380;
|
||||
INSERT INTO spell_chain VALUES
|
||||
(53380, 0, 53380, 1, 0),
|
||||
(53381, 53380, 53380, 2, 0),
|
||||
(53382, 53381, 53380, 3, 0);
|
||||
|
||||
/*The Art of War*/
|
||||
DELETE FROM spell_chain WHERE first_spell = 53486;
|
||||
INSERT INTO spell_chain VALUES
|
||||
(53486, 0, 53486, 1, 0),
|
||||
(53488, 53486, 53486, 2, 0);
|
||||
5
sql/updates/9070_01_mangos_spell_proc_event.sql
Normal file
5
sql/updates/9070_01_mangos_spell_proc_event.sql
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_9068_02_mangos_spell_chain required_9070_01_mangos_spell_proc_event bit;
|
||||
|
||||
DELETE FROM `spell_proc_event` WHERE `entry` IN (58597);
|
||||
INSERT INTO `spell_proc_event` VALUES
|
||||
(58597, 0x00000000, 10, 0x40000000, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0.000000, 100.000000,6);
|
||||
6
sql/updates/9074_01_mangos_command.sql
Normal file
6
sql/updates/9074_01_mangos_command.sql
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_9070_01_mangos_spell_proc_event required_9074_01_mangos_command bit;
|
||||
|
||||
DELETE FROM command where name IN ('server shutdown');
|
||||
|
||||
INSERT INTO `command` VALUES
|
||||
('server shutdown',3,'Syntax: .server shutdown #delay [#exit_code]\r\n\r\nShut the server down after #delay seconds. Use #exit_code or 0 as program exit code.');
|
||||
|
|
@ -219,6 +219,11 @@ pkgdata_DATA = \
|
|||
9034_01_mangos_spell_proc_event.sql \
|
||||
9045_01_mangos_spell_proc_event.sql \
|
||||
9045_02_mangos_spell_chain.sql \
|
||||
9064_01_mangos_spell_proc_event.sql \
|
||||
9068_01_mangos_spell_proc_event.sql \
|
||||
9068_02_mangos_spell_chain.sql \
|
||||
9070_01_mangos_spell_proc_event.sql \
|
||||
9074_01_mangos_command.sql \
|
||||
README
|
||||
|
||||
## Additional files to include when running 'make dist'
|
||||
|
|
@ -418,4 +423,9 @@ EXTRA_DIST = \
|
|||
9034_01_mangos_spell_proc_event.sql \
|
||||
9045_01_mangos_spell_proc_event.sql \
|
||||
9045_02_mangos_spell_chain.sql \
|
||||
9064_01_mangos_spell_proc_event.sql \
|
||||
9068_01_mangos_spell_proc_event.sql \
|
||||
9068_02_mangos_spell_chain.sql \
|
||||
9070_01_mangos_spell_proc_event.sql \
|
||||
9074_01_mangos_command.sql \
|
||||
README
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "CreatureAI.h"
|
||||
#include "Creature.h"
|
||||
#include "DBCStores.h"
|
||||
|
||||
CreatureAI::~CreatureAI()
|
||||
{
|
||||
|
|
@ -28,3 +29,90 @@ void CreatureAI::AttackedBy( Unit* attacker )
|
|||
if(!m_creature->getVictim())
|
||||
AttackStart(attacker);
|
||||
}
|
||||
|
||||
CanCastResult CreatureAI::CanCastSpell(Unit* pTarget, const SpellEntry *pSpell, bool isTriggered)
|
||||
{
|
||||
// If not triggered, we check
|
||||
if (!isTriggered)
|
||||
{
|
||||
// State does not allow
|
||||
if (m_creature->hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DIED))
|
||||
return CAST_FAIL_STATE;
|
||||
|
||||
if (pSpell->PreventionType == SPELL_PREVENTION_TYPE_SILENCE && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
|
||||
return CAST_FAIL_STATE;
|
||||
|
||||
if (pSpell->PreventionType == SPELL_PREVENTION_TYPE_PACIFY && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED))
|
||||
return CAST_FAIL_STATE;
|
||||
|
||||
// Check for power (also done by Spell::CheckCast())
|
||||
if (m_creature->GetPower((Powers)pSpell->powerType) < pSpell->manaCost)
|
||||
return CAST_FAIL_POWER;
|
||||
}
|
||||
|
||||
if (const SpellRangeEntry *pSpellRange = sSpellRangeStore.LookupEntry(pSpell->rangeIndex))
|
||||
{
|
||||
if (pTarget != m_creature)
|
||||
{
|
||||
// pTarget is out of range of this spell (also done by Spell::CheckCast())
|
||||
float fDistance = m_creature->GetCombatDistance(pTarget);
|
||||
|
||||
if (fDistance > (m_creature->IsHostileTo(pTarget) ? pSpellRange->maxRange : pSpellRange->maxRangeFriendly))
|
||||
return CAST_FAIL_TOO_FAR;
|
||||
|
||||
float fMinRange = m_creature->IsHostileTo(pTarget) ? pSpellRange->minRange : pSpellRange->minRangeFriendly;
|
||||
|
||||
if (fMinRange && fDistance < fMinRange)
|
||||
return CAST_FAIL_TOO_CLOSE;
|
||||
}
|
||||
|
||||
return CAST_OK;
|
||||
}
|
||||
else
|
||||
return CAST_FAIL_OTHER;
|
||||
}
|
||||
|
||||
CanCastResult CreatureAI::DoCastSpellIfCan(Unit* pTarget, uint32 uiSpell, uint32 uiCastFlags, uint64 uiOriginalCasterGUID)
|
||||
{
|
||||
Unit* pCaster = m_creature;
|
||||
|
||||
if (uiCastFlags & CAST_FORCE_TARGET_SELF)
|
||||
pCaster = pTarget;
|
||||
|
||||
// Allowed to cast only if not casting (unless we interrupt ourself) or if spell is triggered
|
||||
if (!pCaster->IsNonMeleeSpellCasted(false) || (uiCastFlags & (CAST_TRIGGERED | CAST_INTURRUPT_PREVIOUS)))
|
||||
{
|
||||
if (const SpellEntry* pSpell = sSpellStore.LookupEntry(uiSpell))
|
||||
{
|
||||
// If cast flag CAST_AURA_NOT_PRESENT is active, check if target already has aura on them
|
||||
if (uiCastFlags & CAST_AURA_NOT_PRESENT)
|
||||
{
|
||||
if (pTarget->HasAura(uiSpell))
|
||||
return CAST_FAIL_TARGET_AURA;
|
||||
}
|
||||
|
||||
// Check if cannot cast spell
|
||||
if (!(uiCastFlags & (CAST_FORCE_TARGET_SELF | CAST_FORCE_CAST)))
|
||||
{
|
||||
CanCastResult castResult = CanCastSpell(pTarget, pSpell, uiCastFlags & CAST_TRIGGERED);
|
||||
|
||||
if (castResult != CAST_OK)
|
||||
return castResult;
|
||||
}
|
||||
|
||||
// Interrupt any previous spell
|
||||
if (uiCastFlags & CAST_INTURRUPT_PREVIOUS && pCaster->IsNonMeleeSpellCasted(false))
|
||||
pCaster->InterruptNonMeleeSpells(false);
|
||||
|
||||
pCaster->CastSpell(pTarget, pSpell, uiCastFlags & CAST_TRIGGERED, NULL, NULL, uiOriginalCasterGUID);
|
||||
return CAST_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outErrorDb("DoCastSpellIfCan by creature entry %u attempt to cast spell %u but spell does not exist.", m_creature->GetEntry(), uiSpell);
|
||||
return CAST_FAIL_OTHER;
|
||||
}
|
||||
}
|
||||
else
|
||||
return CAST_FAIL_IS_CASTING;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,18 @@ struct SpellEntry;
|
|||
#define TIME_INTERVAL_LOOK 5000
|
||||
#define VISIBILITY_RANGE 10000
|
||||
|
||||
enum CanCastResult
|
||||
{
|
||||
CAST_OK = 0,
|
||||
CAST_FAIL_IS_CASTING = 1,
|
||||
CAST_FAIL_OTHER = 2,
|
||||
CAST_FAIL_TOO_FAR = 3,
|
||||
CAST_FAIL_TOO_CLOSE = 4,
|
||||
CAST_FAIL_POWER = 5,
|
||||
CAST_FAIL_STATE = 6,
|
||||
CAST_FAIL_TARGET_AURA = 7
|
||||
};
|
||||
|
||||
enum CastFlags
|
||||
{
|
||||
CAST_INTURRUPT_PREVIOUS = 0x01, //Interrupt any spell casting
|
||||
|
|
@ -68,6 +80,10 @@ class MANGOS_DLL_SPEC CreatureAI
|
|||
// Called at any heal cast/item used (call non implemented)
|
||||
virtual void HealBy(Unit * /*healer*/, uint32 /*amount_healed*/) {}
|
||||
|
||||
// Helper functions for cast spell
|
||||
CanCastResult DoCastSpellIfCan(Unit* pTarget, uint32 uiSpell, uint32 uiCastFlags = 0, uint64 uiOriginalCasterGUID = 0);
|
||||
virtual CanCastResult CanCastSpell(Unit* pTarget, const SpellEntry *pSpell, bool isTriggered);
|
||||
|
||||
// Called at any Damage to any victim (before damage apply)
|
||||
virtual void DamageDeal(Unit * /*done_to*/, uint32 & /*damage*/) {}
|
||||
|
||||
|
|
|
|||
|
|
@ -1752,6 +1752,13 @@ uint16 Map::GetAreaFlag(float x, float y, float z) const
|
|||
case 856: // The Noxious Glade (Eastern Plaguelands)
|
||||
case 2456: // Death's Breach (Eastern Plaguelands)
|
||||
if(z > 350.0f) areaflag = 1950; break;
|
||||
// Winterfin Caverns
|
||||
case 1652: // Coldarra
|
||||
case 1653: // The Westrift
|
||||
case 1661: // Winterfin Village
|
||||
if (x > 3823.0f && x < 4141.5f && y > 6247.0f && y < 64890.0f && z < 42.5f)
|
||||
areaflag = 1723;
|
||||
break;
|
||||
// Dalaran
|
||||
case 2492: // Forlorn Woods (Crystalsong Forest)
|
||||
case 2371: // Valley of Echoes (Icecrown Glacier)
|
||||
|
|
|
|||
|
|
@ -463,3 +463,12 @@ bool MotionMaster::GetDestination(float &x, float &y, float &z)
|
|||
|
||||
return top()->GetDestination(x,y,z);
|
||||
}
|
||||
|
||||
void MotionMaster::UpdateFinalDistanceToTarget(float fDistance)
|
||||
{
|
||||
if (!empty())
|
||||
{
|
||||
if (top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
||||
top()->UpdateFinalDistance(fDistance);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,6 +121,9 @@ class MANGOS_DLL_SPEC MotionMaster : private std::stack<MovementGenerator *>
|
|||
|
||||
void propagateSpeedChange();
|
||||
|
||||
// will only work in MMgens where we have a target (TARGETED_MOTION_TYPE)
|
||||
void UpdateFinalDistanceToTarget(float fDistance);
|
||||
|
||||
bool GetDestination(float &x, float &y, float &z);
|
||||
private:
|
||||
void Mutate(MovementGenerator *m); // use Move* functions instead
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ class MANGOS_DLL_SPEC MovementGenerator
|
|||
|
||||
virtual void unitSpeedChanged() { }
|
||||
|
||||
virtual void UpdateFinalDistance(float fDistance) { }
|
||||
|
||||
virtual bool GetDestination(float& /*x*/, float& /*y*/, float& /*z*/) const { return false; }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ char const* petTypeSuffix[MAX_PET_TYPE] =
|
|||
Pet::Pet(PetType type) :
|
||||
Creature(), m_removed(false), m_petType(type), m_happinessTimer(7500), m_duration(0), m_resetTalentsCost(0),
|
||||
m_bonusdamage(0), m_resetTalentsTime(0), m_usedTalentCount(0), m_auraUpdateMask(0), m_loading(false),
|
||||
m_declinedname(NULL)
|
||||
m_declinedname(NULL), m_petModeFlags(PET_MODE_DEFAULT)
|
||||
{
|
||||
m_isPet = true;
|
||||
m_name = "Pet";
|
||||
|
|
@ -1948,3 +1948,20 @@ void Pet::SynchronizeLevelWithOwner()
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Pet::ApplyModeFlags(PetModeFlags mode, bool apply)
|
||||
{
|
||||
if (apply)
|
||||
m_petModeFlags = PetModeFlags(m_petModeFlags | mode);
|
||||
else
|
||||
m_petModeFlags = PetModeFlags(m_petModeFlags & ~mode);
|
||||
|
||||
Unit* owner = GetOwner();
|
||||
if(!owner || owner->GetTypeId()!=TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
WorldPacket data(SMSG_PET_MODE, 12);
|
||||
data << uint64(GetGUID());
|
||||
data << uint32(m_petModeFlags);
|
||||
((Player*)owner)->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,17 @@ enum PetSaveMode
|
|||
PET_SAVE_NOT_IN_SLOT = 100 // for avoid conflict with stable size grow will use 100
|
||||
};
|
||||
|
||||
// There might be a lot more
|
||||
enum PetModeFlags
|
||||
{
|
||||
PET_MODE_UNKNOWN_0 = 0x0000001,
|
||||
PET_MODE_UNKNOWN_2 = 0x0000100,
|
||||
PET_MODE_DISABLE_ACTIONS = 0x8000000,
|
||||
|
||||
// autoset in client at summon
|
||||
PET_MODE_DEFAULT = PET_MODE_UNKNOWN_0 | PET_MODE_UNKNOWN_2,
|
||||
};
|
||||
|
||||
enum HappinessState
|
||||
{
|
||||
UNHAPPY = 1,
|
||||
|
|
@ -182,6 +193,9 @@ class Pet : public Creature
|
|||
bool CanTakeMoreActiveSpells(uint32 SpellIconID);
|
||||
void ToggleAutocast(uint32 spellid, bool apply);
|
||||
|
||||
void ApplyModeFlags(PetModeFlags mode, bool apply);
|
||||
PetModeFlags GetModeFlags() const { return m_petModeFlags; }
|
||||
|
||||
bool HasSpell(uint32 spell) const;
|
||||
|
||||
void LearnPetPassives();
|
||||
|
|
@ -242,6 +256,8 @@ class Pet : public Creature
|
|||
DeclinedName *m_declinedname;
|
||||
|
||||
private:
|
||||
PetModeFlags m_petModeFlags;
|
||||
|
||||
void SaveToDB(uint32, uint8) // overwrited of Creature::SaveToDB - don't must be called
|
||||
{
|
||||
assert(false);
|
||||
|
|
|
|||
|
|
@ -44,9 +44,16 @@ PetAI::PetAI(Creature *c) : CreatureAI(c), i_tracker(TIME_INTERVAL_LOOK), inComb
|
|||
|
||||
void PetAI::MoveInLineOfSight(Unit *u)
|
||||
{
|
||||
if( !m_creature->getVictim() && m_creature->GetCharmInfo() &&
|
||||
m_creature->GetCharmInfo()->HasReactState(REACT_AGGRESSIVE) &&
|
||||
u->isTargetableForAttack() && m_creature->IsHostileTo( u ) &&
|
||||
if (m_creature->getVictim())
|
||||
return;
|
||||
|
||||
if (m_creature->isPet() && ((Pet*)m_creature)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS)
|
||||
return;
|
||||
|
||||
if (!m_creature->GetCharmInfo() || !m_creature->GetCharmInfo()->HasReactState(REACT_AGGRESSIVE))
|
||||
return;
|
||||
|
||||
if (u->isTargetableForAttack() && m_creature->IsHostileTo( u ) &&
|
||||
u->isInAccessablePlaceFor(m_creature))
|
||||
{
|
||||
float attackRadius = m_creature->GetAttackDistance(u);
|
||||
|
|
@ -139,7 +146,7 @@ void PetAI::UpdateAI(const uint32 diff)
|
|||
else
|
||||
m_updateAlliesTimer -= diff;
|
||||
|
||||
if (inCombat && !m_creature->getVictim())
|
||||
if (inCombat && (!m_creature->getVictim() || m_creature->isPet() && ((Pet*)m_creature)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS))
|
||||
_stopAttack();
|
||||
|
||||
// i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
|
||||
|
|
|
|||
|
|
@ -44,23 +44,33 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
|
|||
// used also for charmed creature
|
||||
Unit* pet= ObjectAccessor::GetUnit(*_player, guid1);
|
||||
sLog.outDetail("HandlePetAction.Pet %u flag is %u, spellid is %u, target %u.", uint32(GUID_LOPART(guid1)), uint32(flag), spellid, uint32(GUID_LOPART(guid2)) );
|
||||
if(!pet)
|
||||
if (!pet)
|
||||
{
|
||||
sLog.outError( "Pet %u not exist.", uint32(GUID_LOPART(guid1)) );
|
||||
return;
|
||||
}
|
||||
|
||||
if(pet != GetPlayer()->GetPet() && pet != GetPlayer()->GetCharm())
|
||||
if (pet != GetPlayer()->GetPet() && pet != GetPlayer()->GetCharm())
|
||||
{
|
||||
sLog.outError("HandlePetAction.Pet %u isn't pet of player %s.", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName() );
|
||||
return;
|
||||
}
|
||||
|
||||
if(!pet->isAlive())
|
||||
if (!pet->isAlive())
|
||||
return;
|
||||
|
||||
if(pet->GetTypeId() == TYPEID_PLAYER && !(flag == ACT_COMMAND && spellid == COMMAND_ATTACK))
|
||||
if (pet->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
// controller player can only do melee attack
|
||||
if (!(flag == ACT_COMMAND && spellid == COMMAND_ATTACK))
|
||||
return;
|
||||
}
|
||||
else if (((Creature*)pet)->isPet())
|
||||
{
|
||||
// pet can have action bar disabled
|
||||
if(((Pet*)pet)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS)
|
||||
return;
|
||||
}
|
||||
|
||||
CharmInfo *charmInfo = pet->GetCharmInfo();
|
||||
if(!charmInfo)
|
||||
|
|
@ -316,6 +326,10 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
|
|||
return;
|
||||
}
|
||||
|
||||
// pet can have action bar disabled
|
||||
if(pet->isPet() && ((Pet*)pet)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS)
|
||||
return;
|
||||
|
||||
CharmInfo *charmInfo = pet->GetCharmInfo();
|
||||
if(!charmInfo)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17095,6 +17095,18 @@ void Player::PetSpellInitialize()
|
|||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
void Player::SendPetGUIDs()
|
||||
{
|
||||
if(!GetPetGUID())
|
||||
return;
|
||||
|
||||
// Later this function might get modified for multiple guids
|
||||
WorldPacket data(SMSG_PET_GUIDS, 12);
|
||||
data << uint32(1); // count
|
||||
data << uint64(GetPetGUID());
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
void Player::PossessSpellInitialize()
|
||||
{
|
||||
Unit* charm = GetCharm();
|
||||
|
|
|
|||
|
|
@ -1565,6 +1565,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
}
|
||||
|
||||
void PetSpellInitialize();
|
||||
void SendPetGUIDs();
|
||||
void CharmSpellInitialize();
|
||||
void PossessSpellInitialize();
|
||||
void RemovePetActionBar();
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ const uint32 ItemQualityColors[MAX_ITEM_QUALITY] = {
|
|||
#define SPELL_ATTR_EX4_UNK5 0x00000020 // 5
|
||||
#define SPELL_ATTR_EX4_NOT_STEALABLE 0x00000040 // 6 although such auras might be dispellable, they cannot be stolen
|
||||
#define SPELL_ATTR_EX4_UNK7 0x00000080 // 7
|
||||
#define SPELL_ATTR_EX4_UNK8 0x00000100 // 8
|
||||
#define SPELL_ATTR_EX4_STACK_DOT_MODIFIER 0x00000100 // 8 no effect on non DoTs?
|
||||
#define SPELL_ATTR_EX4_UNK9 0x00000200 // 9
|
||||
#define SPELL_ATTR_EX4_SPELL_VS_EXTEND_COST 0x00000400 // 10 Rogue Shiv have this flag
|
||||
#define SPELL_ATTR_EX4_UNK11 0x00000800 // 11
|
||||
|
|
@ -445,7 +445,7 @@ const uint32 ItemQualityColors[MAX_ITEM_QUALITY] = {
|
|||
#define SPELL_ATTR_EX6_UNK26 0x04000000 // 26 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX6_UNK27 0x08000000 // 27 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX6_UNK28 0x10000000 // 28 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX6_UNK29 0x20000000 // 29 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX6_NO_DMG_PERCENT_MODS 0x20000000 // 29 do not apply damage percent mods (usually in cases where it has already been applied)
|
||||
#define SPELL_ATTR_EX6_UNK30 0x40000000 // 30 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX6_UNK31 0x80000000 // 31 not set in 3.0.3
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -372,12 +372,12 @@ class Spell
|
|||
|
||||
typedef std::list<Unit*> UnitList;
|
||||
void FillTargetMap();
|
||||
void SetTargetMap(uint32 effIndex,uint32 targetMode,UnitList& TagUnitMap);
|
||||
void SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList &targetUnitMap);
|
||||
|
||||
void FillAreaTargets( UnitList& TagUnitMap, float x, float y, float radius, SpellNotifyPushType pushType, SpellTargets spellTargets );
|
||||
void FillRaidOrPartyTargets( UnitList &TagUnitMap, Unit* member, Unit* center, float radius, bool raid, bool withPets, bool withcaster );
|
||||
void FillRaidOrPartyManaPriorityTargets( UnitList &TagUnitMap, Unit* member, Unit* center, float radius, uint32 count, bool raid, bool withPets, bool withcaster );
|
||||
void FillRaidOrPartyHealthPriorityTargets( UnitList &TagUnitMap, Unit* member, Unit* center, float radius, uint32 count, bool raid, bool withPets, bool withcaster );
|
||||
void FillAreaTargets(UnitList &targetUnitMap, float x, float y, float radius, SpellNotifyPushType pushType, SpellTargets spellTargets);
|
||||
void FillRaidOrPartyTargets(UnitList &targetUnitMap, Unit* member, Unit* center, float radius, bool raid, bool withPets, bool withcaster);
|
||||
void FillRaidOrPartyManaPriorityTargets(UnitList &targetUnitMap, Unit* member, Unit* center, float radius, uint32 count, bool raid, bool withPets, bool withcaster);
|
||||
void FillRaidOrPartyHealthPriorityTargets(UnitList &targetUnitMap, Unit* member, Unit* center, float radius, uint32 count, bool raid, bool withPets, bool withcaster);
|
||||
|
||||
template<typename T> WorldObject* FindCorpseUsing();
|
||||
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ enum AuraType
|
|||
SPELL_AURA_MOD_AOE_AVOIDANCE = 160,
|
||||
SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT = 161,
|
||||
SPELL_AURA_POWER_BURN_MANA = 162,
|
||||
SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE = 163,
|
||||
SPELL_AURA_MOD_CRIT_DAMAGE_BONUS = 163,
|
||||
SPELL_AURA_164 = 164,
|
||||
SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS = 165,
|
||||
SPELL_AURA_MOD_ATTACK_POWER_PCT = 166,
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
|||
&Aura::HandleNoImmediateEffect, //160 SPELL_AURA_MOD_AOE_AVOIDANCE implemented in Unit::MagicSpellHitResult
|
||||
&Aura::HandleNoImmediateEffect, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT implemented in Player::RegenerateAll and Player::RegenerateHealth
|
||||
&Aura::HandleAuraPowerBurn, //162 SPELL_AURA_POWER_BURN_MANA
|
||||
&Aura::HandleNoImmediateEffect, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE implememnted in Unit::CalculateMeleeDamage and Unit::SpellCriticalDamageBonus
|
||||
&Aura::HandleNoImmediateEffect, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS implemented in Unit::CalculateMeleeDamage and Unit::SpellCriticalDamageBonus
|
||||
&Aura::HandleUnused, //164 unused (3.0.8a-3.2.2a), only one test spell 10654
|
||||
&Aura::HandleNoImmediateEffect, //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
|
||||
&Aura::HandleAuraModAttackPowerPercent, //166 SPELL_AURA_MOD_ATTACK_POWER_PCT
|
||||
|
|
@ -2241,6 +2241,12 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
|||
if (Unit* caster = GetCaster())
|
||||
m_target->AddThreat(caster, 10.0f, false, GetSpellSchoolMask(GetSpellProto()), GetSpellProto());
|
||||
return;
|
||||
case 7057: // Haunting Spirits
|
||||
// expected to tick with 30 sec period (tick part see in Aura::PeriodicTick)
|
||||
m_isPeriodic = true;
|
||||
m_modifier.periodictime = 30*IN_MILISECONDS;
|
||||
m_periodicTimer = m_modifier.periodictime;
|
||||
return;
|
||||
case 13139: // net-o-matic
|
||||
// root to self part of (root_target->charge->root_self sequence
|
||||
if (Unit* caster = GetCaster())
|
||||
|
|
@ -2389,6 +2395,14 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
|||
|
||||
switch(GetId())
|
||||
{
|
||||
case 28169: // Mutating Injection
|
||||
{
|
||||
// Mutagen Explosion
|
||||
m_target->CastSpell(m_target, 28206, true, NULL, this);
|
||||
// Poison Cloud
|
||||
m_target->CastSpell(m_target, 28240, true, NULL, this);
|
||||
return;
|
||||
}
|
||||
case 36730: // Flame Strike
|
||||
{
|
||||
m_target->CastSpell(m_target, 36731, true, NULL, this);
|
||||
|
|
@ -2813,7 +2827,7 @@ void Aura::HandleAuraMounted(bool apply, bool Real)
|
|||
if (minfo)
|
||||
display_id = minfo->modelid;
|
||||
|
||||
m_target->Mount(display_id);
|
||||
m_target->Mount(display_id, m_spellProto->Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -7014,6 +7028,7 @@ void Aura::PeriodicTick()
|
|||
break;
|
||||
}
|
||||
// Here tick dummy auras
|
||||
case SPELL_AURA_DUMMY: // some spells have dummy aura
|
||||
case SPELL_AURA_PERIODIC_DUMMY:
|
||||
{
|
||||
PeriodicDummyTick();
|
||||
|
|
@ -7099,6 +7114,10 @@ void Aura::PeriodicDummyTick()
|
|||
// 7053 Forsaken Skill: Shadow
|
||||
return;
|
||||
}
|
||||
case 7057: // Haunting Spirits
|
||||
if (roll_chance_i(33))
|
||||
m_target->CastSpell(m_target,m_modifier.m_amount,true,NULL,this);
|
||||
return;
|
||||
// // Panda
|
||||
// case 19230: break;
|
||||
// // Gossip NPC Periodic - Talk
|
||||
|
|
@ -7253,6 +7272,21 @@ void Aura::PeriodicDummyTick()
|
|||
// case 50493: break;
|
||||
// // Love Rocket Barrage
|
||||
// case 50530: break;
|
||||
case 50789: // Summon iron dwarf (left or right)
|
||||
case 59860:
|
||||
m_target->CastSpell(m_target, roll_chance_i(50) ? 50790 : 50791, true, NULL, this);
|
||||
return;
|
||||
case 50792: // Summon iron trogg (left or right)
|
||||
case 59859:
|
||||
m_target->CastSpell(m_target, roll_chance_i(50) ? 50793 : 50794, true, NULL, this);
|
||||
return;
|
||||
case 50801: // Summon malformed ooze (left or right)
|
||||
case 59858:
|
||||
m_target->CastSpell(m_target, roll_chance_i(50) ? 50802 : 50803, true, NULL, this);
|
||||
return;
|
||||
case 50824: // Summon earthen dwarf
|
||||
m_target->CastSpell(m_target, roll_chance_i(50) ? 50825 : 50826, true, NULL, this);
|
||||
return;
|
||||
// Exist more after, need add later
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -749,44 +749,6 @@ void Spell::EffectDummy(uint32 i)
|
|||
((Creature*)unitTarget)->setDeathState(JUST_ALIVED);
|
||||
return;
|
||||
}
|
||||
case 12162: // Deep wounds
|
||||
case 12850: // (now good common check for this spells)
|
||||
case 12868:
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
float damage;
|
||||
// DW should benefit of attack power, damage percent mods etc.
|
||||
// TODO: check if using offhand damage is correct and if it should be divided by 2
|
||||
if (m_caster->haveOffhandWeapon() && m_caster->getAttackTimer(BASE_ATTACK) > m_caster->getAttackTimer(OFF_ATTACK))
|
||||
damage = (m_caster->GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE) + m_caster->GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE))/2;
|
||||
else
|
||||
damage = (m_caster->GetFloatValue(UNIT_FIELD_MINDAMAGE) + m_caster->GetFloatValue(UNIT_FIELD_MAXDAMAGE))/2;
|
||||
|
||||
switch (m_spellInfo->Id)
|
||||
{
|
||||
case 12162: damage *= 0.16f; break; // Rank 1
|
||||
case 12850: damage *= 0.32f; break; // Rank 2
|
||||
case 12868: damage *= 0.48f; break; // Rank 3
|
||||
default:
|
||||
sLog.outError("Spell::EffectDummy: Spell %u not handled in DW",m_spellInfo->Id);
|
||||
return;
|
||||
};
|
||||
|
||||
// get remaining damage of old Deep Wound aura
|
||||
Aura* deepWound = unitTarget->GetAura(12721, 0);
|
||||
if (deepWound)
|
||||
{
|
||||
int32 remainingTicks = deepWound->GetAuraDuration() / deepWound->GetModifier()->periodictime;
|
||||
damage += remainingTicks * deepWound->GetModifier()->m_amount;
|
||||
}
|
||||
|
||||
// 1 tick/sec * 6 sec = 6 ticks
|
||||
int32 deepWoundsDotBasePoints0 = int32(damage / 6);
|
||||
m_caster->CastCustomSpell(unitTarget, 12721, &deepWoundsDotBasePoints0, NULL, NULL, true, NULL);
|
||||
return;
|
||||
}
|
||||
case 13120: // net-o-matic
|
||||
{
|
||||
if (!unitTarget)
|
||||
|
|
@ -6477,7 +6439,11 @@ void Spell::EffectPlayerPull(uint32 i)
|
|||
if(!unitTarget)
|
||||
return;
|
||||
|
||||
unitTarget->KnockBackFrom(m_caster,float(damage ? damage : unitTarget->GetDistance2d(m_caster)),float(m_spellInfo->EffectMiscValue[i])/10);
|
||||
float dist = unitTarget->GetDistance2d(m_caster);
|
||||
if (damage && dist > damage)
|
||||
dist = damage;
|
||||
|
||||
unitTarget->KnockBackFrom(m_caster,-dist,float(m_spellInfo->EffectMiscValue[i])/10);
|
||||
}
|
||||
|
||||
void Spell::EffectDispelMechanic(uint32 i)
|
||||
|
|
|
|||
|
|
@ -1568,6 +1568,11 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons
|
|||
(spellId_2 == 33891 && spellId_1 == 34123))
|
||||
return false;
|
||||
|
||||
// Lifebloom and Wild Growth
|
||||
if (spellInfo_1->SpellIconID == 2101 && spellInfo_2->SpellIconID == 2864 ||
|
||||
spellInfo_2->SpellIconID == 2101 && spellInfo_1->SpellIconID == 2864 )
|
||||
return false;
|
||||
|
||||
// Innervate and Glyph of Innervate and some other spells
|
||||
if (spellInfo_1->SpellIconID == 62 && spellInfo_2->SpellIconID == 62)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -102,6 +102,19 @@ void TargetedMovementGenerator<Creature>::Initialize(Creature &owner)
|
|||
_setTargetLocation(owner);
|
||||
}
|
||||
|
||||
template<>
|
||||
void TargetedMovementGenerator<Player>::UpdateFinalDistance(float fDistance)
|
||||
{
|
||||
// nothing to do for Player
|
||||
}
|
||||
|
||||
template<>
|
||||
void TargetedMovementGenerator<Creature>::UpdateFinalDistance(float fDistance)
|
||||
{
|
||||
i_offset = fDistance;
|
||||
i_recalculateTravel = true;
|
||||
}
|
||||
|
||||
template<>
|
||||
void TargetedMovementGenerator<Player>::Initialize(Player &owner)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ class MANGOS_DLL_SPEC TargetedMovementGenerator
|
|||
}
|
||||
|
||||
void unitSpeedChanged() { i_recalculateTravel=true; }
|
||||
void UpdateFinalDistance(float fDistance);
|
||||
|
||||
private:
|
||||
|
||||
void _setTargetLocation(T &);
|
||||
|
|
|
|||
|
|
@ -216,17 +216,17 @@ void Unit::Update( uint32 p_time )
|
|||
// Check UNIT_STAT_MELEE_ATTACKING or UNIT_STAT_CHASE (without UNIT_STAT_FOLLOW in this case) so pets can reach far away
|
||||
// targets without stopping half way there and running off.
|
||||
// These flags are reset after target dies or another command is given.
|
||||
if( m_HostileRefManager.isEmpty() )
|
||||
if (m_HostileRefManager.isEmpty())
|
||||
{
|
||||
// m_CombatTimer set at aura start and it will be freeze until aura removing
|
||||
if ( m_CombatTimer <= p_time )
|
||||
ClearInCombat();
|
||||
if (m_CombatTimer <= p_time)
|
||||
CombatStop();
|
||||
else
|
||||
m_CombatTimer -= p_time;
|
||||
}
|
||||
}
|
||||
|
||||
if(uint32 base_att = getAttackTimer(BASE_ATTACK))
|
||||
if (uint32 base_att = getAttackTimer(BASE_ATTACK))
|
||||
{
|
||||
setAttackTimer(BASE_ATTACK, (p_time >= base_att ? 0 : base_att - p_time) );
|
||||
}
|
||||
|
|
@ -1292,10 +1292,9 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
|
|||
if(damageInfo->attackType == RANGED_ATTACK)
|
||||
mod += damageInfo->target->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE);
|
||||
else
|
||||
{
|
||||
mod += damageInfo->target->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE);
|
||||
mod += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE);
|
||||
}
|
||||
|
||||
mod += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, SPELL_SCHOOL_MASK_NORMAL);
|
||||
|
||||
uint32 crTypeMask = damageInfo->target->GetCreatureTypeMask();
|
||||
|
||||
|
|
@ -3608,16 +3607,26 @@ bool Unit::AddAura(Aura *Aur)
|
|||
{
|
||||
for(AuraMap::iterator i2 = m_Auras.lower_bound(spair); i2 != m_Auras.upper_bound(spair); ++i2)
|
||||
{
|
||||
if(i2->second->GetCasterGUID()==Aur->GetCasterGUID())
|
||||
Aura* aur2 = i2->second;
|
||||
if(aur2->GetCasterGUID()==Aur->GetCasterGUID())
|
||||
{
|
||||
// Aura can stack on self -> Stack it;
|
||||
if(aurSpellInfo->StackAmount)
|
||||
{
|
||||
// can be created with >1 stack by some spell mods
|
||||
i2->second->modStackAmount(Aur->GetStackAmount());
|
||||
aur2->modStackAmount(Aur->GetStackAmount());
|
||||
delete Aur;
|
||||
return false;
|
||||
}
|
||||
// Carry over removed Aura's remaining damage if Aura still has ticks remaining
|
||||
else if (aur2->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_STACK_DOT_MODIFIER && aurName == SPELL_AURA_PERIODIC_DAMAGE && aur2->GetAuraDuration() > 0)
|
||||
{
|
||||
int32 remainingTicks = 1 + (aur2->GetAuraDuration() / aur2->GetModifier()->periodictime);
|
||||
int32 remainingDamage = aur2->GetModifier()->m_amount * remainingTicks;
|
||||
|
||||
int32 maxTicks = Aur->GetAuraMaxDuration() / Aur->GetModifier()->periodictime;
|
||||
Aur->GetModifier()->m_amount += int32(remainingDamage / maxTicks);
|
||||
}
|
||||
// can be only single (this check done at _each_ aura add
|
||||
RemoveAura(i2,AURA_REMOVE_BY_STACK);
|
||||
break;
|
||||
|
|
@ -5833,6 +5842,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
|||
// Wrath crit
|
||||
if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000001))
|
||||
{
|
||||
if (HasAura(48517))
|
||||
return false;
|
||||
if (!roll_chance_i(60))
|
||||
return false;
|
||||
triggered_spell_id = 48518;
|
||||
|
|
@ -5842,6 +5853,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
|||
// Starfire crit
|
||||
if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000004))
|
||||
{
|
||||
if (HasAura(48518))
|
||||
return false;
|
||||
triggered_spell_id = 48517;
|
||||
target = this;
|
||||
break;
|
||||
|
|
@ -7007,6 +7020,34 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
}
|
||||
break;
|
||||
case SPELLFAMILY_WARRIOR:
|
||||
// Deep Wounds (replace triggered spells to directly apply DoT), dot spell have finilyflags
|
||||
if (auraSpellInfo->SpellFamilyFlags == UI64LIT(0x0) && auraSpellInfo->SpellIconID == 243)
|
||||
{
|
||||
float weaponDamage;
|
||||
// DW should benefit of attack power, damage percent mods etc.
|
||||
// TODO: check if using offhand damage is correct and if it should be divided by 2
|
||||
if (haveOffhandWeapon() && getAttackTimer(BASE_ATTACK) > getAttackTimer(OFF_ATTACK))
|
||||
weaponDamage = (GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE) + GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE))/2;
|
||||
else
|
||||
weaponDamage = (GetFloatValue(UNIT_FIELD_MINDAMAGE) + GetFloatValue(UNIT_FIELD_MAXDAMAGE))/2;
|
||||
|
||||
switch (auraSpellInfo->Id)
|
||||
{
|
||||
case 12834: basepoints[0] = int32(weaponDamage * 16 / 100); break;
|
||||
case 12849: basepoints[0] = int32(weaponDamage * 32 / 100); break;
|
||||
case 12867: basepoints[0] = int32(weaponDamage * 48 / 100); break;
|
||||
// Impossible case
|
||||
default:
|
||||
sLog.outError("Unit::HandleProcTriggerSpell: DW unknown spell rank %u",auraSpellInfo->Id);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 1 tick/sec * 6 sec = 6 ticks
|
||||
basepoints[0] /= 6;
|
||||
|
||||
trigger_spell_id = 12721;
|
||||
break;
|
||||
}
|
||||
if (auraSpellInfo->Id == 50421) // Scent of Blood
|
||||
trigger_spell_id = 50422;
|
||||
break;
|
||||
|
|
@ -8346,6 +8387,9 @@ void Unit::SetPet(Pet* pet)
|
|||
{
|
||||
SetPetGUID(pet ? pet->GetGUID() : 0);
|
||||
|
||||
if(pet && GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)this)->SendPetGUIDs();
|
||||
|
||||
// FIXME: hack, speed must be set only at follow
|
||||
if(pet && GetTypeId()==TYPEID_PLAYER)
|
||||
for(int i = 0; i < MAX_MOVE_TYPE; ++i)
|
||||
|
|
@ -8520,16 +8564,19 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
|
|||
if( GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet() )
|
||||
DoneTotalMod *= ((Creature*)this)->GetSpellDamageMod(((Creature*)this)->GetCreatureInfo()->rank);
|
||||
|
||||
if (!(spellProto->AttributesEx6 & SPELL_ATTR_EX6_NO_DMG_PERCENT_MODS))
|
||||
{
|
||||
AuraList const& mModDamagePercentDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
|
||||
for(AuraList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
|
||||
{
|
||||
if (((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto)) &&
|
||||
if( ((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto)) &&
|
||||
(*i)->GetSpellProto()->EquippedItemClass == -1 &&
|
||||
// -1 == any item class (not wand then)
|
||||
(*i)->GetSpellProto()->EquippedItemInventoryTypeMask == 0)
|
||||
(*i)->GetSpellProto()->EquippedItemInventoryTypeMask == 0 )
|
||||
// 0 == any inventory type (not wand then)
|
||||
{
|
||||
DoneTotalMod *= ((*i)->GetModifier()->m_amount + 100.0f) / 100.0f;
|
||||
DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -9034,17 +9081,6 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
|
|||
break;
|
||||
}
|
||||
case SPELL_DAMAGE_CLASS_MELEE:
|
||||
{
|
||||
// Judgement of Command proc always crits on stunned target
|
||||
if(spellProto->SpellFamilyName == SPELLFAMILY_PALADIN)
|
||||
{
|
||||
if(spellProto->SpellFamilyFlags & 0x0000000000800000LL && spellProto->SpellIconID == 561)
|
||||
{
|
||||
if(pVictim->hasUnitState(UNIT_STAT_STUNNED))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
case SPELL_DAMAGE_CLASS_RANGED:
|
||||
{
|
||||
if (pVictim)
|
||||
|
|
@ -9095,14 +9131,13 @@ uint32 Unit::SpellCriticalDamageBonus(SpellEntry const *spellProto, uint32 damag
|
|||
if(GetWeaponAttackType(spellProto) == RANGED_ATTACK)
|
||||
critPctDamageMod += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE);
|
||||
else
|
||||
{
|
||||
critPctDamageMod += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE);
|
||||
critPctDamageMod += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE);
|
||||
}
|
||||
}
|
||||
else
|
||||
critPctDamageMod += pVictim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_DAMAGE,GetSpellSchoolMask(spellProto));
|
||||
|
||||
critPctDamageMod += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, GetSpellSchoolMask(spellProto));
|
||||
|
||||
uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
|
||||
critPctDamageMod += GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, creatureTypeMask);
|
||||
|
||||
|
|
@ -9839,9 +9874,9 @@ float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM) const
|
|||
return WeaponSpeed * PPM / 600.0f; // result is chance in percents (probability = Speed_in_sec * (PPM / 60))
|
||||
}
|
||||
|
||||
void Unit::Mount(uint32 mount)
|
||||
void Unit::Mount(uint32 mount, uint32 spellId)
|
||||
{
|
||||
if(!mount)
|
||||
if (!mount)
|
||||
return;
|
||||
|
||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNTING);
|
||||
|
|
@ -9850,9 +9885,27 @@ void Unit::Mount(uint32 mount)
|
|||
|
||||
SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT );
|
||||
|
||||
// unsummon pet
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
// Called by Taxi system / GM command
|
||||
if (!spellId)
|
||||
((Player*)this)->UnsummonPetTemporaryIfAny();
|
||||
// Called by mount aura
|
||||
else if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId))
|
||||
{
|
||||
// Flying case (Unsummon any pet)
|
||||
if (IsSpellHaveAura(spellInfo, SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED))
|
||||
((Player*)this)->UnsummonPetTemporaryIfAny();
|
||||
// Normal case (Unsummon only permanent pet)
|
||||
else if (Pet* pet = GetPet())
|
||||
{
|
||||
if (pet->IsPermanentPetFor((Player*)this))
|
||||
((Player*)this)->UnsummonPetTemporaryIfAny();
|
||||
else
|
||||
pet->ApplyModeFlags(PET_MODE_DISABLE_ACTIONS,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::Unmount()
|
||||
|
|
@ -9869,7 +9922,12 @@ void Unit::Unmount()
|
|||
// this prevents adding a pet to a not created map which would otherwise cause a crash
|
||||
// (it could probably happen when logging in after a previous crash)
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if(Pet* pet = GetPet())
|
||||
pet->ApplyModeFlags(PET_MODE_DISABLE_ACTIONS,false);
|
||||
else
|
||||
((Player*)this)->ResummonPetTemporaryUnSummonedIfAny();
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::SetInCombatWith(Unit* enemy)
|
||||
|
|
|
|||
|
|
@ -1026,7 +1026,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
|||
|
||||
bool IsMounted() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT ); }
|
||||
uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); }
|
||||
void Mount(uint32 mount);
|
||||
void Mount(uint32 mount, uint32 spellId = 0);
|
||||
void Unmount();
|
||||
|
||||
uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "9055"
|
||||
#define REVISION_NR "9086"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef __REVISION_SQL_H__
|
||||
#define __REVISION_SQL_H__
|
||||
#define REVISION_DB_CHARACTERS "required_8874_01_characters_character_skills"
|
||||
#define REVISION_DB_MANGOS "required_9045_02_mangos_spell_chain"
|
||||
#define REVISION_DB_MANGOS "required_9074_01_mangos_command"
|
||||
#define REVISION_DB_REALMD "required_9010_01_realmd_realmlist"
|
||||
#endif // __REVISION_SQL_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue