2021-12-05 17:54:36 +00:00
# include "dCommonVars.h"
# include "Entity.h"
# include "CDClientManager.h"
# include "Game.h"
# include "dLogger.h"
# include <PacketUtils.h>
# include <functional>
# include "CDDestructibleComponentTable.h"
# include "CDClientDatabase.h"
# include <sstream>
# include "dServer.h"
# include "GameMessages.h"
# include "EntityManager.h"
# include "dZoneManager.h"
# include "Zone.h"
# include "Spawner.h"
# include "UserManager.h"
# include "dpWorld.h"
# include "Player.h"
2023-01-07 05:17:05 +00:00
# include "LUTriggers.h"
# include "User.h"
# include "EntityTimer.h"
# include "EntityCallbackTimer.h"
# include "Loot.h"
2021-12-05 17:54:36 +00:00
# include "eMissionTaskType.h"
2023-02-10 08:29:53 +00:00
# include "eTriggerEventType.h"
2023-04-25 18:17:40 +00:00
# include "eObjectBits.h"
2021-12-05 17:54:36 +00:00
//Component includes:
# include "Component.h"
# include "ControllablePhysicsComponent.h"
# include "RenderComponent.h"
2023-06-08 15:29:17 +00:00
# include "MultiZoneEntranceComponent.h"
2021-12-05 17:54:36 +00:00
# include "CharacterComponent.h"
# include "DestroyableComponent.h"
# include "BuffComponent.h"
# include "BouncerComponent.h"
# include "InventoryComponent.h"
2022-07-24 18:04:02 +00:00
# include "LevelProgressionComponent.h"
2022-07-24 18:25:10 +00:00
# include "PlayerForcedMovementComponent.h"
2021-12-05 17:54:36 +00:00
# include "ScriptComponent.h"
# include "SkillComponent.h"
# include "SimplePhysicsComponent.h"
# include "SwitchComponent.h"
# include "PhantomPhysicsComponent.h"
# include "RigidbodyPhantomPhysicsComponent.h"
# include "MovingPlatformComponent.h"
# include "MissionComponent.h"
# include "MissionOfferComponent.h"
2023-06-09 22:12:57 +00:00
# include "QuickBuildComponent.h"
2021-12-05 17:54:36 +00:00
# include "BuildBorderComponent.h"
# include "MovementAIComponent.h"
# include "VendorComponent.h"
# include "RocketLaunchpadControlComponent.h"
# include "PropertyComponent.h"
# include "BaseCombatAIComponent.h"
# include "PropertyManagementComponent.h"
# include "PropertyVendorComponent.h"
# include "ProximityMonitorComponent.h"
# include "PropertyEntranceComponent.h"
2023-06-08 15:29:17 +00:00
# include "ModelBehaviorComponent.h"
2021-12-05 17:54:36 +00:00
# include "ZCompression.h"
# include "PetComponent.h"
2023-06-08 15:29:17 +00:00
# include "HavokVehiclePhysicsComponent.h"
2021-12-05 17:54:36 +00:00
# include "PossessableComponent.h"
# include "PossessorComponent.h"
# include "ModuleAssemblyComponent.h"
# include "RacingControlComponent.h"
# include "SoundTriggerComponent.h"
# include "ShootingGalleryComponent.h"
# include "RailActivatorComponent.h"
# include "LUPExhibitComponent.h"
2023-02-10 08:29:53 +00:00
# include "TriggerComponent.h"
2023-03-24 23:16:45 +00:00
# include "eGameMasterLevel.h"
2023-03-04 07:16:37 +00:00
# include "eReplicaComponentType.h"
2023-05-02 22:39:21 +00:00
# include "eReplicaPacketType.h"
2023-06-09 11:05:04 +00:00
# include "RacingStatsComponent.h"
# include "MinigameControlComponent.h"
2021-12-05 17:54:36 +00:00
2023-03-17 14:36:21 +00:00
// Table includes
# include "CDComponentsRegistryTable.h"
# include "CDCurrencyTableTable.h"
# include "CDMovementAIComponentTable.h"
# include "CDProximityMonitorComponentTable.h"
# include "CDRebuildComponentTable.h"
# include "CDObjectSkillsTable.h"
# include "CDObjectsTable.h"
# include "CDScriptComponentTable.h"
# include "CDSkillBehaviorTable.h"
# include "CDZoneTableTable.h"
2023-06-10 06:02:28 +00:00
const std : : vector < ComponentWhitelist > Entity : : m_ComponentWhitelists = {
{ // Unknown use case
eReplicaComponentType : : CONTROLLABLE_PHYSICS ,
eReplicaComponentType : : SIMPLE_PHYSICS ,
eReplicaComponentType : : RENDER
} ,
{ // Used for BBB
eReplicaComponentType : : RENDER ,
eReplicaComponentType : : DESTROYABLE ,
eReplicaComponentType : : ITEM ,
eReplicaComponentType : : BLUEPRINT ,
eReplicaComponentType : : MODEL_BEHAVIOR ,
eReplicaComponentType : : CONTROLLABLE_PHYSICS ,
eReplicaComponentType : : SIMPLE_PHYSICS ,
eReplicaComponentType : : SPAWN
} ,
{ // Unknown use case
eReplicaComponentType : : RENDER ,
eReplicaComponentType : : ITEM ,
eReplicaComponentType : : BLUEPRINT ,
} ,
{ // Used for Pets
eReplicaComponentType : : PET ,
eReplicaComponentType : : SKILL ,
eReplicaComponentType : : DESTROYABLE ,
eReplicaComponentType : : RENDER ,
eReplicaComponentType : : CONTROLLABLE_PHYSICS
} ,
{ // Unknown use case
eReplicaComponentType : : CONTROLLABLE_PHYSICS ,
eReplicaComponentType : : SIMPLE_PHYSICS ,
eReplicaComponentType : : RENDER ,
} ,
} ;
2021-12-05 17:54:36 +00:00
Entity : : Entity ( const LWOOBJID & objectID , EntityInfo info , Entity * parentEntity ) {
m_ObjectID = objectID ;
m_TemplateID = info . lot ;
m_ParentEntity = parentEntity ;
m_Character = nullptr ;
2023-03-24 23:16:45 +00:00
m_GMLevel = eGameMasterLevel : : CIVILIAN ;
2021-12-05 17:54:36 +00:00
m_CollectibleID = 0 ;
m_NetworkID = 0 ;
2023-06-09 08:04:42 +00:00
m_Observers = 0 ;
2021-12-05 17:54:36 +00:00
m_OwnerOverride = LWOOBJID_EMPTY ;
2023-06-09 09:46:01 +00:00
m_Groups . clear ( ) ;
m_Timers . clear ( ) ;
m_ChildEntities . clear ( ) ;
m_TargetsInPhantom . clear ( ) ;
m_DieCallbacks . clear ( ) ;
m_PhantomCollisionCallbacks . clear ( ) ;
2021-12-05 17:54:36 +00:00
m_ScheduleKiller = nullptr ;
2022-06-16 05:58:38 +00:00
m_IsParentChildDirty = true ;
2023-06-09 08:04:42 +00:00
m_IsGhostingCandidate = false ;
m_PlayerIsReadyForUpdates = false ;
m_ShouldDestroyAfterUpdate = false ;
2021-12-05 17:54:36 +00:00
m_Settings = info . settings ;
m_NetworkSettings = info . networkSettings ;
m_DefaultPosition = info . pos ;
m_DefaultRotation = info . rot ;
m_Scale = info . scale ;
m_Spawner = info . spawner ;
m_SpawnerID = info . spawnerID ;
m_HasSpawnerNodeID = info . hasSpawnerNodeID ;
m_SpawnerNodeID = info . spawnerNodeID ;
if ( info . lot ! = 1 ) m_PlayerIsReadyForUpdates = true ;
}
Entity : : ~ Entity ( ) {
2023-06-07 03:48:30 +00:00
if ( m_Character ) m_Character - > SaveXMLToDatabase ( ) ;
2021-12-05 17:54:36 +00:00
CancelAllTimers ( ) ;
CancelCallbackTimers ( ) ;
2023-06-07 03:48:30 +00:00
for ( auto child : m_ChildEntities ) if ( child ) child - > RemoveParent ( ) ;
2022-07-17 04:39:13 +00:00
2023-06-07 03:48:30 +00:00
if ( m_ParentEntity ) m_ParentEntity - > RemoveChild ( this ) ;
2021-12-05 17:54:36 +00:00
}
2023-06-10 06:02:28 +00:00
void Entity : : ApplyComponentWhitelist ( std : : vector < eReplicaComponentType > & components ) {
const auto whitelistIndex = GetVar < int32_t > ( u " componentWhitelist " ) ;
if ( whitelistIndex < 0 | | whitelistIndex > = m_ComponentWhitelists . size ( ) ) return ;
2023-06-10 07:03:07 +00:00
const auto & whitelist = m_ComponentWhitelists . at ( whitelistIndex ) ;
const auto endRange = std : : remove_if ( components . begin ( ) , components . end ( ) , [ & whitelist ] ( const eReplicaComponentType & componentCandidate ) {
return std : : find ( whitelist . begin ( ) , whitelist . end ( ) , componentCandidate ) = = whitelist . end ( ) ;
} ) ;
components . erase ( endRange , components . end ( ) ) ;
2023-06-10 06:02:28 +00:00
}
2021-12-05 17:54:36 +00:00
void Entity : : Initialize ( ) {
2023-06-09 11:05:04 +00:00
// A few edge cases to tackle first
const auto triggerInfo = GetVarAsString ( u " trigger_id " ) ;
if ( ! triggerInfo . empty ( ) ) AddComponent < TriggerComponent > ( triggerInfo ) ;
const auto groupIDs = GetVarAsString ( u " groupID " ) ;
if ( ! groupIDs . empty ( ) ) {
m_Groups = GeneralUtils : : SplitString ( groupIDs , ' ; ' ) ;
if ( m_Groups . back ( ) . empty ( ) ) m_Groups . erase ( m_Groups . end ( ) - 1 ) ;
}
if ( m_ParentEntity ) m_ParentEntity - > AddChild ( this ) ;
// Brick-by-Brick models don't have all their components in the registry for some reason? Might have to be related to using ldf keys for physics
if ( GetLOT ( ) = = 14 ) {
AddComponent < SimplePhysicsComponent > ( 0 ) ;
AddComponent < ModelBehaviorComponent > ( ) ;
AddComponent < RenderComponent > ( ) ;
AddComponent < DestroyableComponent > ( ) ;
return ;
}
2023-06-07 03:48:30 +00:00
auto * componentsRegistry = CDClientManager : : Instance ( ) . GetTable < CDComponentsRegistryTable > ( ) ;
auto components = componentsRegistry - > GetTemplateComponents ( m_TemplateID ) ;
2023-06-09 11:05:04 +00:00
// Apply the whitelist here based on the corresponding ldf key. Removes components that are not whitelisted. List is determined based on the clients whitelist data.
2023-06-07 03:48:30 +00:00
for ( const auto & [ componentTemplate , componentId ] : components ) {
switch ( componentTemplate ) {
case eReplicaComponentType : : CONTROLLABLE_PHYSICS :
2023-06-07 07:23:50 +00:00
AddComponent < ControllablePhysicsComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : RENDER :
2023-06-09 11:05:04 +00:00
AddComponent < RenderComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : SIMPLE_PHYSICS :
break ;
case eReplicaComponentType : : CHARACTER :
2023-06-09 11:05:04 +00:00
AddComponent < CharacterComponent > ( m_Character ) ;
AddComponent < MissionComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : SCRIPT :
break ;
case eReplicaComponentType : : BOUNCER :
2023-06-09 11:05:04 +00:00
AddComponent < BouncerComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : DESTROYABLE :
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : GHOST :
break ;
case eReplicaComponentType : : SKILL :
2023-06-09 11:05:04 +00:00
AddComponent < SkillComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : SPAWN :
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : ITEM :
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : MODULAR_BUILD :
2023-06-07 03:48:30 +00:00
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : BUILD_CONTROLLER :
2023-06-07 03:48:30 +00:00
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : BUILD_ACTIVATOR :
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : ICON_ONLY :
break ;
case eReplicaComponentType : : VENDOR :
2023-06-09 11:05:04 +00:00
AddComponent < VendorComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : INVENTORY :
break ;
case eReplicaComponentType : : PROJECTILE_PHYSICS :
break ;
case eReplicaComponentType : : SHOOTING_GALLERY :
2023-06-09 11:05:04 +00:00
AddComponent < ShootingGalleryComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : RIGID_BODY_PHANTOM_PHYSICS :
break ;
case eReplicaComponentType : : DROP_EFFECT :
break ;
case eReplicaComponentType : : CHEST :
break ;
case eReplicaComponentType : : COLLECTIBLE :
break ;
case eReplicaComponentType : : BLUEPRINT :
break ;
case eReplicaComponentType : : MOVING_PLATFORM :
break ;
case eReplicaComponentType : : PET :
2023-06-09 11:05:04 +00:00
AddComponent < PetComponent > ( componentId ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : PLATFORM_BOUNDARY :
break ;
case eReplicaComponentType : : MODULE :
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : JETPACKPAD :
2023-06-07 03:48:30 +00:00
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : HAVOK_VEHICLE_PHYSICS :
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : MOVEMENT_AI :
break ;
case eReplicaComponentType : : EXHIBIT :
break ;
case eReplicaComponentType : : OVERHEAD_ICON :
break ;
case eReplicaComponentType : : PET_CONTROL :
break ;
case eReplicaComponentType : : MINIFIG :
break ;
case eReplicaComponentType : : PROPERTY :
2023-06-09 11:05:04 +00:00
AddComponent < PropertyComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : PET_CREATOR :
break ;
case eReplicaComponentType : : MODEL_BUILDER :
break ;
case eReplicaComponentType : : SCRIPTED_ACTIVITY :
2023-06-09 11:05:04 +00:00
AddComponent < ScriptedActivityComponent > ( componentId ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : PHANTOM_PHYSICS :
break ;
case eReplicaComponentType : : SPRINGPAD :
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : MODEL_BEHAVIOR :
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : PROPERTY_ENTRANCE :
2023-06-09 11:05:04 +00:00
AddComponent < PropertyEntranceComponent > ( componentId ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : FX :
break ;
case eReplicaComponentType : : PROPERTY_MANAGEMENT :
2023-06-09 11:05:04 +00:00
AddComponent < PropertyManagementComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : VEHICLE_PHYSICS :
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : PHYSICS_SYSTEM :
break ;
case eReplicaComponentType : : QUICK_BUILD :
break ;
case eReplicaComponentType : : SWITCH :
2023-06-09 11:05:04 +00:00
AddComponent < SwitchComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : MINIGAME_CONTROL :
2023-06-09 11:05:04 +00:00
AddComponent < MinigameControlComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : CHANGLING_BUILD :
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : CHOICE_BUILD :
break ;
case eReplicaComponentType : : PACKAGE :
break ;
case eReplicaComponentType : : SOUND_REPEATER :
break ;
case eReplicaComponentType : : SOUND_AMBIENT_2D :
break ;
case eReplicaComponentType : : SOUND_AMBIENT_3D :
break ;
case eReplicaComponentType : : PRECONDITION :
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : FLAG :
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : CUSTOM_BUILD_ASSEMBLY :
break ;
case eReplicaComponentType : : BASE_COMBAT_AI :
2023-06-09 11:05:04 +00:00
AddComponent < BaseCombatAIComponent > ( componentId ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : MODULE_ASSEMBLY :
2023-06-09 11:05:04 +00:00
AddComponent < ModuleAssemblyComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : SHOWCASE_MODEL_HANDLER :
break ;
case eReplicaComponentType : : RACING_MODULE :
break ;
case eReplicaComponentType : : GENERIC_ACTIVATOR :
break ;
case eReplicaComponentType : : PROPERTY_VENDOR :
2023-06-09 11:05:04 +00:00
AddComponent < PropertyVendorComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : HF_LIGHT_DIRECTION_GADGET :
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : ROCKET_LAUNCHPAD_CONTROL :
2023-06-07 03:48:30 +00:00
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : ROCKET_ANIMATION_CONTROL :
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : TRIGGER :
break ;
case eReplicaComponentType : : DROPPED_LOOT :
break ;
case eReplicaComponentType : : RACING_CONTROL :
2023-06-09 11:05:04 +00:00
AddComponent < RacingControlComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : FACTION_TRIGGER :
break ;
case eReplicaComponentType : : MISSION_OFFER :
2023-06-09 11:05:04 +00:00
AddComponent < MissionOfferComponent > ( GetLOT ( ) ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : RACING_STATS :
2023-06-09 11:05:04 +00:00
AddComponent < RacingStatsComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : LUP_EXHIBIT :
2023-06-09 11:05:04 +00:00
AddComponent < LUPExhibitComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : BBB :
break ;
case eReplicaComponentType : : SOUND_TRIGGER :
break ;
case eReplicaComponentType : : PROXIMITY_MONITOR :
break ;
case eReplicaComponentType : : RACING_SOUND_TRIGGER :
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : CHAT_BUBBLE :
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : FRIENDS_LIST :
break ;
case eReplicaComponentType : : GUILD :
break ;
case eReplicaComponentType : : LOCAL_SYSTEM :
break ;
case eReplicaComponentType : : MISSION :
break ;
case eReplicaComponentType : : MUTABLE_MODEL_BEHAVIORS :
break ;
case eReplicaComponentType : : PATHFINDING :
break ;
case eReplicaComponentType : : PET_TAMING_CONTROL :
break ;
case eReplicaComponentType : : PROPERTY_EDITOR :
break ;
case eReplicaComponentType : : SKINNED_RENDER :
break ;
case eReplicaComponentType : : SLASH_COMMAND :
break ;
case eReplicaComponentType : : STATUS_EFFECT :
break ;
case eReplicaComponentType : : TEAMS :
break ;
case eReplicaComponentType : : TEXT_EFFECT :
break ;
case eReplicaComponentType : : TRADE :
break ;
case eReplicaComponentType : : USER_CONTROL :
break ;
case eReplicaComponentType : : IGNORE_LIST :
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : MULTI_ZONE_ENTRANCE :
2023-06-07 03:48:30 +00:00
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : BUFF :
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : INTERACTION_MANAGER :
break ;
case eReplicaComponentType : : DONATION_VENDOR :
break ;
case eReplicaComponentType : : COMBAT_MEDIATOR :
break ;
2023-06-08 15:29:17 +00:00
case eReplicaComponentType : : ACHIEVEMENT_VENDOR :
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : GATE_RUSH_CONTROL :
break ;
case eReplicaComponentType : : RAIL_ACTIVATOR :
break ;
case eReplicaComponentType : : ROLLER :
break ;
case eReplicaComponentType : : PLAYER_FORCED_MOVEMENT :
break ;
case eReplicaComponentType : : CRAFTING :
break ;
case eReplicaComponentType : : POSSESSABLE :
2023-06-09 11:05:04 +00:00
AddComponent < PossessableComponent > ( componentId ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : LEVEL_PROGRESSION :
break ;
case eReplicaComponentType : : POSSESSOR :
break ;
case eReplicaComponentType : : MOUNT_CONTROL :
break ;
case eReplicaComponentType : : UNKNOWN_112 :
break ;
case eReplicaComponentType : : PROPERTY_PLAQUE :
break ;
case eReplicaComponentType : : BUILD_BORDER :
2023-06-09 11:05:04 +00:00
AddComponent < BuildBorderComponent > ( ) ;
2023-06-07 03:48:30 +00:00
break ;
case eReplicaComponentType : : UNKNOWN_115 :
break ;
case eReplicaComponentType : : CULLING_PLANE :
break ;
case eReplicaComponentType : : NUMBER_OF_COMPONENTS :
break ;
case eReplicaComponentType : : INVALID :
default :
Game : : logger - > Log ( " Entity " , " blah %i %i " , componentId , m_TemplateID ) ;
2021-12-05 17:54:36 +00:00
}
}
2023-06-09 09:46:01 +00:00
2023-06-09 11:05:04 +00:00
for ( const auto & [ componentId , component ] : m_Components ) {
2023-06-09 09:46:01 +00:00
component - > LoadTemplateData ( ) ;
}
2023-06-09 11:05:04 +00:00
for ( const auto & [ componentId , component ] : m_Components ) {
2023-06-09 09:46:01 +00:00
component - > LoadConfigData ( ) ;
}
2023-06-09 11:05:04 +00:00
for ( const auto & [ componentId , component ] : m_Components ) {
2023-06-09 09:46:01 +00:00
component - > Startup ( ) ;
}
if ( ! IsPlayer ( ) ) return ; // No save data to load for non players
2023-06-09 11:05:04 +00:00
for ( const auto & [ componentId , component ] : m_Components ) {
2023-06-09 09:46:01 +00:00
component - > LoadFromXml ( m_Character - > GetXMLDoc ( ) ) ;
}
2021-12-05 17:54:36 +00:00
}
bool Entity : : operator = = ( const Entity & other ) const {
return other . m_ObjectID = = m_ObjectID ;
}
bool Entity : : operator ! = ( const Entity & other ) const {
2023-06-09 08:04:42 +00:00
return ! ( other . m_ObjectID = = m_ObjectID ) ;
2021-12-05 17:54:36 +00:00
}
User * Entity : : GetParentUser ( ) const {
if ( ! IsPlayer ( ) ) {
return nullptr ;
}
return static_cast < const Player * > ( this ) - > GetParentUser ( ) ;
}
2023-03-04 07:16:37 +00:00
bool Entity : : HasComponent ( const eReplicaComponentType componentId ) const {
2021-12-05 17:54:36 +00:00
return m_Components . find ( componentId ) ! = m_Components . end ( ) ;
}
2023-06-09 08:04:42 +00:00
std : : vector < ScriptComponent * > Entity : : GetScriptComponents ( ) {
std : : vector < ScriptComponent * > comps ;
2023-06-09 11:05:04 +00:00
for ( const auto & [ componentType , component ] : m_Components ) {
2023-06-07 03:48:30 +00:00
if ( componentType = = eReplicaComponentType : : SCRIPT ) {
2023-06-09 08:04:42 +00:00
comps . push_back ( dynamic_cast < ScriptComponent * > ( component . get ( ) ) ) ;
2021-12-05 17:54:36 +00:00
}
}
2022-07-28 13:39:57 +00:00
2021-12-05 17:54:36 +00:00
return comps ;
}
2023-06-09 08:04:42 +00:00
void Entity : : Subscribe ( const LWOOBJID & scriptObjId , CppScripts : : Script * scriptToAdd , const std : : string & notificationName ) {
2022-12-21 22:33:41 +00:00
if ( notificationName = = " HitOrHealResult " | | notificationName = = " Hit " ) {
2023-06-07 03:48:30 +00:00
auto destroyableComponent = GetComponent < DestroyableComponent > ( ) ;
2022-12-21 22:33:41 +00:00
if ( ! destroyableComponent ) return ;
destroyableComponent - > Subscribe ( scriptObjId , scriptToAdd ) ;
}
}
2023-06-09 08:04:42 +00:00
void Entity : : Unsubscribe ( const LWOOBJID & scriptObjId , const std : : string & notificationName ) {
2022-12-21 22:33:41 +00:00
if ( notificationName = = " HitOrHealResult " | | notificationName = = " Hit " ) {
2023-06-07 03:48:30 +00:00
auto destroyableComponent = GetComponent < DestroyableComponent > ( ) ;
2022-12-21 22:33:41 +00:00
if ( ! destroyableComponent ) return ;
destroyableComponent - > Unsubscribe ( scriptObjId ) ;
}
}
2023-06-09 08:04:42 +00:00
void Entity : : SetProximityRadius ( const float proxRadius , const std : : string & name ) {
2023-06-07 07:23:50 +00:00
auto proximityMonitorComponent = AddComponent < ProximityMonitorComponent > ( ) ;
2023-06-07 03:48:30 +00:00
if ( proximityMonitorComponent ) proximityMonitorComponent - > SetProximityRadius ( proxRadius , name ) ;
2021-12-05 17:54:36 +00:00
}
2023-06-09 08:04:42 +00:00
void Entity : : SetProximityRadius ( dpEntity * entity , const std : : string & name ) {
2023-06-07 07:23:50 +00:00
auto proximityMonitorComponent = AddComponent < ProximityMonitorComponent > ( ) ;
2023-06-07 03:48:30 +00:00
if ( proximityMonitorComponent ) proximityMonitorComponent - > SetProximityRadius ( entity , name ) ;
2021-12-05 17:54:36 +00:00
}
2023-03-24 23:16:45 +00:00
void Entity : : SetGMLevel ( eGameMasterLevel value ) {
2021-12-05 17:54:36 +00:00
m_GMLevel = value ;
if ( GetParentUser ( ) ) {
Character * character = GetParentUser ( ) - > GetLastUsedChar ( ) ;
if ( character ) {
character - > SetGMLevel ( value ) ;
}
}
2023-06-07 03:48:30 +00:00
auto character = GetComponent < CharacterComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( character ) character - > SetGMLevel ( value ) ;
GameMessages : : SendGMLevelBroadcast ( m_ObjectID , value ) ;
}
void Entity : : WriteBaseReplicaData ( RakNet : : BitStream * outBitStream , eReplicaPacketType packetType ) {
2023-05-02 22:39:21 +00:00
if ( packetType = = eReplicaPacketType : : CONSTRUCTION ) {
2021-12-05 17:54:36 +00:00
outBitStream - > Write ( m_ObjectID ) ;
outBitStream - > Write ( m_TemplateID ) ;
if ( IsPlayer ( ) ) {
std : : string name = m_Character ! = nullptr ? m_Character - > GetName ( ) : " Invalid " ;
outBitStream - > Write < uint8_t > ( uint8_t ( name . size ( ) ) ) ;
for ( size_t i = 0 ; i < name . size ( ) ; + + i ) {
outBitStream - > Write < uint16_t > ( name [ i ] ) ;
}
} else {
const auto & name = GetVar < std : : string > ( u " npcName " ) ;
outBitStream - > Write < uint8_t > ( uint8_t ( name . size ( ) ) ) ;
for ( size_t i = 0 ; i < name . size ( ) ; + + i ) {
outBitStream - > Write < uint16_t > ( name [ i ] ) ;
}
}
outBitStream - > Write < uint32_t > ( 0 ) ; //Time since created on server
const auto & syncLDF = GetVar < std : : vector < std : : u16string > > ( u " syncLDF " ) ;
2022-07-19 21:51:35 +00:00
// Only sync for models.
2023-06-08 15:29:17 +00:00
if ( m_Settings . size ( ) > 0 & & ( GetComponent < ModelBehaviorComponent > ( ) & & ! GetComponent < PetComponent > ( ) ) ) {
2021-12-05 17:54:36 +00:00
outBitStream - > Write1 ( ) ; //ldf data
2022-07-28 13:39:57 +00:00
2021-12-05 17:54:36 +00:00
RakNet : : BitStream settingStream ;
settingStream . Write < uint32_t > ( m_Settings . size ( ) ) ;
for ( LDFBaseData * data : m_Settings ) {
if ( data ) {
data - > WriteToPacket ( & settingStream ) ;
}
}
outBitStream - > Write ( settingStream . GetNumberOfBytesUsed ( ) + 1 ) ;
outBitStream - > Write < uint8_t > ( 0 ) ; //no compression used
outBitStream - > Write ( settingStream ) ;
} else if ( ! syncLDF . empty ( ) ) {
std : : vector < LDFBaseData * > ldfData ;
for ( const auto & data : syncLDF ) {
ldfData . push_back ( GetVarData ( data ) ) ;
}
outBitStream - > Write1 ( ) ; //ldf data
RakNet : : BitStream settingStream ;
settingStream . Write < uint32_t > ( ldfData . size ( ) ) ;
for ( LDFBaseData * data : ldfData ) {
if ( data ) {
data - > WriteToPacket ( & settingStream ) ;
}
}
outBitStream - > Write ( settingStream . GetNumberOfBytesUsed ( ) + 1 ) ;
outBitStream - > Write < uint8_t > ( 0 ) ; //no compression used
outBitStream - > Write ( settingStream ) ;
} else {
outBitStream - > Write0 ( ) ; //No ldf data
}
2023-06-07 03:48:30 +00:00
auto triggerComponent = GetComponent < TriggerComponent > ( ) ;
if ( triggerComponent ) {
2023-02-10 08:29:53 +00:00
// has trigger component, check to see if we have events to handle
auto * trigger = triggerComponent - > GetTrigger ( ) ;
outBitStream - > Write < bool > ( trigger & & trigger - > events . size ( ) > 0 ) ;
} else { // no trigger componenet, so definitely no triggers
2021-12-05 17:54:36 +00:00
outBitStream - > Write0 ( ) ;
}
2023-02-10 08:29:53 +00:00
2021-12-05 17:54:36 +00:00
if ( m_ParentEntity ! = nullptr | | m_SpawnerID ! = 0 ) {
outBitStream - > Write1 ( ) ;
2023-04-25 18:17:40 +00:00
if ( m_ParentEntity ! = nullptr ) outBitStream - > Write ( GeneralUtils : : SetBit ( m_ParentEntity - > GetObjectID ( ) , static_cast < uint32_t > ( eObjectBits : : CLIENT ) ) ) ;
2021-12-05 17:54:36 +00:00
else if ( m_Spawner ! = nullptr & & m_Spawner - > m_Info . isNetwork ) outBitStream - > Write ( m_SpawnerID ) ;
2023-04-25 18:17:40 +00:00
else outBitStream - > Write ( GeneralUtils : : SetBit ( m_SpawnerID , static_cast < uint32_t > ( eObjectBits : : CLIENT ) ) ) ;
2021-12-05 17:54:36 +00:00
} else outBitStream - > Write0 ( ) ;
outBitStream - > Write ( m_HasSpawnerNodeID ) ;
if ( m_HasSpawnerNodeID ) outBitStream - > Write ( m_SpawnerNodeID ) ;
//outBitStream->Write0(); //Spawner node id
if ( m_Scale = = 1.0f | | m_Scale = = 0.0f ) outBitStream - > Write0 ( ) ;
else {
outBitStream - > Write1 ( ) ;
outBitStream - > Write ( m_Scale ) ;
}
outBitStream - > Write0 ( ) ; //ObjectWorldState
2023-03-24 23:16:45 +00:00
if ( m_GMLevel ! = eGameMasterLevel : : CIVILIAN ) {
2021-12-05 17:54:36 +00:00
outBitStream - > Write1 ( ) ;
outBitStream - > Write ( m_GMLevel ) ;
} else outBitStream - > Write0 ( ) ; //No GM Level
}
2022-07-28 13:39:57 +00:00
2022-06-16 06:04:03 +00:00
// Only serialize parent / child info should the info be dirty (changed) or if this is the construction of the entity.
2023-05-02 22:39:21 +00:00
outBitStream - > Write ( m_IsParentChildDirty | | packetType = = eReplicaPacketType : : CONSTRUCTION ) ;
if ( m_IsParentChildDirty | | packetType = = eReplicaPacketType : : CONSTRUCTION ) {
2022-06-16 05:58:38 +00:00
m_IsParentChildDirty = false ;
2021-12-05 17:54:36 +00:00
outBitStream - > Write ( m_ParentEntity ! = nullptr ) ;
if ( m_ParentEntity ) {
outBitStream - > Write ( m_ParentEntity - > GetObjectID ( ) ) ;
outBitStream - > Write0 ( ) ;
}
outBitStream - > Write ( m_ChildEntities . size ( ) > 0 ) ;
if ( m_ChildEntities . size ( ) > 0 ) {
outBitStream - > Write ( ( uint16_t ) m_ChildEntities . size ( ) ) ;
for ( Entity * child : m_ChildEntities ) {
outBitStream - > Write ( ( uint64_t ) child - > GetObjectID ( ) ) ;
}
}
}
}
void Entity : : WriteComponents ( RakNet : : BitStream * outBitStream , eReplicaPacketType packetType ) {
}
void Entity : : ResetFlags ( ) {
// Unused
}
void Entity : : UpdateXMLDoc ( tinyxml2 : : XMLDocument * doc ) {
//This function should only ever be called from within Character, meaning doc should always exist when this is called.
//Naturally, we don't include any non-player components in this update function.
for ( const auto & pair : m_Components ) {
if ( pair . second = = nullptr ) continue ;
pair . second - > UpdateXml ( doc ) ;
}
}
void Entity : : Update ( const float deltaTime ) {
2022-07-17 01:21:35 +00:00
uint32_t timerPosition ;
timerPosition = 0 ;
while ( timerPosition < m_Timers . size ( ) ) {
m_Timers [ timerPosition ] - > Update ( deltaTime ) ;
if ( m_Timers [ timerPosition ] - > GetTime ( ) < = 0 ) {
const auto timerName = m_Timers [ timerPosition ] - > GetName ( ) ;
2021-12-05 17:54:36 +00:00
2022-07-17 01:21:35 +00:00
delete m_Timers [ timerPosition ] ;
m_Timers . erase ( m_Timers . begin ( ) + timerPosition ) ;
2021-12-05 17:54:36 +00:00
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnTimerDone ( this , timerName ) ;
}
2023-04-18 17:48:03 +00:00
TriggerEvent ( eTriggerEventType : : TIMER_DONE , this ) ;
2022-07-17 01:21:35 +00:00
} else {
timerPosition + + ;
2021-12-05 17:54:36 +00:00
}
}
for ( int i = 0 ; i < m_CallbackTimers . size ( ) ; i + + ) {
m_CallbackTimers [ i ] - > Update ( deltaTime ) ;
if ( m_CallbackTimers [ i ] - > GetTime ( ) < = 0 ) {
m_CallbackTimers [ i ] - > GetCallback ( ) ( ) ;
delete m_CallbackTimers [ i ] ;
m_CallbackTimers . erase ( m_CallbackTimers . begin ( ) + i ) ;
}
}
2022-07-28 13:39:57 +00:00
2022-07-17 01:21:35 +00:00
// Add pending timers to the list of timers so they start next tick.
if ( m_PendingTimers . size ( ) > 0 ) {
for ( auto namedTimer : m_PendingTimers ) {
m_Timers . push_back ( namedTimer ) ;
}
m_PendingTimers . clear ( ) ;
}
2021-12-05 17:54:36 +00:00
if ( IsSleeping ( ) ) {
Sleep ( ) ;
return ;
} else {
Wake ( ) ;
}
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnUpdate ( this ) ;
}
for ( const auto & pair : m_Components ) {
if ( pair . second = = nullptr ) continue ;
pair . second - > Update ( deltaTime ) ;
}
if ( m_ShouldDestroyAfterUpdate ) {
EntityManager : : Instance ( ) - > DestroyEntity ( this - > GetObjectID ( ) ) ;
}
}
void Entity : : OnCollisionProximity ( LWOOBJID otherEntity , const std : : string & proxName , const std : : string & status ) {
Entity * other = EntityManager : : Instance ( ) - > GetEntity ( otherEntity ) ;
if ( ! other ) return ;
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnProximityUpdate ( this , other , proxName , status ) ;
}
2023-06-07 03:48:30 +00:00
auto rocketComp = GetComponent < RocketLaunchpadControlComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( ! rocketComp ) return ;
rocketComp - > OnProximityUpdate ( other , proxName , status ) ;
}
void Entity : : OnCollisionPhantom ( const LWOOBJID otherEntity ) {
auto * other = EntityManager : : Instance ( ) - > GetEntity ( otherEntity ) ;
if ( ! other ) return ;
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnCollisionPhantom ( this , other ) ;
}
for ( const auto & callback : m_PhantomCollisionCallbacks ) {
callback ( other ) ;
}
2023-06-07 03:48:30 +00:00
auto switchComp = GetComponent < SwitchComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( switchComp ) {
switchComp - > EntityEnter ( other ) ;
}
2023-02-10 08:29:53 +00:00
TriggerEvent ( eTriggerEventType : : ENTER , other ) ;
2021-12-05 17:54:36 +00:00
// POI system
const auto & poi = GetVar < std : : u16string > ( u " POI " ) ;
if ( ! poi . empty ( ) ) {
2023-06-09 08:27:05 +00:00
auto * missionComponent = other - > GetComponent < MissionComponent > ( ) ;
2022-07-28 13:39:57 +00:00
2021-12-05 17:54:36 +00:00
if ( missionComponent ! = nullptr ) {
missionComponent - > Progress ( eMissionTaskType : : EXPLORE , 0 , 0 , GeneralUtils : : UTF16ToWTF8 ( poi ) ) ;
}
}
if ( ! other - > GetIsDead ( ) ) {
2023-06-07 03:48:30 +00:00
auto combat = GetComponent < BaseCombatAIComponent > ( ) ;
2022-07-28 13:39:57 +00:00
2021-12-05 17:54:36 +00:00
if ( combat ! = nullptr ) {
const auto index = std : : find ( m_TargetsInPhantom . begin ( ) , m_TargetsInPhantom . end ( ) , otherEntity ) ;
if ( index ! = m_TargetsInPhantom . end ( ) ) return ;
const auto valid = combat - > IsEnemy ( otherEntity ) ;
if ( ! valid ) return ;
m_TargetsInPhantom . push_back ( otherEntity ) ;
}
}
}
void Entity : : OnCollisionLeavePhantom ( const LWOOBJID otherEntity ) {
auto * other = EntityManager : : Instance ( ) - > GetEntity ( otherEntity ) ;
if ( ! other ) return ;
2023-04-12 16:46:31 +00:00
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnOffCollisionPhantom ( this , other ) ;
}
2023-02-10 08:29:53 +00:00
TriggerEvent ( eTriggerEventType : : EXIT , other ) ;
2021-12-05 17:54:36 +00:00
2023-06-07 03:48:30 +00:00
auto switchComp = GetComponent < SwitchComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( switchComp ) {
switchComp - > EntityLeave ( other ) ;
}
const auto index = std : : find ( m_TargetsInPhantom . begin ( ) , m_TargetsInPhantom . end ( ) , otherEntity ) ;
2022-07-28 13:39:57 +00:00
2021-12-05 17:54:36 +00:00
if ( index = = m_TargetsInPhantom . end ( ) ) return ;
m_TargetsInPhantom . erase ( index ) ;
}
void Entity : : OnFireEventServerSide ( Entity * sender , std : : string args , int32_t param1 , int32_t param2 , int32_t param3 ) {
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnFireEventServerSide ( this , sender , args , param1 , param2 , param3 ) ;
}
}
void Entity : : OnActivityStateChangeRequest ( LWOOBJID senderID , int32_t value1 , int32_t value2 , const std : : u16string & stringValue ) {
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnActivityStateChangeRequest ( this , senderID , value1 , value2 , stringValue ) ;
}
}
void Entity : : OnCinematicUpdate ( Entity * self , Entity * sender , eCinematicEvent event , const std : : u16string & pathName ,
float_t pathTime , float_t totalTime , int32_t waypoint ) {
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnCinematicUpdate ( self , sender , event , pathName , pathTime , totalTime , waypoint ) ;
}
}
void Entity : : NotifyObject ( Entity * sender , const std : : string & name , int32_t param1 , int32_t param2 ) {
GameMessages : : SendNotifyObject ( GetObjectID ( ) , sender - > GetObjectID ( ) , GeneralUtils : : ASCIIToUTF16 ( name ) , UNASSIGNED_SYSTEM_ADDRESS ) ;
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnNotifyObject ( this , sender , name , param1 , param2 ) ;
}
}
void Entity : : OnEmoteReceived ( const int32_t emote , Entity * target ) {
for ( auto * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnEmoteReceived ( this , emote , target ) ;
}
}
void Entity : : OnUse ( Entity * originator ) {
2023-03-25 10:26:39 +00:00
TriggerEvent ( eTriggerEventType : : INTERACT , originator ) ;
2021-12-05 17:54:36 +00:00
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnUse ( this , originator ) ;
}
// component base class when
2022-07-28 13:39:57 +00:00
2021-12-05 17:54:36 +00:00
for ( const auto & pair : m_Components ) {
if ( pair . second = = nullptr ) continue ;
pair . second - > OnUse ( originator ) ;
}
}
void Entity : : OnHitOrHealResult ( Entity * attacker , int32_t damage ) {
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnHitOrHealResult ( this , attacker , damage ) ;
}
}
void Entity : : OnHit ( Entity * attacker ) {
2023-03-25 10:26:39 +00:00
TriggerEvent ( eTriggerEventType : : HIT , attacker ) ;
2021-12-05 17:54:36 +00:00
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnHit ( this , attacker ) ;
}
}
void Entity : : OnZonePropertyEditBegin ( ) {
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnZonePropertyEditBegin ( this ) ;
}
}
void Entity : : OnZonePropertyEditEnd ( ) {
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnZonePropertyEditEnd ( this ) ;
}
}
void Entity : : OnZonePropertyModelEquipped ( ) {
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnZonePropertyModelEquipped ( this ) ;
}
}
void Entity : : OnZonePropertyModelPlaced ( Entity * player ) {
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnZonePropertyModelPlaced ( this , player ) ;
}
}
void Entity : : OnZonePropertyModelPickedUp ( Entity * player ) {
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnZonePropertyModelPickedUp ( this , player ) ;
}
}
void Entity : : OnZonePropertyModelRemoved ( Entity * player ) {
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnZonePropertyModelRemoved ( this , player ) ;
}
}
void Entity : : OnZonePropertyModelRemovedWhileEquipped ( Entity * player ) {
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnZonePropertyModelRemovedWhileEquipped ( this , player ) ;
}
}
void Entity : : OnZonePropertyModelRotated ( Entity * player ) {
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnZonePropertyModelRotated ( this , player ) ;
}
}
void Entity : : OnMessageBoxResponse ( Entity * sender , int32_t button , const std : : u16string & identifier , const std : : u16string & userData ) {
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnMessageBoxResponse ( this , sender , button , identifier , userData ) ;
}
}
void Entity : : OnChoiceBoxResponse ( Entity * sender , int32_t button , const std : : u16string & buttonIdentifier , const std : : u16string & identifier ) {
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnChoiceBoxResponse ( this , sender , button , buttonIdentifier , identifier ) ;
}
}
2023-06-09 08:04:42 +00:00
void Entity : : RequestActivityExit ( Entity * sender , const LWOOBJID & player , const bool canceled ) {
2023-05-11 00:26:04 +00:00
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnRequestActivityExit ( sender , player , canceled ) ;
}
}
2021-12-05 17:54:36 +00:00
void Entity : : Smash ( const LWOOBJID source , const eKillType killType , const std : : u16string & deathType ) {
if ( ! m_PlayerIsReadyForUpdates ) return ;
2023-06-07 03:48:30 +00:00
auto destroyableComponent = GetComponent < DestroyableComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( destroyableComponent = = nullptr ) {
Kill ( EntityManager : : Instance ( ) - > GetEntity ( source ) ) ;
return ;
}
2023-06-07 03:48:30 +00:00
auto possessorComponent = GetComponent < PossessorComponent > ( ) ;
2022-09-02 18:49:19 +00:00
if ( possessorComponent ) {
if ( possessorComponent - > GetPossessable ( ) ! = LWOOBJID_EMPTY ) {
auto * mount = EntityManager : : Instance ( ) - > GetEntity ( possessorComponent - > GetPossessable ( ) ) ;
if ( mount ) possessorComponent - > Dismount ( mount , true ) ;
}
}
2021-12-05 17:54:36 +00:00
destroyableComponent - > Smash ( source , killType , deathType ) ;
}
void Entity : : Kill ( Entity * murderer ) {
if ( ! m_PlayerIsReadyForUpdates ) return ;
for ( const auto & cb : m_DieCallbacks ) {
cb ( ) ;
}
m_DieCallbacks . clear ( ) ;
//OMAI WA MOU, SHINDERIU
for ( CppScripts : : Script * script : CppScripts : : GetEntityScripts ( this ) ) {
script - > OnDie ( this , murderer ) ;
}
if ( m_Spawner ! = nullptr ) {
m_Spawner - > NotifyOfEntityDeath ( m_ObjectID ) ;
}
if ( ! IsPlayer ( ) ) {
EntityManager : : Instance ( ) - > DestroyEntity ( this ) ;
}
2022-07-28 13:39:57 +00:00
2021-12-05 17:54:36 +00:00
const auto & grpNameQBShowBricks = GetVar < std : : string > ( u " grpNameQBShowBricks " ) ;
if ( ! grpNameQBShowBricks . empty ( ) ) {
auto spawners = dZoneManager : : Instance ( ) - > GetSpawnersByName ( grpNameQBShowBricks ) ;
Spawner * spawner = nullptr ;
if ( ! spawners . empty ( ) ) {
spawner = spawners [ 0 ] ;
} else {
spawners = dZoneManager : : Instance ( ) - > GetSpawnersInGroup ( grpNameQBShowBricks ) ;
if ( ! spawners . empty ( ) ) {
spawner = spawners [ 0 ] ;
}
}
if ( spawner ! = nullptr ) {
spawner - > Spawn ( ) ;
}
}
// Track a player being smashed
2023-06-07 03:48:30 +00:00
auto characterComponent = GetComponent < CharacterComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( characterComponent ! = nullptr ) {
characterComponent - > UpdatePlayerStatistic ( TimesSmashed ) ;
}
// Track a player smashing something else
if ( murderer ! = nullptr ) {
2023-06-09 08:27:05 +00:00
auto * murdererCharacterComponent = murderer - > GetComponent < CharacterComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( murdererCharacterComponent ! = nullptr ) {
murdererCharacterComponent - > UpdatePlayerStatistic ( SmashablesSmashed ) ;
}
}
}
void Entity : : AddDieCallback ( const std : : function < void ( ) > & callback ) {
m_DieCallbacks . push_back ( callback ) ;
}
void Entity : : AddCollisionPhantomCallback ( const std : : function < void ( Entity * target ) > & callback ) {
m_PhantomCollisionCallbacks . push_back ( callback ) ;
}
void Entity : : AddRebuildCompleteCallback ( const std : : function < void ( Entity * user ) > & callback ) const {
2023-06-09 22:12:57 +00:00
auto quickBuildComponent = GetComponent < QuickBuildComponent > ( ) ;
if ( quickBuildComponent ! = nullptr ) {
quickBuildComponent - > AddRebuildCompleteCallback ( callback ) ;
2021-12-05 17:54:36 +00:00
}
}
bool Entity : : GetIsDead ( ) const {
2023-06-07 03:48:30 +00:00
auto dest = GetComponent < DestroyableComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( dest & & dest - > GetArmor ( ) = = 0 & & dest - > GetHealth ( ) = = 0 ) return true ;
return false ;
}
void Entity : : AddLootItem ( const Loot : : Info & info ) {
if ( ! IsPlayer ( ) ) return ;
auto & droppedLoot = static_cast < Player * > ( this ) - > GetDroppedLoot ( ) ;
droppedLoot . insert ( std : : make_pair ( info . id , info ) ) ;
}
void Entity : : PickupItem ( const LWOOBJID & objectID ) {
if ( ! IsPlayer ( ) ) return ;
2023-06-07 03:48:30 +00:00
auto inv = GetComponent < InventoryComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( ! inv ) return ;
2023-03-17 14:36:21 +00:00
CDObjectsTable * objectsTable = CDClientManager : : Instance ( ) . GetTable < CDObjectsTable > ( ) ;
2022-07-28 13:39:57 +00:00
2021-12-05 17:54:36 +00:00
auto & droppedLoot = static_cast < Player * > ( this ) - > GetDroppedLoot ( ) ;
for ( const auto & p : droppedLoot ) {
if ( p . first = = objectID ) {
2023-06-07 03:48:30 +00:00
auto characterComponent = GetComponent < CharacterComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( characterComponent ! = nullptr ) {
characterComponent - > TrackLOTCollection ( p . second . lot ) ;
}
const CDObjects & object = objectsTable - > GetByID ( p . second . lot ) ;
if ( object . id ! = 0 & & object . type = = " Powerup " ) {
2023-03-17 14:36:21 +00:00
CDObjectSkillsTable * skillsTable = CDClientManager : : Instance ( ) . GetTable < CDObjectSkillsTable > ( ) ;
2021-12-05 17:54:36 +00:00
std : : vector < CDObjectSkills > skills = skillsTable - > Query ( [ = ] ( CDObjectSkills entry ) { return ( entry . objectTemplate = = p . second . lot ) ; } ) ;
for ( CDObjectSkills skill : skills ) {
2023-03-17 14:36:21 +00:00
CDSkillBehaviorTable * skillBehTable = CDClientManager : : Instance ( ) . GetTable < CDSkillBehaviorTable > ( ) ;
2021-12-05 17:54:36 +00:00
CDSkillBehavior behaviorData = skillBehTable - > GetSkillByID ( skill . skillID ) ;
SkillComponent : : HandleUnmanaged ( behaviorData . behaviorID , GetObjectID ( ) ) ;
2023-06-07 03:48:30 +00:00
auto missionComponent = GetComponent < MissionComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( missionComponent ! = nullptr ) {
missionComponent - > Progress ( eMissionTaskType : : POWERUP , skill . skillID ) ;
}
}
} else {
2023-05-02 22:39:21 +00:00
inv - > AddItem ( p . second . lot , p . second . count , eLootSourceType : : PICKUP , eInventoryType : : INVALID , { } , LWOOBJID_EMPTY , true , false , LWOOBJID_EMPTY , eInventoryType : : INVALID , 1 ) ;
2021-12-05 17:54:36 +00:00
}
}
}
droppedLoot . erase ( objectID ) ;
}
2023-06-09 08:04:42 +00:00
bool Entity : : CanPickupCoins ( const uint64_t & count ) {
2021-12-11 13:21:00 +00:00
if ( ! IsPlayer ( ) ) return false ;
2021-12-11 16:33:54 +00:00
auto * player = static_cast < Player * > ( this ) ;
auto droppedCoins = player - > GetDroppedCoins ( ) ;
if ( count > droppedCoins ) {
2021-12-11 13:21:00 +00:00
return false ;
} else {
2021-12-11 16:33:54 +00:00
player - > SetDroppedCoins ( droppedCoins - count ) ;
2021-12-11 13:21:00 +00:00
return true ;
}
}
2023-06-09 08:04:42 +00:00
void Entity : : RegisterCoinDrop ( const uint64_t & count ) {
2021-12-11 13:21:00 +00:00
if ( ! IsPlayer ( ) ) return ;
2021-12-11 16:33:54 +00:00
auto * player = static_cast < Player * > ( this ) ;
auto droppedCoins = player - > GetDroppedCoins ( ) ;
droppedCoins + = count ;
player - > SetDroppedCoins ( droppedCoins ) ;
2021-12-11 13:21:00 +00:00
}
2021-12-05 17:54:36 +00:00
void Entity : : AddChild ( Entity * child ) {
2022-06-16 05:58:38 +00:00
m_IsParentChildDirty = true ;
2021-12-05 17:54:36 +00:00
m_ChildEntities . push_back ( child ) ;
}
2022-06-17 00:50:33 +00:00
void Entity : : RemoveChild ( Entity * child ) {
if ( ! child ) return ;
2022-07-17 04:39:13 +00:00
uint32_t entityPosition = 0 ;
while ( entityPosition < m_ChildEntities . size ( ) ) {
if ( ! m_ChildEntities [ entityPosition ] | | ( m_ChildEntities [ entityPosition ] ) - > GetObjectID ( ) = = child - > GetObjectID ( ) ) {
2022-06-17 00:50:33 +00:00
m_IsParentChildDirty = true ;
2022-07-17 04:39:13 +00:00
m_ChildEntities . erase ( m_ChildEntities . begin ( ) + entityPosition ) ;
} else {
entityPosition + + ;
2022-06-17 00:50:33 +00:00
}
}
}
2022-07-17 04:39:13 +00:00
void Entity : : RemoveParent ( ) {
this - > m_ParentEntity = nullptr ;
}
2023-06-09 08:04:42 +00:00
void Entity : : AddTimer ( const std : : string & name , float time ) {
2021-12-05 17:54:36 +00:00
EntityTimer * timer = new EntityTimer ( name , time ) ;
2022-07-17 01:21:35 +00:00
m_PendingTimers . push_back ( timer ) ;
2021-12-05 17:54:36 +00:00
}
2023-06-09 08:04:42 +00:00
void Entity : : AddCallbackTimer ( const float time , const std : : function < void ( ) > & callback ) {
2021-12-05 17:54:36 +00:00
EntityCallbackTimer * timer = new EntityCallbackTimer ( time , callback ) ;
m_CallbackTimers . push_back ( timer ) ;
}
bool Entity : : HasTimer ( const std : : string & name ) {
for ( auto * timer : m_Timers ) {
if ( timer - > GetName ( ) = = name ) {
return true ;
}
}
return false ;
}
void Entity : : CancelCallbackTimers ( ) {
for ( auto * callback : m_CallbackTimers ) {
delete callback ;
}
2022-07-28 13:39:57 +00:00
2021-12-05 17:54:36 +00:00
m_CallbackTimers . clear ( ) ;
}
void Entity : : ScheduleKillAfterUpdate ( Entity * murderer ) {
//if (m_Info.spawner) m_Info.spawner->ScheduleKill(this);
EntityManager : : Instance ( ) - > ScheduleForKill ( this ) ;
if ( murderer ) m_ScheduleKiller = murderer ;
}
void Entity : : CancelTimer ( const std : : string & name ) {
for ( int i = 0 ; i < m_Timers . size ( ) ; i + + ) {
if ( m_Timers [ i ] - > GetName ( ) = = name ) {
delete m_Timers [ i ] ;
m_Timers . erase ( m_Timers . begin ( ) + i ) ;
return ;
}
}
}
void Entity : : CancelAllTimers ( ) {
/*for (auto timer : m_Timers) {
if ( timer ) delete timer ;
} */
for ( auto * timer : m_Timers ) {
delete timer ;
}
m_Timers . clear ( ) ;
for ( auto * callBackTimer : m_CallbackTimers ) {
delete callBackTimer ;
}
m_CallbackTimers . clear ( ) ;
}
bool Entity : : IsPlayer ( ) const {
2022-04-24 03:35:39 +00:00
return m_TemplateID = = 1 & & GetSystemAddress ( ) ! = UNASSIGNED_SYSTEM_ADDRESS ;
2021-12-05 17:54:36 +00:00
}
2023-02-10 08:29:53 +00:00
void Entity : : TriggerEvent ( eTriggerEventType event , Entity * optionalTarget ) {
2023-06-07 03:48:30 +00:00
auto triggerComponent = GetComponent < TriggerComponent > ( ) ;
2023-02-10 08:29:53 +00:00
if ( triggerComponent ) triggerComponent - > TriggerEvent ( event , optionalTarget ) ;
2021-12-05 17:54:36 +00:00
}
Entity * Entity : : GetOwner ( ) const {
if ( m_OwnerOverride ! = LWOOBJID_EMPTY ) {
auto * other = EntityManager : : Instance ( ) - > GetEntity ( m_OwnerOverride ) ;
if ( other ! = nullptr ) {
return other - > GetOwner ( ) ;
}
}
return const_cast < Entity * > ( this ) ;
}
const NiPoint3 & Entity : : GetDefaultPosition ( ) const {
return m_DefaultPosition ;
}
const NiQuaternion & Entity : : GetDefaultRotation ( ) const {
return m_DefaultRotation ;
}
2023-06-09 08:04:42 +00:00
void Entity : : SetOwnerOverride ( const LWOOBJID & value ) {
2021-12-05 17:54:36 +00:00
m_OwnerOverride = value ;
}
void Entity : : SetObservers ( int8_t value ) {
if ( value < 0 ) {
value = 0 ;
}
m_Observers = value ;
}
void Entity : : Sleep ( ) {
2023-06-07 03:48:30 +00:00
auto baseCombatAIComponent = GetComponent < BaseCombatAIComponent > ( ) ;
2022-07-28 13:39:57 +00:00
2021-12-05 17:54:36 +00:00
if ( baseCombatAIComponent ! = nullptr ) {
baseCombatAIComponent - > Sleep ( ) ;
}
}
void Entity : : Wake ( ) {
2023-06-07 03:48:30 +00:00
auto baseCombatAIComponent = GetComponent < BaseCombatAIComponent > ( ) ;
2022-07-28 13:39:57 +00:00
2021-12-05 17:54:36 +00:00
if ( baseCombatAIComponent ! = nullptr ) {
baseCombatAIComponent - > Wake ( ) ;
}
}
bool Entity : : IsSleeping ( ) const {
return m_IsGhostingCandidate & & m_Observers = = 0 ;
}
const NiPoint3 & Entity : : GetPosition ( ) const {
auto * controllable = GetComponent < ControllablePhysicsComponent > ( ) ;
if ( controllable ! = nullptr ) {
return controllable - > GetPosition ( ) ;
}
2023-06-07 03:48:30 +00:00
auto phantom = GetComponent < PhantomPhysicsComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( phantom ! = nullptr ) {
return phantom - > GetPosition ( ) ;
}
2023-06-07 03:48:30 +00:00
auto simple = GetComponent < SimplePhysicsComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( simple ! = nullptr ) {
return simple - > GetPosition ( ) ;
}
2023-06-08 15:29:17 +00:00
auto vehicle = GetComponent < HavokVehiclePhysicsComponent > ( ) ;
2021-12-05 17:54:36 +00:00
2023-06-07 03:48:30 +00:00
if ( vehicle ! = nullptr ) {
return vehicle - > GetPosition ( ) ;
2021-12-05 17:54:36 +00:00
}
return NiPoint3 : : ZERO ;
}
const NiQuaternion & Entity : : GetRotation ( ) const {
2023-06-07 03:48:30 +00:00
auto controllable = GetComponent < ControllablePhysicsComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( controllable ! = nullptr ) {
return controllable - > GetRotation ( ) ;
}
2023-06-07 03:48:30 +00:00
auto phantom = GetComponent < PhantomPhysicsComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( phantom ! = nullptr ) {
return phantom - > GetRotation ( ) ;
}
2023-06-07 03:48:30 +00:00
auto simple = GetComponent < SimplePhysicsComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( simple ! = nullptr ) {
return simple - > GetRotation ( ) ;
}
2022-07-28 13:39:57 +00:00
2023-06-08 15:29:17 +00:00
auto vehicle = GetComponent < HavokVehiclePhysicsComponent > ( ) ;
2021-12-05 17:54:36 +00:00
2023-06-07 03:48:30 +00:00
if ( vehicle ! = nullptr ) {
return vehicle - > GetRotation ( ) ;
2021-12-05 17:54:36 +00:00
}
return NiQuaternion : : IDENTITY ;
}
2023-06-09 08:04:42 +00:00
void Entity : : SetPosition ( const NiPoint3 & position ) {
2023-06-07 03:48:30 +00:00
auto controllable = GetComponent < ControllablePhysicsComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( controllable ! = nullptr ) {
controllable - > SetPosition ( position ) ;
}
2023-06-07 03:48:30 +00:00
auto phantom = GetComponent < PhantomPhysicsComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( phantom ! = nullptr ) {
phantom - > SetPosition ( position ) ;
}
2023-06-07 03:48:30 +00:00
auto simple = GetComponent < SimplePhysicsComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( simple ! = nullptr ) {
simple - > SetPosition ( position ) ;
}
2023-06-08 15:29:17 +00:00
auto vehicle = GetComponent < HavokVehiclePhysicsComponent > ( ) ;
2021-12-05 17:54:36 +00:00
2023-06-07 03:48:30 +00:00
if ( vehicle ! = nullptr ) {
vehicle - > SetPosition ( position ) ;
2021-12-05 17:54:36 +00:00
}
EntityManager : : Instance ( ) - > SerializeEntity ( this ) ;
}
2023-06-09 08:04:42 +00:00
void Entity : : SetRotation ( const NiQuaternion & rotation ) {
2023-06-07 03:48:30 +00:00
auto controllable = GetComponent < ControllablePhysicsComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( controllable ! = nullptr ) {
controllable - > SetRotation ( rotation ) ;
}
2023-06-07 03:48:30 +00:00
auto phantom = GetComponent < PhantomPhysicsComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( phantom ! = nullptr ) {
phantom - > SetRotation ( rotation ) ;
}
2023-06-07 03:48:30 +00:00
auto simple = GetComponent < SimplePhysicsComponent > ( ) ;
2021-12-05 17:54:36 +00:00
if ( simple ! = nullptr ) {
simple - > SetRotation ( rotation ) ;
}
2023-06-08 15:29:17 +00:00
auto vehicle = GetComponent < HavokVehiclePhysicsComponent > ( ) ;
2021-12-05 17:54:36 +00:00
2023-06-07 03:48:30 +00:00
if ( vehicle ! = nullptr ) {
vehicle - > SetRotation ( rotation ) ;
2021-12-05 17:54:36 +00:00
}
EntityManager : : Instance ( ) - > SerializeEntity ( this ) ;
}
bool Entity : : GetBoolean ( const std : : u16string & name ) const {
return GetVar < bool > ( name ) ;
}
int32_t Entity : : GetI32 ( const std : : u16string & name ) const {
return GetVar < int32_t > ( name ) ;
}
int64_t Entity : : GetI64 ( const std : : u16string & name ) const {
return GetVar < int64_t > ( name ) ;
}
void Entity : : SetBoolean ( const std : : u16string & name , const bool value ) {
SetVar ( name , value ) ;
}
void Entity : : SetI32 ( const std : : u16string & name , const int32_t value ) {
SetVar ( name , value ) ;
}
void Entity : : SetI64 ( const std : : u16string & name , const int64_t value ) {
SetVar ( name , value ) ;
}
bool Entity : : HasVar ( const std : : u16string & name ) const {
for ( auto * data : m_Settings ) {
if ( data - > GetKey ( ) = = name ) {
return true ;
}
}
2022-07-28 13:39:57 +00:00
2021-12-05 17:54:36 +00:00
return false ;
}
void Entity : : SetNetworkId ( const uint16_t id ) {
m_NetworkID = id ;
}
std : : vector < LWOOBJID > & Entity : : GetTargetsInPhantom ( ) {
std : : vector < LWOOBJID > valid ;
// Clean up invalid targets, like disconnected players
for ( auto i = 0u ; i < m_TargetsInPhantom . size ( ) ; + + i ) {
const auto id = m_TargetsInPhantom . at ( i ) ;
auto * entity = EntityManager : : Instance ( ) - > GetEntity ( id ) ;
if ( entity = = nullptr ) {
continue ;
}
valid . push_back ( id ) ;
}
m_TargetsInPhantom = valid ;
return m_TargetsInPhantom ;
}
void Entity : : SendNetworkVar ( const std : : string & data , const SystemAddress & sysAddr ) {
GameMessages : : SendSetNetworkScriptVar ( this , sysAddr , data ) ;
}
LDFBaseData * Entity : : GetVarData ( const std : : u16string & name ) const {
for ( auto * data : m_Settings ) {
if ( data = = nullptr ) {
continue ;
}
if ( data - > GetKey ( ) ! = name ) {
continue ;
}
return data ;
}
return nullptr ;
}
std : : string Entity : : GetVarAsString ( const std : : u16string & name ) const {
auto * data = GetVarData ( name ) ;
if ( data = = nullptr ) {
return " " ;
}
return data - > GetValueAsString ( ) ;
}
void Entity : : Resurrect ( ) {
if ( IsPlayer ( ) ) {
GameMessages : : SendResurrect ( this ) ;
}
}
2023-06-09 08:04:42 +00:00
void Entity : : AddToGroups ( const std : : string & group ) {
2021-12-05 17:54:36 +00:00
if ( std : : find ( m_Groups . begin ( ) , m_Groups . end ( ) , group ) = = m_Groups . end ( ) ) {
m_Groups . push_back ( group ) ;
}
}
2022-04-13 08:49:55 +00:00
void Entity : : RetroactiveVaultSize ( ) {
auto inventoryComponent = GetComponent < InventoryComponent > ( ) ;
if ( ! inventoryComponent ) return ;
auto itemsVault = inventoryComponent - > GetInventory ( eInventoryType : : VAULT_ITEMS ) ;
auto modelVault = inventoryComponent - > GetInventory ( eInventoryType : : VAULT_MODELS ) ;
if ( itemsVault - > GetSize ( ) = = modelVault - > GetSize ( ) ) return ;
modelVault - > SetSize ( itemsVault - > GetSize ( ) ) ;
}