logo

ARMA REFORGER | ADDITIONAL SCRIPTS

Tutorial Special Scripts

While the different frameworks and its mechanics are explained in their own separate tutorials and the most important stuff has been shown in the NightOps – Basic Mission Guide by Herbiie, this article aims to explain some additional scripts utilized in Zeal’s NightOps – Everon 1985 showcase campaign. The scripts explained here can be used in many different situations to solve mission-related things which aren’t covered by the frameworks core mechanics. All examples in this tutorial will be shown via the showcase campaign “Everon 1985” which, at the time of writing has 3 missions using these scripts and more to follow as the framework features are enhanced.


1. CHANGE TASK STATE VIA SCRIPT

Creating, Assigning or Finishing a task out of a script remotely

There are many ways in the NightOps – Dynamic Task Framework and the NightOps – Custom Modes Framework to change the state of an existing task. Like using the missionTrigger for example. But there might be a situation where a task should be changed via an external script attached to another trigger or in a user action. This part of the tutorial covers ways to address and change a task added via the NightOps – Dynamic Task Framework.

In the first task of Mission 1 at the lighthouse is a faction control trigger. It fires only once US players are in the trigger sphere and while all USSR characters are gone. Using an additional “onActivate” script allows us to attach the code lines needed to finish the task.

Since the trigger is attached as a child to the task, there is no need to search the world for the entitybyName, instead we can use GetParent() to find the parent task.

	IEntity taskEntity = GetParent();
        NO_SCR_EditorTask task = NO_SCR_EditorTask.Cast(taskEntity);
	task.ChangeStateOfTask(TriggerType.Finish);

Another way, also used in Mission 1 when capturing the Encryption Key of the Com Truck, is to place the code into a user action added via the ActionsManagerComponent of a prefab. In the following case, the script doesn’t select the task via GetParent() since the pOwnerEntity (vehicle which “owns” the attached action) isn’t a child of the task. So it searches in the world for the named task entity “m01_tsk_3”, since that’s the name of the task:


	IEntity taskEntity = GetGame().GetWorld().FindEntityByName("m01_tsk_3");
        NO_SCR_EditorTask task = NO_SCR_EditorTask.Cast(taskEntity);
	task.ChangeStateOfTask(TriggerType.Finish);

There are several states a task can be changed to, like “Create”, “Assign” and “Finish” which will be explained more detailed in the “NightOps – Dynamic Task Framework” tutorial.


2. SPAWNPOINT FOLLOWS VEHICLE

Looping script to attach a spawnpoint on a dynamically spawned vehicle

While a pre-placed vehicle can have spawnpoint added as a child and it will follow the vehicle as it moves around, when using the NightOps – Dynamic Spawn Framework, there is the need for code to make a spawnpoint follow a moving vehicle. At the time of writing this tutorial, it is recommended by Bohemia Interactive to spawn a vehicle dynamically to make it work properly in a multiplayer environment.

In Mission 1, a custom prefab of a BTR is created with an additional component attached to it. This is so it can be spawned as a vehicle via the Dynamic Spawn Framework. The additional component is called “NO_SCR_IdentifierComponent” with the id set to “APC” which allows us to later detect this vehicle via script.

Next to the vehicle, there is a normal spawnpoint placed in the world, but it needs a component called “NWKMovementComponent” added to work in a multiplayer environment. Make sure, that this spawnPoint is not a child of another entity so its origin is independent.

In a trigger, which can be fired by any means, this code is needed in “OnActivate” to detect the “apc” to be identified along with the pre-placed spawnpoint and to move its position to the “apc” at a set interval.

override void OnActivate(IEntity ent)
	{

		//Enable spawnpoint follow the APC mechanic
		RplComponent rplComponent =  RplComponent.Cast(FindComponent(RplComponent));
		if (rplComponent && !rplComponent.IsProxy())
  		GetWorld().QueryEntitiesBySphere(GetOrigin(), 10000, QueryHit, QueryFilter, EQueryEntitiesFlags.ALL);
 
    }
    
//Detects "apc" identified vehicle
    bool QueryFilter(IEntity ent)
    {
        NO_SCR_IdentifierComponent idComponent =  
        
        NO_SCR_IdentifierComponent.Cast(ent.FindComponent(NO_SCR_IdentifierComponent));
        
        if (!idComponent)
            return false;
        
        return idComponent.GetIdentifier() == "apc";
    }
    
    //Detects pre-placed spawnpoint named "spawnPoint"
    bool QueryHit(IEntity ent)
    {
        SCR_SpawnPoint spawnPoint = 
        SCR_SpawnPoint.Cast(GetWorld().FindEntityByName("spawnPoint"));
        
        // If we can find the spawnpoint and target vehicle (ent)
        if (spawnPoint)
        {
            // Unlock it
            spawnPoint.SetFactionKey("US");
            
            // Keep moving it
	    RplComponent rplComponent = 
            RplComponent.Cast(FindComponent(RplComponent));
	    if (rplComponent && !rplComponent.IsProxy())
            	GetGame().GetCallqueue().CallLater(UpdateAPCSpawnPosition, 1000, true, spawnPoint, ent);
        }
        
        // Ends further queries as we will use the first match found
        return false;
    }
    
   //Removes spawnpoint (by setting its FactionKey to "0" when vehicle is destroyed)   
    void UpdateAPCSpawnPosition(SCR_SpawnPoint spawnPoint, IEntity target)
    {
        SCR_DamageManagerComponent damageManager = 
        SCR_DamageManagerComponent.Cast(target.FindComponent(SCR_DamageManagerComponent));
        
        if (!damageManager)
            return;
        
        if (damageManager.IsDestroyed())
        {
            // VEHICLE DEAD SECTION
            GetGame().GetCallqueue().Remove(UpdateAPCSpawnPosition);
            spawnPoint.SetFactionKey("0");
        }

        //Sets position of spawnpoint to vehicles position while vehicle is alive
        else
        {
            // VEHICLE ALIVE SECTION
            spawnPoint.SetOrigin(target.GetOrigin());
        }
    }

This code is well documented with //comments. But it basically looks for the “apc” identified vehicle and the spawnpoint named “spawnPoint” then checks if the vehicle is alive. IF the vehicle is destroyed, it hides the spawnpoint and while the vehicle is not destroyed, it sets the spawnpoint position to the vehicle origin.


3. ACTIVATE MISSION TRIGGER VIA SCRIPT

Activating and deactivating missionTriggers by script remotely

MissionTriggers from NightOps – Custom Modes Framework are powerful triggers with a lot of custom functions to modify the mission experience like changing the weather, teleporting the players, spawning enemies or finishing tasks once a player or all players enter it. The missionTrigger can be active or inactive on game start to avoid players triggering it by accident. While it will be covered completely in the NightOps – Custom Modes Framework Tutorial, this guide shows a way to activate it remotely via script.

In Mission 1, once the player captured the “Encryption Key” of the Com Truck, he will be tasked to reach the exfil area. This is a missionTrigger and should only be activated once the “Encryption Key” action is used. While the trigger could activate itself now, via its own function “Activate on Task State” when a task is changed (and this is the recommended way) it is also possible to do so via a script:

NO_SCR_PlayerTriggerEntity trigger = 
NO_SCR_PlayerTriggerEntity.Cast(GetGame().GetWorld().FindEntityByName("exfilTrg"));
	if(trigger)
	trigger.SetActive(true);
		

This code looks in the world for an trigger named “exfilTrg” and if that trigger exists, it will activate it.

A trigger could also be de-activated via “.SetActive(false)”.


4. ACTIVATE SPAWN TRIGGER VIA SCRIPT

Activating a spawnTrigger remoteley via script

While there exist a lot of ways to utilize the NightOps – Dynamic Spawn Framework to spawn new units, there is always the option to do so via script. In Mission 2 its used several times for example in actions to activate prepared spawnTriggers with this script:

NO_SCR_SpawnTrigger.Cast(GetGame().GetWorld().FindEntityByName("spawnTrg")).Spawn();

The placed spawnTrigger is named “spawnTrg” in this example. It could also be disabled later via “.Despawn();”

  • Share

Leave a reply

Your email address will not be published. Required fields are marked *