Monitors Tutorial

A Monitor is an MMM provided class that you can use to keep track of and respond to the changes in the state of a condition. This means that you don't have to keep manually checking conditions in your script - you simply tell the monitor how to check and it will inform you when the condition changes.

Condition States and Hooks

A condition can either be true or false; you can be notified at the following times. See the MonitorHook.Type enumeration.

Name Description
MonitorHook.Type.OnTrue When the condition becomes true
MonitorHook.Type.OnFalse When the condition becomes false
MonitorHook.Type.WhileTrue While the condition is true
MonitorHook.Type.WhileFalse While the condition is false
MonitorHook.Type.OnStop
When the Monitor is stopped

Creating a Condition

A condition is implemented by creating a function that returns either true or false. To demonstrate, we will create a simple condition and add one or two callbacks. Our condition will be to check if the player team has more than 500 dilithium. We will then add hooks for OnTrue and OnFalse. We will then create extra monitors that impose a soft limit on the player's dilithium total using WhileTrue and WhileFalse.

The Condition

The code for the condition is quite simple. We simply return if the diithium amount of Player 1 (the player team) is greater than or equal to 500. If it is, the condition returns true; otherwise it returns false. Here is the code for the condition:

function checkDilithium( amount )
    return Player(1).resources.dilithium >= amount
end

The function takes one argument - the threshold amount. This will be passed to the function by the Monitor and we will tell the Monitor what to pass when we create it.

Creating the Monitor

To create the Monitor, we call the Monitor constructor. In this example we will create a Monitor called "DilithiumMonitor". We want the initial state to be false, so that we are notified as soon as the condition becomes true.

Since our condition function is not part of any object, we pass nil as the conditionTable. We pass 500 as the argument, as that is the threshold we want to check against, as stated above.

local newMonitor = Monitor( "DilithiumMonitor", false, nil, checkDilithium, 500 )

Hooking

We want to be notified when the condition becomes true - so when the player gets more than 500 ditlithium. We'll use the MonitorHooks.OnTrue hook for this, but first let's define the function that will be hooked.

The Hook Function

In our hook function we will spawn an Akira class as a reward for the player. Then, as we don't want to be triggered again, we stop the monitor. The code for the hook function is shown below.

function onDilithiumTargetReached( monitor, hook )
    --When the player gets 500, spawn an Akira class as a reward.
    Entity.add( "fed_akiraZ.odf", 1, Vector(3000, 0, 3000) )
    --We don't want this to happen again, so we kill the monitor
   monitor:stop()
end

Registering the Hook

Now that we've written the hook function and created the monitor we can register the hook function. As stated we will hook on to the OnTrue event. This code should go below the code that created the monitor.

newMonitor:hook( "onDilithiumTargetReached", MonitorHook.Type.OnTrue, nil, onDilithiumTargetReached, nil )

Putting it all Together

Here's the whole script for this mission.

class 'MonitorTutorial'

function MonitorTutorial:__init( )

end

function MonitorTutorial:setup( )
    --This function checks to see if the the player has the required amount of dilithium
    function checkDilithium( amount )
        return Player( 1 ).resources.dilithium >= amount
    end

    --This function is called when the target is reached ( the monitor condition becomes true )
    function onDilithiumTargetReached( monitor, hook )
        --When the player gets 500, spawn an Akira class as a reward.
        Entity.add( "fed_akiraZ.odf", 1, Vector( 500, 0, 250 ) )
        --We don't want this to happen again, so we kill the monitor
        monitor:stop()
    end

    local newMonitor = Monitor( "DilithiumMonitor", false, nil, checkDilithium, 500 )
    newMonitor:hook( "onDilithiumTargetReached", MonitorHook.Type.OnTrue, nil, onDilithiumTargetReached, nil )

    Objectives:load( "MonitorTutorialObjectives.txt" )
    Objectives.visible = true

end

MMM.register( MonitorTutorial() )

Download

Download for map and script