Core/Spells: Implemented mounts
This commit is contained in:
1 parent
b9e64f9624
commit
0df5e19bd6
9 files changed
+128
-15
No files matched your search
@@ -450,6 +450,12 @@ enum ItemLimitCategoryMode
|
||||
ITEM_LIMIT_CATEGORY_MODE_EQUIP = 1, // limit applied to amount equipped items (including used gems)
|
||||
};
|
||||
|
||||
enum MountFlags
|
||||
{
|
||||
MOUNT_FLAG_CAN_PITCH = 0x4, // client checks MOVEMENTFLAG2_FULL_SPEED_PITCHING
|
||||
MOUNT_FLAG_CAN_SWIM = 0x8, // client checks MOVEMENTFLAG_SWIMMING
|
||||
};
|
||||
|
||||
enum TotemCategoryType
|
||||
{
|
||||
TOTEM_CATEGORY_TYPE_KNIFE = 1,
|
||||
|
||||
@@ -140,9 +140,11 @@ DBCStorage <MapDifficultyEntry> sMapDifficultyStore(MapDifficultyEntryfmt); // o
|
||||
MapDifficultyMap sMapDifficultyMap;
|
||||
|
||||
DBCStorage <MovieEntry> sMovieStore(MovieEntryfmt);
|
||||
DBCStorage <MountCapabilityEntry> sMountCapabilityStore(MountCapabilityfmt);
|
||||
DBCStorage <MountTypeEntry> sMountTypeStore(MountTypefmt);
|
||||
|
||||
DBCStorage <NameGenEntry> sNameGenStore(NameGenfmt);
|
||||
GenNameVectorArraysMap sGenNameVectoArraysMap;
|
||||
NameGenVectorArraysMap sGenNameVectoArraysMap;
|
||||
|
||||
DBCStorage <OverrideSpellDataEntry> sOverrideSpellDataStore(OverrideSpellDatafmt);
|
||||
|
||||
@@ -418,6 +420,9 @@ void LoadDBCStores(const std::string& dataPath)
|
||||
sMapDifficultyMap[MAKE_PAIR32(entry->MapId, entry->Difficulty)] = MapDifficulty(entry->resetTime, entry->maxPlayers, entry->areaTriggerText[0] > 0);
|
||||
sMapDifficultyStore.Clear();
|
||||
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sMountCapabilityStore, dbcPath, "MountCapability.dbc");//14545
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sMountTypeStore, dbcPath, "MountType.dbc");//14545
|
||||
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sNameGenStore, dbcPath, "NameGen.dbc");//14545
|
||||
for (uint32 i = 0; i < sNameGenStore.GetNumRows(); ++i)
|
||||
if (NameGenEntry const* entry = sNameGenStore.LookupEntry(i))
|
||||
|
||||
@@ -140,6 +140,8 @@ extern DBCStorage <LFGDungeonEntry> sLFGDungeonStore;
|
||||
extern DBCStorage <LockEntry> sLockStore;
|
||||
extern DBCStorage <MailTemplateEntry> sMailTemplateStore;
|
||||
extern DBCStorage <MapEntry> sMapStore;
|
||||
extern DBCStorage <MountCapabilityEntry> sMountCapabilityStore;
|
||||
extern DBCStorage <MountTypeEntry> sMountTypeStore;
|
||||
extern DBCStorage <NameGenEntry> sNameGenStore;
|
||||
extern DBCStorage <PhaseEntry> sPhaseStore;
|
||||
//extern DBCStorage <MapDifficultyEntry> sMapDifficultyStore; -- use GetMapDifficultyData insteed
|
||||
|
||||
@@ -1396,6 +1396,26 @@ struct MapDifficultyEntry
|
||||
//char* difficultyString; // 6 m_difficultystring
|
||||
};
|
||||
|
||||
struct MountCapabilityEntry
|
||||
{
|
||||
uint32 Id;
|
||||
uint32 Flags;
|
||||
uint32 RequiredRidingSkill;
|
||||
uint32 RequiredArea;
|
||||
uint32 RequiredAura;
|
||||
uint32 RequiredSpell;
|
||||
uint32 SpeedModSpell;
|
||||
int32 RequiredMap;
|
||||
};
|
||||
|
||||
#define MAX_MOUNT_CAPABILITIES 24
|
||||
|
||||
struct MountTypeEntry
|
||||
{
|
||||
uint32 Id;
|
||||
uint32 MountCapability[MAX_MOUNT_CAPABILITIES];
|
||||
};
|
||||
|
||||
struct MovieEntry
|
||||
{
|
||||
uint32 Id; // 0 index
|
||||
@@ -2257,7 +2277,7 @@ struct VectorArray
|
||||
std::vector<std::string> stringVectorArray[2];
|
||||
};
|
||||
|
||||
typedef std::map<uint32, VectorArray> GenNameVectorArraysMap;
|
||||
typedef std::map<uint32, VectorArray> NameGenVectorArraysMap;
|
||||
|
||||
// Structures not used for casting to loaded DBC data and not required then packing
|
||||
struct MapDifficulty
|
||||
|
||||
@@ -95,6 +95,8 @@ const char MailTemplateEntryfmt[]="nxs";
|
||||
const char MapEntryfmt[]="nxixxxsixxixiffxiixx";
|
||||
const char MapDifficultyEntryfmt[]="diisiix";
|
||||
const char MovieEntryfmt[]="nxxx";
|
||||
const char MountCapabilityfmt[]="niiiiiii";
|
||||
const char MountTypefmt[]="niiiiiiiiiiiiiiiiiiiiiiii";
|
||||
const char NameGenfmt[] = "dsii";
|
||||
const char OverrideSpellDatafmt[]="niiiiiiiiiixx";
|
||||
const char QuestSortEntryfmt[]="nx";
|
||||
|
||||
@@ -12018,6 +12018,64 @@ void Unit::Dismount()
|
||||
}
|
||||
}
|
||||
|
||||
MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const
|
||||
{
|
||||
if (!mountType)
|
||||
return NULL;
|
||||
|
||||
MountTypeEntry const* mountTypeEntry = sMountTypeStore.LookupEntry(mountType);
|
||||
if (!mountTypeEntry)
|
||||
return NULL;
|
||||
|
||||
uint32 zoneId, areaId;
|
||||
GetZoneAndAreaId(zoneId, areaId);
|
||||
uint32 ridingSkill = 5000;
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
ridingSkill = ToPlayer()->GetSkillValue(SKILL_RIDING);
|
||||
|
||||
for (uint32 i = MAX_MOUNT_CAPABILITIES; i > 0; --i)
|
||||
{
|
||||
MountCapabilityEntry const* mountCapability = sMountCapabilityStore.LookupEntry(mountTypeEntry->MountCapability[i - 1]);
|
||||
if (!mountCapability)
|
||||
continue;
|
||||
|
||||
if (ridingSkill < mountCapability->RequiredRidingSkill)
|
||||
continue;
|
||||
|
||||
if (HasExtraUnitMovementFlag(MOVEMENTFLAG2_FULL_SPEED_PITCHING))
|
||||
{
|
||||
if (!(mountCapability->Flags & MOUNT_FLAG_CAN_PITCH))
|
||||
continue;
|
||||
}
|
||||
else if (HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING))
|
||||
{
|
||||
if (!(mountCapability->Flags & MOUNT_FLAG_CAN_SWIM))
|
||||
continue;
|
||||
}
|
||||
else if (!(mountCapability->Flags & 0x1)) // unknown flags, checked in 4.2.2 14545 client
|
||||
{
|
||||
if (!(mountCapability->Flags & 0x2))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mountCapability->RequiredMap != -1 && GetMapId() != mountCapability->RequiredMap)
|
||||
continue;
|
||||
|
||||
if (mountCapability->RequiredArea && (mountCapability->RequiredArea != zoneId && mountCapability->RequiredArea != areaId))
|
||||
continue;
|
||||
|
||||
if (mountCapability->RequiredAura && !HasAura(mountCapability->RequiredAura))
|
||||
continue;
|
||||
|
||||
if (mountCapability->RequiredSpell && (GetTypeId() != TYPEID_PLAYER || !ToPlayer()->HasSpell(mountCapability->RequiredSpell)))
|
||||
continue;
|
||||
|
||||
return mountCapability;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Unit::SetInCombatWith(Unit* enemy)
|
||||
{
|
||||
Unit* eOwner = enemy->GetCharmerOrOwnerOrSelf();
|
||||
@@ -16973,7 +17031,7 @@ void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ)
|
||||
WorldPacket data(SMSG_MOVE_KNOCK_BACK, (1+8+4+4+4+4+4));
|
||||
uint64 guid = GetGUID();
|
||||
uint8* bytes = (uint8*)&guid;
|
||||
|
||||
|
||||
data.WriteByteMask(bytes[5]);
|
||||
data.WriteByteMask(bytes[2]);
|
||||
data.WriteByteMask(bytes[6]);
|
||||
@@ -17313,7 +17371,7 @@ void Unit::JumpTo(float speedXY, float speedZ, bool forward)
|
||||
WorldPacket data(SMSG_MOVE_KNOCK_BACK, (1+8+4+4+4+4+4));
|
||||
uint64 guid = GetGUID();
|
||||
uint8* bytes = (uint8*)&guid;
|
||||
|
||||
|
||||
data.WriteByteMask(bytes[5]);
|
||||
data.WriteByteMask(bytes[2]);
|
||||
data.WriteByteMask(bytes[6]);
|
||||
|
||||
@@ -1444,6 +1444,7 @@ class Unit : public WorldObject
|
||||
uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); }
|
||||
void Mount(uint32 mount, uint32 vehicleId = 0, uint32 creatureEntry = 0);
|
||||
void Dismount();
|
||||
MountCapabilityEntry const* GetMountCapability(uint32 mountType) const;
|
||||
|
||||
uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
|
||||
void DealDamageMods(Unit* pVictim, uint32 &damage, uint32* absorb);
|
||||
|
||||
@@ -747,6 +747,10 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
|
||||
if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID && GetSpellInfo()->SpellFamilyFlags[2] & 0x00000008)
|
||||
amount = GetBase()->GetUnitOwner()->GetShapeshiftForm() == FORM_CAT ? amount : 0;
|
||||
break;
|
||||
case SPELL_AURA_MOUNTED:
|
||||
if (MountCapabilityEntry const* mountCapability = GetBase()->GetUnitOwner()->GetMountCapability(uint32(GetMiscValueB())))
|
||||
amount = mountCapability->Id;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2808,7 +2812,7 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo
|
||||
if (target->GetTypeId() == TYPEID_PLAYER)
|
||||
team = target->ToPlayer()->GetTeam();
|
||||
|
||||
uint32 displayID = sObjectMgr->ChooseDisplayId(team, ci);
|
||||
uint32 displayID = ObjectMgr::ChooseDisplayId(team, ci);
|
||||
sObjectMgr->GetCreatureModelRandomGender(&displayID);
|
||||
|
||||
//some spell has one aura of mount and one of vehicle
|
||||
@@ -2818,6 +2822,10 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo
|
||||
displayID = 0;
|
||||
|
||||
target->Mount(displayID, ci->VehicleId, GetMiscValue());
|
||||
|
||||
// cast speed aura
|
||||
if (MountCapabilityEntry const* mountCapability = target->GetMountCapability(uint32(GetMiscValueB())))
|
||||
target->CastSpell(target, mountCapability->SpeedModSpell, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2826,7 +2834,13 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo
|
||||
// need to remove ALL arura related to mounts, this will stop client crash with broom stick
|
||||
// and never endless flying after using Headless Horseman's Mount
|
||||
if (mode & AURA_EFFECT_HANDLE_REAL)
|
||||
{
|
||||
target->RemoveAurasByType(SPELL_AURA_MOUNTED);
|
||||
|
||||
// remove speed aura
|
||||
if (MountCapabilityEntry const* mountCapability = target->GetMountCapability(uint32(GetMiscValueB())))
|
||||
target->RemoveAurasDueToSpell(mountCapability->SpeedModSpell, target->GetGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4781,7 +4795,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
|
||||
if (Aura* newAura = target->AddAura(71564, target))
|
||||
newAura->SetStackAmount(newAura->GetSpellInfo()->StackAmount);
|
||||
break;
|
||||
case 59628: // Tricks of the Trade
|
||||
case 59628: // Tricks of the Trade
|
||||
if (caster && caster->GetMisdirectionTarget())
|
||||
target->SetReducedThreatPercent(100, caster->GetMisdirectionTarget()->GetGUID());
|
||||
break;
|
||||
@@ -4944,7 +4958,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
|
||||
target->SetReducedThreatPercent(0,0);
|
||||
else
|
||||
target->SetReducedThreatPercent(0,caster->GetMisdirectionTarget()->GetGUID());
|
||||
break;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -147,6 +147,16 @@ void AuraApplication::_InitFlags(Unit* caster, uint8 effMask)
|
||||
}
|
||||
m_flags |= positiveFound ? AFLAG_POSITIVE : AFLAG_NEGATIVE;
|
||||
}
|
||||
|
||||
// there are more auras that require this flag, this is just the beginning
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
{
|
||||
if (((1 << i) & effMask) && GetBase()->GetSpellInfo()->Effects[i].ApplyAuraName == SPELL_AURA_MOUNTED)
|
||||
{
|
||||
m_flags |= AFLAG_ANY_EFFECT_AMOUNT_SENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AuraApplication::_HandleEffect(uint8 effIndex, bool apply)
|
||||
@@ -208,14 +218,9 @@ void AuraApplication::BuildUpdatePacket(ByteBuffer& data, bool remove) const
|
||||
}
|
||||
|
||||
if (flags & AFLAG_ANY_EFFECT_AMOUNT_SENT)
|
||||
{
|
||||
if (flags & AFLAG_EFF_INDEX_0)
|
||||
data << uint32(0); // Effect 0 value
|
||||
if (flags & AFLAG_EFF_INDEX_1)
|
||||
data << uint32(0); // Effect 1 value
|
||||
if (flags & AFLAG_EFF_INDEX_2)
|
||||
data << uint32(0); // Effect 2 value
|
||||
}
|
||||
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
if (AuraEffect const* eff = aura->GetEffect(i)) // NULL if effect flag not set
|
||||
data << int32(eff->GetAmount());
|
||||
}
|
||||
|
||||
void AuraApplication::ClientUpdate(bool remove)
|
||||
|
||||
Reference in new issue
Block a user