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()
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
if (NOT EXISTS ${PROJECT_BINARY_DIR}/navmeshes/)
configure_file(
configure_file(
${CMAKE_SOURCE_DIR}/resources/navmeshes.zip ${PROJECT_BINARY_DIR}/navmeshes.zip
COPYONLY
)
)
file(ARCHIVE_EXTRACT INPUT ${PROJECT_BINARY_DIR}/navmeshes.zip)
file(REMOVE ${PROJECT_BINARY_DIR}/navmeshes.zip)
endif()
file(ARCHIVE_EXTRACT INPUT ${PROJECT_BINARY_DIR}/navmeshes.zip DESTINATION ${PROJECT_BINARY_DIR}/navmeshes)
file(REMOVE ${PROJECT_BINARY_DIR}/navmeshes.zip)
# Copy vanity files on first build
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);
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) {
SendFriendResponse(requestor, requestor, eAddFriendResponseType::MYTHRAN);
return;

View File

@ -134,6 +134,10 @@ void CatchUnhandled(int sig) {
// Loop through the returned addresses, and get the symbols to be demangled
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
for (size_t i = 0; i < size; i++) {
// Take a string like './WorldServer(_ZN19SlashCommandHandler17HandleChatCommandERKSbIDsSt11char_traitsIDsESaIDsEEP6EntityRK13SystemAddress+0x6187) [0x55869c44ecf7]'
@ -155,19 +159,14 @@ void CatchUnhandled(int sig) {
}
LOG("[%02zu] %s", i, functionName.c_str());
if (file != NULL) {
fprintf(file, "[%02zu] %s\n", i, functionName.c_str());
}
}
# else // defined(__GNUG__)
backtrace_symbols_fd(array, size, STDOUT_FILENO);
# 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__
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.
*/
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__

View File

@ -394,12 +394,13 @@ void Character::SetIsNewLogin() {
auto* currentChild = flags->FirstChildElement();
while (currentChild) {
auto* nextChild = currentChild->NextSiblingElement();
if (currentChild->Attribute("si")) {
flags->DeleteChild(currentChild);
LOG("Removed isLoggedIn flag from character %i:%s, saving character to database", GetID(), GetName().c_str());
WriteToDatabase();
}
currentChild = currentChild->NextSiblingElement();
currentChild = nextChild;
}
}
@ -554,15 +555,6 @@ void Character::OnZoneLoad() {
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>();
if (inventoryComponent == nullptr) {

View File

@ -76,6 +76,10 @@
#include "eGameMasterLevel.h"
#include "eReplicaComponentType.h"
#include "eReplicaPacketType.h"
#include "ZoneControlComponent.h"
#include "RacingStatsComponent.h"
#include "CollectibleComponent.h"
#include "ItemComponent.h"
// Table includes
#include "CDComponentsRegistryTable.h"
@ -95,7 +99,6 @@ Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity)
m_ParentEntity = parentEntity;
m_Character = nullptr;
m_GMLevel = eGameMasterLevel::CIVILIAN;
m_CollectibleID = 0;
m_NetworkID = 0;
m_Groups = {};
m_OwnerOverride = LWOOBJID_EMPTY;
@ -153,7 +156,7 @@ void Entity::Initialize() {
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
@ -184,21 +187,17 @@ void Entity::Initialize() {
if (m_TemplateID == 14) {
const auto simplePhysicsComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SIMPLE_PHYSICS);
SimplePhysicsComponent* comp = new SimplePhysicsComponent(simplePhysicsComponentID, this);
m_Components.insert(std::make_pair(eReplicaComponentType::SIMPLE_PHYSICS, comp));
AddComponent<SimplePhysicsComponent>(simplePhysicsComponentID);
ModelComponent* modelcomp = new ModelComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::MODEL, modelcomp));
AddComponent<ModelComponent>();
RenderComponent* render = new RenderComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::RENDER, render));
AddComponent<RenderComponent>();
auto destroyableComponent = new DestroyableComponent(this);
auto* destroyableComponent = AddComponent<DestroyableComponent>();
destroyableComponent->SetHealth(1);
destroyableComponent->SetMaxHealth(1.0f);
destroyableComponent->SetFaction(-1, true);
destroyableComponent->SetIsSmashable(true);
m_Components.insert(std::make_pair(eReplicaComponentType::DESTROYABLE, destroyableComponent));
// We have all our components.
return;
}
@ -210,49 +209,46 @@ void Entity::Initialize() {
*/
if (GetParentUser()) {
auto missions = new MissionComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::MISSION, missions));
missions->LoadFromXml(m_Character->GetXMLDoc());
AddComponent<MissionComponent>()->LoadFromXml(m_Character->GetXMLDoc());
}
uint32_t petComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PET);
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) {
m_Components.insert(std::make_pair(eReplicaComponentType::ZONE_CONTROL, nullptr));
AddComponent<ZoneControlComponent>();
}
uint32_t possessableComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::POSSESSABLE);
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) {
m_Components.insert(std::make_pair(eReplicaComponentType::MODULE_ASSEMBLY, new ModuleAssemblyComponent(this)));
AddComponent<ModuleAssemblyComponent>();
}
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) {
m_Components.insert(std::make_pair(eReplicaComponentType::LUP_EXHIBIT, new LUPExhibitComponent(this)));
AddComponent<LUPExhibitComponent>();
}
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);
if (propertyEntranceComponentID > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::PROPERTY_ENTRANCE,
new PropertyEntranceComponent(propertyEntranceComponentID, this)));
AddComponent<PropertyEntranceComponent>(propertyEntranceComponentID);
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::CONTROLLABLE_PHYSICS) > 0) {
ControllablePhysicsComponent* controllablePhysics = new ControllablePhysicsComponent(this);
auto* controllablePhysics = AddComponent<ControllablePhysicsComponent>();
if (m_Character) {
controllablePhysics->LoadFromXml(m_Character->GetXMLDoc());
@ -285,8 +281,6 @@ void Entity::Initialize() {
controllablePhysics->SetPosition(m_DefaultPosition);
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.
@ -294,54 +288,42 @@ void Entity::Initialize() {
const auto simplePhysicsComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SIMPLE_PHYSICS);
if (!markedAsPhantom && simplePhysicsComponentID > 0) {
SimplePhysicsComponent* comp = new SimplePhysicsComponent(simplePhysicsComponentID, this);
m_Components.insert(std::make_pair(eReplicaComponentType::SIMPLE_PHYSICS, comp));
AddComponent<SimplePhysicsComponent>(simplePhysicsComponentID);
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS) > 0) {
RigidbodyPhantomPhysicsComponent* comp = new RigidbodyPhantomPhysicsComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS, comp));
AddComponent<RigidbodyPhantomPhysicsComponent>();
}
if (markedAsPhantom || compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PHANTOM_PHYSICS) > 0) {
PhantomPhysicsComponent* phantomPhysics = new PhantomPhysicsComponent(this);
phantomPhysics->SetPhysicsEffectActive(false);
m_Components.insert(std::make_pair(eReplicaComponentType::PHANTOM_PHYSICS, phantomPhysics));
AddComponent<PhantomPhysicsComponent>()->SetPhysicsEffectActive(false);
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::VEHICLE_PHYSICS) > 0) {
VehiclePhysicsComponent* vehiclePhysicsComponent = new VehiclePhysicsComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::VEHICLE_PHYSICS, vehiclePhysicsComponent));
auto* vehiclePhysicsComponent = AddComponent<VehiclePhysicsComponent>();
vehiclePhysicsComponent->SetPosition(m_DefaultPosition);
vehiclePhysicsComponent->SetRotation(m_DefaultRotation);
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SOUND_TRIGGER, -1) != -1) {
auto* comp = new SoundTriggerComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::SOUND_TRIGGER, comp));
AddComponent<SoundTriggerComponent>();
} else if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RACING_SOUND_TRIGGER, -1) != -1) {
auto* comp = new RacingSoundTriggerComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::RACING_SOUND_TRIGGER, comp));
AddComponent<RacingSoundTriggerComponent>();
}
//Also check for the collectible id:
m_CollectibleID = GetVarAs<int32_t>(u"collectible_id");
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUFF) > 0) {
BuffComponent* comp = new BuffComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::BUFF, comp));
AddComponent<BuffComponent>();
}
int collectibleComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::COLLECTIBLE);
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.
*/
int buffComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUFF);
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;
if (buffComponentID > 0 || collectibleComponentID > 0 || isSmashable) {
DestroyableComponent* comp = new DestroyableComponent(this);
DestroyableComponent* comp = AddComponent<DestroyableComponent>();
if (m_Character) {
comp->LoadFromXml(m_Character->GetXMLDoc());
} 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) {
// 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
auto* levelComp = new LevelProgressionComponent(this);
levelComp->LoadFromXml(m_Character->GetXMLDoc());
m_Components.insert(std::make_pair(eReplicaComponentType::LEVEL_PROGRESSION, levelComp));
AddComponent<LevelProgressionComponent>()->LoadFromXml(m_Character->GetXMLDoc());
m_Components.insert(std::make_pair(eReplicaComponentType::PLAYER_FORCED_MOVEMENT, new PlayerForcedMovementComponent(this)));
AddComponent<PlayerForcedMovementComponent>();
CharacterComponent* charComp = new CharacterComponent(this, m_Character);
charComp->LoadFromXml(m_Character->GetXMLDoc());
m_Components.insert(std::make_pair(eReplicaComponentType::CHARACTER, charComp));
AddComponent<CharacterComponent>(m_Character)->LoadFromXml(m_Character->GetXMLDoc());
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::INVENTORY) > 0 || m_Character) {
InventoryComponent* comp = nullptr;
if (m_Character) comp = new InventoryComponent(this, m_Character->GetXMLDoc());
else comp = new InventoryComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::INVENTORY, comp));
auto* xmlDoc = m_Character ? m_Character->GetXMLDoc() : nullptr;
AddComponent<InventoryComponent>(xmlDoc);
}
// 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) {
auto comp = new MultiZoneEntranceComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::MULTI_ZONE_ENTRANCE, comp));
AddComponent<MultiZoneEntranceComponent>();
}
/**
@ -520,7 +493,7 @@ void Entity::Initialize() {
}
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
@ -532,148 +505,137 @@ void Entity::Initialize() {
if (zoneData != nullptr) {
int zoneScriptID = zoneData->scriptID;
CDScriptComponent zoneScriptData = scriptCompTable->GetByID(zoneScriptID);
ScriptComponent* comp = new ScriptComponent(this, zoneScriptData.script_name, true);
m_Components.insert(std::make_pair(eReplicaComponentType::SCRIPT, comp));
AddComponent<ScriptComponent>(zoneScriptData.script_name, true);
}
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SKILL, -1) != -1 || m_Character) {
SkillComponent* comp = new SkillComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::SKILL, comp));
AddComponent<SkillComponent>();
}
const auto combatAiId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BASE_COMBAT_AI);
if (combatAiId > 0) {
BaseCombatAIComponent* comp = new BaseCombatAIComponent(this, combatAiId);
m_Components.insert(std::make_pair(eReplicaComponentType::BASE_COMBAT_AI, comp));
AddComponent<BaseCombatAIComponent>(combatAiId);
}
if (int componentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::QUICK_BUILD) > 0) {
RebuildComponent* comp = new RebuildComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::QUICK_BUILD, comp));
auto* rebuildComponent = AddComponent<RebuildComponent>();
CDRebuildComponentTable* rebCompTable = CDClientManager::Instance().GetTable<CDRebuildComponentTable>();
std::vector<CDRebuildComponent> rebCompData = rebCompTable->Query([=](CDRebuildComponent entry) { return (entry.id == rebuildComponentID); });
if (rebCompData.size() > 0) {
comp->SetResetTime(rebCompData[0].reset_time);
comp->SetCompleteTime(rebCompData[0].complete_time);
comp->SetTakeImagination(rebCompData[0].take_imagination);
comp->SetInterruptible(rebCompData[0].interruptible);
comp->SetSelfActivator(rebCompData[0].self_activator);
comp->SetActivityId(rebCompData[0].activityID);
comp->SetPostImaginationCost(rebCompData[0].post_imagination_cost);
comp->SetTimeBeforeSmash(rebCompData[0].time_before_smash);
rebuildComponent->SetResetTime(rebCompData[0].reset_time);
rebuildComponent->SetCompleteTime(rebCompData[0].complete_time);
rebuildComponent->SetTakeImagination(rebCompData[0].take_imagination);
rebuildComponent->SetInterruptible(rebCompData[0].interruptible);
rebuildComponent->SetSelfActivator(rebCompData[0].self_activator);
rebuildComponent->SetActivityId(rebCompData[0].activityID);
rebuildComponent->SetPostImaginationCost(rebCompData[0].post_imagination_cost);
rebuildComponent->SetTimeBeforeSmash(rebCompData[0].time_before_smash);
const auto rebuildResetTime = GetVar<float>(u"rebuild_reset_time");
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");
if (activityID > 0) {
comp->SetActivityId(activityID);
rebuildComponent->SetActivityId(activityID);
Loot::CacheMatrix(activityID);
}
const auto compTime = GetVar<float>(u"compTime");
if (compTime > 0) {
comp->SetCompleteTime(compTime);
rebuildComponent->SetCompleteTime(compTime);
}
}
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SWITCH, -1) != -1) {
SwitchComponent* comp = new SwitchComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::SWITCH, comp));
AddComponent<SwitchComponent>();
}
if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::VENDOR) > 0)) {
VendorComponent* comp = new VendorComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::VENDOR, comp));
AddComponent<VendorComponent>();
} else if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::DONATION_VENDOR, -1) != -1)) {
DonationVendorComponent* comp = new DonationVendorComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::DONATION_VENDOR, comp));
AddComponent<DonationVendorComponent>();
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_VENDOR, -1) != -1) {
auto* component = new PropertyVendorComponent(this);
m_Components.insert_or_assign(eReplicaComponentType::PROPERTY_VENDOR, component);
AddComponent<PropertyVendorComponent>();
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_MANAGEMENT, -1) != -1) {
auto* component = new PropertyManagementComponent(this);
m_Components.insert_or_assign(eReplicaComponentType::PROPERTY_MANAGEMENT, component);
AddComponent<PropertyManagementComponent>();
}
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);
m_Components.insert(std::make_pair(eReplicaComponentType::BOUNCER, comp));
AddComponent<BouncerComponent>();
}
int32_t renderComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RENDER);
if ((renderComponentId > 0 && m_TemplateID != 2365) || m_Character) {
RenderComponent* render = new RenderComponent(this, renderComponentId);
m_Components.insert(std::make_pair(eReplicaComponentType::RENDER, render));
AddComponent<RenderComponent>(renderComponentId);
}
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) {
m_Components.insert(std::make_pair(eReplicaComponentType::BUILD_BORDER, new BuildBorderComponent(this)));
AddComponent<BuildBorderComponent>();
}
// Scripted activity component
int scriptedActivityID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SCRIPTED_ACTIVITY);
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>()) {
m_Components.insert(std::make_pair(eReplicaComponentType::MODEL, new ModelComponent(this)));
if (m_Components.find(eReplicaComponentType::DESTROYABLE) == m_Components.end()) {
auto destroyableComponent = new DestroyableComponent(this);
AddComponent<ModelComponent>();
if (!HasComponent(eReplicaComponentType::DESTROYABLE)) {
auto* destroyableComponent = AddComponent<DestroyableComponent>();
destroyableComponent->SetHealth(1);
destroyableComponent->SetMaxHealth(1.0f);
destroyableComponent->SetFaction(-1, true);
destroyableComponent->SetIsSmashable(true);
m_Components.insert(std::make_pair(eReplicaComponentType::DESTROYABLE, destroyableComponent));
}
}
PetComponent* petComponent;
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
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) {
m_Components.insert(std::make_pair(eReplicaComponentType::PROPERTY, new PropertyComponent(this)));
AddComponent<PropertyComponent>();
}
const int rocketId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ROCKET_LAUNCH);
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);
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);
@ -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) {
MovementAIInfo moveInfo = MovementAIInfo();
@ -712,7 +674,7 @@ void Entity::Initialize() {
moveInfo.wanderDelayMax = 5;
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");
@ -722,8 +684,7 @@ void Entity::Initialize() {
if (path) {
// if we have a moving platform path, then we need a moving platform component
if (path->pathType == PathType::MovingPlatform) {
MovingPlatformComponent* plat = new MovingPlatformComponent(this, pathName);
m_Components.insert(std::make_pair(eReplicaComponentType::MOVING_PLATFORM, plat));
AddComponent<MovingPlatformComponent>(pathName);
// else if we are a movement path
} /*else if (path->pathType == PathType::Movement) {
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
int32_t movingPlatformComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MOVING_PLATFORM, -1);
if (movingPlatformComponentId >= 0) {
MovingPlatformComponent* plat = new MovingPlatformComponent(this, pathName);
m_Components.insert(std::make_pair(eReplicaComponentType::MOVING_PLATFORM, plat));
AddComponent<MovingPlatformComponent>(pathName);
}
}
@ -748,8 +708,7 @@ void Entity::Initialize() {
std::vector<CDProximityMonitorComponent> proxCompData = proxCompTable->Query([=](CDProximityMonitorComponent entry) { return (entry.id == proximityMonitorID); });
if (proxCompData.size() > 0) {
std::vector<std::string> proximityStr = GeneralUtils::SplitString(proxCompData[0].Proximities, ',');
ProximityMonitorComponent* comp = new ProximityMonitorComponent(this, std::stoi(proximityStr[0]), std::stoi(proximityStr[1]));
m_Components.insert(std::make_pair(eReplicaComponentType::PROXIMITY_MONITOR, comp));
AddComponent<ProximityMonitorComponent>(std::stoi(proximityStr[0]), std::stoi(proximityStr[1]));
}
}
@ -840,14 +799,6 @@ bool Entity::HasComponent(const eReplicaComponentType componentId) const {
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*> comps;
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) {
ProximityMonitorComponent* proxMon = GetComponent<ProximityMonitorComponent>();
if (!proxMon) {
proxMon = new ProximityMonitorComponent(this);
m_Components.insert_or_assign(eReplicaComponentType::PROXIMITY_MONITOR, proxMon);
}
auto* proxMon = GetComponent<ProximityMonitorComponent>();
if (!proxMon) proxMon = AddComponent<ProximityMonitorComponent>();
proxMon->SetProximityRadius(proxRadius, name);
}
void Entity::SetProximityRadius(dpEntity* entity, std::string name) {
ProximityMonitorComponent* proxMon = GetComponent<ProximityMonitorComponent>();
if (!proxMon) {
proxMon = new ProximityMonitorComponent(this);
m_Components.insert_or_assign(eReplicaComponentType::PROXIMITY_MONITOR, proxMon);
}
ProximityMonitorComponent* proxMon = AddComponent<ProximityMonitorComponent>();
proxMon->SetProximityRadius(entity, name);
}
@ -1104,13 +1048,14 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType
destroyableSerialized = true;
}
if (HasComponent(eReplicaComponentType::COLLECTIBLE)) {
CollectibleComponent* collectibleComponent;
if (TryGetComponent(eReplicaComponentType::COLLECTIBLE, collectibleComponent)) {
DestroyableComponent* destroyableComponent;
if (TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent) && !destroyableSerialized) {
destroyableComponent->Serialize(outBitStream, bIsInitialUpdate);
}
destroyableSerialized = true;
outBitStream->Write(m_CollectibleID); // Collectable component
collectibleComponent->Serialize(outBitStream, bIsInitialUpdate);
}
PetComponent* petComponent;
@ -1148,8 +1093,9 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType
characterComponent->Serialize(outBitStream, bIsInitialUpdate);
}
if (HasComponent(eReplicaComponentType::ITEM)) {
outBitStream->Write0();
ItemComponent* itemComponent;
if (TryGetComponent(eReplicaComponentType::ITEM, itemComponent)) {
itemComponent->Serialize(outBitStream, bIsInitialUpdate);
}
InventoryComponent* inventoryComponent;
@ -1245,8 +1191,9 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType
}
}
if (HasComponent(eReplicaComponentType::ZONE_CONTROL)) {
outBitStream->Write<uint32_t>(0x40000000);
ZoneControlComponent* zoneControlComponent;
if (TryGetComponent(eReplicaComponentType::ZONE_CONTROL, zoneControlComponent)) {
zoneControlComponent->Serialize(outBitStream, bIsInitialUpdate);
}
// BBB Component, unused currently
@ -2102,3 +2049,8 @@ void Entity::RetroactiveVaultSize() {
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; }
uint8_t GetCollectibleID() const { return uint8_t(m_CollectibleID); }
uint8_t GetCollectibleID() const;
Entity* GetParentEntity() const { return m_ParentEntity; }
@ -274,6 +274,9 @@ public:
template<typename T>
T GetVarAs(const std::u16string& name) const;
template<typename ComponentType, typename... VaArgs>
ComponentType* AddComponent(VaArgs... args);
/**
* Get the LDF data.
*/
@ -501,3 +504,36 @@ T Entity::GetNetworkVar(const std::u16string& name) {
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() {
for (auto entry = m_EntitiesToSerialize.begin(); entry != m_EntitiesToSerialize.end(); entry++) {
auto* entity = GetEntity(*entry);
for (int32_t i = 0; i < m_EntitiesToSerialize.size(); i++) {
const LWOOBJID toSerialize = m_EntitiesToSerialize.at(i);
auto* entity = GetEntity(toSerialize);
if (!entity) continue;
@ -193,7 +194,7 @@ void EntityManager::SerializeEntities() {
if (entity->GetIsGhostingCandidate()) {
for (auto* player : Player::GetAllPlayers()) {
if (player->IsObserved(*entry)) {
if (player->IsObserved(toSerialize)) {
Game::server->Send(&stream, player->GetSystemAddress(), false);
}
}
@ -205,11 +206,12 @@ void EntityManager::SerializeEntities() {
}
void EntityManager::KillEntities() {
for (auto entry = m_EntitiesToKill.begin(); entry != m_EntitiesToKill.end(); entry++) {
auto* entity = GetEntity(*entry);
for (int32_t i = 0; i < m_EntitiesToKill.size(); i++) {
const LWOOBJID toKill = m_EntitiesToKill.at(i);
auto* entity = GetEntity(toKill);
if (!entity) {
LOG("Attempting to kill null entity %llu", *entry);
LOG("Attempting to kill null entity %llu", toKill);
continue;
}
@ -223,8 +225,9 @@ void EntityManager::KillEntities() {
}
void EntityManager::DeleteEntities() {
for (auto entry = m_EntitiesToDelete.begin(); entry != m_EntitiesToDelete.end(); entry++) {
auto entityToDelete = GetEntity(*entry);
for (int32_t i = 0; i < m_EntitiesToDelete.size(); i++) {
const LWOOBJID toDelete = m_EntitiesToDelete.at(i);
auto entityToDelete = GetEntity(toDelete);
if (entityToDelete) {
// Get all this info first before we delete the player.
auto networkIdToErase = entityToDelete->GetNetworkId();
@ -238,9 +241,9 @@ void EntityManager::DeleteEntities() {
if (ghostingToDelete != m_EntitiesToGhost.end()) m_EntitiesToGhost.erase(ghostingToDelete);
} 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();
}

View File

@ -47,7 +47,7 @@ struct AiSkillEntry
*/
class BaseCombatAIComponent : public Component {
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() override;

View File

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

View File

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

View File

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

View File

@ -3,11 +3,13 @@ set(DGAME_DCOMPONENTS_SOURCES "BaseCombatAIComponent.cpp"
"BuffComponent.cpp"
"BuildBorderComponent.cpp"
"CharacterComponent.cpp"
"CollectibleComponent.cpp"
"Component.cpp"
"ControllablePhysicsComponent.cpp"
"DestroyableComponent.cpp"
"DonationVendorComponent.cpp"
"InventoryComponent.cpp"
"ItemComponent.cpp"
"LevelProgressionComponent.cpp"
"LUPExhibitComponent.cpp"
"MissionComponent.cpp"
@ -42,4 +44,7 @@ set(DGAME_DCOMPONENTS_SOURCES "BaseCombatAIComponent.cpp"
"SwitchComponent.cpp"
"TriggerComponent.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 {
public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::CHARACTER;
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::CHARACTER;
CharacterComponent(Entity* parent, Character* character);
~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 {
public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::CONTROLLABLE_PHYSICS;
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::CONTROLLABLE_PHYSICS;
ControllablePhysicsComponent(Entity* entity);
~ControllablePhysicsComponent() override;

View File

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

View File

@ -38,7 +38,7 @@ enum class eItemType : int32_t;
class InventoryComponent : public Component
{
public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::INVENTORY;
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::INVENTORY;
explicit InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document = nullptr);
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
{
public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::EXHIBIT;
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::EXHIBIT;
LUPExhibitComponent(Entity* parent);
~LUPExhibitComponent();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,7 +10,7 @@
*/
class MultiZoneEntranceComponent : public Component {
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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -13,8 +13,8 @@
*/
class PropertyEntranceComponent : public Component {
public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_ENTRANCE;
explicit PropertyEntranceComponent(uint32_t componentID, Entity* parent);
explicit PropertyEntranceComponent(Entity* parent, uint32_t componentID);
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_ENTRANCE;
/**
* 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
{
public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_MANAGEMENT;
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_MANAGEMENT;
PropertyManagementComponent(Entity* parent);
static PropertyManagementComponent* Instance();

View File

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

View File

@ -19,7 +19,7 @@
*/
class ProximityMonitorComponent : public Component {
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() override;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -13,7 +13,7 @@
#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_Rotation = m_Parent->GetDefaultRotation();

View File

@ -28,9 +28,9 @@ enum class eClimbableType : int32_t {
*/
class SimplePhysicsComponent : public PhysicsComponent {
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;
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;

View File

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

View File

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

View File

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

View File

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

View File

@ -28,7 +28,7 @@ struct RemoteInputInfo {
*/
class VehiclePhysicsComponent : public PhysicsComponent {
public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::VEHICLE_PHYSICS;
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::VEHICLE_PHYSICS;
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;
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 };
dtQueryFilter filter{};

View File

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

View File

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

View File

@ -19,7 +19,7 @@ class Entity;
*/
class ScriptComponent : public Component {
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() override;

View File

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

View File

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

Binary file not shown.

View File

@ -16,8 +16,7 @@ protected:
void SetUp() override {
SetUpDependencies();
baseEntity = new Entity(15, GameDependenciesTest::info);
destroyableComponent = new DestroyableComponent(baseEntity);
baseEntity->AddComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent);
destroyableComponent = baseEntity->AddComponent<DestroyableComponent>();
// Initialize some values to be not default
destroyableComponent->SetMaxHealth(12345.0f);
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
*/
@ -318,9 +325,7 @@ TEST_F(DestroyableTest, DestroyableComponentFactionTest) {
TEST_F(DestroyableTest, DestroyableComponentValiditiyTest) {
auto* enemyEntity = new Entity(19, info);
auto* enemyDestroyableComponent = new DestroyableComponent(enemyEntity);
enemyEntity->AddComponent(eReplicaComponentType::DESTROYABLE, enemyDestroyableComponent);
enemyDestroyableComponent->AddFactionNoLookup(16);
enemyEntity->AddComponent<DestroyableComponent>()->AddFactionNoLookup(16);
destroyableComponent->AddEnemyFaction(16);
EXPECT_TRUE(destroyableComponent->IsEnemy(enemyEntity));
EXPECT_FALSE(destroyableComponent->IsFriend(enemyEntity));

View File

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