mirror of
				https://github.com/DarkflameUniverse/DarkflameServer.git
				synced 2025-10-31 20:52:01 +00:00 
			
		
		
		
	Merge branch 'main' into item-component
This commit is contained in:
		| @@ -414,6 +414,7 @@ enum eReplicaComponentType : int32_t { | |||||||
| 	COMPONENT_TYPE_MODULE_ASSEMBLY = 61,			//!< The ModuleAssembly Component | 	COMPONENT_TYPE_MODULE_ASSEMBLY = 61,			//!< The ModuleAssembly Component | ||||||
| 	COMPONENT_TYPE_PROPERTY_VENDOR = 65,			//!< The PropertyVendor Component | 	COMPONENT_TYPE_PROPERTY_VENDOR = 65,			//!< The PropertyVendor Component | ||||||
| 	COMPONENT_TYPE_ROCKET_LAUNCH = 67,			//!< The RocketLaunch Component | 	COMPONENT_TYPE_ROCKET_LAUNCH = 67,			//!< The RocketLaunch Component | ||||||
|  | 	COMPONENT_TYPE_TRIGGER = 69, | ||||||
| 	COMPONENT_TYPE_RACING_CONTROL = 71,			//!< The RacingControl Component | 	COMPONENT_TYPE_RACING_CONTROL = 71,			//!< The RacingControl Component | ||||||
| 	COMPONENT_TYPE_MISSION_OFFER = 73,			//!< The MissionOffer Component | 	COMPONENT_TYPE_MISSION_OFFER = 73,			//!< The MissionOffer Component | ||||||
| 	COMPONENT_TYPE_EXHIBIT = 75,			//!< The Exhibit Component | 	COMPONENT_TYPE_EXHIBIT = 75,			//!< The Exhibit Component | ||||||
|   | |||||||
							
								
								
									
										119
									
								
								dCommon/dEnums/eTriggerCommandType.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								dCommon/dEnums/eTriggerCommandType.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | |||||||
|  | #ifndef __ETRIGGERCOMMANDTYPE__H__ | ||||||
|  | #define __ETRIGGERCOMMANDTYPE__H__ | ||||||
|  |  | ||||||
|  | // For info about Trigger Command see: | ||||||
|  | // https://docs.lu-dev.net/en/latest/file-structures/lutriggers.html?highlight=trigger#possible-values-commands | ||||||
|  |  | ||||||
|  | enum class eTriggerCommandType { | ||||||
|  | 	INVALID, | ||||||
|  | 	ZONE_PLAYER, | ||||||
|  | 	FIRE_EVENT, | ||||||
|  | 	DESTROY_OBJ, | ||||||
|  | 	TOGGLE_TRIGGER, | ||||||
|  | 	RESET_REBUILD, | ||||||
|  | 	SET_PATH, | ||||||
|  | 	SET_PICK_TYPE, | ||||||
|  | 	MOVE_OBJECT, | ||||||
|  | 	ROTATE_OBJECT, | ||||||
|  | 	PUSH_OBJECT, | ||||||
|  | 	REPEL_OBJECT, | ||||||
|  | 	SET_TIMER, | ||||||
|  | 	CANCEL_TIMER, | ||||||
|  | 	PLAY_CINEMATIC, | ||||||
|  | 	TOGGLE_BBB, | ||||||
|  | 	UPDATE_MISSION, | ||||||
|  | 	SET_BOUNCER_STATE, | ||||||
|  | 	BOUNCE_ALL_ON_BOUNCER, | ||||||
|  | 	TURN_AROUND_ON_PATH, | ||||||
|  | 	GO_FORWARD_ON_PATH, | ||||||
|  | 	GO_BACKWARD_ON_PATH, | ||||||
|  | 	STOP_PATHING, | ||||||
|  | 	START_PATHING, | ||||||
|  | 	LOCK_OR_UNLOCK_CONTROLS, | ||||||
|  | 	PLAY_EFFECT, | ||||||
|  | 	STOP_EFFECT, | ||||||
|  | 	ACTIVATE_MUSIC_CUE, | ||||||
|  | 	DEACTIVATE_MUSIC_CUE, | ||||||
|  | 	FLASH_MUSIC_CUE, | ||||||
|  | 	SET_MUSIC_PARAMETER, | ||||||
|  | 	PLAY_2D_AMBIENT_SOUND, | ||||||
|  | 	STOP_2D_AMBIENT_SOUND, | ||||||
|  | 	PLAY_3D_AMBIENT_SOUND, | ||||||
|  | 	STOP_3D_AMBIENT_SOUND, | ||||||
|  | 	ACTIVATE_MIXER_PROGRAM, | ||||||
|  | 	DEACTIVATE_MIXER_PROGRAM, | ||||||
|  | 	CAST_SKILL, | ||||||
|  | 	DISPLAY_ZONE_SUMMARY, | ||||||
|  | 	SET_PHYSICS_VOLUME_EFFECT, | ||||||
|  | 	SET_PHYSICS_VOLUME_STATUS, | ||||||
|  | 	SET_MODEL_TO_BUILD, | ||||||
|  | 	SPAWN_MODEL_BRICKS, | ||||||
|  | 	ACTIVATE_SPAWNER_NETWORK, | ||||||
|  | 	DEACTIVATE_SPAWNER_NETWORK, | ||||||
|  | 	RESET_SPAWNER_NETWORK, | ||||||
|  | 	DESTROY_SPAWNER_NETWORK_OBJECTS, | ||||||
|  | 	GO_TO_WAYPOINT, | ||||||
|  | 	ACTIVATE_PHYSICS | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TriggerCommandType { | ||||||
|  | public: | ||||||
|  | 	static eTriggerCommandType StringToTriggerCommandType(std::string commandString) { | ||||||
|  | 		const std::map<std::string, eTriggerCommandType> TriggerCommandMap = { | ||||||
|  | 			{ "zonePlayer", eTriggerCommandType::ZONE_PLAYER}, | ||||||
|  | 			{ "fireEvent", eTriggerCommandType::FIRE_EVENT}, | ||||||
|  | 			{ "destroyObj", eTriggerCommandType::DESTROY_OBJ}, | ||||||
|  | 			{ "toggleTrigger", eTriggerCommandType::TOGGLE_TRIGGER}, | ||||||
|  | 			{ "resetRebuild", eTriggerCommandType::RESET_REBUILD}, | ||||||
|  | 			{ "setPath", eTriggerCommandType::SET_PATH}, | ||||||
|  | 			{ "setPickType", eTriggerCommandType::SET_PICK_TYPE}, | ||||||
|  | 			{ "moveObject", eTriggerCommandType::MOVE_OBJECT}, | ||||||
|  | 			{ "rotateObject", eTriggerCommandType::ROTATE_OBJECT}, | ||||||
|  | 			{ "pushObject", eTriggerCommandType::PUSH_OBJECT}, | ||||||
|  | 			{ "repelObject", eTriggerCommandType::REPEL_OBJECT}, | ||||||
|  | 			{ "setTimer", eTriggerCommandType::SET_TIMER}, | ||||||
|  | 			{ "cancelTimer", eTriggerCommandType::CANCEL_TIMER}, | ||||||
|  | 			{ "playCinematic", eTriggerCommandType::PLAY_CINEMATIC}, | ||||||
|  | 			{ "toggleBBB", eTriggerCommandType::TOGGLE_BBB}, | ||||||
|  | 			{ "updateMission", eTriggerCommandType::UPDATE_MISSION}, | ||||||
|  | 			{ "setBouncerState", eTriggerCommandType::SET_BOUNCER_STATE}, | ||||||
|  | 			{ "bounceAllOnBouncer", eTriggerCommandType::BOUNCE_ALL_ON_BOUNCER}, | ||||||
|  | 			{ "turnAroundOnPath", eTriggerCommandType::TURN_AROUND_ON_PATH}, | ||||||
|  | 			{ "goForwardOnPath", eTriggerCommandType::GO_FORWARD_ON_PATH}, | ||||||
|  | 			{ "goBackwardOnPath", eTriggerCommandType::GO_BACKWARD_ON_PATH}, | ||||||
|  | 			{ "stopPathing", eTriggerCommandType::STOP_PATHING}, | ||||||
|  | 			{ "startPathing", eTriggerCommandType::START_PATHING}, | ||||||
|  | 			{ "LockOrUnlockControls", eTriggerCommandType::LOCK_OR_UNLOCK_CONTROLS}, | ||||||
|  | 			{ "PlayEffect", eTriggerCommandType::PLAY_EFFECT}, | ||||||
|  | 			{ "StopEffect", eTriggerCommandType::STOP_EFFECT}, | ||||||
|  | 			{ "activateMusicCue", eTriggerCommandType::ACTIVATE_MUSIC_CUE}, | ||||||
|  | 			{ "deactivateMusicCue", eTriggerCommandType::DEACTIVATE_MUSIC_CUE}, | ||||||
|  | 			{ "flashMusicCue", eTriggerCommandType::FLASH_MUSIC_CUE}, | ||||||
|  | 			{ "setMusicParameter", eTriggerCommandType::SET_MUSIC_PARAMETER}, | ||||||
|  | 			{ "play2DAmbientSound", eTriggerCommandType::PLAY_2D_AMBIENT_SOUND}, | ||||||
|  | 			{ "stop2DAmbientSound", eTriggerCommandType::STOP_2D_AMBIENT_SOUND}, | ||||||
|  | 			{ "play3DAmbientSound", eTriggerCommandType::PLAY_3D_AMBIENT_SOUND}, | ||||||
|  | 			{ "stop3DAmbientSound", eTriggerCommandType::STOP_3D_AMBIENT_SOUND}, | ||||||
|  | 			{ "activateMixerProgram", eTriggerCommandType::ACTIVATE_MIXER_PROGRAM}, | ||||||
|  | 			{ "deactivateMixerProgram", eTriggerCommandType::DEACTIVATE_MIXER_PROGRAM}, | ||||||
|  | 			{ "CastSkill", eTriggerCommandType::CAST_SKILL}, | ||||||
|  | 			{ "displayZoneSummary", eTriggerCommandType::DISPLAY_ZONE_SUMMARY}, | ||||||
|  | 			{ "SetPhysicsVolumeEffect", eTriggerCommandType::SET_PHYSICS_VOLUME_EFFECT}, | ||||||
|  | 			{ "SetPhysicsVolumeStatus", eTriggerCommandType::SET_PHYSICS_VOLUME_STATUS}, | ||||||
|  | 			{ "setModelToBuild", eTriggerCommandType::SET_MODEL_TO_BUILD}, | ||||||
|  | 			{ "spawnModelBricks", eTriggerCommandType::SPAWN_MODEL_BRICKS}, | ||||||
|  | 			{ "ActivateSpawnerNetwork", eTriggerCommandType::ACTIVATE_SPAWNER_NETWORK}, | ||||||
|  | 			{ "DeactivateSpawnerNetwork", eTriggerCommandType::DEACTIVATE_SPAWNER_NETWORK}, | ||||||
|  | 			{ "ResetSpawnerNetwork", eTriggerCommandType::RESET_SPAWNER_NETWORK}, | ||||||
|  | 			{ "DestroySpawnerNetworkObjects", eTriggerCommandType::DESTROY_SPAWNER_NETWORK_OBJECTS}, | ||||||
|  | 			{ "Go_To_Waypoint", eTriggerCommandType::GO_TO_WAYPOINT}, | ||||||
|  | 			{ "ActivatePhysics", eTriggerCommandType::ACTIVATE_PHYSICS} | ||||||
|  | 		}; | ||||||
|  |  | ||||||
|  | 		auto intermed = TriggerCommandMap.find(commandString); | ||||||
|  | 		return (intermed != TriggerCommandMap.end()) ? intermed->second : eTriggerCommandType::INVALID; | ||||||
|  | 	}; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif  //!__ETRIGGERCOMMANDTYPE__H__ | ||||||
							
								
								
									
										53
									
								
								dCommon/dEnums/eTriggerEventType.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								dCommon/dEnums/eTriggerEventType.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | |||||||
|  | #ifndef __ETRIGGEREVENTTYPE__H__ | ||||||
|  | #define __ETRIGGEREVENTTYPE__H__ | ||||||
|  |  | ||||||
|  | enum class eTriggerEventType { | ||||||
|  | 	INVALID, | ||||||
|  | 	DESTROY, | ||||||
|  | 	CUSTOM_EVENT, | ||||||
|  | 	ENTER, | ||||||
|  | 	EXIT, | ||||||
|  | 	CREATE, | ||||||
|  | 	HIT, | ||||||
|  | 	TIMER_DONE, | ||||||
|  | 	REBUILD_COMPLETE, | ||||||
|  | 	ACTIVATED, | ||||||
|  | 	DEACTIVATED, | ||||||
|  | 	ARRIVED, | ||||||
|  | 	ARRIVED_AT_END_OF_PATH, | ||||||
|  | 	ZONE_SUMMARY_DISMISSED, | ||||||
|  | 	ARRIVED_AT_DESIRED_WAYPOINT, | ||||||
|  | 	PET_ON_SWITCH, | ||||||
|  | 	PET_OFF_SWITCH, | ||||||
|  | 	INTERACT | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class TriggerEventType { | ||||||
|  | public: | ||||||
|  | 	static eTriggerEventType StringToTriggerEventType(std::string commandString) { | ||||||
|  | 		const std::map<std::string, eTriggerEventType> TriggerEventMap = { | ||||||
|  | 			{"OnDestroy", eTriggerEventType::DESTROY}, | ||||||
|  | 			{"OnCustomEvent", eTriggerEventType::CUSTOM_EVENT}, | ||||||
|  | 			{"OnEnter", eTriggerEventType::ENTER}, | ||||||
|  | 			{"OnExit", eTriggerEventType::EXIT}, | ||||||
|  | 			{"OnCreate", eTriggerEventType::CREATE}, | ||||||
|  | 			{"OnHit", eTriggerEventType::HIT}, | ||||||
|  | 			{"OnTimerDone", eTriggerEventType::TIMER_DONE}, | ||||||
|  | 			{"OnRebuildComplete", eTriggerEventType::REBUILD_COMPLETE}, | ||||||
|  | 			{"OnActivated", eTriggerEventType::ACTIVATED}, | ||||||
|  | 			{"OnDeactivated", eTriggerEventType::DEACTIVATED}, | ||||||
|  | 			{"OnArrived", eTriggerEventType::ARRIVED}, | ||||||
|  | 			{"OnArrivedAtEndOfPath", eTriggerEventType::ARRIVED_AT_END_OF_PATH}, | ||||||
|  | 			{"OnZoneSummaryDismissed", eTriggerEventType::ZONE_SUMMARY_DISMISSED}, | ||||||
|  | 			{"OnArrivedAtDesiredWaypoint", eTriggerEventType::ARRIVED_AT_DESIRED_WAYPOINT}, | ||||||
|  | 			{"OnPetOnSwitch", eTriggerEventType::PET_ON_SWITCH}, | ||||||
|  | 			{"OnPetOffSwitch", eTriggerEventType::PET_OFF_SWITCH}, | ||||||
|  | 			{"OnInteract", eTriggerEventType::INTERACT}, | ||||||
|  | 		}; | ||||||
|  |  | ||||||
|  | 		auto intermed = TriggerEventMap.find(commandString); | ||||||
|  | 		return (intermed != TriggerEventMap.end()) ? intermed->second : eTriggerEventType::INVALID; | ||||||
|  | 	}; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif  //!__ETRIGGEREVENTTYPE__H__ | ||||||
							
								
								
									
										137
									
								
								dGame/Entity.cpp
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								dGame/Entity.cpp
									
									
									
									
									
								
							| @@ -23,6 +23,7 @@ | |||||||
| #include "EntityCallbackTimer.h" | #include "EntityCallbackTimer.h" | ||||||
| #include "Loot.h" | #include "Loot.h" | ||||||
| #include "eMissionTaskType.h" | #include "eMissionTaskType.h" | ||||||
|  | #include "eTriggerEventType.h" | ||||||
|  |  | ||||||
| //Component includes: | //Component includes: | ||||||
| #include "Component.h" | #include "Component.h" | ||||||
| @@ -68,6 +69,7 @@ | |||||||
| #include "ShootingGalleryComponent.h" | #include "ShootingGalleryComponent.h" | ||||||
| #include "RailActivatorComponent.h" | #include "RailActivatorComponent.h" | ||||||
| #include "LUPExhibitComponent.h" | #include "LUPExhibitComponent.h" | ||||||
|  | #include "TriggerComponent.h" | ||||||
| #include "ItemComponent.h" | #include "ItemComponent.h" | ||||||
|  |  | ||||||
| Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity) { | Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity) { | ||||||
| @@ -77,7 +79,6 @@ Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity) | |||||||
| 	m_Character = nullptr; | 	m_Character = nullptr; | ||||||
| 	m_GMLevel = 0; | 	m_GMLevel = 0; | ||||||
| 	m_CollectibleID = 0; | 	m_CollectibleID = 0; | ||||||
| 	m_Trigger = nullptr; //new LUTriggers::Trigger(); |  | ||||||
| 	m_NetworkID = 0; | 	m_NetworkID = 0; | ||||||
| 	m_Groups = {}; | 	m_Groups = {}; | ||||||
| 	m_OwnerOverride = LWOOBJID_EMPTY; | 	m_OwnerOverride = LWOOBJID_EMPTY; | ||||||
| @@ -133,30 +134,9 @@ void Entity::Initialize() { | |||||||
| 	 * Setup trigger | 	 * Setup trigger | ||||||
| 	 */ | 	 */ | ||||||
|  |  | ||||||
| 	const auto triggerName = GetVarAsString(u"trigger_id"); | 	const auto triggerInfo = GetVarAsString(u"trigger_id"); | ||||||
|  |  | ||||||
| 	if (!triggerName.empty()) { | 	if (!triggerInfo.empty()) m_Components.emplace(COMPONENT_TYPE_TRIGGER, new TriggerComponent(this, triggerInfo)); | ||||||
| 		std::stringstream ss(triggerName); |  | ||||||
| 		std::vector<std::string> tokens; |  | ||||||
| 		std::string token; |  | ||||||
| 		while (std::getline(ss, token, ':')) { |  | ||||||
| 			tokens.push_back(token); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		uint32_t sceneID = std::stoi(tokens[0]); |  | ||||||
| 		uint32_t triggerID = std::stoi(tokens[1]); |  | ||||||
|  |  | ||||||
| 		if (m_Trigger != nullptr) { |  | ||||||
| 			delete m_Trigger; |  | ||||||
| 			m_Trigger = nullptr; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		m_Trigger = dZoneManager::Instance()->GetZone()->GetTrigger(sceneID, triggerID); |  | ||||||
|  |  | ||||||
| 		if (m_Trigger == nullptr) { |  | ||||||
| 			m_Trigger = new LUTriggers::Trigger(); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Setup groups | 	 * Setup groups | ||||||
| @@ -770,7 +750,7 @@ void Entity::Initialize() { | |||||||
|  |  | ||||||
| no_ghosting: | no_ghosting: | ||||||
|  |  | ||||||
| 	TriggerEvent("OnCreate"); | 	TriggerEvent(eTriggerEventType::CREATE); | ||||||
|  |  | ||||||
| 	if (m_Character) { | 	if (m_Character) { | ||||||
| 		auto* controllablePhysicsComponent = GetComponent<ControllablePhysicsComponent>(); | 		auto* controllablePhysicsComponent = GetComponent<ControllablePhysicsComponent>(); | ||||||
| @@ -947,12 +927,16 @@ void Entity::WriteBaseReplicaData(RakNet::BitStream* outBitStream, eReplicaPacke | |||||||
| 			outBitStream->Write0(); //No ldf data | 			outBitStream->Write0(); //No ldf data | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (m_Trigger != nullptr && m_Trigger->events.size() > 0) { | 		TriggerComponent* triggerComponent; | ||||||
| 			outBitStream->Write1(); | 		if (TryGetComponent(COMPONENT_TYPE_TRIGGER, triggerComponent)) { | ||||||
| 		} else { | 			// 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 | ||||||
| 			outBitStream->Write0(); | 			outBitStream->Write0(); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  |  | ||||||
| 		if (m_ParentEntity != nullptr || m_SpawnerID != 0) { | 		if (m_ParentEntity != nullptr || m_SpawnerID != 0) { | ||||||
| 			outBitStream->Write1(); | 			outBitStream->Write1(); | ||||||
| 			if (m_ParentEntity != nullptr) outBitStream->Write(GeneralUtils::SetBit(m_ParentEntity->GetObjectID(), OBJECT_BIT_CLIENT)); | 			if (m_ParentEntity != nullptr) outBitStream->Write(GeneralUtils::SetBit(m_ParentEntity->GetObjectID(), OBJECT_BIT_CLIENT)); | ||||||
| @@ -1312,7 +1296,7 @@ void Entity::OnCollisionPhantom(const LWOOBJID otherEntity) { | |||||||
| 		switchComp->EntityEnter(other); | 		switchComp->EntityEnter(other); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	TriggerEvent("OnEnter", other); | 	TriggerEvent(eTriggerEventType::ENTER, other); | ||||||
|  |  | ||||||
| 	// POI system | 	// POI system | ||||||
| 	const auto& poi = GetVar<std::u16string>(u"POI"); | 	const auto& poi = GetVar<std::u16string>(u"POI"); | ||||||
| @@ -1346,7 +1330,7 @@ void Entity::OnCollisionLeavePhantom(const LWOOBJID otherEntity) { | |||||||
| 	auto* other = EntityManager::Instance()->GetEntity(otherEntity); | 	auto* other = EntityManager::Instance()->GetEntity(otherEntity); | ||||||
| 	if (!other) return; | 	if (!other) return; | ||||||
|  |  | ||||||
| 	TriggerEvent("OnLeave", other); | 	TriggerEvent(eTriggerEventType::EXIT, other); | ||||||
|  |  | ||||||
| 	SwitchComponent* switchComp = GetComponent<SwitchComponent>(); | 	SwitchComponent* switchComp = GetComponent<SwitchComponent>(); | ||||||
| 	if (switchComp) { | 	if (switchComp) { | ||||||
| @@ -1394,7 +1378,7 @@ void Entity::OnEmoteReceived(const int32_t emote, Entity* target) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void Entity::OnUse(Entity* originator) { | void Entity::OnUse(Entity* originator) { | ||||||
| 	TriggerEvent("OnInteract"); | 	TriggerEvent(eTriggerEventType::INTERACT); | ||||||
|  |  | ||||||
| 	for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { | 	for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { | ||||||
| 		script->OnUse(this, originator); | 		script->OnUse(this, originator); | ||||||
| @@ -1738,94 +1722,9 @@ bool Entity::IsPlayer() const { | |||||||
| 	return m_TemplateID == 1 && GetSystemAddress() != UNASSIGNED_SYSTEM_ADDRESS; | 	return m_TemplateID == 1 && GetSystemAddress() != UNASSIGNED_SYSTEM_ADDRESS; | ||||||
| } | } | ||||||
|  |  | ||||||
| void Entity::TriggerEvent(std::string eventID, Entity* optionalTarget) { | void Entity::TriggerEvent(eTriggerEventType event, Entity* optionalTarget) { | ||||||
| 	if (m_Trigger != nullptr && m_Trigger->enabled) { | 	auto* triggerComponent = GetComponent<TriggerComponent>(); | ||||||
| 		for (LUTriggers::Event* triggerEvent : m_Trigger->events) { | 	if (triggerComponent) triggerComponent->TriggerEvent(event, optionalTarget); | ||||||
| 			if (triggerEvent->eventID == eventID) { |  | ||||||
| 				for (LUTriggers::Command* cmd : triggerEvent->commands) { |  | ||||||
| 					HandleTriggerCommand(cmd->id, cmd->target, cmd->targetName, cmd->args, optionalTarget); |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // This should probably get it's own triggers class at some point... |  | ||||||
| void Entity::HandleTriggerCommand(std::string id, std::string target, std::string targetName, std::string args, Entity* optionalTarget) { |  | ||||||
| 	std::vector<std::string> argArray; |  | ||||||
| 	// Parse args |  | ||||||
| 	std::stringstream ssData(args); |  | ||||||
| 	std::string token; |  | ||||||
| 	char deliminator = ','; |  | ||||||
|  |  | ||||||
| 	while (std::getline(ssData, token, deliminator)) { |  | ||||||
| 		std::string lowerToken; |  | ||||||
| 		for (char character : token) { |  | ||||||
| 			lowerToken.push_back(std::tolower(character)); // make lowercase to ensure it works |  | ||||||
| 		} |  | ||||||
| 		argArray.push_back(lowerToken); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	std::vector<Entity*> targetEntities; |  | ||||||
| 	if (target == "self") targetEntities.push_back(this); |  | ||||||
| 	if (target == "objGroup") targetEntities = EntityManager::Instance()->GetEntitiesInGroup(targetName); |  | ||||||
| 	if (optionalTarget) targetEntities.push_back(optionalTarget); |  | ||||||
| 	if (targetEntities.size() == 0) return; |  | ||||||
| 	for (Entity* targetEntity : targetEntities) { |  | ||||||
| 		if (!targetEntity) continue; |  | ||||||
|  |  | ||||||
| 		if (id == "SetPhysicsVolumeEffect") { |  | ||||||
| 			PhantomPhysicsComponent* phanPhys = GetComponent<PhantomPhysicsComponent>(); |  | ||||||
| 			if (!phanPhys) return; |  | ||||||
|  |  | ||||||
| 			phanPhys->SetPhysicsEffectActive(true); |  | ||||||
| 			uint32_t effectType = 0; |  | ||||||
| 			if (argArray[0] == "push") effectType = 0; |  | ||||||
| 			else if (argArray[0] == "attract") effectType = 1; |  | ||||||
| 			else if (argArray[0] == "repulse") effectType = 2; |  | ||||||
| 			else if (argArray[0] == "gravity") effectType = 3; |  | ||||||
| 			else if (argArray[0] == "friction") effectType = 4; |  | ||||||
|  |  | ||||||
| 			phanPhys->SetEffectType(effectType); |  | ||||||
| 			phanPhys->SetDirectionalMultiplier(std::stof(argArray[1])); |  | ||||||
| 			if (argArray.size() > 4) { |  | ||||||
| 				NiPoint3 direction = NiPoint3::ZERO; |  | ||||||
| 				GeneralUtils::TryParse<float>(argArray[2], direction.x); |  | ||||||
| 				GeneralUtils::TryParse<float>(argArray[3], direction.y); |  | ||||||
| 				GeneralUtils::TryParse<float>(argArray[4], direction.z); |  | ||||||
| 				phanPhys->SetDirection(direction); |  | ||||||
| 			} |  | ||||||
| 			if (argArray.size() > 5) { |  | ||||||
| 				phanPhys->SetMin(std::stoi(argArray[6])); |  | ||||||
| 				phanPhys->SetMax(std::stoi(argArray[7])); |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if (target == "self") { |  | ||||||
| 				EntityManager::Instance()->ConstructEntity(this); |  | ||||||
| 			} |  | ||||||
| 		} else if (id == "updateMission") { |  | ||||||
| 			CDMissionTasksTable* missionTasksTable = CDClientManager::Instance()->GetTable<CDMissionTasksTable>("MissionTasks"); |  | ||||||
| 			std::vector<CDMissionTasks> missionTasks = missionTasksTable->Query([=](CDMissionTasks entry) { |  | ||||||
| 				std::string lowerTargetGroup; |  | ||||||
| 				for (char character : entry.targetGroup) { |  | ||||||
| 					lowerTargetGroup.push_back(std::tolower(character)); // make lowercase to ensure it works |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				return (lowerTargetGroup == argArray[4]); |  | ||||||
| 				}); |  | ||||||
|  |  | ||||||
| 			for (const CDMissionTasks& task : missionTasks) { |  | ||||||
| 				MissionComponent* missionComponent = targetEntity->GetComponent<MissionComponent>(); |  | ||||||
| 				if (!missionComponent) continue; |  | ||||||
|  |  | ||||||
| 				missionComponent->ForceProgress(task.id, task.uid, std::stoi(argArray[2])); |  | ||||||
| 			} |  | ||||||
| 		} else if (id == "fireEvent") { |  | ||||||
| 			for (CppScripts::Script* script : CppScripts::GetEntityScripts(targetEntity)) { |  | ||||||
| 				script->OnFireEventServerSide(targetEntity, this, args, 0, 0, 0); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
| Entity* Entity::GetOwner() const { | Entity* Entity::GetOwner() const { | ||||||
|   | |||||||
| @@ -18,9 +18,6 @@ namespace Loot { | |||||||
| namespace tinyxml2 { | namespace tinyxml2 { | ||||||
| 	class XMLDocument; | 	class XMLDocument; | ||||||
| }; | }; | ||||||
| namespace LUTriggers { |  | ||||||
| 	struct Trigger; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| class Player; | class Player; | ||||||
| class EntityInfo; | class EntityInfo; | ||||||
| @@ -33,6 +30,7 @@ class Component; | |||||||
| class Item; | class Item; | ||||||
| class Character; | class Character; | ||||||
| class EntityCallbackTimer; | class EntityCallbackTimer; | ||||||
|  | enum class eTriggerEventType; | ||||||
|  |  | ||||||
| namespace CppScripts { | namespace CppScripts { | ||||||
| 	class Script; | 	class Script; | ||||||
| @@ -67,8 +65,6 @@ public: | |||||||
|  |  | ||||||
| 	Entity* GetParentEntity() const { return m_ParentEntity; } | 	Entity* GetParentEntity() const { return m_ParentEntity; } | ||||||
|  |  | ||||||
| 	LUTriggers::Trigger* GetTrigger() const { return m_Trigger; } |  | ||||||
|  |  | ||||||
| 	std::vector<std::string>& GetGroups() { return m_Groups; }; | 	std::vector<std::string>& GetGroups() { return m_Groups; }; | ||||||
|  |  | ||||||
| 	Spawner* GetSpawner() const { return m_Spawner; } | 	Spawner* GetSpawner() const { return m_Spawner; } | ||||||
| @@ -221,9 +217,8 @@ public: | |||||||
| 	void RegisterCoinDrop(uint64_t count); | 	void RegisterCoinDrop(uint64_t count); | ||||||
|  |  | ||||||
| 	void ScheduleKillAfterUpdate(Entity* murderer = nullptr); | 	void ScheduleKillAfterUpdate(Entity* murderer = nullptr); | ||||||
| 	void TriggerEvent(std::string eveneventtID, Entity* optionalTarget = nullptr); | 	void TriggerEvent(eTriggerEventType event, Entity* optionalTarget = nullptr); | ||||||
| 	void ScheduleDestructionAfterUpdate() { m_ShouldDestroyAfterUpdate = true; } | 	void ScheduleDestructionAfterUpdate() { m_ShouldDestroyAfterUpdate = true; } | ||||||
| 	void HandleTriggerCommand(std::string id, std::string target, std::string targetName, std::string args, Entity* optionalTarget); |  | ||||||
|  |  | ||||||
| 	virtual NiPoint3 GetRespawnPosition() const { return NiPoint3::ZERO; } | 	virtual NiPoint3 GetRespawnPosition() const { return NiPoint3::ZERO; } | ||||||
| 	virtual NiQuaternion GetRespawnRotation() const { return NiQuaternion::IDENTITY; } | 	virtual NiQuaternion GetRespawnRotation() const { return NiQuaternion::IDENTITY; } | ||||||
| @@ -308,8 +303,6 @@ protected: | |||||||
| 	bool m_HasSpawnerNodeID; | 	bool m_HasSpawnerNodeID; | ||||||
| 	uint32_t m_SpawnerNodeID; | 	uint32_t m_SpawnerNodeID; | ||||||
|  |  | ||||||
| 	LUTriggers::Trigger* m_Trigger; |  | ||||||
|  |  | ||||||
| 	Character* m_Character; | 	Character* m_Character; | ||||||
|  |  | ||||||
| 	Entity* m_ParentEntity; //For spawners and the like | 	Entity* m_ParentEntity; //For spawners and the like | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
| #include "dLogger.h" | #include "dLogger.h" | ||||||
| #include "MessageIdentifiers.h" | #include "MessageIdentifiers.h" | ||||||
| #include "dConfig.h" | #include "dConfig.h" | ||||||
|  | #include "eTriggerEventType.h" | ||||||
|  |  | ||||||
| EntityManager* EntityManager::m_Address = nullptr; | EntityManager* EntityManager::m_Address = nullptr; | ||||||
|  |  | ||||||
| @@ -585,7 +586,7 @@ void EntityManager::ScheduleForKill(Entity* entity) { | |||||||
|  |  | ||||||
| 	SwitchComponent* switchComp = entity->GetComponent<SwitchComponent>(); | 	SwitchComponent* switchComp = entity->GetComponent<SwitchComponent>(); | ||||||
| 	if (switchComp) { | 	if (switchComp) { | ||||||
| 		entity->TriggerEvent("OnDectivated"); | 		entity->TriggerEvent(eTriggerEventType::DEACTIVATED); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	const auto objectId = entity->GetObjectID(); | 	const auto objectId = entity->GetObjectID(); | ||||||
|   | |||||||
| @@ -40,5 +40,6 @@ set(DGAME_DCOMPONENTS_SOURCES "BaseCombatAIComponent.cpp" | |||||||
| 	"SkillComponent.cpp" | 	"SkillComponent.cpp" | ||||||
| 	"SoundTriggerComponent.cpp" | 	"SoundTriggerComponent.cpp" | ||||||
| 	"SwitchComponent.cpp" | 	"SwitchComponent.cpp" | ||||||
|  | 	"TriggerComponent.cpp" | ||||||
| 	"VehiclePhysicsComponent.cpp" | 	"VehiclePhysicsComponent.cpp" | ||||||
| 	"VendorComponent.cpp" PARENT_SCOPE) | 	"VendorComponent.cpp" PARENT_SCOPE) | ||||||
|   | |||||||
| @@ -22,10 +22,13 @@ | |||||||
| #include "EchoStartSkill.h" | #include "EchoStartSkill.h" | ||||||
| #include "dMessageIdentifiers.h" | #include "dMessageIdentifiers.h" | ||||||
| #include "DoClientProjectileImpact.h" | #include "DoClientProjectileImpact.h" | ||||||
|  | #include "CDClientManager.h" | ||||||
|  |  | ||||||
| ProjectileSyncEntry::ProjectileSyncEntry() { | ProjectileSyncEntry::ProjectileSyncEntry() { | ||||||
| } | } | ||||||
|  |  | ||||||
|  | std::unordered_map<uint32_t, uint32_t> SkillComponent::m_skillBehaviorCache = {}; | ||||||
|  |  | ||||||
| bool SkillComponent::CastPlayerSkill(const uint32_t behaviorId, const uint32_t skillUid, RakNet::BitStream* bitStream, const LWOOBJID target, uint32_t skillID) { | bool SkillComponent::CastPlayerSkill(const uint32_t behaviorId, const uint32_t skillUid, RakNet::BitStream* bitStream, const LWOOBJID target, uint32_t skillID) { | ||||||
| 	auto* context = new BehaviorContext(this->m_Parent->GetObjectID()); | 	auto* context = new BehaviorContext(this->m_Parent->GetObjectID()); | ||||||
|  |  | ||||||
| @@ -210,6 +213,29 @@ void SkillComponent::RegisterCalculatedProjectile(const LWOOBJID projectileId, B | |||||||
| 	this->m_managedProjectiles.push_back(entry); | 	this->m_managedProjectiles.push_back(entry); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool SkillComponent::CastSkill(const uint32_t skillId, LWOOBJID target, const LWOOBJID optionalOriginatorID){ | ||||||
|  | 	uint32_t behaviorId = -1; | ||||||
|  | 	// try to find it via the cache | ||||||
|  | 	const auto& pair = m_skillBehaviorCache.find(skillId); | ||||||
|  |  | ||||||
|  | 	// if it's not in the cache look it up and cache it | ||||||
|  | 	if (pair == m_skillBehaviorCache.end()) { | ||||||
|  | 		auto skillTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior"); | ||||||
|  | 		behaviorId = skillTable->GetSkillByID(skillId).behaviorID; | ||||||
|  | 		m_skillBehaviorCache.insert_or_assign(skillId, behaviorId); | ||||||
|  | 	} else { | ||||||
|  | 		behaviorId = pair->second; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// check to see if we got back a valid behavior | ||||||
|  | 	if (behaviorId == -1) { | ||||||
|  | 		Game::logger->LogDebug("SkillComponent", "Tried to cast skill %i but found no behavior", skillId); | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return CalculateBehavior(skillId, behaviorId, target, false, false, optionalOriginatorID).success; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, const uint32_t behaviorId, const LWOOBJID target, const bool ignoreTarget, const bool clientInitalized, const LWOOBJID originatorOverride) { | SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, const uint32_t behaviorId, const LWOOBJID target, const bool ignoreTarget, const bool clientInitalized, const LWOOBJID originatorOverride) { | ||||||
| 	auto* bitStream = new RakNet::BitStream(); | 	auto* bitStream = new RakNet::BitStream(); | ||||||
|   | |||||||
| @@ -119,6 +119,15 @@ public: | |||||||
| 	 */ | 	 */ | ||||||
| 	void RegisterPlayerProjectile(LWOOBJID projectileId, BehaviorContext* context, const BehaviorBranchContext& branch, LOT lot); | 	void RegisterPlayerProjectile(LWOOBJID projectileId, BehaviorContext* context, const BehaviorBranchContext& branch, LOT lot); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Wrapper for CalculateBehavior that mimics the call structure in scripts and helps reduce magic numbers | ||||||
|  | 	 * @param skillId the skill to cast | ||||||
|  | 	 * @param target the target of the skill | ||||||
|  | 	 * @param optionalOriginatorID change the originator of the skill | ||||||
|  | 	 * @return if the case succeeded | ||||||
|  | 	 */ | ||||||
|  | 	bool CastSkill(const uint32_t skillId, LWOOBJID target = LWOOBJID_EMPTY, const LWOOBJID optionalOriginatorID = LWOOBJID_EMPTY); | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Initializes a server-side skill calculation. | 	 * Initializes a server-side skill calculation. | ||||||
| 	 * @param skillId the skill ID | 	 * @param skillId the skill ID | ||||||
| @@ -190,6 +199,11 @@ private: | |||||||
| 	 */ | 	 */ | ||||||
| 	uint32_t m_skillUid; | 	uint32_t m_skillUid; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Cache for looking up a behavior id via a skill ID | ||||||
|  | 	 */ | ||||||
|  | 	static std::unordered_map<uint32_t, uint32_t> m_skillBehaviorCache; | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Sync a server-side projectile calculation. | 	 * Sync a server-side projectile calculation. | ||||||
| 	 * @param entry the projectile information | 	 * @param entry the projectile information | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #include "SwitchComponent.h" | #include "SwitchComponent.h" | ||||||
| #include "EntityManager.h" | #include "EntityManager.h" | ||||||
|  | #include "eTriggerEventType.h" | ||||||
|  |  | ||||||
| std::vector<SwitchComponent*> SwitchComponent::petSwitches; | std::vector<SwitchComponent*> SwitchComponent::petSwitches; | ||||||
|  |  | ||||||
| @@ -42,7 +43,7 @@ void SwitchComponent::EntityEnter(Entity* entity) { | |||||||
| 		} | 		} | ||||||
| 		m_Active = true; | 		m_Active = true; | ||||||
| 		if (!m_Parent) return; | 		if (!m_Parent) return; | ||||||
| 		m_Parent->TriggerEvent("OnActivated"); | 		m_Parent->TriggerEvent(eTriggerEventType::ACTIVATED); | ||||||
|  |  | ||||||
| 		const auto grpName = m_Parent->GetVarAsString(u"grp_name"); | 		const auto grpName = m_Parent->GetVarAsString(u"grp_name"); | ||||||
|  |  | ||||||
| @@ -78,7 +79,7 @@ void SwitchComponent::Update(float deltaTime) { | |||||||
| 		if (m_Timer <= 0.0f) { | 		if (m_Timer <= 0.0f) { | ||||||
| 			m_Active = false; | 			m_Active = false; | ||||||
| 			if (!m_Parent) return; | 			if (!m_Parent) return; | ||||||
| 			m_Parent->TriggerEvent("OnDectivated"); | 			m_Parent->TriggerEvent(eTriggerEventType::DEACTIVATED); | ||||||
|  |  | ||||||
| 			const auto grpName = m_Parent->GetVarAsString(u"grp_name"); | 			const auto grpName = m_Parent->GetVarAsString(u"grp_name"); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										187
									
								
								dGame/dComponents/TriggerComponent.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								dGame/dComponents/TriggerComponent.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,187 @@ | |||||||
|  | #include "TriggerComponent.h" | ||||||
|  | #include "dZoneManager.h" | ||||||
|  | #include "LUTriggers.h" | ||||||
|  | #include "eTriggerCommandType.h" | ||||||
|  | #include "MissionComponent.h" | ||||||
|  | #include "PhantomPhysicsComponent.h" | ||||||
|  | #include "CDMissionTasksTable.h" | ||||||
|  |  | ||||||
|  | TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo): Component(parent) { | ||||||
|  | 	m_Parent = parent; | ||||||
|  | 	m_Trigger = nullptr; | ||||||
|  |  | ||||||
|  | 	std::vector<std::string> tokens = GeneralUtils::SplitString(triggerInfo, ':'); | ||||||
|  |  | ||||||
|  | 	uint32_t sceneID; | ||||||
|  | 	GeneralUtils::TryParse<uint32_t>(tokens.at(0), sceneID); | ||||||
|  | 	uint32_t triggerID; | ||||||
|  | 	GeneralUtils::TryParse<uint32_t>(tokens.at(1), triggerID); | ||||||
|  |  | ||||||
|  | 	m_Trigger = dZoneManager::Instance()->GetZone()->GetTrigger(sceneID, triggerID); | ||||||
|  |  | ||||||
|  | 	if (!m_Trigger) m_Trigger = new LUTriggers::Trigger(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TriggerComponent::TriggerEvent(eTriggerEventType event, Entity* optionalTarget) { | ||||||
|  | 	if (m_Trigger && m_Trigger->enabled) { | ||||||
|  | 		for (LUTriggers::Event* triggerEvent : m_Trigger->events) { | ||||||
|  | 			if (triggerEvent->id == event) { | ||||||
|  | 				for (LUTriggers::Command* command : triggerEvent->commands) { | ||||||
|  | 					HandleTriggerCommand(command, optionalTarget); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity* optionalTarget) { | ||||||
|  | 	auto argArray =  GeneralUtils::SplitString(command->args, ','); | ||||||
|  |  | ||||||
|  | 	// determine targets | ||||||
|  | 	std::vector<Entity*> targetEntities = GatherTargets(command, optionalTarget); | ||||||
|  |  | ||||||
|  | 	// if we have no targets, then we are done | ||||||
|  | 	if (targetEntities.empty()) return; | ||||||
|  |  | ||||||
|  | 	for (Entity* targetEntity : targetEntities) { | ||||||
|  | 		if (!targetEntity) continue; | ||||||
|  |  | ||||||
|  | 		switch (command->id) { | ||||||
|  | 			case eTriggerCommandType::ZONE_PLAYER: break; | ||||||
|  | 			case eTriggerCommandType::FIRE_EVENT: | ||||||
|  | 				HandleFireEvent(targetEntity, command->args); | ||||||
|  | 				break; | ||||||
|  | 			case eTriggerCommandType::DESTROY_OBJ: break; | ||||||
|  | 			case eTriggerCommandType::TOGGLE_TRIGGER: break; | ||||||
|  | 			case eTriggerCommandType::RESET_REBUILD: break; | ||||||
|  | 			case eTriggerCommandType::SET_PATH: break; | ||||||
|  | 			case eTriggerCommandType::SET_PICK_TYPE: break; | ||||||
|  | 			case eTriggerCommandType::MOVE_OBJECT: break; | ||||||
|  | 			case eTriggerCommandType::ROTATE_OBJECT: break; | ||||||
|  | 			case eTriggerCommandType::PUSH_OBJECT: break; | ||||||
|  | 			case eTriggerCommandType::REPEL_OBJECT: break; | ||||||
|  | 			case eTriggerCommandType::SET_TIMER: break; | ||||||
|  | 			case eTriggerCommandType::CANCEL_TIMER: break; | ||||||
|  | 			case eTriggerCommandType::PLAY_CINEMATIC: break; | ||||||
|  | 			case eTriggerCommandType::TOGGLE_BBB: break; | ||||||
|  | 			case eTriggerCommandType::UPDATE_MISSION: | ||||||
|  | 				HandleUpdateMission(targetEntity, argArray); | ||||||
|  | 				break; | ||||||
|  | 			case eTriggerCommandType::SET_BOUNCER_STATE: break; | ||||||
|  | 			case eTriggerCommandType::BOUNCE_ALL_ON_BOUNCER: break; | ||||||
|  | 			case eTriggerCommandType::TURN_AROUND_ON_PATH: break; | ||||||
|  | 			case eTriggerCommandType::GO_FORWARD_ON_PATH: break; | ||||||
|  | 			case eTriggerCommandType::GO_BACKWARD_ON_PATH: break; | ||||||
|  | 			case eTriggerCommandType::STOP_PATHING: break; | ||||||
|  | 			case eTriggerCommandType::START_PATHING: break; | ||||||
|  | 			case eTriggerCommandType::LOCK_OR_UNLOCK_CONTROLS: break; | ||||||
|  | 			case eTriggerCommandType::PLAY_EFFECT: break; | ||||||
|  | 			case eTriggerCommandType::STOP_EFFECT: break; | ||||||
|  | 			case eTriggerCommandType::ACTIVATE_MUSIC_CUE: break; | ||||||
|  | 			case eTriggerCommandType::DEACTIVATE_MUSIC_CUE: break; | ||||||
|  | 			case eTriggerCommandType::FLASH_MUSIC_CUE: break; | ||||||
|  | 			case eTriggerCommandType::SET_MUSIC_PARAMETER: break; | ||||||
|  | 			case eTriggerCommandType::PLAY_2D_AMBIENT_SOUND: break; | ||||||
|  | 			case eTriggerCommandType::STOP_2D_AMBIENT_SOUND: break; | ||||||
|  | 			case eTriggerCommandType::PLAY_3D_AMBIENT_SOUND: break; | ||||||
|  | 			case eTriggerCommandType::STOP_3D_AMBIENT_SOUND: break; | ||||||
|  | 			case eTriggerCommandType::ACTIVATE_MIXER_PROGRAM: break; | ||||||
|  | 			case eTriggerCommandType::DEACTIVATE_MIXER_PROGRAM: break; | ||||||
|  | 			case eTriggerCommandType::CAST_SKILL: break; | ||||||
|  | 			case eTriggerCommandType::DISPLAY_ZONE_SUMMARY: break; | ||||||
|  | 			case eTriggerCommandType::SET_PHYSICS_VOLUME_EFFECT: | ||||||
|  | 				HandleSetPhysicsVolume(targetEntity, argArray, command->target); | ||||||
|  | 				break; | ||||||
|  | 			case eTriggerCommandType::SET_PHYSICS_VOLUME_STATUS: break; | ||||||
|  | 			case eTriggerCommandType::SET_MODEL_TO_BUILD: break; | ||||||
|  | 			case eTriggerCommandType::SPAWN_MODEL_BRICKS: break; | ||||||
|  | 			case eTriggerCommandType::ACTIVATE_SPAWNER_NETWORK: break; | ||||||
|  | 			case eTriggerCommandType::DEACTIVATE_SPAWNER_NETWORK: break; | ||||||
|  | 			case eTriggerCommandType::RESET_SPAWNER_NETWORK: break; | ||||||
|  | 			case eTriggerCommandType::DESTROY_SPAWNER_NETWORK_OBJECTS: break; | ||||||
|  | 			case eTriggerCommandType::GO_TO_WAYPOINT: break; | ||||||
|  | 			case eTriggerCommandType::ACTIVATE_PHYSICS: break; | ||||||
|  | 			default: | ||||||
|  | 				Game::logger->LogDebug("TriggerComponent", "Event %i was not handled!", command->id); | ||||||
|  | 				break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | std::vector<Entity*> TriggerComponent::GatherTargets(LUTriggers::Command* command, Entity* optionalTarget) { | ||||||
|  | 	std::vector<Entity*> entities = {}; | ||||||
|  |  | ||||||
|  | 	if (command->target == "self") entities.push_back(m_Parent); | ||||||
|  | 	else if (command->target == "zone") { /*TODO*/ } | ||||||
|  | 	else if (command->target == "target") { /*TODO*/ } | ||||||
|  | 	else if (command->target == "targetTeam") { /*TODO*/ } | ||||||
|  | 	else if (command->target == "objGroup") entities = EntityManager::Instance()->GetEntitiesInGroup(command->targetName); | ||||||
|  | 	else if (command->target == "allPlayers") { /*TODO*/ } | ||||||
|  | 	else if (command->target == "allNPCs") { /*TODO*/ } | ||||||
|  |  | ||||||
|  | 	if (optionalTarget) entities.push_back(optionalTarget); | ||||||
|  |  | ||||||
|  | 	return entities; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TriggerComponent::HandleSetPhysicsVolume(Entity* targetEntity, std::vector<std::string> argArray, std::string target) { | ||||||
|  | 	PhantomPhysicsComponent* phanPhys = m_Parent->GetComponent<PhantomPhysicsComponent>(); | ||||||
|  | 	if (!phanPhys) return; | ||||||
|  |  | ||||||
|  | 	phanPhys->SetPhysicsEffectActive(true); | ||||||
|  | 	uint32_t effectType = 0; | ||||||
|  | 	std::transform(argArray.at(0).begin(), argArray.at(0).end(), argArray.at(0).begin(), ::tolower); //Transform to lowercase | ||||||
|  | 	if (argArray.at(0) == "push") effectType = 0; | ||||||
|  | 	else if (argArray.at(0) == "attract") effectType = 1; | ||||||
|  | 	else if (argArray.at(0) == "repulse") effectType = 2; | ||||||
|  | 	else if (argArray.at(0) == "gravity") effectType = 3; | ||||||
|  | 	else if (argArray.at(0) == "friction") effectType = 4; | ||||||
|  |  | ||||||
|  | 	phanPhys->SetEffectType(effectType); | ||||||
|  | 	phanPhys->SetDirectionalMultiplier(std::stof(argArray.at(1))); | ||||||
|  | 	if (argArray.size() > 4) { | ||||||
|  | 		NiPoint3 direction = NiPoint3::ZERO; | ||||||
|  | 		GeneralUtils::TryParse<float>(argArray.at(2), direction.x); | ||||||
|  | 		GeneralUtils::TryParse<float>(argArray.at(3), direction.y); | ||||||
|  | 		GeneralUtils::TryParse<float>(argArray.at(4), direction.z); | ||||||
|  | 		phanPhys->SetDirection(direction); | ||||||
|  | 	} | ||||||
|  | 	if (argArray.size() > 5) { | ||||||
|  | 		uint32_t min; | ||||||
|  | 		GeneralUtils::TryParse<uint32_t>(argArray.at(6), min); | ||||||
|  | 		phanPhys->SetMin(min); | ||||||
|  |  | ||||||
|  | 		uint32_t max; | ||||||
|  | 		GeneralUtils::TryParse<uint32_t>(argArray.at(7), max); | ||||||
|  | 		phanPhys->SetMax(max); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// TODO: why is this contruct and not serialize? | ||||||
|  | 	if (target == "self") EntityManager::Instance()->ConstructEntity(m_Parent); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TriggerComponent::HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray) { | ||||||
|  | 	CDMissionTasksTable* missionTasksTable = CDClientManager::Instance()->GetTable<CDMissionTasksTable>("MissionTasks"); | ||||||
|  | 	std::vector<CDMissionTasks> missionTasks = missionTasksTable->Query([=](CDMissionTasks entry) { | ||||||
|  | 		std::string lowerTargetGroup; | ||||||
|  | 		for (char character : entry.targetGroup) { | ||||||
|  | 			lowerTargetGroup.push_back(std::tolower(character)); // make lowercase to ensure it works | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return (lowerTargetGroup == argArray[4]); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	for (const CDMissionTasks& task : missionTasks) { | ||||||
|  | 		MissionComponent* missionComponent = targetEntity->GetComponent<MissionComponent>(); | ||||||
|  | 		if (!missionComponent) continue; | ||||||
|  |  | ||||||
|  | 		missionComponent->ForceProgress(task.id, task.uid, std::stoi(argArray[2])); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TriggerComponent::HandleFireEvent(Entity* targetEntity, std::string args) { | ||||||
|  | 	for (CppScripts::Script* script : CppScripts::GetEntityScripts(targetEntity)) { | ||||||
|  | 		script->OnFireEventServerSide(targetEntity, m_Parent, args, 0, 0, 0); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										34
									
								
								dGame/dComponents/TriggerComponent.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								dGame/dComponents/TriggerComponent.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | #ifndef __TRIGGERCOMPONENT__H__ | ||||||
|  | #define __TRIGGERCOMPONENT__H__ | ||||||
|  |  | ||||||
|  | #include "Component.h" | ||||||
|  |  | ||||||
|  | namespace LUTriggers { | ||||||
|  | 	struct Trigger; | ||||||
|  | 	struct Command; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class TriggerComponent : public Component { | ||||||
|  | public: | ||||||
|  | 	static const uint32_t ComponentType = COMPONENT_TYPE_TRIGGER; | ||||||
|  |  | ||||||
|  | 	explicit TriggerComponent(Entity* parent, const std::string triggerInfo); | ||||||
|  |  | ||||||
|  | 	void TriggerEvent(eTriggerEventType event, Entity* optionalTarget = nullptr); | ||||||
|  | 	LUTriggers::Trigger* GetTrigger() const { return m_Trigger; } | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |  | ||||||
|  | 	void HandleTriggerCommand(LUTriggers::Command* command, Entity* optionalTarget); | ||||||
|  | 	std::vector<std::string> ParseArgs(std::string args); | ||||||
|  | 	std::vector<Entity*> GatherTargets(LUTriggers::Command* command, Entity* optionalTarget); | ||||||
|  |  | ||||||
|  | 	// Trigger Event Handlers | ||||||
|  | 	void HandleSetPhysicsVolume(Entity* targetEntity, std::vector<std::string> argArray, std::string target); | ||||||
|  | 	void HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray); | ||||||
|  | 	void HandleFireEvent(Entity* targetEntity, std::string args); | ||||||
|  | 	void HandleCastSkill(Entity* targetEntity, uint32_t skillID); | ||||||
|  |  | ||||||
|  | 	LUTriggers::Trigger* m_Trigger; | ||||||
|  | }; | ||||||
|  | #endif  //!__TRIGGERCOMPONENT__H__ | ||||||
| @@ -73,6 +73,7 @@ | |||||||
| #include "MovingPlatformComponent.h" | #include "MovingPlatformComponent.h" | ||||||
| #include "dMessageIdentifiers.h" | #include "dMessageIdentifiers.h" | ||||||
| #include "eMissionState.h" | #include "eMissionState.h" | ||||||
|  | #include "TriggerComponent.h" | ||||||
|  |  | ||||||
| void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) { | void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) { | ||||||
| 	std::string chatCommand; | 	std::string chatCommand; | ||||||
| @@ -1984,8 +1985,12 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit | |||||||
| 					ChatPackets::SendSystemMessage(sysAddr, u"Active: " + (GeneralUtils::to_u16string(phantomPhysicsComponent->GetPhysicsEffectActive()))); | 					ChatPackets::SendSystemMessage(sysAddr, u"Active: " + (GeneralUtils::to_u16string(phantomPhysicsComponent->GetPhysicsEffectActive()))); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				if (closest->GetTrigger() != nullptr) { | 				auto* triggerComponent = closest->GetComponent<TriggerComponent>(); | ||||||
| 					ChatPackets::SendSystemMessage(sysAddr, u"Trigger: " + (GeneralUtils::to_u16string(closest->GetTrigger()->id))); | 				if (triggerComponent){ | ||||||
|  | 					auto trigger = triggerComponent->GetTrigger(); | ||||||
|  | 					if (trigger) { | ||||||
|  | 						ChatPackets::SendSystemMessage(sysAddr, u"Trigger: " + (GeneralUtils::to_u16string(trigger->id))); | ||||||
|  | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -14,10 +14,10 @@ void CoilBackpackBase::NotifyHitOrHealResult(Entity* self, Entity* attacker, int | |||||||
| 		if (self->GetVar<uint8_t>(u"coilCount") > 4) { | 		if (self->GetVar<uint8_t>(u"coilCount") > 4) { | ||||||
| 			auto* skillComponent = self->GetComponent<SkillComponent>(); | 			auto* skillComponent = self->GetComponent<SkillComponent>(); | ||||||
| 			if (!skillComponent) return; | 			if (!skillComponent) return; | ||||||
| 			skillComponent->CalculateBehavior(m_SkillId, m_BehaviorId, self->GetObjectID()); | 			skillComponent->CastSkill(m_SkillId); | ||||||
| 			self->SetVar<uint8_t>(u"coilCount", 0); | 			self->SetVar<uint8_t>(u"coilCount", 0); | ||||||
| 		} | 		} | ||||||
| 	}	 | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void CoilBackpackBase::OnFactionTriggerItemUnequipped(Entity* itemOwner, LWOOBJID itemObjId) { | void CoilBackpackBase::OnFactionTriggerItemUnequipped(Entity* itemOwner, LWOOBJID itemObjId) { | ||||||
|   | |||||||
| @@ -5,9 +5,8 @@ | |||||||
|  |  | ||||||
| class CoilBackpackBase: public CppScripts::Script { | class CoilBackpackBase: public CppScripts::Script { | ||||||
| public: | public: | ||||||
| 	CoilBackpackBase(uint32_t skillId, uint32_t behaviorId) { | 	CoilBackpackBase(uint32_t skillId) { | ||||||
| 		m_SkillId = skillId; | 		m_SkillId = skillId; | ||||||
| 		m_BehaviorId = behaviorId; |  | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	void OnFactionTriggerItemEquipped(Entity* itemOwner, LWOOBJID itemObjId) override; | 	void OnFactionTriggerItemEquipped(Entity* itemOwner, LWOOBJID itemObjId) override; | ||||||
| @@ -15,7 +14,6 @@ public: | |||||||
| 	void OnFactionTriggerItemUnequipped(Entity* itemOwner, LWOOBJID itemObjId) override; | 	void OnFactionTriggerItemUnequipped(Entity* itemOwner, LWOOBJID itemObjId) override; | ||||||
| private: | private: | ||||||
| 	uint32_t m_SkillId = 0; | 	uint32_t m_SkillId = 0; | ||||||
| 	uint32_t m_BehaviorId = 0; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif  //!__GemPackBase__H__ | #endif  //!__GemPackBase__H__ | ||||||
|   | |||||||
| @@ -5,10 +5,9 @@ | |||||||
|  |  | ||||||
| class GemPack : public CoilBackpackBase { | class GemPack : public CoilBackpackBase { | ||||||
| public: | public: | ||||||
| 	GemPack() : CoilBackpackBase(skillId, behaviorId) {}; | 	GemPack() : CoilBackpackBase(skillId) {}; | ||||||
| private: | private: | ||||||
| 	static const uint32_t skillId = 1488; | 	static const uint32_t skillId = 1488; | ||||||
| 	static const uint32_t behaviorId = 36779; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif  //!__GEMPACK__H__ | #endif  //!__GEMPACK__H__ | ||||||
|   | |||||||
| @@ -5,10 +5,9 @@ | |||||||
|  |  | ||||||
| class ShardArmor : public CoilBackpackBase { | class ShardArmor : public CoilBackpackBase { | ||||||
| public: | public: | ||||||
| 	ShardArmor() : CoilBackpackBase(skillId, behaviorId) {}; | 	ShardArmor() : CoilBackpackBase(skillId) {}; | ||||||
| private: | private: | ||||||
| 	static const uint32_t skillId = 1249; | 	static const uint32_t skillId = 1249; | ||||||
| 	static const uint32_t behaviorId = 29086; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif  //!__SHARDARMOR__H__ | #endif  //!__SHARDARMOR__H__ | ||||||
|   | |||||||
| @@ -5,10 +5,9 @@ | |||||||
|  |  | ||||||
| class TeslaPack : public CoilBackpackBase { | class TeslaPack : public CoilBackpackBase { | ||||||
| public: | public: | ||||||
| 	TeslaPack() : CoilBackpackBase(skillId, behaviorId) {}; | 	TeslaPack() : CoilBackpackBase(skillId) {}; | ||||||
| private: | private: | ||||||
| 	static const uint32_t skillId = 1001; | 	static const uint32_t skillId = 1001; | ||||||
| 	static const uint32_t behaviorId = 20917; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif  //!__TESLAPACK__H__ | #endif  //!__TESLAPACK__H__ | ||||||
|   | |||||||
| @@ -6,17 +6,20 @@ | |||||||
|  |  | ||||||
| class Command; | class Command; | ||||||
| class Event; | class Event; | ||||||
|  | enum class eTriggerCommandType; | ||||||
|  | enum class eTriggerEventType; | ||||||
|  |  | ||||||
|  |  | ||||||
| namespace LUTriggers { | namespace LUTriggers { | ||||||
| 	struct Command { | 	struct Command { | ||||||
| 		std::string id; | 		eTriggerCommandType id; | ||||||
| 		std::string target; | 		std::string target; | ||||||
| 		std::string targetName; | 		std::string targetName; | ||||||
| 		std::string args; | 		std::string args; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct Event { | 	struct Event { | ||||||
| 		std::string eventID; | 		eTriggerEventType id; | ||||||
| 		std::vector<Command*> commands; | 		std::vector<Command*> commands; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -14,6 +14,9 @@ | |||||||
| #include "Spawner.h" | #include "Spawner.h" | ||||||
| #include "dZoneManager.h" | #include "dZoneManager.h" | ||||||
|  |  | ||||||
|  | #include "eTriggerCommandType.h" | ||||||
|  | #include "eTriggerEventType.h" | ||||||
|  |  | ||||||
| Zone::Zone(const LWOMAPID& mapID, const LWOINSTANCEID& instanceID, const LWOCLONEID& cloneID) : | Zone::Zone(const LWOMAPID& mapID, const LWOINSTANCEID& instanceID, const LWOCLONEID& cloneID) : | ||||||
| 	m_ZoneID(mapID, instanceID, cloneID) { | 	m_ZoneID(mapID, instanceID, cloneID) { | ||||||
| 	m_NumberOfScenesLoaded = 0; | 	m_NumberOfScenesLoaded = 0; | ||||||
| @@ -296,11 +299,11 @@ std::vector<LUTriggers::Trigger*> Zone::LoadLUTriggers(std::string triggerFile, | |||||||
| 		auto currentEvent = currentTrigger->FirstChildElement("event"); | 		auto currentEvent = currentTrigger->FirstChildElement("event"); | ||||||
| 		while (currentEvent) { | 		while (currentEvent) { | ||||||
| 			LUTriggers::Event* newEvent = new LUTriggers::Event(); | 			LUTriggers::Event* newEvent = new LUTriggers::Event(); | ||||||
| 			newEvent->eventID = currentEvent->Attribute("id"); | 			newEvent->id = TriggerEventType::StringToTriggerEventType(currentEvent->Attribute("id")); | ||||||
| 			auto currentCommand = currentEvent->FirstChildElement("command"); | 			auto currentCommand = currentEvent->FirstChildElement("command"); | ||||||
| 			while (currentCommand) { | 			while (currentCommand) { | ||||||
| 				LUTriggers::Command* newCommand = new LUTriggers::Command(); | 				LUTriggers::Command* newCommand = new LUTriggers::Command(); | ||||||
| 				newCommand->id = currentCommand->Attribute("id"); | 				newCommand->id = TriggerCommandType::StringToTriggerCommandType(currentCommand->Attribute("id")); | ||||||
| 				newCommand->target = currentCommand->Attribute("target"); | 				newCommand->target = currentCommand->Attribute("target"); | ||||||
| 				if (currentCommand->Attribute("targetName") != NULL) { | 				if (currentCommand->Attribute("targetName") != NULL) { | ||||||
| 					newCommand->targetName = currentCommand->Attribute("targetName"); | 					newCommand->targetName = currentCommand->Attribute("targetName"); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Aaron Kimbre
					Aaron Kimbre