-
Notifications
You must be signed in to change notification settings - Fork 101
Lua Scripting
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.
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
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"
}
}
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)
The following return types exist:
ReturnType = {
None,
Boolean,
Integer,
String,
Float,
Vector3
}
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.
You can reload all your scripts in-game by simply turning the mod off and on again with the CTRL + L
shortcut.
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
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.
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)
Some natives require pointers as arguments. You can use Holder
s 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).
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