Skip to content

Commit 1f98b95

Browse files
committed
Added ECS Components (UnitAuraInfo)
Updated ECS Singletons (ClientDBSingleton) Updated ECS Systems (NetworkConnection, UpdateUnitEntities) Updated ECS Utils (MessageBuilderUtil, SpellUtil) Updated Editors (ItemEditor, SpellEditor) Updated GameConsoleCommands Updated ModelLoader Updated Scripting Handlers (EventHandler, UIHandler, UnitHandler, Spell) Added Scripting Files (Input, ActionBar) Updated Scripting Files (ItemUtil, Button, CursorInfo, Templates, UnitFrame, CharacterEquipment, Bootstrap Init, CharacterSelect, Chat, LoginScreen, Nameplates, PlayerUnitFrames) Updated Lua Types.def Updated Engine Submodule
1 parent b1ccac2 commit 1f98b95

33 files changed

+1879
-228
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
#include <Base/Types.h>
3+
4+
#include <entt/fwd.hpp>
5+
6+
#include <robinhood/robinhood.h>
7+
8+
namespace ECS
9+
{
10+
struct AuraInfo
11+
{
12+
public:
13+
u32 unitID;
14+
u32 auraID;
15+
16+
u32 spellID;
17+
u64 expireTimestamp;
18+
u16 stacks;
19+
};
20+
21+
namespace Components
22+
{
23+
struct UnitAuraInfo
24+
{
25+
public:
26+
std::vector<AuraInfo> auras;
27+
robin_hood::unordered_map<u32, u32> auraIDToAuraIndex;
28+
robin_hood::unordered_map<u32, u32> spellIDToAuraIndex;
29+
};
30+
}
31+
}

Source/Game-Lib/Game-Lib/ECS/Singletons/Database/ClientDBSingleton.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ enum class ClientDBHash : u32
4949
UnitRaceCustomizationChoice = GetHash("UnitRaceCustomizationChoice"_h),
5050
Spell = GetHash("Spell"_h),
5151
SpellEffects = GetHash("SpellEffects"_h),
52+
SpellProcData = GetHash("SpellProcData"_h),
53+
SpellProcLink = GetHash("SpellProcLink"_h),
5254
Light = GetHash("Light"_h),
5355
LightData = GetHash("LightData"_h),
5456
LightParams = GetHash("LightParams"_h),

Source/Game-Lib/Game-Lib/ECS/Systems/NetworkConnection.cpp

Lines changed: 154 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "Game-Lib/ECS/Components/ProximityTrigger.h"
1717
#include "Game-Lib/ECS/Components/Tags.h"
1818
#include "Game-Lib/ECS/Components/Unit.h"
19+
#include "Game-Lib/ECS/Components/UnitAuraInfo.h"
1920
#include "Game-Lib/ECS/Components/UnitCustomization.h"
2021
#include "Game-Lib/ECS/Components/UnitEquipment.h"
2122
#include "Game-Lib/ECS/Components/UnitMovementOverTime.h"
@@ -364,6 +365,7 @@ namespace ECS::Systems
364365
registry->emplace<Components::Transform>(newEntity);
365366
registry->emplace<Components::Name>(newEntity);
366367
registry->emplace<Components::Model>(newEntity);
368+
registry->emplace<Components::UnitAuraInfo>(newEntity);
367369
registry->emplace<Components::UnitCustomization>(newEntity);
368370
registry->emplace<Components::UnitEquipment>(newEntity);
369371
registry->emplace<Components::UnitMovementOverTime>(newEntity);
@@ -378,6 +380,7 @@ namespace ECS::Systems
378380
unit.networkID = packet.guid;
379381
unit.name = packet.name;
380382
unit.targetEntity = entt::null;
383+
unit.unitClass = static_cast<GameDefine::UnitClass>(packet.unitClass);
381384
unit.scale = packet.scale.x;
382385

383386
if (unit.networkID.GetType() == ObjectGUID::Type::Player)
@@ -587,6 +590,15 @@ namespace ECS::Systems
587590
::Util::Unit::AddPower(unitPowersComponent, powerType, packet.base, packet.current, packet.max);
588591
}
589592

593+
Scripting::Zenith* zenith = Scripting::Util::Zenith::GetGlobal();
594+
zenith->CallEvent(Generated::LuaUnitEventEnum::PowerUpdate, Generated::LuaUnitEventDataPowerUpdate{
595+
.unitID = entt::to_integral(entity),
596+
.powerType = packet.kind,
597+
.base = packet.base,
598+
.current = packet.current,
599+
.max = packet.max
600+
});
601+
590602
return true;
591603
}
592604
bool HandleOnUnitResistanceUpdate(Network::SocketID socketID, Generated::UnitResistanceUpdatePacket& packet)
@@ -614,6 +626,15 @@ namespace ECS::Systems
614626
::Util::Unit::AddResistance(unitResistancesComponent, resistanceType, packet.base, packet.current, packet.max);
615627
}
616628

629+
Scripting::Zenith* zenith = Scripting::Util::Zenith::GetGlobal();
630+
zenith->CallEvent(Generated::LuaUnitEventEnum::ResistanceUpdate, Generated::LuaUnitEventDataResistanceUpdate{
631+
.unitID = entt::to_integral(entity),
632+
.resistanceType = packet.kind,
633+
.base = packet.base,
634+
.current = packet.current,
635+
.max = packet.max
636+
});
637+
617638
return true;
618639
}
619640
bool HandleOnUnitStatUpdate(Network::SocketID socketID, Generated::UnitStatUpdatePacket& packet)
@@ -641,6 +662,13 @@ namespace ECS::Systems
641662
::Util::Unit::AddStat(unitStatsComponent, statType, packet.base, packet.current);
642663
}
643664

665+
Scripting::Zenith* zenith = Scripting::Util::Zenith::GetGlobal();
666+
zenith->CallEvent(Generated::LuaUnitEventEnum::StatUpdate, Generated::LuaUnitEventDataStatUpdate{
667+
.unitID = entt::to_integral(entity),
668+
.statType = packet.kind,
669+
.base = packet.base,
670+
.current = packet.current
671+
});
644672
return true;
645673
}
646674

@@ -663,11 +691,10 @@ namespace ECS::Systems
663691
return true;
664692
}
665693

666-
Scripting::Zenith* zenith = Scripting::Util::Zenith::GetGlobal();
667-
668694
auto& unit = registry->get<Components::Unit>(entity);
669695
unit.targetEntity = targetEntity;
670696

697+
Scripting::Zenith* zenith = Scripting::Util::Zenith::GetGlobal();
671698
zenith->CallEvent(Generated::LuaUnitEventEnum::TargetChanged, Generated::LuaUnitEventDataTargetChanged{
672699
.unitID = entt::to_integral(entity),
673700
.targetID = entt::to_integral(targetEntity)
@@ -1411,6 +1438,127 @@ namespace ECS::Systems
14111438
return true;
14121439
}
14131440

1441+
bool HandleOnServerUnitAddAura(Network::SocketID socketID, Generated::ServerUnitAddAuraPacket& packet)
1442+
{
1443+
entt::registry& registry = *ServiceLocator::GetEnttRegistries()->gameRegistry;
1444+
auto& networkState = registry.ctx().get<Singletons::NetworkState>();
1445+
1446+
entt::entity unitID;
1447+
if (!Util::Network::GetEntityIDFromObjectGUID(networkState, packet.guid, unitID))
1448+
{
1449+
NC_LOG_WARNING("Network : Received UnitAddAura for non-existent entity ({0})", packet.guid.ToString());
1450+
return true;
1451+
}
1452+
1453+
auto& unitAuraInfo = registry.get<Components::UnitAuraInfo>(unitID);
1454+
1455+
// Calculate aura expiration timestamp
1456+
u64 currentTime = static_cast<u64>(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
1457+
u64 expirationTime = currentTime + static_cast<u64>(packet.duration * 1000.0f);
1458+
1459+
u32 auraIndex = static_cast<u32>(unitAuraInfo.auras.size());
1460+
auto& auraInfo = unitAuraInfo.auras.emplace_back();
1461+
auraInfo.unitID = entt::to_integral(unitID);
1462+
auraInfo.auraID = packet.auraInstanceID;
1463+
auraInfo.spellID = packet.spellID;
1464+
auraInfo.expireTimestamp = expirationTime;
1465+
auraInfo.stacks = packet.stacks;
1466+
1467+
unitAuraInfo.auraIDToAuraIndex[packet.auraInstanceID] = auraIndex;
1468+
unitAuraInfo.spellIDToAuraIndex[packet.spellID] = auraIndex;
1469+
1470+
Scripting::Zenith* zenith = Scripting::Util::Zenith::GetGlobal();
1471+
zenith->CallEvent(Generated::LuaUnitEventEnum::AuraAdd, Generated::LuaUnitEventDataAuraAdd{
1472+
.unitID = entt::to_integral(unitID),
1473+
.auraID = packet.auraInstanceID,
1474+
.spellID = packet.spellID,
1475+
.duration = packet.duration,
1476+
.stacks = packet.stacks
1477+
});
1478+
1479+
return true;
1480+
}
1481+
1482+
bool HandleOnServerUnitUpdateAura(Network::SocketID socketID, Generated::ServerUnitUpdateAuraPacket& packet)
1483+
{
1484+
entt::registry& registry = *ServiceLocator::GetEnttRegistries()->gameRegistry;
1485+
auto& networkState = registry.ctx().get<Singletons::NetworkState>();
1486+
1487+
entt::entity unitID;
1488+
if (!Util::Network::GetEntityIDFromObjectGUID(networkState, packet.guid, unitID))
1489+
{
1490+
NC_LOG_WARNING("Network : Received UnitUpdateAura for non-existent entity ({0})", packet.guid.ToString());
1491+
return true;
1492+
}
1493+
1494+
auto& unitAuraInfo = registry.get<Components::UnitAuraInfo>(unitID);
1495+
if (!unitAuraInfo.auraIDToAuraIndex.contains(packet.auraInstanceID))
1496+
{
1497+
NC_LOG_WARNING("Network : Received UnitUpdateAura for non-existent aura ({0}) on entity ({1})", packet.auraInstanceID, packet.guid.ToString());
1498+
return true;
1499+
}
1500+
1501+
u32 auraIndex = unitAuraInfo.auraIDToAuraIndex[packet.auraInstanceID];
1502+
auto& auraInfo = unitAuraInfo.auras[auraIndex];
1503+
u64 currentTime = static_cast<u64>(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
1504+
u64 expirationTime = currentTime + static_cast<u64>(packet.duration * 1000.0f);
1505+
1506+
auraInfo.expireTimestamp = expirationTime;
1507+
auraInfo.stacks = packet.stacks;
1508+
1509+
Scripting::Zenith* zenith = Scripting::Util::Zenith::GetGlobal();
1510+
zenith->CallEvent(Generated::LuaUnitEventEnum::AuraUpdate, Generated::LuaUnitEventDataAuraUpdate{
1511+
.unitID = entt::to_integral(unitID),
1512+
.auraID = packet.auraInstanceID,
1513+
.duration = packet.duration,
1514+
.stacks = packet.stacks
1515+
});
1516+
1517+
return true;
1518+
}
1519+
1520+
bool HandleOnServerUnitRemoveAura(Network::SocketID socketID, Generated::ServerUnitRemoveAuraPacket& packet)
1521+
{
1522+
entt::registry& registry = *ServiceLocator::GetEnttRegistries()->gameRegistry;
1523+
auto& networkState = registry.ctx().get<Singletons::NetworkState>();
1524+
1525+
entt::entity unitID;
1526+
if (!Util::Network::GetEntityIDFromObjectGUID(networkState, packet.guid, unitID))
1527+
{
1528+
NC_LOG_WARNING("Network : Received UnitRemoveAura for non-existent entity ({0})", packet.guid.ToString());
1529+
return true;
1530+
}
1531+
1532+
auto& unitAuraInfo = registry.get<Components::UnitAuraInfo>(unitID);
1533+
if (!unitAuraInfo.auraIDToAuraIndex.contains(packet.auraInstanceID))
1534+
{
1535+
NC_LOG_WARNING("Network : Received UnitRemoveAura for non-existent aura ({0}) on entity ({1})", packet.auraInstanceID, packet.guid.ToString());
1536+
return true;
1537+
}
1538+
1539+
Scripting::Zenith* zenith = Scripting::Util::Zenith::GetGlobal();
1540+
zenith->CallEvent(Generated::LuaUnitEventEnum::AuraRemove, Generated::LuaUnitEventDataAuraRemove{
1541+
.unitID = entt::to_integral(unitID),
1542+
.auraID = packet.auraInstanceID
1543+
});
1544+
1545+
u32 auraIndex = unitAuraInfo.auraIDToAuraIndex[packet.auraInstanceID];
1546+
u32 auraSpellID = unitAuraInfo.auras[auraIndex].spellID;
1547+
unitAuraInfo.auras.erase(unitAuraInfo.auras.begin() + auraIndex);
1548+
1549+
// Rebuild the auraIDToAuraIndex and spellIDToAuraIndex maps
1550+
unitAuraInfo.auraIDToAuraIndex.clear();
1551+
unitAuraInfo.spellIDToAuraIndex.clear();
1552+
1553+
for (u32 i = 0; i < unitAuraInfo.auras.size(); ++i)
1554+
{
1555+
unitAuraInfo.auraIDToAuraIndex[unitAuraInfo.auras[i].auraID] = i;
1556+
unitAuraInfo.spellIDToAuraIndex[unitAuraInfo.auras[i].spellID] = i;
1557+
}
1558+
1559+
return true;
1560+
}
1561+
14141562
void NetworkConnection::Init(entt::registry& registry)
14151563
{
14161564
entt::registry::context& ctx = registry.ctx();
@@ -1461,6 +1609,10 @@ namespace ECS::Systems
14611609
networkState.gameMessageRouter->RegisterPacketHandler(Network::ConnectionStatus::Connected, HandleOnSendChatMessage);
14621610
networkState.gameMessageRouter->RegisterPacketHandler(Network::ConnectionStatus::Connected, HandleOnServerTriggerAdd);
14631611
networkState.gameMessageRouter->RegisterPacketHandler(Network::ConnectionStatus::Connected, HandleOnServerTriggerRemove);
1612+
1613+
networkState.gameMessageRouter->RegisterPacketHandler(Network::ConnectionStatus::Connected, HandleOnServerUnitAddAura);
1614+
networkState.gameMessageRouter->RegisterPacketHandler(Network::ConnectionStatus::Connected, HandleOnServerUnitUpdateAura);
1615+
networkState.gameMessageRouter->RegisterPacketHandler(Network::ConnectionStatus::Connected, HandleOnServerUnitRemoveAura);
14641616

14651617
networkState.gameMessageRouter->SetMessageHandler(Generated::SendCombatEventPacket::PACKET_ID, Network::GameMessageHandler(Network::ConnectionStatus::Connected, 0u, -1, &HandleOnCombatEvent));
14661618
}

Source/Game-Lib/Game-Lib/ECS/Systems/UpdateUnitEntities.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
#include <Jolt/Physics/Collision/CastResult.h>
4242
#include <Jolt/Physics/Collision/RayCast.h>
4343

44+
#include <tracy/tracy.hpp>
45+
4446
namespace ECS::Systems
4547
{
4648
class NetworkedEntityFilter : public JPH::BodyFilter
@@ -137,9 +139,6 @@ namespace ECS::Systems
137139
}
138140

139141
auto& discoveredModel = modelLoader->GetDiscoveredModel(model.modelHash);
140-
#ifdef NC_DEBUG
141-
NC_LOG_INFO("Entity \"{0}\" Loaded New Model \"{1}\"", name->name, discoveredModel.name);
142-
#endif
143142
modelLoader->DisableAllGroupsForModel(model);
144143

145144
if (auto* unitCustomization = registry.try_get<Components::UnitCustomization>(entity))

Source/Game-Lib/Game-Lib/ECS/Util/Database/SpellUtil.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,8 @@ namespace ECSUtil::Spell
3939
storage->MarkDirty();
4040
}
4141

42-
if (!clientDBSingleton.Has(ClientDBHash::SpellEffects))
42+
if (clientDBSingleton.Register<Generated::SpellEffectsRecord>())
4343
{
44-
clientDBSingleton.Register<Generated::SpellEffectsRecord>();
4544
auto* storage = clientDBSingleton.Get(ClientDBHash::SpellEffects);
4645

4746
Generated::SpellEffectsRecord defaultSpellEffect;
@@ -58,6 +57,35 @@ namespace ECSUtil::Spell
5857
storage->Replace(0, defaultSpellEffect);
5958
}
6059

60+
if (clientDBSingleton.Register<Generated::SpellProcDataRecord>())
61+
{
62+
auto* storage = clientDBSingleton.Get(ClientDBHash::SpellProcData);
63+
64+
Generated::SpellProcDataRecord defaultSpellProcData;
65+
defaultSpellProcData.phaseMask = 0;
66+
defaultSpellProcData.typeMask = 0;
67+
defaultSpellProcData.hitMask = 0;
68+
defaultSpellProcData.flags = std::numeric_limits<u64>().max();
69+
defaultSpellProcData.procsPerMinute = 0.0f;
70+
defaultSpellProcData.chanceToProc = 0.0f;
71+
defaultSpellProcData.internalCooldownMS = std::numeric_limits<u32>().max();
72+
defaultSpellProcData.charges = 0;
73+
74+
storage->Replace(0, defaultSpellProcData);
75+
}
76+
77+
if (clientDBSingleton.Register<Generated::SpellProcLinkRecord>())
78+
{
79+
auto* storage = clientDBSingleton.Get(ClientDBHash::SpellProcLink);
80+
81+
Generated::SpellProcLinkRecord defaultSpellProcLink;
82+
defaultSpellProcLink.spellID = 0;
83+
defaultSpellProcLink.effectMask = 0;
84+
defaultSpellProcLink.procDataID = 0;
85+
86+
storage->Replace(0, defaultSpellProcLink);
87+
}
88+
6189
auto* spellStorage = clientDBSingleton.Get(ClientDBHash::Spell);
6290
auto* spellEffectsStorage = clientDBSingleton.Get(ClientDBHash::SpellEffects);
6391

Source/Game-Lib/Game-Lib/ECS/Util/MessageBuilderUtil.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,7 @@ namespace ECS::Util::MessageBuilder
572572

573573
.castTime = spell.castTime,
574574
.cooldown = spell.cooldown,
575+
.duration = spell.duration
575576
};
576577

577578
buffer->Put(Generated::CheatCommandEnum::SpellSet);
@@ -606,6 +607,28 @@ namespace ECS::Util::MessageBuilder
606607

607608
return result;
608609
}
610+
bool BuildCheatSpellProcDataSet(std::shared_ptr<Bytebuffer>& buffer, ClientDB::Data* spellProcDataStorage, u32 spellProcDataID, const Generated::SpellProcDataRecord& spellProcData)
611+
{
612+
bool result = CreatePacket(buffer, Generated::SendCheatCommandPacket::PACKET_ID, [&, spellProcDataID]()
613+
{
614+
buffer->Put(Generated::CheatCommandEnum::SpellProcDataSet);
615+
buffer->PutU32(spellProcDataID);
616+
buffer->Serialize(spellProcData);
617+
});
618+
619+
return result;
620+
}
621+
bool BuildCheatSpellProcLinkSet(std::shared_ptr<Bytebuffer>& buffer, ClientDB::Data* spellProcLinkStorage, u32 spellProcLinkID, const Generated::SpellProcLinkRecord& spellProcLink)
622+
{
623+
bool result = CreatePacket(buffer, Generated::SendCheatCommandPacket::PACKET_ID, [&, spellProcLinkID]()
624+
{
625+
buffer->Put(Generated::CheatCommandEnum::SpellProcLinkSet);
626+
buffer->PutU32(spellProcLinkID);
627+
buffer->Serialize(spellProcLink);
628+
});
629+
630+
return result;
631+
}
609632
bool BuildCreatureAddScript(std::shared_ptr<Bytebuffer>& buffer, const std::string& scriptName)
610633
{
611634
bool result = CreatePacket(buffer, Generated::SendCheatCommandPacket::PACKET_ID, [&]()

Source/Game-Lib/Game-Lib/ECS/Util/MessageBuilderUtil.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ namespace ECS
109109
bool BuildCheatTriggerRemove(std::shared_ptr<Bytebuffer>& buffer, u32 triggerID);
110110
bool BuildCheatSpellSet(std::shared_ptr<Bytebuffer>& buffer, ClientDB::Data* spellStorage, u32 spellID, const Generated::SpellRecord& spell);
111111
bool BuildCheatSpellEffectSet(std::shared_ptr<Bytebuffer>& buffer, ClientDB::Data* spellEffectsStorage, u32 spellEffectsID, const Generated::SpellEffectsRecord& spellEffect);
112+
bool BuildCheatSpellProcDataSet(std::shared_ptr<Bytebuffer>& buffer, ClientDB::Data* spellProcDataStorage, u32 spellProcDataID, const Generated::SpellProcDataRecord& spellProcData);
113+
bool BuildCheatSpellProcLinkSet(std::shared_ptr<Bytebuffer>& buffer, ClientDB::Data* spellProcLinkStorage, u32 spellProcLinkID, const Generated::SpellProcLinkRecord& spellProcLink);
112114
bool BuildCreatureAddScript(std::shared_ptr<Bytebuffer>& buffer, const std::string& scriptName);
113115
bool BuildCreatureRemoveScript(std::shared_ptr<Bytebuffer>& buffer);
114116
}

Source/Game-Lib/Game-Lib/Editor/ItemEditor.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -313,12 +313,11 @@ namespace Editor
313313
{
314314
{.id = 0, .label = "None" },
315315
{.id = 1, .label = "Health" },
316-
{.id = 2, .label = "Mana" },
317-
{.id = 3, .label = "Stamina" },
318-
{.id = 4, .label = "Strength" },
319-
{.id = 5, .label = "Agility" },
320-
{.id = 6, .label = "Intellect" },
321-
{.id = 7, .label = "Spirit" }
316+
{.id = 2, .label = "Stamina" },
317+
{.id = 3, .label = "Strength" },
318+
{.id = 4, .label = "Agility" },
319+
{.id = 5, .label = "Intellect" },
320+
{.id = 6, .label = "Spirit" }
322321
};
323322

324323
auto& currentItem = itemStorage->Get<Generated::ItemRecord>(currentIndex);

0 commit comments

Comments
 (0)