# Missions Model

## Register New Mission

```lua
RegisterMission(missionData)
```

* MissionData: `object`

  * Id: `string`
    * Custom ID *(Cannot be same as other missions)*
  * Name: `string`
    * Custom Mission Name&#x20;
  * Description: `string`
    * Custom Mission Description
  * Options: `object`
    * Conditions: `object`
      * AccessJobs: `table`
        * A list of authorized Jobs
      * GameHour: `object`
        * HourMin: `number`
        * HourMax: `number`
        * MinuteMin: `number`
        * MinuteMax: `number`
      * PreCondition: `function`
        * Must be return `TRUE` or `FALSE`
        * Example: `return IsPedArmer() and true or false`
      * Rewards: `table`
        * Custom: `function`
          * This is a **`SERVER`**&#x66;unction, so you can use xPlayer or QbPlayer, etc.
      * GameVariables: `object`
        * A custom mission variables
        * **INFO:** This variables can be modified in live game
        * Example:&#x20;

          `GameVariables = { StartPosition = vec3(100, 100, 50) }`
        * So in the game mission you can call GameVariables.StartPosition
  * Objetives: `table`
    * Description: `string`
    * Stages: `table`
      * onFinish: `function`
      * onStart: `function`
    * onStageComplete: `function`
      * When stage is complete
    * Preload: `function`
      * Preload functions before objetive start
    * onComplete: `function`
      * When objetive ends
  * onStart: `function`
    * When the mission start
  * onComplete: `function`
    * When the mission ends
    * as parameters you get:
      * `isForced`: Indicate if the mission has been forced to finish *(for example: admin canceled the mission)*
      * `reason`: Receive an end reason.

### Empty Model

{% code fullWidth="false" %}

```lua
RegisterMission({
    Id = "",
    Name = "",
    Description = "",

    Options = {
        Conditions = {
            AccessJobs = { "any" },
            PreCondition = function(gameVariables)
                return true
            end,
        },
        Rewards = {
            Custom = function(playerId)
                
            end
        },

        GameVariables = { }
    },

    Objectives = {
        [1] = {
            Description = "",
            
            Stages = {
                [1] = {
                    onFinish = function()

                    end,

                    onStart = function()
                        return GM().NextStage(true)
                    end,

                    isComplete = false, -- Internal variable, dont touch.
                },
            },

            onStageComplete = function(stageId)
            
            end,

            Preload = function(startStage)
 
                return startStage
            end,

            onComplete = function(isForced, reason)

            end,

            isComplete = false -- Internal variable, dont touch.
        }
    },

    onStart = function(startObjective)
 
        return startObjective
    end,

    onComplete = function(isForced, reason)
        print("Mission is finished: ", reason)
    end
})
```

{% endcode %}

### Start Logic

PMM is responsible for initiating a mission within the system. This function performs various checks and conditions before starting the mission, and sets the data for the current mission, current objective, and current stage.

#### **Functioning**

* First, the mission data corresponding to the provided missionId is obtained.
* Destroy any previous game or activity in progress should be terminated.
* A series of checks and conditions are then performed before starting the mission, such as checking the player's access to the required job and game time. These checks are based on mission options and conditions.
* If all the conditions are true, some additional actions are executed, such as checking the server preconditions and conditions.
* If all checks and conditions are passed, the data for the current mission, current objective, and current stage are set.
* The variables and effects necessary to start the mission are established.
* The Preload and onStart functions of the current target and the current stage are executed respectively.
* Finally, the callback function is called with a success boolean and a reason string to indicate whether the mission started successfully and provide additional information about the result.
* It is important to note that this function is designed to be used within the PMM system and is expected to be called from internal system components or from resources integrated with PMM.<br>

### **Start Logic (Simple)**

1. Check if any game is running and destroy it.
2. Check pre-conditions to start game.
3. Start missions effects (Some internal logic)
4. Execute Mission.onStart().
5. Execute Objetive.Preload().
6. Execute Stage\[1].onStart().
7. The game start!

## **Mission Structure**

The logical order of the PMM is:&#x20;

Stage 1, Stage 2... etc. If there are no more stages they will continue to the next objective, if there are no more objectives, they will end the mission successfully.

**Buuut!** You can also create **cause-and-effect missions**, where when making decisions you can skip stages or objectives. (Game variables can help a lot in this)

> Can you imagine a mission where you have to decide which path to take to save your life?

You have to understand the following:&#x20;

*A mission fits one or more objectives, objectives that have one or more stages to complete.*

**Important:** It is recommended to follow the order of the delivered structure, however, it is not mandatory if you want to do your mission in a single objective with a single stage.

**Important 2:** The FULL mission works within a loop, so you should only use the return from the end of each stage / objective and **not add additional returns ones**.

**Example:** (Robbery Mission)

* Objective 1: "Get into the bank"
  * Stage 1: Break the door
  * Stage 2: Enter the center of the bank
* Objective 2: Extract money
  * Stage 1: Install drill
  * Stage 2: Wait (waves of enemies)
  * Stage 3: The security door opens and they must enter
  * Stage 4: Steal 1000 dollars
* Objective 3: Flee
  * Stage 1: Get out of the bank
  * Stage 2: Move 200 meters away.

Or a simpler mission could be:

**Example 2:** (Robbery Mission):

* Objective 1: Steal and escape
  * Stage 1: Steal 5 boxes of chocolates and then run away

In fact, you can do everything in one stage or expand neatly to continue through each stage and break up your code.

### Objectives

If you want generate more objectives, simply copy and paste after \[1] = {}

\
**Remember to replace \[X] for the next objective id.**

```lua
[x] = { ------- REPLACE ME | REPLACE ME  | REPLACE ME  | REPLACE ME 
    Description = "",
    
    Stages = {
        [1] = { -- BUSCAR VEHICULO
            onFinish = function()

            end,

            onStart = function()
                return GM().NextStage(true)
            end,

            isComplete = false, -- Internal variable, dont touch.
        },
    },

    onStageComplete = function(stageId)
    
    end,

    Preload = function(startStage)

        return startStage
    end,

    onComplete = function(isForced, reason)

    end,

    isComplete = false -- Internal variable, dont touch.
}
```

### &#x20;Stages

Same as objectives, make sure replace X and add before \[1] = {} in stages.

```lua
[X] = { ------- REPLACE ME | REPLACE ME  | REPLACE ME  | REPLACE ME
    onFinish = function()

    end,

    onStart = function()
        return GM().NextStage(true)
    end,

    isComplete = false, -- Internal variable, dont touch.
},
```

### **Example Advanced Mission**

**Meta:**

* Objective 1:
  * Stage 1
  * Stage 2
  * Stage 3
* Objective 2:
  * Stage 1
  * Stage 2

```lua
RegisterMission({
    Id = "",
    Name = "",
    Description = "",

    Options = {
        Conditions = {
            AccessJobs = { "any" },
            PreCondition = function(gameVariables)
                return true
            end,
        },
        Rewards = {
            Custom = function(playerId)
                
            end
        },

        GameVariables = { }
    },

    Objectives = {
        [1] = {
            Description = "",
            
            Stages = {
                [1] = {
                    onFinish = function()

                    end,

                    onStart = function()
                        return GM().NextStage(true)
                    end,

                    isComplete = false, -- Internal variable, dont touch.
                },
                [2] = {
                    onFinish = function()

                    end,

                    onStart = function()
                        return GM().NextStage(true)
                    end,

                    isComplete = false, -- Internal variable, dont touch.
                },
                [3] = {
                    onFinish = function()

                    end,

                    onStart = function()
                        return GM().NextStage(true)
                    end,

                    isComplete = false, -- Internal variable, dont touch.
                },
            },

            onStageComplete = function(stageId)
            
            end,

            Preload = function(startStage)
 
                return startStage
            end,

            onComplete = function(isForced, reason)

            end,

            isComplete = false -- Internal variable, dont touch.
        },
        [2] = {
            Description = "",
            
            Stages = {
                [1] = {
                    onFinish = function()

                    end,

                    onStart = function()
                        return GM().NextStage(true)
                    end,

                    isComplete = false, -- Internal variable, dont touch.
                },
                [2] = {
                    onFinish = function()

                    end,

                    onStart = function()
                        return GM().NextStage(true)
                    end,

                    isComplete = false, -- Internal variable, dont touch.
                },
            },

            onStageComplete = function(stageId)
            
            end,

            Preload = function(startStage)
 
                return startStage
            end,

            onComplete = function(isForced, reason)

            end,

            isComplete = false -- Internal variable, dont touch.
        }
    },

    onStart = function(startObjective)
 
        return startObjective
    end,

    onComplete = function(isForced, reason)
        print("Mission is finished: ", reason)
    end
})
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://abpstudios.gitbook.io/abp-docs/abp-missions/guide/missions-model.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
