5. TASK MARKER SWITCHING CUSTOM POSITIONS
Switching the task markers 3D location to custom positions and back to task
The NightOps – Dynamic Task Framework allows to set the task marker to a custom position instead of its original task location. This is done in the task property’s attribute-field “Additional Marker Position”.
In Mission 2, there is a trigger named “wpTrg_A_1” at the outskirts of the objective location. The task marker is initially switched to that trigger and only if a player enters this trigger sphere, the marker will reset to its original task position emulating a waypoint system leading the player via several positions to the task.
IEntity taskEntity = GetWorld().FindEntityByName("tsk_main_A_1");
NO_SCR_EditorTask task = NO_SCR_EditorTask.Cast(taskEntity);
task.m_sAdditionalMarkerPosition = "";
The script searches the world for the task named “tsk_main_A_1” and changes its additionalMarkerPosition to an empty string “”. So it will reset to its original task position.
Another way would be to add another entities name into the “” so the marker wouldn’t reset to its task location but to the location of the other named entity.
6. TASK MARKER FOLLOWS A UNIT
Attaching the additionalMarkerPosition entity to a moving unit
Another way to utilize the additionalMarkerPosition via script is to use an invisible entity like a commentEntity which is attached to a unit. So it appears as if the task marker is moving with that unit. The NightOps framework also offers a component to rename a unit in runtime which can rename a dynamically spawned unit and then, set the additionalMarkerPosition to that units set name.
Another method, little bit more flexible but also more hacky, is to place an commentEntity in the world and attach this via the same script, shown in this tutorial for the moving spawnpoint to an spawned unit. All that’s needed then is to add the “NWKMovementComponent” to the commentEntity and set the additionalMarkerPosition to the commentEntity as well.
Mission 2 use this trick for the fleeing HVT in operation HITMAN. By default, the HVT is not spawned in the world. It will be spawned once the player has entered a trigger nearby. The HVT has some waypoints to follow – so it seems like, when he spawns, he flees the area.
- Place a commentEntity named “marker_hvt” and add the NWKMovementComponent to it
- set the additionalMarkerPosition of the task to the commentEntity’s name
- Prepare a custom group or vehicle with the NO_SCR_IdentifierComponent with an id like “HVT”
- Add the following script to a trigger “OnActivate” to let the commentEntity follow the custom unit
override void OnActivate(IEntity ent)
{
//Spawns HVT
private RplComponent m_pRplComponent;
if(!m_pRplComponent)
m_pRplComponent =
RplComponent.Cast(ent.FindComponent(RplComponent));
if(m_pRplComponent.IsMaster())
NO_SCR_SpawnTrigger.Cast(GetWorld().FindEntityByName("east_HVT_spawnTrg")).Spawn();
//Waits 10 seconds before attaching the commentEntity to make sure the HVT is spawned already
GetGame().GetCallqueue().CallLater(DelayedHint1, 10000, false);
}
//Attach marker to HVT for task tracking
protected void DelayedHint1()
{
RplComponent rplComponent =
RplComponent.Cast(FindComponent(RplComponent));
if (rplComponent && !rplComponent.IsProxy())
GetWorld().QueryEntitiesBySphere(GetOrigin(), 10000, QueryHit, QueryFilter, EQueryEntitiesFlags.ALL);
}
bool QueryFilter(IEntity ent)
{
NO_SCR_IdentifierComponent idComponent =
NO_SCR_IdentifierComponent.Cast(ent.FindComponent(NO_SCR_IdentifierComponent));
if (!idComponent)
return false;
return idComponent.GetIdentifier() == "hvt";
}
bool QueryHit(IEntity ent)
{
CommentEntity marker = CommentEntity.Cast(GetWorld().FindEntityByName("marker_hvt"));
// If we can find the marker and hvt
if (marker)
{
// Keep moving it
RplComponent rplComponent = RplComponent.Cast(FindComponent(RplComponent));
if (rplComponent && !rplComponent.IsProxy())
GetGame().GetCallqueue().CallLater(UpdateHVTPosition, 1000, true, marker, ent);
}
// Ends further queries as we will use the first match found
return false;
}
//Updates the HVT position
void UpdateHVTPosition(CommentEntity marker, IEntity ent)
{
//Stops updating if HVT is dead
if (!IsAlive(ent))
{
// VEHICLE DEAD SECTION
GetGame().GetCallqueue().Remove(UpdateHVTPosition);
}
if (!marker)
{
GetGame().GetCallqueue().Remove(UpdateHVTPosition);
return;
}
//Sets marker position to HVT location
marker.SetOrigin(ent.GetOrigin());
}
7. Intel Piece to pickup
Picking up an intel piece via user action and make it disappear in the world via script
This is just a handy little way to show how to delete an entity. Because that is all that’s happening in Mission 2 when picking up an Intel piece next to finishing a task, spawning new units etc. The following script is attached via actionsManagerComponent to the intel piece:
override void PerformAction(IEntity pOwnerEntity, IEntity pUserEntity)
{
//Removes intel piece from world by deleting it
SCR_EntityHelper.DeleteEntityAndChildren(pOwnerEntity);
}
Since the action is attached to the intel piece, the player can pickup, there is no need to find the entity by name and only use “pOwnerEntity” which is adressing the owner of the action.
8. Immobilized vehicle un-blocking in runtime
Spawning a vehicle which cant drive but can be later mobilized via script
In the Nightops – Everon 1985 campaign are several enemy BTRs spawned, that the player shouldn’t be able to use once the crew is dead for balance reasons. Or like the Com Truck in Mission 1, where the player is tasked to steal the “Encryption Key” but should not be able to drive the truck away (especially since the mission will fail if the vehicle gets destroyed).
For that purpose, the NightOps – Custom Modes Framework delivers a script, which immobilizes a vehicle. This ensures that the driver cannot start the engine (since its technically damaged). But a mission designer may want to re-mobilize the vehicle at a later stage. This can be done via script.
First, the vehicle prefab needs the “NO_SCR_ImmobilizerComponent” added. It can be ticked, if the vehicle should be immobilized right from the start or later via script. Then, for this particular tutorial example, we added the “NO_SCR_DTF_RenamerComponent” which is a component from the NightOps – Dynamic Task Framework and has a similar purpose as the “NO_SCR_IdentifierComponent” renaming the unnamed spawned vehicle so it can be adressed by the script:
IEntity entity = GetWorld().FindEntityByName("btr_disabled");
NO_SCR_ImmobilizerComponent ic = NO_SCR_ImmobilizerComponent.Cast(entity.FindComponent(NO_SCR_ImmobilizerComponent));
ic.SetImmobilized(false);
Since we spawned the vehicle initially immobilized, we changed it via script “.SetImmobilized(false)” to un-block it. The other way around, its also possible to immobilize it again by “.SetImmobilized(true)”.