Merge remote-tracking branch 'origin/main' into dCinema

This commit is contained in:
wincent 2023-10-28 11:23:29 +02:00
commit 3f90a4dd0b
68 changed files with 320 additions and 261 deletions

View File

@ -148,16 +148,19 @@ foreach (resource_file ${RESOURCE_FILES})
endforeach() endforeach()
message(STATUS "Resource file integrity check complete") message(STATUS "Resource file integrity check complete")
# if navmeshes directory does not exist, create it
if (NOT EXISTS ${PROJECT_BINARY_DIR}/navmeshes)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/navmeshes)
endif()
# Copy navmesh data on first build and extract it # Copy navmesh data on first build and extract it
if (NOT EXISTS ${PROJECT_BINARY_DIR}/navmeshes/) configure_file(
configure_file(
${CMAKE_SOURCE_DIR}/resources/navmeshes.zip ${PROJECT_BINARY_DIR}/navmeshes.zip ${CMAKE_SOURCE_DIR}/resources/navmeshes.zip ${PROJECT_BINARY_DIR}/navmeshes.zip
COPYONLY COPYONLY
) )
file(ARCHIVE_EXTRACT INPUT ${PROJECT_BINARY_DIR}/navmeshes.zip) file(ARCHIVE_EXTRACT INPUT ${PROJECT_BINARY_DIR}/navmeshes.zip DESTINATION ${PROJECT_BINARY_DIR}/navmeshes)
file(REMOVE ${PROJECT_BINARY_DIR}/navmeshes.zip) file(REMOVE ${PROJECT_BINARY_DIR}/navmeshes.zip)
endif()
# Copy vanity files on first build # Copy vanity files on first build
set(VANITY_FILES "CREDITS.md" "INFO.md" "TESTAMENT.md" "NPC.xml") set(VANITY_FILES "CREDITS.md" "INFO.md" "TESTAMENT.md" "NPC.xml")

View File

@ -118,6 +118,11 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
inStream.Read(isBestFriendRequest); inStream.Read(isBestFriendRequest);
auto requestor = playerContainer.GetPlayerData(requestorPlayerID); auto requestor = playerContainer.GetPlayerData(requestorPlayerID);
if (!requestor) {
LOG("No requestor player %llu sent to %s found.", requestorPlayerID, playerName.c_str());
return;
}
if (requestor->playerName == playerName) { if (requestor->playerName == playerName) {
SendFriendResponse(requestor, requestor, eAddFriendResponseType::MYTHRAN); SendFriendResponse(requestor, requestor, eAddFriendResponseType::MYTHRAN);
return; return;

View File

@ -134,6 +134,10 @@ void CatchUnhandled(int sig) {
// Loop through the returned addresses, and get the symbols to be demangled // Loop through the returned addresses, and get the symbols to be demangled
char** strings = backtrace_symbols(array, size); char** strings = backtrace_symbols(array, size);
FILE* file = fopen(fileName.c_str(), "w+");
if (file != NULL) {
fprintf(file, "Error: signal %d:\n", sig);
}
// Print the stack trace // Print the stack trace
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
// Take a string like './WorldServer(_ZN19SlashCommandHandler17HandleChatCommandERKSbIDsSt11char_traitsIDsESaIDsEEP6EntityRK13SystemAddress+0x6187) [0x55869c44ecf7]' // Take a string like './WorldServer(_ZN19SlashCommandHandler17HandleChatCommandERKSbIDsSt11char_traitsIDsESaIDsEEP6EntityRK13SystemAddress+0x6187) [0x55869c44ecf7]'
@ -155,19 +159,14 @@ void CatchUnhandled(int sig) {
} }
LOG("[%02zu] %s", i, functionName.c_str()); LOG("[%02zu] %s", i, functionName.c_str());
if (file != NULL) {
fprintf(file, "[%02zu] %s\n", i, functionName.c_str());
}
} }
# else // defined(__GNUG__) # else // defined(__GNUG__)
backtrace_symbols_fd(array, size, STDOUT_FILENO); backtrace_symbols_fd(array, size, STDOUT_FILENO);
# endif // defined(__GNUG__) # endif // defined(__GNUG__)
FILE* file = fopen(fileName.c_str(), "w+");
if (file != NULL) {
// print out all the frames to stderr
fprintf(file, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, fileno(file));
fclose(file);
}
#else // __include_backtrace__ #else // __include_backtrace__
struct backtrace_state* state = backtrace_create_state( struct backtrace_state* state = backtrace_create_state(

View File

@ -27,20 +27,6 @@ enum class ePermissionMap : uint64_t {
* The character has restricted chat access, bit 6. * The character has restricted chat access, bit 6.
*/ */
RestrictedChatAccess = 0x1 << 6, RestrictedChatAccess = 0x1 << 6,
//
// Combined permissions
//
/**
* The character is marked as 'old', restricted from trade and mail.
*/
Old = RestrictedTradeAccess | RestrictedMailAccess,
/**
* The character is soft banned, restricted from trade, mail, and chat.
*/
SoftBanned = RestrictedTradeAccess | RestrictedMailAccess | RestrictedChatAccess,
}; };
#endif //!__EPERMISSIONMAP__H__ #endif //!__EPERMISSIONMAP__H__

View File

@ -394,12 +394,13 @@ void Character::SetIsNewLogin() {
auto* currentChild = flags->FirstChildElement(); auto* currentChild = flags->FirstChildElement();
while (currentChild) { while (currentChild) {
auto* nextChild = currentChild->NextSiblingElement();
if (currentChild->Attribute("si")) { if (currentChild->Attribute("si")) {
flags->DeleteChild(currentChild); flags->DeleteChild(currentChild);
LOG("Removed isLoggedIn flag from character %i:%s, saving character to database", GetID(), GetName().c_str()); LOG("Removed isLoggedIn flag from character %i:%s, saving character to database", GetID(), GetName().c_str());
WriteToDatabase(); WriteToDatabase();
} }
currentChild = currentChild->NextSiblingElement(); currentChild = nextChild;
} }
} }
@ -554,15 +555,6 @@ void Character::OnZoneLoad() {
return; return;
} }
/**
* Restrict old character to 1 million coins
*/
if (HasPermission(ePermissionMap::Old)) {
if (GetCoins() > 1000000) {
SetCoins(1000000, eLootSourceType::NONE);
}
}
auto* inventoryComponent = m_OurEntity->GetComponent<InventoryComponent>(); auto* inventoryComponent = m_OurEntity->GetComponent<InventoryComponent>();
if (inventoryComponent == nullptr) { if (inventoryComponent == nullptr) {

View File

@ -76,6 +76,10 @@
#include "eGameMasterLevel.h" #include "eGameMasterLevel.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
#include "eReplicaPacketType.h" #include "eReplicaPacketType.h"
#include "ZoneControlComponent.h"
#include "RacingStatsComponent.h"
#include "CollectibleComponent.h"
#include "ItemComponent.h"
// Table includes // Table includes
#include "CDComponentsRegistryTable.h" #include "CDComponentsRegistryTable.h"
@ -95,7 +99,6 @@ Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity)
m_ParentEntity = parentEntity; m_ParentEntity = parentEntity;
m_Character = nullptr; m_Character = nullptr;
m_GMLevel = eGameMasterLevel::CIVILIAN; m_GMLevel = eGameMasterLevel::CIVILIAN;
m_CollectibleID = 0;
m_NetworkID = 0; m_NetworkID = 0;
m_Groups = {}; m_Groups = {};
m_OwnerOverride = LWOOBJID_EMPTY; m_OwnerOverride = LWOOBJID_EMPTY;
@ -153,7 +156,7 @@ void Entity::Initialize() {
const auto triggerInfo = GetVarAsString(u"trigger_id"); const auto triggerInfo = GetVarAsString(u"trigger_id");
if (!triggerInfo.empty()) m_Components.emplace(eReplicaComponentType::TRIGGER, new TriggerComponent(this, triggerInfo)); if (!triggerInfo.empty()) AddComponent<TriggerComponent>(triggerInfo);
/** /**
* Setup groups * Setup groups
@ -184,21 +187,17 @@ void Entity::Initialize() {
if (m_TemplateID == 14) { if (m_TemplateID == 14) {
const auto simplePhysicsComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SIMPLE_PHYSICS); const auto simplePhysicsComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SIMPLE_PHYSICS);
SimplePhysicsComponent* comp = new SimplePhysicsComponent(simplePhysicsComponentID, this); AddComponent<SimplePhysicsComponent>(simplePhysicsComponentID);
m_Components.insert(std::make_pair(eReplicaComponentType::SIMPLE_PHYSICS, comp));
ModelComponent* modelcomp = new ModelComponent(this); AddComponent<ModelComponent>();
m_Components.insert(std::make_pair(eReplicaComponentType::MODEL, modelcomp));
RenderComponent* render = new RenderComponent(this); AddComponent<RenderComponent>();
m_Components.insert(std::make_pair(eReplicaComponentType::RENDER, render));
auto destroyableComponent = new DestroyableComponent(this); auto* destroyableComponent = AddComponent<DestroyableComponent>();
destroyableComponent->SetHealth(1); destroyableComponent->SetHealth(1);
destroyableComponent->SetMaxHealth(1.0f); destroyableComponent->SetMaxHealth(1.0f);
destroyableComponent->SetFaction(-1, true); destroyableComponent->SetFaction(-1, true);
destroyableComponent->SetIsSmashable(true); destroyableComponent->SetIsSmashable(true);
m_Components.insert(std::make_pair(eReplicaComponentType::DESTROYABLE, destroyableComponent));
// We have all our components. // We have all our components.
return; return;
} }
@ -210,49 +209,46 @@ void Entity::Initialize() {
*/ */
if (GetParentUser()) { if (GetParentUser()) {
auto missions = new MissionComponent(this); AddComponent<MissionComponent>()->LoadFromXml(m_Character->GetXMLDoc());
m_Components.insert(std::make_pair(eReplicaComponentType::MISSION, missions));
missions->LoadFromXml(m_Character->GetXMLDoc());
} }
uint32_t petComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PET); uint32_t petComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PET);
if (petComponentId > 0) { if (petComponentId > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::PET, new PetComponent(this, petComponentId))); AddComponent<PetComponent>(petComponentId);
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ZONE_CONTROL) > 0) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ZONE_CONTROL) > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::ZONE_CONTROL, nullptr)); AddComponent<ZoneControlComponent>();
} }
uint32_t possessableComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::POSSESSABLE); uint32_t possessableComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::POSSESSABLE);
if (possessableComponentId > 0) { if (possessableComponentId > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::POSSESSABLE, new PossessableComponent(this, possessableComponentId))); AddComponent<PossessableComponent>(possessableComponentId);
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MODULE_ASSEMBLY) > 0) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MODULE_ASSEMBLY) > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::MODULE_ASSEMBLY, new ModuleAssemblyComponent(this))); AddComponent<ModuleAssemblyComponent>();
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RACING_STATS) > 0) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RACING_STATS) > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::RACING_STATS, nullptr)); AddComponent<RacingStatsComponent>();
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::LUP_EXHIBIT, -1) >= 0) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::LUP_EXHIBIT, -1) >= 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::LUP_EXHIBIT, new LUPExhibitComponent(this))); AddComponent<LUPExhibitComponent>();
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RACING_CONTROL) > 0) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RACING_CONTROL) > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::RACING_CONTROL, new RacingControlComponent(this))); AddComponent<RacingControlComponent>();
} }
const auto propertyEntranceComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_ENTRANCE); const auto propertyEntranceComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_ENTRANCE);
if (propertyEntranceComponentID > 0) { if (propertyEntranceComponentID > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::PROPERTY_ENTRANCE, AddComponent<PropertyEntranceComponent>(propertyEntranceComponentID);
new PropertyEntranceComponent(propertyEntranceComponentID, this)));
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::CONTROLLABLE_PHYSICS) > 0) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::CONTROLLABLE_PHYSICS) > 0) {
ControllablePhysicsComponent* controllablePhysics = new ControllablePhysicsComponent(this); auto* controllablePhysics = AddComponent<ControllablePhysicsComponent>();
if (m_Character) { if (m_Character) {
controllablePhysics->LoadFromXml(m_Character->GetXMLDoc()); controllablePhysics->LoadFromXml(m_Character->GetXMLDoc());
@ -285,8 +281,6 @@ void Entity::Initialize() {
controllablePhysics->SetPosition(m_DefaultPosition); controllablePhysics->SetPosition(m_DefaultPosition);
controllablePhysics->SetRotation(m_DefaultRotation); controllablePhysics->SetRotation(m_DefaultRotation);
} }
m_Components.insert(std::make_pair(eReplicaComponentType::CONTROLLABLE_PHYSICS, controllablePhysics));
} }
// If an entity is marked a phantom, simple physics is made into phantom phyics. // If an entity is marked a phantom, simple physics is made into phantom phyics.
@ -294,54 +288,42 @@ void Entity::Initialize() {
const auto simplePhysicsComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SIMPLE_PHYSICS); const auto simplePhysicsComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SIMPLE_PHYSICS);
if (!markedAsPhantom && simplePhysicsComponentID > 0) { if (!markedAsPhantom && simplePhysicsComponentID > 0) {
SimplePhysicsComponent* comp = new SimplePhysicsComponent(simplePhysicsComponentID, this); AddComponent<SimplePhysicsComponent>(simplePhysicsComponentID);
m_Components.insert(std::make_pair(eReplicaComponentType::SIMPLE_PHYSICS, comp));
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS) > 0) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS) > 0) {
RigidbodyPhantomPhysicsComponent* comp = new RigidbodyPhantomPhysicsComponent(this); AddComponent<RigidbodyPhantomPhysicsComponent>();
m_Components.insert(std::make_pair(eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS, comp));
} }
if (markedAsPhantom || compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PHANTOM_PHYSICS) > 0) { if (markedAsPhantom || compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PHANTOM_PHYSICS) > 0) {
PhantomPhysicsComponent* phantomPhysics = new PhantomPhysicsComponent(this); AddComponent<PhantomPhysicsComponent>()->SetPhysicsEffectActive(false);
phantomPhysics->SetPhysicsEffectActive(false);
m_Components.insert(std::make_pair(eReplicaComponentType::PHANTOM_PHYSICS, phantomPhysics));
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::VEHICLE_PHYSICS) > 0) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::VEHICLE_PHYSICS) > 0) {
VehiclePhysicsComponent* vehiclePhysicsComponent = new VehiclePhysicsComponent(this); auto* vehiclePhysicsComponent = AddComponent<VehiclePhysicsComponent>();
m_Components.insert(std::make_pair(eReplicaComponentType::VEHICLE_PHYSICS, vehiclePhysicsComponent));
vehiclePhysicsComponent->SetPosition(m_DefaultPosition); vehiclePhysicsComponent->SetPosition(m_DefaultPosition);
vehiclePhysicsComponent->SetRotation(m_DefaultRotation); vehiclePhysicsComponent->SetRotation(m_DefaultRotation);
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SOUND_TRIGGER, -1) != -1) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SOUND_TRIGGER, -1) != -1) {
auto* comp = new SoundTriggerComponent(this); AddComponent<SoundTriggerComponent>();
m_Components.insert(std::make_pair(eReplicaComponentType::SOUND_TRIGGER, comp));
} else if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RACING_SOUND_TRIGGER, -1) != -1) { } else if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RACING_SOUND_TRIGGER, -1) != -1) {
auto* comp = new RacingSoundTriggerComponent(this); AddComponent<RacingSoundTriggerComponent>();
m_Components.insert(std::make_pair(eReplicaComponentType::RACING_SOUND_TRIGGER, comp));
} }
//Also check for the collectible id:
m_CollectibleID = GetVarAs<int32_t>(u"collectible_id");
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUFF) > 0) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUFF) > 0) {
BuffComponent* comp = new BuffComponent(this); AddComponent<BuffComponent>();
m_Components.insert(std::make_pair(eReplicaComponentType::BUFF, comp));
} }
int collectibleComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::COLLECTIBLE); int collectibleComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::COLLECTIBLE);
if (collectibleComponentID > 0) { if (collectibleComponentID > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::COLLECTIBLE, nullptr)); AddComponent<CollectibleComponent>(GetVarAs<int32_t>(u"collectible_id"));
} }
/** /**
* Multiple components require the destructible component. * Multiple components require the destructible component.
*/ */
int buffComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUFF); int buffComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUFF);
int rebuildComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::QUICK_BUILD); int rebuildComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::QUICK_BUILD);
@ -355,7 +337,7 @@ void Entity::Initialize() {
bool isSmashable = GetVarAs<int32_t>(u"is_smashable") != 0; bool isSmashable = GetVarAs<int32_t>(u"is_smashable") != 0;
if (buffComponentID > 0 || collectibleComponentID > 0 || isSmashable) { if (buffComponentID > 0 || collectibleComponentID > 0 || isSmashable) {
DestroyableComponent* comp = new DestroyableComponent(this); DestroyableComponent* comp = AddComponent<DestroyableComponent>();
if (m_Character) { if (m_Character) {
comp->LoadFromXml(m_Character->GetXMLDoc()); comp->LoadFromXml(m_Character->GetXMLDoc());
} else { } else {
@ -440,36 +422,27 @@ void Entity::Initialize() {
} }
} }
} }
m_Components.insert(std::make_pair(eReplicaComponentType::DESTROYABLE, comp));
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::CHARACTER) > 0 || m_Character) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::CHARACTER) > 0 || m_Character) {
// Character Component always has a possessor, level, and forced movement components // Character Component always has a possessor, level, and forced movement components
m_Components.insert(std::make_pair(eReplicaComponentType::POSSESSOR, new PossessorComponent(this))); AddComponent<PossessorComponent>();
// load in the xml for the level // load in the xml for the level
auto* levelComp = new LevelProgressionComponent(this); AddComponent<LevelProgressionComponent>()->LoadFromXml(m_Character->GetXMLDoc());
levelComp->LoadFromXml(m_Character->GetXMLDoc());
m_Components.insert(std::make_pair(eReplicaComponentType::LEVEL_PROGRESSION, levelComp));
m_Components.insert(std::make_pair(eReplicaComponentType::PLAYER_FORCED_MOVEMENT, new PlayerForcedMovementComponent(this))); AddComponent<PlayerForcedMovementComponent>();
CharacterComponent* charComp = new CharacterComponent(this, m_Character); AddComponent<CharacterComponent>(m_Character)->LoadFromXml(m_Character->GetXMLDoc());
charComp->LoadFromXml(m_Character->GetXMLDoc());
m_Components.insert(std::make_pair(eReplicaComponentType::CHARACTER, charComp));
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::INVENTORY) > 0 || m_Character) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::INVENTORY) > 0 || m_Character) {
InventoryComponent* comp = nullptr; auto* xmlDoc = m_Character ? m_Character->GetXMLDoc() : nullptr;
if (m_Character) comp = new InventoryComponent(this, m_Character->GetXMLDoc()); AddComponent<InventoryComponent>(xmlDoc);
else comp = new InventoryComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::INVENTORY, comp));
} }
// if this component exists, then we initialize it. it's value is always 0 // if this component exists, then we initialize it. it's value is always 0
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MULTI_ZONE_ENTRANCE, -1) != -1) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MULTI_ZONE_ENTRANCE, -1) != -1) {
auto comp = new MultiZoneEntranceComponent(this); AddComponent<MultiZoneEntranceComponent>();
m_Components.insert(std::make_pair(eReplicaComponentType::MULTI_ZONE_ENTRANCE, comp));
} }
/** /**
@ -520,7 +493,7 @@ void Entity::Initialize() {
} }
if (!scriptName.empty() || client || m_Character || scriptComponentID >= 0) { if (!scriptName.empty() || client || m_Character || scriptComponentID >= 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::SCRIPT, new ScriptComponent(this, scriptName, true, client && scriptName.empty()))); AddComponent<ScriptComponent>(scriptName, true, client && scriptName.empty());
} }
// ZoneControl script // ZoneControl script
@ -532,148 +505,137 @@ void Entity::Initialize() {
if (zoneData != nullptr) { if (zoneData != nullptr) {
int zoneScriptID = zoneData->scriptID; int zoneScriptID = zoneData->scriptID;
CDScriptComponent zoneScriptData = scriptCompTable->GetByID(zoneScriptID); CDScriptComponent zoneScriptData = scriptCompTable->GetByID(zoneScriptID);
AddComponent<ScriptComponent>(zoneScriptData.script_name, true);
ScriptComponent* comp = new ScriptComponent(this, zoneScriptData.script_name, true);
m_Components.insert(std::make_pair(eReplicaComponentType::SCRIPT, comp));
} }
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SKILL, -1) != -1 || m_Character) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SKILL, -1) != -1 || m_Character) {
SkillComponent* comp = new SkillComponent(this); AddComponent<SkillComponent>();
m_Components.insert(std::make_pair(eReplicaComponentType::SKILL, comp));
} }
const auto combatAiId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BASE_COMBAT_AI); const auto combatAiId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BASE_COMBAT_AI);
if (combatAiId > 0) { if (combatAiId > 0) {
BaseCombatAIComponent* comp = new BaseCombatAIComponent(this, combatAiId); AddComponent<BaseCombatAIComponent>(combatAiId);
m_Components.insert(std::make_pair(eReplicaComponentType::BASE_COMBAT_AI, comp));
} }
if (int componentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::QUICK_BUILD) > 0) { if (int componentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::QUICK_BUILD) > 0) {
RebuildComponent* comp = new RebuildComponent(this); auto* rebuildComponent = AddComponent<RebuildComponent>();
m_Components.insert(std::make_pair(eReplicaComponentType::QUICK_BUILD, comp));
CDRebuildComponentTable* rebCompTable = CDClientManager::Instance().GetTable<CDRebuildComponentTable>(); CDRebuildComponentTable* rebCompTable = CDClientManager::Instance().GetTable<CDRebuildComponentTable>();
std::vector<CDRebuildComponent> rebCompData = rebCompTable->Query([=](CDRebuildComponent entry) { return (entry.id == rebuildComponentID); }); std::vector<CDRebuildComponent> rebCompData = rebCompTable->Query([=](CDRebuildComponent entry) { return (entry.id == rebuildComponentID); });
if (rebCompData.size() > 0) { if (rebCompData.size() > 0) {
comp->SetResetTime(rebCompData[0].reset_time); rebuildComponent->SetResetTime(rebCompData[0].reset_time);
comp->SetCompleteTime(rebCompData[0].complete_time); rebuildComponent->SetCompleteTime(rebCompData[0].complete_time);
comp->SetTakeImagination(rebCompData[0].take_imagination); rebuildComponent->SetTakeImagination(rebCompData[0].take_imagination);
comp->SetInterruptible(rebCompData[0].interruptible); rebuildComponent->SetInterruptible(rebCompData[0].interruptible);
comp->SetSelfActivator(rebCompData[0].self_activator); rebuildComponent->SetSelfActivator(rebCompData[0].self_activator);
comp->SetActivityId(rebCompData[0].activityID); rebuildComponent->SetActivityId(rebCompData[0].activityID);
comp->SetPostImaginationCost(rebCompData[0].post_imagination_cost); rebuildComponent->SetPostImaginationCost(rebCompData[0].post_imagination_cost);
comp->SetTimeBeforeSmash(rebCompData[0].time_before_smash); rebuildComponent->SetTimeBeforeSmash(rebCompData[0].time_before_smash);
const auto rebuildResetTime = GetVar<float>(u"rebuild_reset_time"); const auto rebuildResetTime = GetVar<float>(u"rebuild_reset_time");
if (rebuildResetTime != 0.0f) { if (rebuildResetTime != 0.0f) {
comp->SetResetTime(rebuildResetTime); rebuildComponent->SetResetTime(rebuildResetTime);
if (m_TemplateID == 9483) // Look away! // Known bug with moving platform in FV that casues it to build at the end instead of the start.
// This extends the smash time so players can ride up the lift.
if (m_TemplateID == 9483)
{ {
comp->SetResetTime(comp->GetResetTime() + 25); rebuildComponent->SetResetTime(rebuildComponent->GetResetTime() + 25);
} }
} }
const auto activityID = GetVar<int32_t>(u"activityID"); const auto activityID = GetVar<int32_t>(u"activityID");
if (activityID > 0) { if (activityID > 0) {
comp->SetActivityId(activityID); rebuildComponent->SetActivityId(activityID);
Loot::CacheMatrix(activityID); Loot::CacheMatrix(activityID);
} }
const auto compTime = GetVar<float>(u"compTime"); const auto compTime = GetVar<float>(u"compTime");
if (compTime > 0) { if (compTime > 0) {
comp->SetCompleteTime(compTime); rebuildComponent->SetCompleteTime(compTime);
} }
} }
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SWITCH, -1) != -1) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SWITCH, -1) != -1) {
SwitchComponent* comp = new SwitchComponent(this); AddComponent<SwitchComponent>();
m_Components.insert(std::make_pair(eReplicaComponentType::SWITCH, comp));
} }
if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::VENDOR) > 0)) { if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::VENDOR) > 0)) {
VendorComponent* comp = new VendorComponent(this); AddComponent<VendorComponent>();
m_Components.insert(std::make_pair(eReplicaComponentType::VENDOR, comp));
} else if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::DONATION_VENDOR, -1) != -1)) { } else if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::DONATION_VENDOR, -1) != -1)) {
DonationVendorComponent* comp = new DonationVendorComponent(this); AddComponent<DonationVendorComponent>();
m_Components.insert(std::make_pair(eReplicaComponentType::DONATION_VENDOR, comp));
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_VENDOR, -1) != -1) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_VENDOR, -1) != -1) {
auto* component = new PropertyVendorComponent(this); AddComponent<PropertyVendorComponent>();
m_Components.insert_or_assign(eReplicaComponentType::PROPERTY_VENDOR, component);
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_MANAGEMENT, -1) != -1) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_MANAGEMENT, -1) != -1) {
auto* component = new PropertyManagementComponent(this); AddComponent<PropertyManagementComponent>();
m_Components.insert_or_assign(eReplicaComponentType::PROPERTY_MANAGEMENT, component);
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BOUNCER, -1) != -1) { // you have to determine it like this because all bouncers have a componentID of 0 if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BOUNCER, -1) != -1) { // you have to determine it like this because all bouncers have a componentID of 0
BouncerComponent* comp = new BouncerComponent(this); AddComponent<BouncerComponent>();
m_Components.insert(std::make_pair(eReplicaComponentType::BOUNCER, comp));
} }
int32_t renderComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RENDER); int32_t renderComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RENDER);
if ((renderComponentId > 0 && m_TemplateID != 2365) || m_Character) { if ((renderComponentId > 0 && m_TemplateID != 2365) || m_Character) {
RenderComponent* render = new RenderComponent(this, renderComponentId); AddComponent<RenderComponent>(renderComponentId);
m_Components.insert(std::make_pair(eReplicaComponentType::RENDER, render));
} }
if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MISSION_OFFER) > 0) || m_Character) { if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MISSION_OFFER) > 0) || m_Character) {
m_Components.insert(std::make_pair(eReplicaComponentType::MISSION_OFFER, new MissionOfferComponent(this, m_TemplateID))); AddComponent<MissionOfferComponent>(m_TemplateID);
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUILD_BORDER, -1) != -1) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUILD_BORDER, -1) != -1) {
m_Components.insert(std::make_pair(eReplicaComponentType::BUILD_BORDER, new BuildBorderComponent(this))); AddComponent<BuildBorderComponent>();
} }
// Scripted activity component // Scripted activity component
int scriptedActivityID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SCRIPTED_ACTIVITY); int scriptedActivityID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SCRIPTED_ACTIVITY);
if ((scriptedActivityID > 0)) { if ((scriptedActivityID > 0)) {
m_Components.insert(std::make_pair(eReplicaComponentType::SCRIPTED_ACTIVITY, new ScriptedActivityComponent(this, scriptedActivityID))); AddComponent<ScriptedActivityComponent>(scriptedActivityID);
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MODEL, -1) != -1 && !GetComponent<PetComponent>()) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MODEL, -1) != -1 && !GetComponent<PetComponent>()) {
m_Components.insert(std::make_pair(eReplicaComponentType::MODEL, new ModelComponent(this))); AddComponent<ModelComponent>();
if (m_Components.find(eReplicaComponentType::DESTROYABLE) == m_Components.end()) { if (!HasComponent(eReplicaComponentType::DESTROYABLE)) {
auto destroyableComponent = new DestroyableComponent(this); auto* destroyableComponent = AddComponent<DestroyableComponent>();
destroyableComponent->SetHealth(1); destroyableComponent->SetHealth(1);
destroyableComponent->SetMaxHealth(1.0f); destroyableComponent->SetMaxHealth(1.0f);
destroyableComponent->SetFaction(-1, true); destroyableComponent->SetFaction(-1, true);
destroyableComponent->SetIsSmashable(true); destroyableComponent->SetIsSmashable(true);
m_Components.insert(std::make_pair(eReplicaComponentType::DESTROYABLE, destroyableComponent));
} }
} }
PetComponent* petComponent; PetComponent* petComponent;
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ITEM) > 0 && !TryGetComponent(eReplicaComponentType::PET, petComponent) && !HasComponent(eReplicaComponentType::MODEL)) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ITEM) > 0 && !TryGetComponent(eReplicaComponentType::PET, petComponent) && !HasComponent(eReplicaComponentType::MODEL)) {
m_Components.insert(std::make_pair(eReplicaComponentType::ITEM, nullptr)); AddComponent<ItemComponent>();
} }
// Shooting gallery component // Shooting gallery component
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SHOOTING_GALLERY) > 0) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SHOOTING_GALLERY) > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::SHOOTING_GALLERY, new ShootingGalleryComponent(this))); AddComponent<ShootingGalleryComponent>();
} }
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY, -1) != -1) { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY, -1) != -1) {
m_Components.insert(std::make_pair(eReplicaComponentType::PROPERTY, new PropertyComponent(this))); AddComponent<PropertyComponent>();
} }
const int rocketId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ROCKET_LAUNCH); const int rocketId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ROCKET_LAUNCH);
if ((rocketId > 0)) { if ((rocketId > 0)) {
m_Components.insert(std::make_pair(eReplicaComponentType::ROCKET_LAUNCH, new RocketLaunchpadControlComponent(this, rocketId))); AddComponent<RocketLaunchpadControlComponent>(rocketId);
} }
const int32_t railComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RAIL_ACTIVATOR); const int32_t railComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RAIL_ACTIVATOR);
if (railComponentID > 0) { if (railComponentID > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::RAIL_ACTIVATOR, new RailActivatorComponent(this, railComponentID))); AddComponent<RailActivatorComponent>(railComponentID);
} }
int movementAIID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MOVEMENT_AI); int movementAIID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MOVEMENT_AI);
@ -701,7 +663,7 @@ void Entity::Initialize() {
} }
} }
m_Components.insert(std::make_pair(eReplicaComponentType::MOVEMENT_AI, new MovementAIComponent(this, moveInfo))); AddComponent<MovementAIComponent>(moveInfo);
} }
} else if (petComponentId > 0 || combatAiId > 0 && GetComponent<BaseCombatAIComponent>()->GetTetherSpeed() > 0) { } else if (petComponentId > 0 || combatAiId > 0 && GetComponent<BaseCombatAIComponent>()->GetTetherSpeed() > 0) {
MovementAIInfo moveInfo = MovementAIInfo(); MovementAIInfo moveInfo = MovementAIInfo();
@ -712,7 +674,7 @@ void Entity::Initialize() {
moveInfo.wanderDelayMax = 5; moveInfo.wanderDelayMax = 5;
moveInfo.wanderDelayMin = 2; moveInfo.wanderDelayMin = 2;
m_Components.insert(std::make_pair(eReplicaComponentType::MOVEMENT_AI, new MovementAIComponent(this, moveInfo))); AddComponent<MovementAIComponent>(moveInfo);
} }
std::string pathName = GetVarAsString(u"attached_path"); std::string pathName = GetVarAsString(u"attached_path");
@ -722,8 +684,7 @@ void Entity::Initialize() {
if (path) { if (path) {
// if we have a moving platform path, then we need a moving platform component // if we have a moving platform path, then we need a moving platform component
if (path->pathType == PathType::MovingPlatform) { if (path->pathType == PathType::MovingPlatform) {
MovingPlatformComponent* plat = new MovingPlatformComponent(this, pathName); AddComponent<MovingPlatformComponent>(pathName);
m_Components.insert(std::make_pair(eReplicaComponentType::MOVING_PLATFORM, plat));
// else if we are a movement path // else if we are a movement path
} /*else if (path->pathType == PathType::Movement) { } /*else if (path->pathType == PathType::Movement) {
auto movementAIcomp = GetComponent<MovementAIComponent>(); auto movementAIcomp = GetComponent<MovementAIComponent>();
@ -737,8 +698,7 @@ void Entity::Initialize() {
// else we still need to setup moving platform if it has a moving platform comp but no path // else we still need to setup moving platform if it has a moving platform comp but no path
int32_t movingPlatformComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MOVING_PLATFORM, -1); int32_t movingPlatformComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MOVING_PLATFORM, -1);
if (movingPlatformComponentId >= 0) { if (movingPlatformComponentId >= 0) {
MovingPlatformComponent* plat = new MovingPlatformComponent(this, pathName); AddComponent<MovingPlatformComponent>(pathName);
m_Components.insert(std::make_pair(eReplicaComponentType::MOVING_PLATFORM, plat));
} }
} }
@ -748,8 +708,7 @@ void Entity::Initialize() {
std::vector<CDProximityMonitorComponent> proxCompData = proxCompTable->Query([=](CDProximityMonitorComponent entry) { return (entry.id == proximityMonitorID); }); std::vector<CDProximityMonitorComponent> proxCompData = proxCompTable->Query([=](CDProximityMonitorComponent entry) { return (entry.id == proximityMonitorID); });
if (proxCompData.size() > 0) { if (proxCompData.size() > 0) {
std::vector<std::string> proximityStr = GeneralUtils::SplitString(proxCompData[0].Proximities, ','); std::vector<std::string> proximityStr = GeneralUtils::SplitString(proxCompData[0].Proximities, ',');
ProximityMonitorComponent* comp = new ProximityMonitorComponent(this, std::stoi(proximityStr[0]), std::stoi(proximityStr[1])); AddComponent<ProximityMonitorComponent>(std::stoi(proximityStr[0]), std::stoi(proximityStr[1]));
m_Components.insert(std::make_pair(eReplicaComponentType::PROXIMITY_MONITOR, comp));
} }
} }
@ -840,14 +799,6 @@ bool Entity::HasComponent(const eReplicaComponentType componentId) const {
return m_Components.find(componentId) != m_Components.end(); return m_Components.find(componentId) != m_Components.end();
} }
void Entity::AddComponent(const eReplicaComponentType componentId, Component* component) {
if (HasComponent(componentId)) {
return;
}
m_Components.insert_or_assign(componentId, component);
}
std::vector<ScriptComponent*> Entity::GetScriptComponents() { std::vector<ScriptComponent*> Entity::GetScriptComponents() {
std::vector<ScriptComponent*> comps; std::vector<ScriptComponent*> comps;
for (std::pair<eReplicaComponentType, void*> p : m_Components) { for (std::pair<eReplicaComponentType, void*> p : m_Components) {
@ -876,20 +827,13 @@ void Entity::Unsubscribe(LWOOBJID scriptObjId, const std::string& notificationNa
} }
void Entity::SetProximityRadius(float proxRadius, std::string name) { void Entity::SetProximityRadius(float proxRadius, std::string name) {
ProximityMonitorComponent* proxMon = GetComponent<ProximityMonitorComponent>(); auto* proxMon = GetComponent<ProximityMonitorComponent>();
if (!proxMon) { if (!proxMon) proxMon = AddComponent<ProximityMonitorComponent>();
proxMon = new ProximityMonitorComponent(this);
m_Components.insert_or_assign(eReplicaComponentType::PROXIMITY_MONITOR, proxMon);
}
proxMon->SetProximityRadius(proxRadius, name); proxMon->SetProximityRadius(proxRadius, name);
} }
void Entity::SetProximityRadius(dpEntity* entity, std::string name) { void Entity::SetProximityRadius(dpEntity* entity, std::string name) {
ProximityMonitorComponent* proxMon = GetComponent<ProximityMonitorComponent>(); ProximityMonitorComponent* proxMon = AddComponent<ProximityMonitorComponent>();
if (!proxMon) {
proxMon = new ProximityMonitorComponent(this);
m_Components.insert_or_assign(eReplicaComponentType::PROXIMITY_MONITOR, proxMon);
}
proxMon->SetProximityRadius(entity, name); proxMon->SetProximityRadius(entity, name);
} }
@ -1104,13 +1048,14 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType
destroyableSerialized = true; destroyableSerialized = true;
} }
if (HasComponent(eReplicaComponentType::COLLECTIBLE)) { CollectibleComponent* collectibleComponent;
if (TryGetComponent(eReplicaComponentType::COLLECTIBLE, collectibleComponent)) {
DestroyableComponent* destroyableComponent; DestroyableComponent* destroyableComponent;
if (TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent) && !destroyableSerialized) { if (TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent) && !destroyableSerialized) {
destroyableComponent->Serialize(outBitStream, bIsInitialUpdate); destroyableComponent->Serialize(outBitStream, bIsInitialUpdate);
} }
destroyableSerialized = true; destroyableSerialized = true;
outBitStream->Write(m_CollectibleID); // Collectable component collectibleComponent->Serialize(outBitStream, bIsInitialUpdate);
} }
PetComponent* petComponent; PetComponent* petComponent;
@ -1148,8 +1093,9 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType
characterComponent->Serialize(outBitStream, bIsInitialUpdate); characterComponent->Serialize(outBitStream, bIsInitialUpdate);
} }
if (HasComponent(eReplicaComponentType::ITEM)) { ItemComponent* itemComponent;
outBitStream->Write0(); if (TryGetComponent(eReplicaComponentType::ITEM, itemComponent)) {
itemComponent->Serialize(outBitStream, bIsInitialUpdate);
} }
InventoryComponent* inventoryComponent; InventoryComponent* inventoryComponent;
@ -1245,8 +1191,9 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType
} }
} }
if (HasComponent(eReplicaComponentType::ZONE_CONTROL)) { ZoneControlComponent* zoneControlComponent;
outBitStream->Write<uint32_t>(0x40000000); if (TryGetComponent(eReplicaComponentType::ZONE_CONTROL, zoneControlComponent)) {
zoneControlComponent->Serialize(outBitStream, bIsInitialUpdate);
} }
// BBB Component, unused currently // BBB Component, unused currently
@ -2102,3 +2049,8 @@ void Entity::RetroactiveVaultSize() {
modelVault->SetSize(itemsVault->GetSize()); modelVault->SetSize(itemsVault->GetSize());
} }
uint8_t Entity::GetCollectibleID() const {
auto* collectible = GetComponent<CollectibleComponent>();
return collectible ? collectible->GetCollectibleId() : 0;
}

View File

@ -66,7 +66,7 @@ public:
eGameMasterLevel GetGMLevel() const { return m_GMLevel; } eGameMasterLevel GetGMLevel() const { return m_GMLevel; }
uint8_t GetCollectibleID() const { return uint8_t(m_CollectibleID); } uint8_t GetCollectibleID() const;
Entity* GetParentEntity() const { return m_ParentEntity; } Entity* GetParentEntity() const { return m_ParentEntity; }
@ -274,6 +274,9 @@ public:
template<typename T> template<typename T>
T GetVarAs(const std::u16string& name) const; T GetVarAs(const std::u16string& name) const;
template<typename ComponentType, typename... VaArgs>
ComponentType* AddComponent(VaArgs... args);
/** /**
* Get the LDF data. * Get the LDF data.
*/ */
@ -501,3 +504,36 @@ T Entity::GetNetworkVar(const std::u16string& name) {
return LDFData<T>::Default; return LDFData<T>::Default;
} }
/**
* @brief Adds a component of type ComponentType to this entity and forwards the arguments to the constructor.
*
* @tparam ComponentType The component class type to add. Must derive from Component.
* @tparam VaArgs The argument types to forward to the constructor.
* @param args The arguments to forward to the constructor. The first argument passed to the ComponentType constructor will be this entity.
* @return ComponentType* The added component. Will never return null.
*/
template<typename ComponentType, typename... VaArgs>
inline ComponentType* Entity::AddComponent(VaArgs... args) {
static_assert(std::is_base_of_v<Component, ComponentType>, "ComponentType must be a Component");
// Get the component if it already exists, or default construct a nullptr
auto*& componentToReturn = m_Components[ComponentType::ComponentType];
// If it doesn't exist, create it and forward the arguments to the constructor
if (!componentToReturn) {
componentToReturn = new ComponentType(this, std::forward<VaArgs>(args)...);
} else {
// In this case the block is already allocated and ready for use
// so we use a placement new to construct the component again as was requested by the caller.
// Placement new means we already have memory allocated for the object, so this just calls its constructor again.
// This is useful for when we want to create a new object in the same memory location as an old one.
componentToReturn->~Component();
new(componentToReturn) ComponentType(this, std::forward<VaArgs>(args)...);
}
// Finally return the created or already existing component.
// Because of the assert above, this should always be a ComponentType* but I need a way to guarantee the map cannot be modifed outside this function
// To allow a static cast here instead of a dynamic one.
return dynamic_cast<ComponentType*>(componentToReturn);
}

View File

@ -177,8 +177,9 @@ void EntityManager::DestroyEntity(Entity* entity) {
} }
void EntityManager::SerializeEntities() { void EntityManager::SerializeEntities() {
for (auto entry = m_EntitiesToSerialize.begin(); entry != m_EntitiesToSerialize.end(); entry++) { for (int32_t i = 0; i < m_EntitiesToSerialize.size(); i++) {
auto* entity = GetEntity(*entry); const LWOOBJID toSerialize = m_EntitiesToSerialize.at(i);
auto* entity = GetEntity(toSerialize);
if (!entity) continue; if (!entity) continue;
@ -193,7 +194,7 @@ void EntityManager::SerializeEntities() {
if (entity->GetIsGhostingCandidate()) { if (entity->GetIsGhostingCandidate()) {
for (auto* player : Player::GetAllPlayers()) { for (auto* player : Player::GetAllPlayers()) {
if (player->IsObserved(*entry)) { if (player->IsObserved(toSerialize)) {
Game::server->Send(&stream, player->GetSystemAddress(), false); Game::server->Send(&stream, player->GetSystemAddress(), false);
} }
} }
@ -205,11 +206,12 @@ void EntityManager::SerializeEntities() {
} }
void EntityManager::KillEntities() { void EntityManager::KillEntities() {
for (auto entry = m_EntitiesToKill.begin(); entry != m_EntitiesToKill.end(); entry++) { for (int32_t i = 0; i < m_EntitiesToKill.size(); i++) {
auto* entity = GetEntity(*entry); const LWOOBJID toKill = m_EntitiesToKill.at(i);
auto* entity = GetEntity(toKill);
if (!entity) { if (!entity) {
LOG("Attempting to kill null entity %llu", *entry); LOG("Attempting to kill null entity %llu", toKill);
continue; continue;
} }
@ -223,8 +225,9 @@ void EntityManager::KillEntities() {
} }
void EntityManager::DeleteEntities() { void EntityManager::DeleteEntities() {
for (auto entry = m_EntitiesToDelete.begin(); entry != m_EntitiesToDelete.end(); entry++) { for (int32_t i = 0; i < m_EntitiesToDelete.size(); i++) {
auto entityToDelete = GetEntity(*entry); const LWOOBJID toDelete = m_EntitiesToDelete.at(i);
auto entityToDelete = GetEntity(toDelete);
if (entityToDelete) { if (entityToDelete) {
// Get all this info first before we delete the player. // Get all this info first before we delete the player.
auto networkIdToErase = entityToDelete->GetNetworkId(); auto networkIdToErase = entityToDelete->GetNetworkId();
@ -238,9 +241,9 @@ void EntityManager::DeleteEntities() {
if (ghostingToDelete != m_EntitiesToGhost.end()) m_EntitiesToGhost.erase(ghostingToDelete); if (ghostingToDelete != m_EntitiesToGhost.end()) m_EntitiesToGhost.erase(ghostingToDelete);
} else { } else {
LOG("Attempted to delete non-existent entity %llu", *entry); LOG("Attempted to delete non-existent entity %llu", toDelete);
} }
m_Entities.erase(*entry); m_Entities.erase(toDelete);
} }
m_EntitiesToDelete.clear(); m_EntitiesToDelete.clear();
} }

View File

@ -47,7 +47,7 @@ struct AiSkillEntry
*/ */
class BaseCombatAIComponent : public Component { class BaseCombatAIComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::BASE_COMBAT_AI; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::BASE_COMBAT_AI;
BaseCombatAIComponent(Entity* parentEntity, uint32_t id); BaseCombatAIComponent(Entity* parentEntity, uint32_t id);
~BaseCombatAIComponent() override; ~BaseCombatAIComponent() override;

View File

@ -12,7 +12,7 @@
*/ */
class BouncerComponent : public Component { class BouncerComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::BOUNCER; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::BOUNCER;
BouncerComponent(Entity* parentEntity); BouncerComponent(Entity* parentEntity);
~BouncerComponent() override; ~BouncerComponent() override;

View File

@ -42,7 +42,7 @@ struct Buff
*/ */
class BuffComponent : public Component { class BuffComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::BUFF; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::BUFF;
explicit BuffComponent(Entity* parent); explicit BuffComponent(Entity* parent);

View File

@ -16,7 +16,7 @@
*/ */
class BuildBorderComponent : public Component { class BuildBorderComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::BUILD_BORDER; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::BUILD_BORDER;
BuildBorderComponent(Entity* parent); BuildBorderComponent(Entity* parent);
~BuildBorderComponent() override; ~BuildBorderComponent() override;

View File

@ -3,11 +3,13 @@ set(DGAME_DCOMPONENTS_SOURCES "BaseCombatAIComponent.cpp"
"BuffComponent.cpp" "BuffComponent.cpp"
"BuildBorderComponent.cpp" "BuildBorderComponent.cpp"
"CharacterComponent.cpp" "CharacterComponent.cpp"
"CollectibleComponent.cpp"
"Component.cpp" "Component.cpp"
"ControllablePhysicsComponent.cpp" "ControllablePhysicsComponent.cpp"
"DestroyableComponent.cpp" "DestroyableComponent.cpp"
"DonationVendorComponent.cpp" "DonationVendorComponent.cpp"
"InventoryComponent.cpp" "InventoryComponent.cpp"
"ItemComponent.cpp"
"LevelProgressionComponent.cpp" "LevelProgressionComponent.cpp"
"LUPExhibitComponent.cpp" "LUPExhibitComponent.cpp"
"MissionComponent.cpp" "MissionComponent.cpp"
@ -42,4 +44,7 @@ set(DGAME_DCOMPONENTS_SOURCES "BaseCombatAIComponent.cpp"
"SwitchComponent.cpp" "SwitchComponent.cpp"
"TriggerComponent.cpp" "TriggerComponent.cpp"
"VehiclePhysicsComponent.cpp" "VehiclePhysicsComponent.cpp"
"VendorComponent.cpp" PARENT_SCOPE) "VendorComponent.cpp"
"ZoneControlComponent.cpp"
PARENT_SCOPE
)

View File

@ -62,7 +62,7 @@ enum StatisticID {
*/ */
class CharacterComponent : public Component { class CharacterComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::CHARACTER; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::CHARACTER;
CharacterComponent(Entity* parent, Character* character); CharacterComponent(Entity* parent, Character* character);
~CharacterComponent() override; ~CharacterComponent() override;

View File

@ -0,0 +1,5 @@
#include "CollectibleComponent.h"
void CollectibleComponent::Serialize(RakNet::BitStream* outBitStream, bool isConstruction) {
outBitStream->Write(GetCollectibleId());
}

View File

@ -0,0 +1,18 @@
#ifndef __COLLECTIBLECOMPONENT__H__
#define __COLLECTIBLECOMPONENT__H__
#include "Component.h"
#include "eReplicaComponentType.h"
class CollectibleComponent : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::COLLECTIBLE;
CollectibleComponent(Entity* parentEntity, int32_t collectibleId) : Component(parentEntity), m_CollectibleId(collectibleId) {}
int16_t GetCollectibleId() const { return m_CollectibleId; }
void Serialize(RakNet::BitStream* outBitStream, bool isConstruction) override;
private:
int16_t m_CollectibleId = 0;
};
#endif //!__COLLECTIBLECOMPONENT__H__

View File

@ -21,7 +21,7 @@ enum class eStateChangeType : uint32_t;
*/ */
class ControllablePhysicsComponent : public PhysicsComponent { class ControllablePhysicsComponent : public PhysicsComponent {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::CONTROLLABLE_PHYSICS; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::CONTROLLABLE_PHYSICS;
ControllablePhysicsComponent(Entity* entity); ControllablePhysicsComponent(Entity* entity);
~ControllablePhysicsComponent() override; ~ControllablePhysicsComponent() override;

View File

@ -19,7 +19,7 @@ enum class eStateChangeType : uint32_t;
*/ */
class DestroyableComponent : public Component { class DestroyableComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::DESTROYABLE; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::DESTROYABLE;
DestroyableComponent(Entity* parentEntity); DestroyableComponent(Entity* parentEntity);
~DestroyableComponent() override; ~DestroyableComponent() override;

View File

@ -38,7 +38,7 @@ enum class eItemType : int32_t;
class InventoryComponent : public Component class InventoryComponent : public Component
{ {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::INVENTORY; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::INVENTORY;
explicit InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document = nullptr); explicit InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document = nullptr);
void Update(float deltaTime) override; void Update(float deltaTime) override;

View File

@ -0,0 +1,5 @@
#include "ItemComponent.h"
void ItemComponent::Serialize(RakNet::BitStream* outBitStream, bool isConstruction) {
outBitStream->Write0();
}

View File

@ -0,0 +1,16 @@
#ifndef __ITEMCOMPONENT__H__
#define __ITEMCOMPONENT__H__
#include "Component.h"
#include "eReplicaComponentType.h"
class ItemComponent : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::ITEM;
ItemComponent(Entity* entity) : Component(entity) {}
void Serialize(RakNet::BitStream* bitStream, bool isConstruction) override;
};
#endif //!__ITEMCOMPONENT__H__

View File

@ -11,7 +11,7 @@
class LUPExhibitComponent : public Component class LUPExhibitComponent : public Component
{ {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::EXHIBIT; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::EXHIBIT;
LUPExhibitComponent(Entity* parent); LUPExhibitComponent(Entity* parent);
~LUPExhibitComponent(); ~LUPExhibitComponent();

View File

@ -13,7 +13,7 @@
class LevelProgressionComponent : public Component { class LevelProgressionComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::LEVEL_PROGRESSION; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::LEVEL_PROGRESSION;
/** /**
* Constructor for this component * Constructor for this component

View File

@ -27,7 +27,7 @@ class AchievementCacheKey;
class MissionComponent : public Component class MissionComponent : public Component
{ {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::MISSION; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MISSION;
explicit MissionComponent(Entity* parent); explicit MissionComponent(Entity* parent);
~MissionComponent() override; ~MissionComponent() override;

View File

@ -61,7 +61,7 @@ private:
*/ */
class MissionOfferComponent : public Component { class MissionOfferComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::MISSION_OFFER; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MISSION_OFFER;
MissionOfferComponent(Entity* parent, LOT parentLot); MissionOfferComponent(Entity* parent, LOT parentLot);
~MissionOfferComponent() override; ~MissionOfferComponent() override;

View File

@ -13,7 +13,7 @@ class Entity;
*/ */
class ModelComponent : public Component { class ModelComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::MODEL; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MODEL;
ModelComponent(Entity* parent); ModelComponent(Entity* parent);

View File

@ -12,7 +12,7 @@
*/ */
class ModuleAssemblyComponent : public Component { class ModuleAssemblyComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::MODULE_ASSEMBLY; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MODULE_ASSEMBLY;
ModuleAssemblyComponent(Entity* parent); ModuleAssemblyComponent(Entity* parent);
~ModuleAssemblyComponent() override; ~ModuleAssemblyComponent() override;

View File

@ -57,7 +57,7 @@ struct MovementAIInfo {
*/ */
class MovementAIComponent : public Component { class MovementAIComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVEMENT_AI; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVEMENT_AI;
MovementAIComponent(Entity* parentEntity, MovementAIInfo info); MovementAIComponent(Entity* parentEntity, MovementAIInfo info);

View File

@ -106,7 +106,7 @@ public:
*/ */
class MovingPlatformComponent : public Component { class MovingPlatformComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVING_PLATFORM; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVING_PLATFORM;
MovingPlatformComponent(Entity* parent, const std::string& pathName); MovingPlatformComponent(Entity* parent, const std::string& pathName);
~MovingPlatformComponent() override; ~MovingPlatformComponent() override;

View File

@ -10,7 +10,7 @@
*/ */
class MultiZoneEntranceComponent : public Component { class MultiZoneEntranceComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::MULTI_ZONE_ENTRANCE; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MULTI_ZONE_ENTRANCE;
/** /**
* Constructor for this component, builds the m_LUPWorlds vector * Constructor for this component, builds the m_LUPWorlds vector

View File

@ -21,7 +21,7 @@ enum class PetAbilityType
class PetComponent : public Component class PetComponent : public Component
{ {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::PET; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PET;
explicit PetComponent(Entity* parentEntity, uint32_t componentId); explicit PetComponent(Entity* parentEntity, uint32_t componentId);
~PetComponent() override; ~PetComponent() override;

View File

@ -27,7 +27,7 @@ enum class ePhysicsEffectType : uint32_t ;
*/ */
class PhantomPhysicsComponent : public PhysicsComponent { class PhantomPhysicsComponent : public PhysicsComponent {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::PHANTOM_PHYSICS; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PHANTOM_PHYSICS;
PhantomPhysicsComponent(Entity* parent); PhantomPhysicsComponent(Entity* parent);
~PhantomPhysicsComponent() override; ~PhantomPhysicsComponent() override;

View File

@ -10,7 +10,7 @@
*/ */
class PlayerForcedMovementComponent : public Component { class PlayerForcedMovementComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::PLAYER_FORCED_MOVEMENT; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PLAYER_FORCED_MOVEMENT;
/** /**
* Constructor for this component * Constructor for this component

View File

@ -14,7 +14,7 @@
*/ */
class PossessableComponent : public Component { class PossessableComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::POSSESSABLE; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::POSSESSABLE;
PossessableComponent(Entity* parentEntity, uint32_t componentId); PossessableComponent(Entity* parentEntity, uint32_t componentId);

View File

@ -18,7 +18,7 @@ enum class ePossessionType : uint8_t {
*/ */
class PossessorComponent : public Component { class PossessorComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::POSSESSOR; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::POSSESSOR;
PossessorComponent(Entity* parent); PossessorComponent(Entity* parent);
~PossessorComponent() override; ~PossessorComponent() override;

View File

@ -22,7 +22,7 @@ struct PropertyState {
*/ */
class PropertyComponent : public Component { class PropertyComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY;
explicit PropertyComponent(Entity* parentEntity); explicit PropertyComponent(Entity* parentEntity);
~PropertyComponent() override; ~PropertyComponent() override;
[[nodiscard]] PropertyState* GetPropertyState() const { return m_PropertyState; }; [[nodiscard]] PropertyState* GetPropertyState() const { return m_PropertyState; };

View File

@ -15,7 +15,7 @@
#include "eObjectBits.h" #include "eObjectBits.h"
#include "eGameMasterLevel.h" #include "eGameMasterLevel.h"
PropertyEntranceComponent::PropertyEntranceComponent(uint32_t componentID, Entity* parent) : Component(parent) { PropertyEntranceComponent::PropertyEntranceComponent(Entity* parent, uint32_t componentID) : Component(parent) {
this->propertyQueries = {}; this->propertyQueries = {};
auto table = CDClientManager::Instance().GetTable<CDPropertyEntranceComponentTable>(); auto table = CDClientManager::Instance().GetTable<CDPropertyEntranceComponentTable>();

View File

@ -13,8 +13,8 @@
*/ */
class PropertyEntranceComponent : public Component { class PropertyEntranceComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_ENTRANCE; explicit PropertyEntranceComponent(Entity* parent, uint32_t componentID);
explicit PropertyEntranceComponent(uint32_t componentID, Entity* parent); inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_ENTRANCE;
/** /**
* Handles an OnUse request for some other entity, rendering the property browse menu * Handles an OnUse request for some other entity, rendering the property browse menu

View File

@ -32,7 +32,7 @@ enum class PropertyPrivacyOption
class PropertyManagementComponent : public Component class PropertyManagementComponent : public Component
{ {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_MANAGEMENT; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_MANAGEMENT;
PropertyManagementComponent(Entity* parent); PropertyManagementComponent(Entity* parent);
static PropertyManagementComponent* Instance(); static PropertyManagementComponent* Instance();

View File

@ -10,7 +10,7 @@
class PropertyVendorComponent : public Component class PropertyVendorComponent : public Component
{ {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_VENDOR; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_VENDOR;
explicit PropertyVendorComponent(Entity* parent); explicit PropertyVendorComponent(Entity* parent);
/** /**

View File

@ -19,7 +19,7 @@
*/ */
class ProximityMonitorComponent : public Component { class ProximityMonitorComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::PROXIMITY_MONITOR; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROXIMITY_MONITOR;
ProximityMonitorComponent(Entity* parentEntity, int smallRadius = -1, int largeRadius = -1); ProximityMonitorComponent(Entity* parentEntity, int smallRadius = -1, int largeRadius = -1);
~ProximityMonitorComponent() override; ~ProximityMonitorComponent() override;

View File

@ -105,7 +105,7 @@ struct RacingPlayerInfo {
*/ */
class RacingControlComponent : public Component { class RacingControlComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::RACING_CONTROL; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RACING_CONTROL;
RacingControlComponent(Entity* parentEntity); RacingControlComponent(Entity* parentEntity);
~RacingControlComponent(); ~RacingControlComponent();

View File

@ -0,0 +1,14 @@
#ifndef __RACINGSTATSCOMPONENT__H__
#define __RACINGSTATSCOMPONENT__H__
#include "Component.h"
#include "eReplicaComponentType.h"
class RacingStatsComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RACING_STATS;
RacingStatsComponent(Entity* parent) : Component(parent) {}
};
#endif //!__RACINGSTATSCOMPONENT__H__

View File

@ -15,7 +15,7 @@ public:
explicit RailActivatorComponent(Entity* parent, int32_t componentID); explicit RailActivatorComponent(Entity* parent, int32_t componentID);
~RailActivatorComponent() override; ~RailActivatorComponent() override;
static const eReplicaComponentType ComponentType = eReplicaComponentType::RAIL_ACTIVATOR; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RAIL_ACTIVATOR;
/** /**
* Handles the OnUse event from some entity, initiates the rail movement * Handles the OnUse event from some entity, initiates the rail movement

View File

@ -22,7 +22,7 @@ enum class eQuickBuildFailReason : uint32_t;
*/ */
class RebuildComponent : public Component { class RebuildComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::QUICK_BUILD; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::QUICK_BUILD;
RebuildComponent(Entity* entity); RebuildComponent(Entity* entity);
~RebuildComponent() override; ~RebuildComponent() override;

View File

@ -56,7 +56,7 @@ struct Effect {
*/ */
class RenderComponent : public Component { class RenderComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::RENDER; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RENDER;
RenderComponent(Entity* entity, int32_t componentId = -1); RenderComponent(Entity* entity, int32_t componentId = -1);
~RenderComponent() override; ~RenderComponent() override;

View File

@ -19,7 +19,7 @@
*/ */
class RigidbodyPhantomPhysicsComponent : public PhysicsComponent { class RigidbodyPhantomPhysicsComponent : public PhysicsComponent {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS;
RigidbodyPhantomPhysicsComponent(Entity* parent); RigidbodyPhantomPhysicsComponent(Entity* parent);

View File

@ -18,7 +18,7 @@ class PreconditionExpression;
*/ */
class RocketLaunchpadControlComponent : public Component { class RocketLaunchpadControlComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::ROCKET_LAUNCH; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::ROCKET_LAUNCH;
RocketLaunchpadControlComponent(Entity* parent, int rocketId); RocketLaunchpadControlComponent(Entity* parent, int rocketId);
~RocketLaunchpadControlComponent() override; ~RocketLaunchpadControlComponent() override;

View File

@ -156,7 +156,7 @@ struct ActivityPlayer {
*/ */
class ScriptedActivityComponent : public Component { class ScriptedActivityComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::SCRIPTED_ACTIVITY; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SCRIPTED_ACTIVITY;
ScriptedActivityComponent(Entity* parent, int activityID); ScriptedActivityComponent(Entity* parent, int activityID);
~ScriptedActivityComponent() override; ~ScriptedActivityComponent() override;

View File

@ -73,7 +73,7 @@ struct StaticShootingGalleryParams {
*/ */
class ShootingGalleryComponent : public Component { class ShootingGalleryComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::SHOOTING_GALLERY; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SHOOTING_GALLERY;
explicit ShootingGalleryComponent(Entity* parent); explicit ShootingGalleryComponent(Entity* parent);
~ShootingGalleryComponent(); ~ShootingGalleryComponent();

View File

@ -13,7 +13,7 @@
#include "Entity.h" #include "Entity.h"
SimplePhysicsComponent::SimplePhysicsComponent(uint32_t componentID, Entity* parent) : PhysicsComponent(parent) { SimplePhysicsComponent::SimplePhysicsComponent(Entity* parent, uint32_t componentID) : PhysicsComponent(parent) {
m_Position = m_Parent->GetDefaultPosition(); m_Position = m_Parent->GetDefaultPosition();
m_Rotation = m_Parent->GetDefaultRotation(); m_Rotation = m_Parent->GetDefaultRotation();

View File

@ -28,9 +28,9 @@ enum class eClimbableType : int32_t {
*/ */
class SimplePhysicsComponent : public PhysicsComponent { class SimplePhysicsComponent : public PhysicsComponent {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::SIMPLE_PHYSICS; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SIMPLE_PHYSICS;
SimplePhysicsComponent(uint32_t componentID, Entity* parent); SimplePhysicsComponent(Entity* parent, uint32_t componentID);
~SimplePhysicsComponent() override; ~SimplePhysicsComponent() override;
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;

View File

@ -59,7 +59,7 @@ struct SkillExecutionResult {
*/ */
class SkillComponent : public Component { class SkillComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::SKILL; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SKILL;
explicit SkillComponent(Entity* parent); explicit SkillComponent(Entity* parent);
~SkillComponent() override; ~SkillComponent() override;

View File

@ -58,7 +58,7 @@ struct MixerProgram{
class SoundTriggerComponent : public Component { class SoundTriggerComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::SOUND_TRIGGER; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SOUND_TRIGGER;
explicit SoundTriggerComponent(Entity* parent); explicit SoundTriggerComponent(Entity* parent);
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
void ActivateMusicCue(const std::string& name, float bordemTime = -1.0); void ActivateMusicCue(const std::string& name, float bordemTime = -1.0);

View File

@ -16,7 +16,7 @@
*/ */
class SwitchComponent : public Component { class SwitchComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::SWITCH; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SWITCH;
SwitchComponent(Entity* parent); SwitchComponent(Entity* parent);
~SwitchComponent() override; ~SwitchComponent() override;

View File

@ -7,7 +7,7 @@
class TriggerComponent : public Component { class TriggerComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::TRIGGER; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::TRIGGER;
explicit TriggerComponent(Entity* parent, const std::string triggerInfo); explicit TriggerComponent(Entity* parent, const std::string triggerInfo);

View File

@ -28,7 +28,7 @@ struct RemoteInputInfo {
*/ */
class VehiclePhysicsComponent : public PhysicsComponent { class VehiclePhysicsComponent : public PhysicsComponent {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::VEHICLE_PHYSICS; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::VEHICLE_PHYSICS;
VehiclePhysicsComponent(Entity* parentEntity); VehiclePhysicsComponent(Entity* parentEntity);

View File

@ -0,0 +1,5 @@
#include "ZoneControlComponent.h"
void ZoneControlComponent::Serialize(RakNet::BitStream* outBitStream, bool isConstruction) {
outBitStream->Write<uint32_t>(0x40000000);
}

View File

@ -0,0 +1,15 @@
#ifndef __ZONECONTROLCOMPONENT__H__
#define __ZONECONTROLCOMPONENT__H__
#include "Component.h"
#include "eReplicaComponentType.h"
class ZoneControlComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::ZONE_CONTROL;
ZoneControlComponent(Entity* parent) : Component(parent) {}
void Serialize(RakNet::BitStream* outBitStream, bool isConstruction);
};
#endif //!__ZONECONTROLCOMPONENT__H__

View File

@ -131,7 +131,7 @@ float dNavMesh::GetHeightAtPoint(const NiPoint3& location, const float halfExten
pos[2] = location.z; pos[2] = location.z;
dtPolyRef nearestRef = 0; dtPolyRef nearestRef = 0;
float polyPickExt[3] = { 0.0f, halfExtentsHeight, 0.0f }; float polyPickExt[3] = { 32.0f, halfExtentsHeight, 32.0f };
float nearestPoint[3] = { 0.0f, 0.0f, 0.0f }; float nearestPoint[3] = { 0.0f, 0.0f, 0.0f };
dtQueryFilter filter{}; dtQueryFilter filter{};

View File

@ -52,7 +52,7 @@ void BossSpiderQueenEnemyServer::OnStartup(Entity* self) {
} }
void BossSpiderQueenEnemyServer::OnDie(Entity* self, Entity* killer) { void BossSpiderQueenEnemyServer::OnDie(Entity* self, Entity* killer) {
if (Game::zoneManager->GetZoneID().GetMapID() == instanceZoneID) { if (Game::zoneManager->GetZoneID().GetMapID() == instanceZoneID && killer) {
auto* missionComponent = killer->GetComponent<MissionComponent>(); auto* missionComponent = killer->GetComponent<MissionComponent>();
if (missionComponent == nullptr) if (missionComponent == nullptr)
return; return;
@ -196,7 +196,7 @@ void BossSpiderQueenEnemyServer::SpiderWaveManager(Entity* self) {
for (auto en : hatchList) { for (auto en : hatchList) {
if (en == randomEgg) { if (en == randomEgg) {
randomEggLoc++; randomEggLoc++;
randomEgg = spiderEggs[randomEggLoc]; randomEgg = spiderEggs.at(randomEggLoc % spiderEggs.size());
} }
} }
@ -288,7 +288,7 @@ void BossSpiderQueenEnemyServer::RunRainOfFire(Entity* self) {
if (index == 0) { if (index == 0) {
impactList.insert(impactList.end(), spawned.begin(), spawned.end()); impactList.insert(impactList.end(), spawned.begin(), spawned.end());
} else { } else if (!spawned.empty()) {
const auto randomIndex = GeneralUtils::GenerateRandomNumber<int32_t>(0, spawned.size() - 1); const auto randomIndex = GeneralUtils::GenerateRandomNumber<int32_t>(0, spawned.size() - 1);
impactList.push_back(spawned[randomIndex]); impactList.push_back(spawned[randomIndex]);

View File

@ -15,8 +15,7 @@ void NtFactionSpyServer::OnStartup(Entity* self) {
// Set the proximity to sense later // Set the proximity to sense later
auto* proximityMonitor = self->GetComponent<ProximityMonitorComponent>(); auto* proximityMonitor = self->GetComponent<ProximityMonitorComponent>();
if (proximityMonitor == nullptr) { if (proximityMonitor == nullptr) {
proximityMonitor = new ProximityMonitorComponent(self, -1, -1); proximityMonitor = self->AddComponent<ProximityMonitorComponent>(-1, -1);
self->AddComponent(eReplicaComponentType::PROXIMITY_MONITOR, proximityMonitor);
} }
proximityMonitor->SetProximityRadius(self->GetVar<float_t>(m_SpyProximityVariable), m_ProximityName); proximityMonitor->SetProximityRadius(self->GetVar<float_t>(m_SpyProximityVariable), m_ProximityName);

View File

@ -19,7 +19,7 @@ class Entity;
*/ */
class ScriptComponent : public Component { class ScriptComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::SCRIPT; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SCRIPT;
ScriptComponent(Entity* parent, std::string scriptName, bool serialized, bool client = false); ScriptComponent(Entity* parent, std::string scriptName, bool serialized, bool client = false);
~ScriptComponent() override; ~ScriptComponent() override;

View File

@ -12,6 +12,5 @@ void AgStromlingProperty::OnStartup(Entity* self) {
4 4
}; };
auto* movementAIComponent = new MovementAIComponent(self, movementInfo); self->AddComponent<MovementAIComponent>(movementInfo);
self->AddComponent(eReplicaComponentType::MOVEMENT_AI, movementAIComponent);
} }

View File

@ -302,9 +302,7 @@ void SGCannon::DoSpawnTimerFunc(Entity* self, const std::string& name) {
auto* enemy = Game::entityManager->CreateEntity(info, nullptr, self); auto* enemy = Game::entityManager->CreateEntity(info, nullptr, self);
Game::entityManager->ConstructEntity(enemy); Game::entityManager->ConstructEntity(enemy);
auto* movementAI = new MovementAIComponent(enemy, {}); auto* movementAI = enemy->AddComponent<MovementAIComponent>(MovementAIInfo{});
enemy->AddComponent(eReplicaComponentType::MOVEMENT_AI, movementAI);
movementAI->SetMaxSpeed(toSpawn.initialSpeed); movementAI->SetMaxSpeed(toSpawn.initialSpeed);
movementAI->SetCurrentSpeed(toSpawn.initialSpeed); movementAI->SetCurrentSpeed(toSpawn.initialSpeed);

Binary file not shown.

View File

@ -16,8 +16,7 @@ protected:
void SetUp() override { void SetUp() override {
SetUpDependencies(); SetUpDependencies();
baseEntity = new Entity(15, GameDependenciesTest::info); baseEntity = new Entity(15, GameDependenciesTest::info);
destroyableComponent = new DestroyableComponent(baseEntity); destroyableComponent = baseEntity->AddComponent<DestroyableComponent>();
baseEntity->AddComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent);
// Initialize some values to be not default // Initialize some values to be not default
destroyableComponent->SetMaxHealth(12345.0f); destroyableComponent->SetMaxHealth(12345.0f);
destroyableComponent->SetHealth(23); destroyableComponent->SetHealth(23);
@ -37,6 +36,14 @@ protected:
} }
}; };
TEST_F(DestroyableTest, PlacementNewAddComponentTest) {
ASSERT_NE(destroyableComponent, nullptr);
ASSERT_EQ(destroyableComponent->GetArmor(), 7);
baseEntity->AddComponent<DestroyableComponent>();
ASSERT_NE(baseEntity->GetComponent<DestroyableComponent>(), nullptr);
ASSERT_EQ(destroyableComponent->GetArmor(), 0);
}
/** /**
* Test Construction of a DestroyableComponent * Test Construction of a DestroyableComponent
*/ */
@ -318,9 +325,7 @@ TEST_F(DestroyableTest, DestroyableComponentFactionTest) {
TEST_F(DestroyableTest, DestroyableComponentValiditiyTest) { TEST_F(DestroyableTest, DestroyableComponentValiditiyTest) {
auto* enemyEntity = new Entity(19, info); auto* enemyEntity = new Entity(19, info);
auto* enemyDestroyableComponent = new DestroyableComponent(enemyEntity); enemyEntity->AddComponent<DestroyableComponent>()->AddFactionNoLookup(16);
enemyEntity->AddComponent(eReplicaComponentType::DESTROYABLE, enemyDestroyableComponent);
enemyDestroyableComponent->AddFactionNoLookup(16);
destroyableComponent->AddEnemyFaction(16); destroyableComponent->AddEnemyFaction(16);
EXPECT_TRUE(destroyableComponent->IsEnemy(enemyEntity)); EXPECT_TRUE(destroyableComponent->IsEnemy(enemyEntity));
EXPECT_FALSE(destroyableComponent->IsFriend(enemyEntity)); EXPECT_FALSE(destroyableComponent->IsFriend(enemyEntity));

View File

@ -15,8 +15,7 @@ protected:
void SetUp() override { void SetUp() override {
SetUpDependencies(); SetUpDependencies();
baseEntity = std::make_unique<Entity>(15, GameDependenciesTest::info); baseEntity = std::make_unique<Entity>(15, GameDependenciesTest::info);
simplePhysicsComponent = new SimplePhysicsComponent(1, baseEntity.get()); simplePhysicsComponent = baseEntity->AddComponent<SimplePhysicsComponent>(1);
baseEntity->AddComponent(SimplePhysicsComponent::ComponentType, simplePhysicsComponent);
simplePhysicsComponent->SetClimbableType(eClimbableType::CLIMBABLE_TYPE_WALL); simplePhysicsComponent->SetClimbableType(eClimbableType::CLIMBABLE_TYPE_WALL);
simplePhysicsComponent->SetPosition(NiPoint3(1.0f, 2.0f, 3.0f)); simplePhysicsComponent->SetPosition(NiPoint3(1.0f, 2.0f, 3.0f));
simplePhysicsComponent->SetRotation(NiQuaternion(1.0f, 2.0f, 3.0f, 4.0f)); simplePhysicsComponent->SetRotation(NiQuaternion(1.0f, 2.0f, 3.0f, 4.0f));