Reference
ss.powerplays
Power Plays are the traps of a level: the fuel trucks, the parked cars and coaches, the helicopters, and the big
ones that change the route. ss.powerplays lists every Power Play the loaded level has, whether a
player could reach it right now or not, and a script can set one off, reset it or switch it off. A Power Play
is a live object: reading a field reads the game at that moment. Power
Plays only exist within a race.
Static members#
These elements are static to the class itself and can be accessed like so:
local ahead = ss.powerplays.near(ss.vehicle.position, 150)Static functions#
| Function | Return Values | Description |
|---|---|---|
ss.powerplays[integer index] |
powerplay powerplay | Returns the Power Play at the given index: 0-based, in the level's own order. Returns nil if there is no such Power Play. |
ss.powerplays.count |
integer count | The number of Power Plays in the loaded level. 0 outside a race. |
ss.powerplays.all() |
table of powerplay powerplays | Returns a table of references to all Power Plays in the loaded level. |
ss.powerplays.each() |
function iterator | Returns an iterator over all Power Plays in the loaded level, for use in a for loop. |
ss.powerplays.find(string pattern) |
table of powerplay powerplays | Returns a table of references to all Power Plays whose name matches the given Lua pattern, case-insensitively. find("fueltruck") returns every fuel truck; find("^Cars_5$") returns the one with exactly that name. |
ss.powerplays.near(
vector-like point,
number radius
) |
table of powerplay powerplays | Returns a table of references to all Power Plays within the given radius, in metres, of the given point, nearest first. The radius defaults to 100. Power Plays without a position are never in the result. |
Instance members#
Instance members must be accessed through a reference to a specific Power Play object.
local truck = ss.powerplays.find("fueltruck")[1]
if truck.ready then truck:fire(ss.player) endInstance Methods#
| Function | Return Values | Description |
|---|---|---|
fire() |
boolean fired, string reason | Sets the Power Play off as nobody's. Returns true if the game accepted the fire. Otherwise returns false and the reason; see Firing a Power Play. |
fire(
player who
) |
boolean fired, string reason | Sets the Power Play off as the given player's. who can be a player, a vehicle or a player index. Results in an error if that player is not in the race. |
fire(
player who,
integer trigger
) |
boolean fired, string reason | Sets the Power Play off by one of its triggers, 0-based, for Power Plays that have more than one. Pass nil for who to fire it as nobody's. |
reset() |
boolean reset | Puts the Power Play back as the level loaded it, so that it can be fired again. The game does this on its next frame, and the Power Play is idle about a second later. Also works while the Power Play is playing. |
mem(
integer offset,
string type
) |
any value | Returns a value of the Power Play's object at a specific memory address-offset. See ss.mem for the types. |
mem(
integer offset,
string type,
any value
) |
nil | Sets a value of the Power Play's object at a specific memory address-offset. |
memdump(
integer lowerBound,
integer upperBound
) |
nil | Logs the current state of the object's memory addresses in the given range, for debugging. |
Instance Fields#
| Type | Field | Read-only? | Description |
|---|---|---|---|
| boolean | valid |
Yes | Validates that the Power Play exists in the loaded level. A Power Play kept across the end of a race becomes invalid: its fields read nil and its methods result in an error. |
| string | name |
Yes | The Power Play's name in the level, such as FuelTruck, Cars_5 or PA11_PetrolStation_P. |
| integer | index |
Yes | The Power Play's index, as taken by ss.powerplays[index] and passed by the powerplay event. |
| integer | id |
Yes | The game's own id for the Power Play. The powerplay event passes the same number as id. |
| vec3 | position |
Yes | Where the Power Play stands, in metres. nil for Power Plays that keep no position of their own: the route changes and the ones that belong to Nemesis actors. |
| integer | level |
Yes | The number of power bar segments the Power Play costs a player: 1, or 3 for the route changes and the other big ones. A fire from a script costs nothing. |
| integer | triggers |
Yes | The number of triggers the Power Play has. Most have 1. A Power Play with 0 triggers cannot be fired. |
| string | state |
Yes | idle (nothing of it has gone off), playing (going off right now) or played (over). Most Power Plays stay played until they are reset; a few return to idle by themselves. |
| boolean | ready |
Yes | Whether the game would accept a fire of the Power Play right now. False while it is going off, after it has gone off, and while it is switched off. See Firing a Power Play. |
| boolean | enabled |
No | Whether the Power Play is part of the race. Setting this field to false switches it off for everybody: no player and no AI can fire it, and neither can a script. |
| integer | address |
Yes | The address of the Power Play's object, for ss.mem. |
Instance Memory Offsets#
These offsets can be manipulated by the instance's mem method. They are relative to address.
| Field | Fieldtype | Description |
|---|---|---|
0x50 |
int |
The number of triggers. Use field triggers |
0x58 |
float |
The timer, in seconds. It runs while the Power Play is playing. |
0x60 |
int |
1 while the timer runs. Use field state |
0x94 |
3 floats |
The position. Use field position |
0x120 |
int |
The id. Use field id |
0x1bc |
byte |
The reset request. The game clears it once the reset is done. Use method reset |
0x1c6 |
u16 |
The level. Use field level |
0x1ec |
byte |
Enabled. Use field enabled |
Firing a Power Play#
fire hands the Power Play to the game the same way a player's button does, so everything that
follows is the game's own: the explosion, the wrecks, the debris. The Power Play goes off two frames later,
and that is when the powerplay event runs, with
scripted set to true.
A fire from a script is free. It does not look at anybody's power bar and does not spend it, and the Power
Play's level does not matter. Nobody has to be near it either.
Some of the big Power Plays can be fired a second time a while after the first, as they can by a player.
ready reads true again when that second fire is possible, even though state still
reads playing.
When the game cannot accept the fire, fire returns false and one of these reasons:
| Type | Field | Description |
|---|---|---|
| string | it is playing |
The Power Play is going off right now and has no further stage ready. |
| string | it has played and was not reset |
Most Power Plays go off once. Call reset first, then fire it again about a second later. |
| string | it is queued already |
The same Power Play was fired twice in one frame. |
| string | it is switched off |
Its enabled field is false. |
| string | no such trigger |
The trigger index is past the Power Play's triggers, or the Power Play has none. |
| string | that trigger plays nothing |
The trigger exists but is empty. Use another trigger of the Power Play. |
| string | the fire queue is full |
The game takes at most 32 fires per frame. |
-- Fires every Power Play near the leader as the local player's, once every five seconds.
ss.on("race_start", function()
ss.every(5, function()
local leader
for car in ss.vehicles.each() do
if not leader or car.race.position < leader.race.position then leader = car end
end
if not leader or leader.is_local then return end
for _, pp in ipairs(ss.powerplays.near(leader.position + leader.forward * 40, 120)) do
if pp.ready then pp:fire(ss.player) end
end
end)
end)Using a Power Play again#
Most Power Plays go off once and then stay played. reset rebuilds one through the
game's own reset. Wait until ready reads true before firing it again.
-- Blows up the same row of parked cars every eight seconds.
local cars = ss.powerplays.find("^Cars_5$")[1]
ss.every(8, function()
if not cars.valid then return end
if cars.ready then
cars:fire()
elseif cars.state == "played" then
cars:reset()
end
end)Switching a Power Play off#
Setting enabled to false takes a Power Play out of the race for everybody. It is in nobody's
reach, the AI's included, and fire returns false. Setting it back to true brings it back.
-- The airport without its two route changes.
ss.on("race_start", function()
for _, pp in ipairs(ss.powerplays.find("^RCA")) do pp.enabled = false end
end)for pp in ss.powerplays.each() do ss.log(tostring(pp)) end to see what a track has.