aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2012-01-27 11:24:41 +0100
committerShauren <shauren.trinity@gmail.com>2012-01-27 11:24:41 +0100
commit0df5e19bd6b1cbad20ba80c73db3bc8693c6bece (patch)
tree7f0857de898a084bed2b36331274c24bcb5c77c2
parentb9e64f962458829a8b27d2b578a3aa744e7651b0 (diff)
Core/Spells: Implemented mounts
-rwxr-xr-xsrc/server/game/DataStores/DBCEnums.h6
-rwxr-xr-xsrc/server/game/DataStores/DBCStores.cpp7
-rwxr-xr-xsrc/server/game/DataStores/DBCStores.h2
-rwxr-xr-xsrc/server/game/DataStores/DBCStructure.h22
-rwxr-xr-xsrc/server/game/DataStores/DBCfmt.h2
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp62
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h1
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuraEffects.cpp20
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuras.cpp21
9 files changed, 128 insertions, 15 deletions
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index b850aa0ef46..33a15c3b457 100755
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -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,
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index 3367eac6e7d..0a7b1776bc9 100755
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -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))
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index 635d319abbb..5fa8d83fc4b 100755
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -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
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index 0bde8e01359..608824b140f 100755
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -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
diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h
index b133537a5a3..59af1d0e7c6 100755
--- a/src/server/game/DataStores/DBCfmt.h
+++ b/src/server/game/DataStores/DBCfmt.h
@@ -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";
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 034ab9ba92d..430b6adb6ec 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -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]);
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 8274b62145f..21dcb4bf3fe 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -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);
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index c54f644a43c..8521d48cd9e 100755
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -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;
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 44ba17c32cb..ff3d9fcddf3 100755
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -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)