Core/Creatures: Implemented extra flag to use offhand attacks
Port From (https://github.com/TrinityCore/TrinityCore/commit/2a51edc5bcebe40c114e37ef3b24da6c8f095892)
This commit is contained in:
@@ -209,9 +209,9 @@ namespace Framework.Constants
|
|||||||
NoTaunt = 0x100, // Creature Is Immune To Taunt Auras And Effect Attack Me
|
NoTaunt = 0x100, // Creature Is Immune To Taunt Auras And Effect Attack Me
|
||||||
NoMoveFlagsUpdate = 0x200, // Creature won't update movement flags
|
NoMoveFlagsUpdate = 0x200, // Creature won't update movement flags
|
||||||
GhostVisibility = 0x400, // creature will be only visible for dead players
|
GhostVisibility = 0x400, // creature will be only visible for dead players
|
||||||
Unused11 = 0x00000800,
|
UseOffhandAttack = 0x800, // creature will use offhand attacks
|
||||||
Unused12 = 0x00001000,
|
Unused12 = 0x1000,
|
||||||
Unused13 = 0x00002000,
|
Unused13 = 0x2000,
|
||||||
Worldevent = 0x4000, // Custom Flag For World Event Creatures (Left Room For Merging)
|
Worldevent = 0x4000, // Custom Flag For World Event Creatures (Left Room For Merging)
|
||||||
Guard = 0x8000, // Creature Is Guard
|
Guard = 0x8000, // Creature Is Guard
|
||||||
Unused16 = 0x00010000,
|
Unused16 = 0x00010000,
|
||||||
@@ -220,21 +220,21 @@ namespace Framework.Constants
|
|||||||
TauntDiminish = 0x80000, // Taunt Is A Subject To Diminishing Returns On This Creautre
|
TauntDiminish = 0x80000, // Taunt Is A Subject To Diminishing Returns On This Creautre
|
||||||
AllDiminish = 0x100000, // Creature Is Subject To All Diminishing Returns As Player Are
|
AllDiminish = 0x100000, // Creature Is Subject To All Diminishing Returns As Player Are
|
||||||
NoPlayerDamageReq = 0x200000, // creature does not need to take player damage for kill credit
|
NoPlayerDamageReq = 0x200000, // creature does not need to take player damage for kill credit
|
||||||
Unused22 = 0x00400000,
|
Unused22 = 0x400000,
|
||||||
Unused23 = 0x00800000,
|
Unused23 = 0x800000,
|
||||||
Unused24 = 0x01000000,
|
Unused24 = 0x1000000,
|
||||||
Unused25 = 0x02000000,
|
Unused25 = 0x2000000,
|
||||||
Unused26 = 0x04000000,
|
Unused26 = 0x4000000,
|
||||||
Unused27 = 0x08000000,
|
Unused27 = 0x8000000,
|
||||||
DungeonBoss = 0x10000000, // Creature Is A Dungeon Boss (Set Dynamically, Do Not Add In Db)
|
DungeonBoss = 0x10000000, // Creature Is A Dungeon Boss (Set Dynamically, Do Not Add In Db)
|
||||||
IgnorePathfinding = 0x20000000, // creature ignore pathfinding
|
IgnorePathfinding = 0x20000000, // creature ignore pathfinding
|
||||||
ImmunityKnockback = 0x40000000, // creature is immune to knockback effects
|
ImmunityKnockback = 0x40000000, // creature is immune to knockback effects
|
||||||
Unused31 = 0x80000000,
|
Unused31 = 0x80000000,
|
||||||
|
|
||||||
// Masks
|
// Masks
|
||||||
AllUnused = (Unused11 | Unused12 | Unused13 | Unused16 | Unused22 | Unused23 | Unused24 | Unused25 | Unused26 | Unused27 | Unused31),
|
AllUnused = (Unused12 | Unused13 | Unused16 | Unused22 | Unused23 | Unused24 | Unused25 | Unused26 | Unused27 | Unused31),
|
||||||
|
|
||||||
DBAllowed = (0xFFFFFFFF & ~(AllUnused | CreatureFlagsExtra.DungeonBoss))
|
DBAllowed = (0xFFFFFFFF & ~(AllUnused | DungeonBoss))
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum CreatureType
|
public enum CreatureType
|
||||||
|
|||||||
@@ -234,9 +234,9 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get difficulty 1 mode entry
|
// get difficulty 1 mode entry
|
||||||
CreatureTemplate cinfo = null;
|
CreatureTemplate cInfo = null;
|
||||||
DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(GetMap().GetDifficultyID());
|
DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(GetMap().GetDifficultyID());
|
||||||
while (cinfo == null && difficultyEntry != null)
|
while (cInfo == null && difficultyEntry != null)
|
||||||
{
|
{
|
||||||
int idx = CreatureTemplate.DifficultyIDToDifficultyEntryIndex(difficultyEntry.Id);
|
int idx = CreatureTemplate.DifficultyIDToDifficultyEntryIndex(difficultyEntry.Id);
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
@@ -244,7 +244,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
if (normalInfo.DifficultyEntry[idx] != 0)
|
if (normalInfo.DifficultyEntry[idx] != 0)
|
||||||
{
|
{
|
||||||
cinfo = Global.ObjectMgr.GetCreatureTemplate(normalInfo.DifficultyEntry[idx]);
|
cInfo = Global.ObjectMgr.GetCreatureTemplate(normalInfo.DifficultyEntry[idx]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,29 +254,29 @@ namespace Game.Entities
|
|||||||
difficultyEntry = CliDB.DifficultyStorage.LookupByKey(difficultyEntry.FallbackDifficultyID);
|
difficultyEntry = CliDB.DifficultyStorage.LookupByKey(difficultyEntry.FallbackDifficultyID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cinfo == null)
|
if (cInfo == null)
|
||||||
cinfo = normalInfo;
|
cInfo = normalInfo;
|
||||||
|
|
||||||
// Initialize loot duplicate count depending on raid difficulty
|
// Initialize loot duplicate count depending on raid difficulty
|
||||||
if (GetMap().Is25ManRaid())
|
if (GetMap().Is25ManRaid())
|
||||||
loot.maxDuplicates = 3;
|
loot.maxDuplicates = 3;
|
||||||
|
|
||||||
SetEntry(entry); // normal entry always
|
SetEntry(entry); // normal entry always
|
||||||
m_creatureInfo = cinfo; // map mode related always
|
m_creatureInfo = cInfo; // map mode related always
|
||||||
|
|
||||||
// equal to player Race field, but creature does not have race
|
// equal to player Race field, but creature does not have race
|
||||||
SetRace(0);
|
SetRace(0);
|
||||||
SetClass((Class)cinfo.UnitClass);
|
SetClass((Class)cInfo.UnitClass);
|
||||||
|
|
||||||
// Cancel load if no model defined
|
// Cancel load if no model defined
|
||||||
if (cinfo.GetFirstValidModel() == null)
|
if (cInfo.GetFirstValidModel() == null)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) has no model defined in table `creature_template`, can't load. ", entry);
|
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) has no model defined in table `creature_template`, can't load. ", entry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreatureModel model = ObjectManager.ChooseDisplayId(cinfo, data);
|
CreatureModel model = ObjectManager.ChooseDisplayId(cInfo, data);
|
||||||
CreatureModelInfo minfo = Global.ObjectMgr.GetCreatureModelRandomGender(ref model, cinfo);
|
CreatureModelInfo minfo = Global.ObjectMgr.GetCreatureModelRandomGender(ref model, cInfo);
|
||||||
if (minfo == null) // Cancel load if no model defined
|
if (minfo == null) // Cancel load if no model defined
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) has invalid model {1} defined in table `creature_template`, can't load.", entry, model.CreatureDisplayID);
|
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) has invalid model {1} defined in table `creature_template`, can't load.", entry, model.CreatureDisplayID);
|
||||||
@@ -289,9 +289,9 @@ namespace Game.Entities
|
|||||||
// Load creature equipment
|
// Load creature equipment
|
||||||
if (data == null || data.equipmentId == 0)
|
if (data == null || data.equipmentId == 0)
|
||||||
LoadEquipment(); // use default equipment (if available)
|
LoadEquipment(); // use default equipment (if available)
|
||||||
else if(data != null && data.equipmentId != 0) // override, 0 means no equipment
|
else
|
||||||
{
|
{
|
||||||
m_originalEquipmentId = (sbyte)data.equipmentId;
|
m_originalEquipmentId = data.equipmentId;
|
||||||
LoadEquipment(data.equipmentId);
|
LoadEquipment(data.equipmentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,17 +304,19 @@ namespace Game.Entities
|
|||||||
SetModHasteRegen(1.0f);
|
SetModHasteRegen(1.0f);
|
||||||
SetModTimeRate(1.0f);
|
SetModTimeRate(1.0f);
|
||||||
|
|
||||||
SetSpeedRate(UnitMoveType.Walk, cinfo.SpeedWalk);
|
SetSpeedRate(UnitMoveType.Walk, cInfo.SpeedWalk);
|
||||||
SetSpeedRate(UnitMoveType.Run, cinfo.SpeedRun);
|
SetSpeedRate(UnitMoveType.Run, cInfo.SpeedRun);
|
||||||
SetSpeedRate(UnitMoveType.Swim, 1.0f); // using 1.0 rate
|
SetSpeedRate(UnitMoveType.Swim, 1.0f); // using 1.0 rate
|
||||||
SetSpeedRate(UnitMoveType.Flight, 1.0f); // using 1.0 rate
|
SetSpeedRate(UnitMoveType.Flight, 1.0f); // using 1.0 rate
|
||||||
|
|
||||||
SetObjectScale(cinfo.Scale);
|
SetObjectScale(cInfo.Scale);
|
||||||
|
|
||||||
SetHoverHeight(cinfo.HoverHeight);
|
SetHoverHeight(cInfo.HoverHeight);
|
||||||
|
|
||||||
|
SetCanDualWield(cInfo.FlagsExtra.HasAnyFlag(CreatureFlagsExtra.UseOffhandAttack));
|
||||||
|
|
||||||
// checked at loading
|
// checked at loading
|
||||||
DefaultMovementType = (MovementGeneratorType)(data != null ? data.movementType : cinfo.MovementType);
|
DefaultMovementType = (MovementGeneratorType)(data != null ? data.movementType : cInfo.MovementType);
|
||||||
if (m_respawnradius == 0 && DefaultMovementType == MovementGeneratorType.Random)
|
if (m_respawnradius == 0 && DefaultMovementType == MovementGeneratorType.Random)
|
||||||
DefaultMovementType = MovementGeneratorType.Idle;
|
DefaultMovementType = MovementGeneratorType.Idle;
|
||||||
|
|
||||||
@@ -362,6 +364,8 @@ namespace Game.Entities
|
|||||||
|
|
||||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.StateAnimID), Global.DB2Mgr.GetEmptyAnimStateID());
|
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.StateAnimID), Global.DB2Mgr.GetEmptyAnimStateID());
|
||||||
|
|
||||||
|
SetCanDualWield(cInfo.FlagsExtra.HasAnyFlag(CreatureFlagsExtra.UseOffhandAttack));
|
||||||
|
|
||||||
SetBaseAttackTime(WeaponAttackType.BaseAttack, cInfo.BaseAttackTime);
|
SetBaseAttackTime(WeaponAttackType.BaseAttack, cInfo.BaseAttackTime);
|
||||||
SetBaseAttackTime(WeaponAttackType.OffAttack, cInfo.BaseAttackTime);
|
SetBaseAttackTime(WeaponAttackType.OffAttack, cInfo.BaseAttackTime);
|
||||||
SetBaseAttackTime(WeaponAttackType.RangedAttack, cInfo.RangeAttackTime);
|
SetBaseAttackTime(WeaponAttackType.RangedAttack, cInfo.RangeAttackTime);
|
||||||
|
|||||||
@@ -467,9 +467,9 @@ namespace Game.Entities
|
|||||||
SetEmoteState(Emote.OneshotNone);
|
SetEmoteState(Emote.OneshotNone);
|
||||||
}
|
}
|
||||||
|
|
||||||
// delay offhand weapon attack to next attack time
|
// delay offhand weapon attack by 50% of the base attack time
|
||||||
if (HaveOffhandWeapon() && GetTypeId() != TypeId.Player)
|
if (HaveOffhandWeapon() && GetTypeId() != TypeId.Player)
|
||||||
ResetAttackTimer(WeaponAttackType.OffAttack);
|
SetAttackTimer(WeaponAttackType.OffAttack, Math.Max(GetAttackTimer(WeaponAttackType.OffAttack), GetAttackTimer(WeaponAttackType.BaseAttack) + MathFunctions.CalculatePct(GetBaseAttackTime(WeaponAttackType.BaseAttack), 50)));
|
||||||
|
|
||||||
if (meleeAttack)
|
if (meleeAttack)
|
||||||
SendMeleeAttackStart(victim);
|
SendMeleeAttackStart(victim);
|
||||||
|
|||||||
Reference in New Issue
Block a user