Skip to content

Lua Scripting

pongo1231 edited this page May 7, 2022 · 42 revisions

Starting with mod version 1.9 you are able to write your own effects completely in Lua! Here's how it works:

If you don't have a natives_def.lua already: Go to the scripts folder inside the repository and run the generate_natives.py script. After a few seconds it should have generated a natives_def.lua file in the same folder. Move the resulting file into your game's chaosmod folder.

Afterwards create a custom_scripts folder in the same directory. That's where all the lua scripts will be stored in.

Now create your own lua script inside that folder.

Example

Here's an example of what a script can look like:

ScriptInfo = {
    Name = "Party Time",
    ScriptId = "misc_partytime",
    TimedType = "Normal",
    IncompatibleIds = {
        "vehs_rainbow"
    }
}

function OnStart()
    print("Yay party! :D")
end

function OnStop()
    print("Party over :(")

    local playerPed = PLAYER_PED_ID()
    local playerVehicle = GET_VEHICLE_PED_IS_IN(playerPed)

    if playerVehicle then
        SET_ENTITY_AS_MISSION_ENTITY(playerVehicle)
        DELETE_ENTITY(Holder(playerVehicle))
    end
end

function OnTick()
    for _, vehicle in ipairs(GetAllVehicles()) do
        SET_VEHICLE_ENGINE_HEALTH(vehicle, -1.0)
        SET_VEHICLE_CUSTOM_PRIMARY_COLOUR(vehicle, math.random(255), math.random(255), math.random(255))
    end
end

Script Info

Your script will need to contain a ScriptInfo table to be able to register as an effect. The table either must or can contain the following:

ScriptInfo = {
    Name = "Party Time",                  -- The name of your effect to display, required
    ScriptId = "misc_partytime",          -- An unique id for your effect, required
    TimedType = "Normal",                 -- The timed type of your effect, optional (defaults to none)
    WeightMultiplier = 5,                 -- Weight multiplier of your effect to make it more / less likely to occur randomly, optional (defaults to 5)
    IsMeta = false,                       -- Whether this effect is a meta effect, optional (defaults to false)
    ExcludeFromVoting = false,            -- Whether this effect should be excluded from voting (defaults to false)
    IsUtility = false,                    -- Whether this effect should only be able to be activated through the debug menu (defaults to false)
    EffectGroup = "_group_weatherchange", -- Effect group to associate this effect with, groups effects together and affects weighting (defaults to none)
    ShortcutKeycode = 0,                  -- Trigger effect if virtual keycode is pressed, see https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes - 0 to disable (defaults to 0)
    IncompatibleIds = {                   -- A list of incompatible effects listed by their ids, optional (defaults to none)
        "vehs_rainbow"
    }
}

Timed Types

The following timed types exist:

"None"           -- Non-timed effect
"Normal"         -- Normal timed effect
"Short"          -- Short timed effect
"Permanent"      -- Permanent effect
"Custom"         -- Timed effect with custom duration in seconds (also needs CustomTime entry in ScriptInfo)

Return Types

The following return types exist:

ReturnType = {
    None,
    Boolean,
    Integer,
    String,
    Float,
    Vector3
}

Errors

Errors are printed in the chaoslog.txt file.

You can enable a console window for logs by creating a .enableconsole file inside the chaosmod folder.

Hot Reloading

You can reload all your scripts in-game by simply turning the mod off and on again with the CTRL + L shortcut.

Available Functions

Other than functions provided by the base, math, table, string and bit32 lua libraries and the natives provided by natives_def.lua, the following functions are available:

print(string): Prints a string in the `chaosLog.txt` file
_invoke(nativeHash, returnType, arguments...): Invokes a native
WAIT(ms): Pauses the current fiber for `x` milliseconds
GetTickCount(): Calls the WIN32 `GetTickCount64` function

GetAllPeds(): Returns all existing peds on the world
GetAllVehicles(): Returns all existing vehicles on the world
GetAllProps(): Returns all existing props on the world

CreatePoolPed(pedType, modelHash, x, y, z, heading): Creates a ped and adds it to the mod's pool for automatic cleanup
CreatePoolVehicle(modelHash, x, y, z, heading): Creates a vehicle and adds it to the mod's pool for automatic cleanup
CreatePoolProp(modelHash, x, y, z, dynamic): Creates a prop and adds it to the mod's pool for automatic cleanup

CreateTempVehicle(modelHash, x, y, z, heading): Creates a vehicle with `SET_VEHICLE_AS_NO_LONGER_NEEDED` already applied

GetAllWeapons(): Returns every existing weapon in the game
GetAllPedModels(): Returns every existing ped model in the game
GetAllVehicleModels(): Returns every existing vehicle model in the game

Effect Groups

Effects groups are a collection of different effects. During weighting, effects within an effect group will be affected by the weight of the current effect group. Effect groups are meant to group effects with a similar purpose (e.g. spawning a vehicle) together to keep the effect selection as diverse as possible. A list of built-in effect groups can be found here.

It's also possible to register your own effect groups:

EffectGroupInfo = {
    Name = "group_test",   -- Name, should start with `group_` as a convention 
    WeightMultiplier = 1   -- Weight multiplier, Ranges from 1 (lowest) - 65535 (highest), defaults to 1
}

Effect groups may not have a duplicate name; later registrations of an effect group with the same name will be ignored and the weight multiplier of the previous registration will be used. As a recommendation, you should keep the effect group definitions in separate script files for organization purposes.

Meta Modifiers

You can modify some of the behaviors of the mod using Meta Modifiers.

function OnStart()
    MetaModifiers.FlipChaosUI(true)
    MetaModifiers.AdditionalEffectsToDispatch(99999)
end

function OnStop()
    MetaModifiers.FlipChaosUI(false)
    MetaModifiers.AdditionalEffectsToDispatch(0)
end

As of writing, the following modifiers are available:

EffectDurationModifier(float)
TimerSpeedModifier(float)
AdditionalEffectsToDispatch(ubyte)
HideChaosUI(bool)
DisableChaos(bool)
FlipChaosUI(bool)

Pointers

Some natives require pointers as arguments. You can use Holders in those cases.

Storing data inside a Holder and accessing it afterwards:

local r, g, b = Holder(), Holder(), Holder()

GET_VEHICLE_CUSTOM_PRIMARY_COLOUR(vehicle, r, g, b)

print(r:AsInteger() .. " " .. g:AsInteger() .. " " .. b:AsInteger())

(You can also use AsBoolean, AsFloat, AsString or AsVector3 depending on the type of the stored data)

Sending data to a native:

DELETE_ENTITY(Holder(vehicle))

Note that the data passed to the Holder won't be modified (e.g. DELETE_ENTITY won't set vehicle to nil in this case).

Vector3

Receiving a Vector3:

local playerCoords = GET_ENTITY_COORDS(playerPed)

print(playerCoords.x .. " " .. playerCoords.y .. " " .. playerCoords.z)

Creating a Vector3:

local vector = Vector3(5.0, 3.0, 1.0)

print(vector.x .. " " .. vector.y .. " " .. vector.z)
-- Will print: 5.0 3.0 1.0
Clone this wiki locally