OpenRCT2/distribution/openrct2.d.ts

2682 lines
74 KiB
TypeScript

/*****************************************************************************
* Copyright (c) 2014-2021 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
// OpenRCT2 Scripting API definition file
// To enable IntelliSense for your scripts in Visual Studio or Visual Studio Code,
// add the following line to the top of your script and change the path appropriately.
//
// /// <reference path="/path/to/openrct2.d.ts" />
//
export type PluginType = "local" | "remote";
declare global {
/**
* Global context for accessing all other APIs.
*/
/** APIs for cheats. */
var cheats: Cheats;
/** APIs for interacting with the stdout console. */
var console: Console;
/** Core APIs for plugins. */
var context: Context;
/** APIs for getting or setting the in-game date. */
var date: GameDate;
/** APIs for manipulating the map. */
var map: GameMap;
/** APIs for managing the server or interacting with the server or clients. */
var network: Network;
/** APIs for the park and management of it. */
var park: Park;
/** APIs for the current scenario. */
var scenario: Scenario;
/** APIs for the climate and weather. */
var climate: Climate;
/**
* APIs for creating and editing title sequences.
* These will only be available to clients that are not running headless mode.
*/
var titleSequenceManager: TitleSequenceManager;
/**
* APIs for controlling the user interface.
* These will only be available to servers and clients that are not running headless mode.
* Plugin writers should check if ui is available using `typeof ui !== 'undefined'`.
*/
var ui: Ui;
/**
* Registers the plugin. This may only be called once.
* @param metadata Information about the plugin and the entry point.
*/
function registerPlugin(metadata: PluginMetadata): void;
/**
* Represents a JavaScript object that can or should be disposed when no longer needed.
*/
interface IDisposable {
dispose(): void;
}
/**
* A coordinate within the game's client screen in pixels.
*/
interface ScreenCoordsXY {
x: number;
y: number;
}
/**
* Represents the width and height in pixels.
*/
interface ScreenSize {
width: number;
height: number;
}
/**
* A coordinate within the game.
* Each in-game tile is a size of 32x32.
*/
interface CoordsXY {
x: number;
y: number;
}
/**
* A coordinate within the game.
* Each in-game tile is a size of 32x32.
* The z-coordinate raises 16 per land increment. A full-height wall is 32 in height.
*/
interface CoordsXYZ extends CoordsXY {
z: number;
}
/**
* A coordinate within the game.
* Each in-game tile is a size of 32x32.
* The z-coordinate raises 16 per land increment. A full-height wall is 32 in height.
* The direction is between 0 and 3.
*/
interface CoordsXYZD extends CoordsXYZ {
direction: number;
}
/**
* A rectangular area specified using two coordinates.
*/
interface MapRange {
leftTop: CoordsXY;
rightBottom: CoordsXY;
}
/**
* Represents lateral and vertical g-forces.
*/
interface GForces {
lateralG: number;
verticalG: number;
}
/**
* Represents information about the plugin such as type, name, author and version.
* It also includes the entry point.
*/
interface PluginMetadata {
name: string;
version: string;
authors: string | string[];
type: PluginType;
licence: string;
minApiVersion?: number;
targetApiVersion?: number;
main: () => void;
}
/**
* Console APIs
* Currently interact with stdout.
*/
interface Console {
clear(): void;
log(message?: any, ...optionalParams: any[]): void;
/**
* Executes a command using the legacy console REPL. This should not be used
* by plugins, and exists only for servers to continue using old commands until
* all functionality can be accomplished with this scripting API.
*
* @deprecated
* @param command The command and arguments to execute.
*/
executeLegacy(command: string): void;
}
/**
* Core APIs for storage and subscriptions.
*/
interface Context {
/**
* Gets the current version of the plugin api. This is an integer that increments
* by 1 every time a change to the plugin api is made.
*/
readonly apiVersion: number;
/**
* The user's current configuration.
*/
configuration: Configuration;
/**
* Shared generic storage for all plugins. Data is persistent across instances
* of OpenRCT2 and is stored externally as a single JSON file in the OpenRCT2
* user directory. Internally it is a JavaScript object. Objects and arrays
* are only copied by reference. The external file is only written when using
* the `set` method, do not rely on the file being saved by modifying your own
* objects. Functions and other internal structures will not be persisted.
*/
sharedStorage: Configuration;
/**
* Render the current state of the map and save to disc.
* Useful for server administration and timelapse creation.
* @param options Options that control the capture and output file.
*/
captureImage(options: CaptureOptions): void;
/**
* Gets the loaded object at the given index.
* @param type The object type.
* @param index The index.
*/
getObject(type: ObjectType, index: number): LoadedObject;
getObject(type: "ride", index: number): RideObject;
getObject(type: "small_scenery", index: number): SmallSceneryObject;
getAllObjects(type: ObjectType): LoadedObject[];
getAllObjects(type: "ride"): RideObject[];
/**
* Gets a random integer within the specified range using the game's pseudo-
* random number generator. This is part of the game state and shared across
* all clients, you therefore must be in a context that can mutate the game
* state. Use this to generate random numbers instead of Math.Random during
* game logic routines such as hooks and game actions.
* @param min The minimum value inclusive.
* @param max The maximum value exclusive.
*/
getRandom(min: number, max: number): number;
/**
* Formats a new string using the given format string and the arguments.
* @param fmt The format string, e.g. "Guests: {COMMA16}"
* @param args The arguments to insert into the string.
*/
formatString(fmt: string, ...args: any[]): string;
/**
* Registers a new game action that allows clients to interact with the game.
* @param action The unique name of the action.
* @param query Logic for validating and returning a price for an action.
* @param execute Logic for validating and executing the action.
* @throws An error if the action has already been registered by this or another plugin.
*/
registerAction(
action: string,
query: (args: object) => GameActionResult,
execute: (args: object) => GameActionResult): void;
/**
* Query the result of running a game action. This allows you to check the outcome and validity of
* an action without actually executing it.
* @param action The name of the action.
* @param args The action parameters.
* @param callback The function to be called with the result of the action.
*/
queryAction(action: ActionType, args: object, callback: (result: GameActionResult) => void): void;
queryAction(action: string, args: object, callback: (result: GameActionResult) => void): void;
/**
* Executes a game action. In a network game, this will send a request to the server and wait
* for the server to reply.
* @param action The name of the action.
* @param args The action parameters.
* @param callback The function to be called with the result of the action.
*/
executeAction(action: ActionType, args: object, callback: (result: GameActionResult) => void): void;
executeAction(action: string, args: object, callback: (result: GameActionResult) => void): void;
/**
* Subscribes to the given hook.
*/
subscribe(hook: HookType, callback: Function): IDisposable;
subscribe(hook: "action.query", callback: (e: GameActionEventArgs) => void): IDisposable;
subscribe(hook: "action.execute", callback: (e: GameActionEventArgs) => void): IDisposable;
subscribe(hook: "interval.tick", callback: () => void): IDisposable;
subscribe(hook: "interval.day", callback: () => void): IDisposable;
subscribe(hook: "network.chat", callback: (e: NetworkChatEventArgs) => void): IDisposable;
subscribe(hook: "network.authenticate", callback: (e: NetworkAuthenticateEventArgs) => void): IDisposable;
subscribe(hook: "network.join", callback: (e: NetworkEventArgs) => void): IDisposable;
subscribe(hook: "network.leave", callback: (e: NetworkEventArgs) => void): IDisposable;
subscribe(hook: "ride.ratings.calculate", callback: (e: RideRatingsCalculateArgs) => void): IDisposable;
subscribe(hook: "action.location", callback: (e: ActionLocationArgs) => void): IDisposable;
subscribe(hook: "guest.generation", callback: (id: number) => void): IDisposable;
subscribe(hook: "vehicle.crash", callback: (e: VehicleCrashArgs) => void): IDisposable;
/**
* Registers a function to be called every so often in realtime, specified by the given delay.
* @param callback The function to call every time the delay has elapsed.
* @param delay The number of milliseconds to wait between each call to the given function.
*/
setInterval(callback: Function, delay: number): number;
/**
* Like `setInterval`, except the callback will only execute once after the given delay.
* @param callback The function to call after the given delay has elapsed.
* @param delay The number of milliseconds to wait for before calling the given function.
*/
setTimeout(callback: Function, delay: number): number;
/**
* Removes the registered interval specified by the numeric handle. The handles
* are shared with `setTimeout`.
* @param handle
*/
clearInterval(handle: number): void;
/**
* Removes the registered timeout specified by the numeric handle. The handles
* are shared with `setInterval`.
* @param handle The numerical handle of the registered timeout to remove.
*/
clearTimeout(handle: number): void;
}
interface Configuration {
getAll(namespace: string): { [name: string]: any };
get<T>(key: string): T | undefined;
get<T>(key: string, defaultValue: T): T;
set<T>(key: string, value: T): void;
has(key: string): boolean;
}
interface CaptureOptions {
/**
* A relative filename from the screenshot directory to save the capture as.
* By default, the filename will be automatically generated using the system date and time.
*/
filename?: string;
/**
* Width of the capture in pixels.
* Do not set if you would like a giant screenshot.
*/
width?: number;
/**
* Height of the capture in pixels.
* Do not set if you would like a giant screenshot.
*/
height?: number;
/**
* Map position to centre the view on in map units.
* Do not set if you would like a giant screenshot.
*/
position?: CoordsXY;
/**
* The zoom level, 0 is 1:1, 1 is 2:1, 2 is 4:1 etc.
*/
zoom: number;
/**
* Rotation of the camera from 0 to 3.
*/
rotation: number;
/**
* Whether to enable transparency in the screenshot.
*/
transparent?: boolean;
}
type ObjectType =
"ride" |
"small_scenery" |
"large_scenery" |
"wall" |
"banner" |
"footpath" |
"footpath_addition" |
"scenery_group" |
"park_entrance" |
"water" |
"terrain_surface" |
"terrain_edge" |
"station" |
"music" |
"footpath_surface" |
"footpath_railings";
type HookType =
"interval.tick" | "interval.day" |
"network.chat" | "network.action" | "network.join" | "network.leave" |
"ride.ratings.calculate" | "action.location" | "vehicle.crash";
type ExpenditureType =
"ride_construction" |
"ride_runningcosts" |
"land_purchase" |
"landscaping" |
"park_entrance_tickets" |
"park_ride_tickets" |
"shop_sales" |
"shop_stock" |
"food_drink_sales" |
"food_drink_stock" |
"wages" |
"marketing" |
"research" |
"interest";
type ActionType =
"balloonpress" |
"bannerplace" |
"bannerremove" |
"bannersetcolour" |
"bannersetname" |
"bannersetstyle" |
"clearscenery" |
"climateset" |
"footpathplace" |
"footpathplacefromtrack" |
"footpathremove" |
"footpathadditionplace" |
"footpathadditionremove" |
"guestsetflags" |
"guestsetname" |
"landbuyrights" |
"landlower" |
"landraise" |
"landsetheight" |
"landsetrights" |
"landsmoothaction" |
"largesceneryplace" |
"largesceneryremove" |
"largescenerysetcolour" |
"loadorquit" |
"mazeplacetrack" |
"mazesettrack" |
"networkmodifygroup" |
"parkentranceremove" |
"parkmarketing" |
"parksetdate" |
"parksetloan" |
"parksetname" |
"parksetparameter" |
"parksetresearchfunding" |
"pausetoggle" |
"peeppickup" |
"placeparkentrance" |
"placepeepspawn" |
"playerkick" |
"playersetgroup" |
"ridecreate" |
"ridedemolish" |
"rideentranceexitplace" |
"rideentranceexitremove" |
"ridesetappearance" |
"ridesetcolourscheme" |
"ridesetname" |
"ridesetprice" |
"ridesetsetting" |
"ridesetstatus" |
"ridesetvehicles" |
"scenariosetsetting" |
"setcheataction" |
"setparkentrancefee" |
"signsetname" |
"smallsceneryplace" |
"smallsceneryremove" |
"stafffire" |
"staffhire" |
"staffsetcolour" |
"staffsetcostume" |
"staffsetname" |
"staffsetorders" |
"staffsetpatrolarea" |
"surfacesetstyle" |
"tilemodify" |
"trackdesign" |
"trackplace" |
"trackremove" |
"tracksetbrakespeed" |
"wallplace" |
"wallremove" |
"wallsetcolour" |
"waterlower" |
"waterraise" |
"watersetheight";
interface GameActionEventArgs {
readonly player: number;
readonly type: number;
readonly action: string;
readonly isClientOnly: boolean;
readonly args: object;
result: GameActionResult;
}
interface GameActionResult {
error?: number;
errorTitle?: string;
errorMessage?: string;
position?: CoordsXYZ;
cost?: number;
expenditureType?: ExpenditureType;
}
interface RideCreateGameActionResult extends GameActionResult {
readonly ride: number;
}
interface NetworkEventArgs {
readonly player: number;
}
interface NetworkChatEventArgs extends NetworkEventArgs {
message: string;
}
interface NetworkAuthenticateEventArgs {
readonly name: number;
readonly ipAddress: string;
readonly publicKeyHash: string;
cancel: boolean;
}
interface RideRatingsCalculateArgs {
readonly rideId: number;
excitement: number;
intensity: number;
nausea: number;
}
interface ActionLocationArgs {
readonly x: number;
readonly y: number;
readonly player: number;
readonly type: number;
readonly isClientOnly: boolean;
result: boolean;
}
type VehicleCrashIntoType = "another_vehicle" | "land" | "water";
interface VehicleCrashArgs {
readonly id: number;
readonly crashIntoType: VehicleCrashIntoType;
}
/**
* APIs for the in-game date.
*/
interface GameDate {
/**
* The total number of ticks that have elapsed since the beginning of the game / scenario. This
* should never reset.
*/
readonly ticksElapsed: number;
/**
* The total number of months that have elapsed. This will equate to 0 in March, Year 1 and
* increase by 1 every month, i.e. by 8 every year.
* Note: this represents the current date and may be reset by cheats or scripts.
*/
monthsElapsed: number;
/**
* The total number of years that have elapsed. This always equates to (monthsElapsed / 8).
*/
readonly yearsElapsed: number;
/**
* How far through the month we are between 0 and 65536. This is incremented by 4 each tick, so
* every month takes ~6.8 minutes to complete making a year take just under an hour.
*/
monthProgress: number;
/** The day of the month from 1 to 31. */
readonly day: number;
/** The current month of the year from 0 to 7, where 0 is March and 7 is October. */
readonly month: number;
/** The current year starting from 1. */
readonly year: number;
}
/**
* APIs for the map.
*/
interface GameMap {
readonly size: CoordsXY;
readonly numRides: number;
readonly numEntities: number;
readonly rides: Ride[];
getRide(id: number): Ride;
getTile(x: number, y: number): Tile;
getEntity(id: number): Entity;
getAllEntities(type: EntityType): Entity[];
/**
* @deprecated since version 34, use guest or staff instead.
*/
getAllEntities(type: "peep"): Peep[];
getAllEntities(type: "guest"): Guest[];
getAllEntities(type: "staff"): Staff[];
getAllEntities(type: "car"): Car[];
getAllEntities(type: "litter"): Litter[];
createEntity(type: EntityType, initializer: object): Entity;
}
type TileElementType =
"surface" | "footpath" | "track" | "small_scenery" | "wall" | "entrance" | "large_scenery" | "banner"
/** This only exist to retrieve the types for existing corrupt elements. For hiding elements, use the isHidden field instead. */
| "openrct2_corrupt_deprecated";
type Direction = 0 | 1 | 2 | 3;
type TileElement =
SurfaceElement | FootpathElement | TrackElement | SmallSceneryElement | WallElement | EntranceElement
| LargeSceneryElement | BannerElement | CorruptElement;
interface BaseTileElement {
type: TileElementType;
baseHeight: number;
baseZ: number;
clearanceHeight: number;
clearanceZ: number;
occupiedQuadrants: number;
isGhost: boolean;
isHidden: boolean; /** Take caution when changing this field, it may invalidate TileElements you have stored in your script. */
}
interface SurfaceElement extends BaseTileElement {
type: "surface";
slope: number;
surfaceStyle: number;
edgeStyle: number;
waterHeight: number;
grassLength: number;
ownership: number;
parkFences: number;
readonly hasOwnership: boolean;
readonly hasConstructionRights: boolean;
}
interface FootpathElement extends BaseTileElement {
type: "footpath";
object: number;
surfaceObject: number;
railingsObject: number;
edges: number;
corners: number;
slopeDirection: number | null;
isBlockedByVehicle: boolean;
isWide: boolean;
isQueue: boolean;
queueBannerDirection: number | null;
ride: number | null;
station: number | null;
addition: number | null;
additionStatus: number | null;
isAdditionBroken: boolean | null;
isAdditionGhost: boolean | null;
}
interface TrackElement extends BaseTileElement {
type: "track";
direction: Direction;
trackType: number;
sequence: number | null;
mazeEntry: number | null;
colourScheme: number | null;
seatRotation: number | null;
ride: number;
station: number | null;
brakeBoosterSpeed: number | null;
hasChainLift: boolean;
isInverted: boolean;
hasCableLift: boolean;
}
interface SmallSceneryElement extends BaseTileElement {
type: "small_scenery";
direction: Direction;
object: number;
primaryColour: number;
secondaryColour: number;
quadrant: number;
age: number;
}
interface WallElement extends BaseTileElement {
type: "wall";
direction: Direction;
object: number;
primaryColour: number;
secondaryColour: number;
tertiaryColour: number;
bannerIndex: number | null;
slope: Direction;
}
interface EntranceElement extends BaseTileElement {
type: "entrance";
direction: Direction;
object: number;
ride: number;
station: number;
sequence: number;
footpathObject: number;
footpathSurfaceObject: number;
}
interface LargeSceneryElement extends BaseTileElement {
type: "large_scenery";
direction: Direction;
object: number;
primaryColour: number;
secondaryColour: number;
bannerIndex: number | null;
sequence: number;
}
interface BannerElement extends BaseTileElement {
type: "banner";
direction: Direction;
bannerIndex: number;
}
interface CorruptElement extends BaseTileElement {
type: "openrct2_corrupt_deprecated";
}
/**
* Represents a tile containing tile elements on the map. This is a fixed handle
* for a given tile position. It can be re-used safely between game ticks.
*/
interface Tile {
/** The x position in tiles. */
readonly x: number;
/** The y position in tiles. */
readonly y: number;
/** Gets an array of all the tile elements on this tile. */
readonly elements: TileElement[];
/** Gets the number of tile elements on this tile. */
readonly numElements: number;
/**
* Gets or sets the raw data for this tile.
* This can provide more control and efficiency for tile manipulation but requires
* knowledge of tile element structures and may change between versions of OpenRCT2.
*/
data: Uint8Array;
/** Gets the tile element at the given index on this tile. */
getElement(index: number): TileElement;
/** Gets the tile element at the given index on this tile. */
getElement<T extends TileElement>(index: number): T;
/** Inserts a new tile element at the given index on this tile. */
insertElement(index: number): TileElement;
/** Removes the tile element at the given index from this tile. */
removeElement(index: number): void;
}
/**
* Represents the definition of a loaded object (.DAT or .json) such a ride type or scenery item.
*/
interface LoadedObject {
/**
* The object type.
*/
readonly type: ObjectType;
/**
* The index of the loaded object for the object type.
*/
readonly index: number;
/**
* The unique identifier of the object, e.g. "rct2.burgb".
* Only JSON objects will have an identifier.
*/
readonly identifier: string;
/**
* The original unique identifier of the object, e.g. "BURGB ".
* This may have trailing spaces if the name is shorter than 8 characters.
* Only .DAT objects or JSON objects based on .DAT objects will have legacy identifiers.
*/
readonly legacyIdentifier: string;
/**
* The name in the user's current language.
*/
readonly name: string;
}
/**
* Represents the object definition of a ride or stall.
*/
interface RideObject extends LoadedObject {
/**
* The description of the ride / stall in the player's current language.
*/
readonly description: string;
/**
* A text description describing the capacity of the ride in the player's current language.
*/
readonly capacity: string;
readonly flags: number;
readonly rideType: number[];
readonly minCarsInTrain: number;
readonly maxCarsInTrain: number;
readonly carsPerFlatRide: number;
readonly zeroCars: number;
readonly tabVehicle: number;
readonly defaultVehicle: number;
readonly frontVehicle: number;
readonly secondVehicle: number;
readonly rearVehicle: number;
readonly thirdVehicle: number;
readonly vehicles: RideObjectVehicle[];
readonly excitementMultiplier: number;
readonly intensityMultiplier: number;
readonly nauseaMultiplier: number;
readonly maxHeight: number;
readonly shopItem: number;
readonly shopItemSecondary: number;
}
/**
* Represents a defined vehicle within a Ride object definition.
*/
interface RideObjectVehicle {
readonly rotationFrameMask: number;
readonly numVerticalFrames: number;
readonly numHorizontalFrames: number;
readonly spacing: number;
readonly carMass: number;
readonly tabHeight: number;
readonly numSeats: number;
readonly spriteFlags: number;
readonly spriteWidth: number;
readonly spriteHeightNegative: number;
readonly spriteHeightPositive: number;
readonly animation: number;
readonly flags: number;
readonly baseNumFrames: number;
readonly baseImageId: number;
readonly restraintImageId: number;
readonly gentleSlopeImageId: number;
readonly steepSlopeImageId: number;
readonly verticalSlopeImageId: number;
readonly diagonalSlopeImageId: number;
readonly bankedImageId: number;
readonly inlineTwistImageId: number;
readonly flatToGentleBankImageId: number;
readonly diagonalToGentleSlopeBankImageId: number;
readonly gentleSlopeToBankImageId: number;
readonly gentleSlopeBankTurnImageId: number;
readonly flatBankToGentleSlopeImageId: number;
readonly curvedLiftHillImageId: number;
readonly corkscrewImageId: number;
readonly noVehicleImages: number;
readonly noSeatingRows: number;
readonly spinningInertia: number;
readonly spinningFriction: number;
readonly frictionSoundId: number;
readonly logFlumeReverserVehicleType: number;
readonly soundRange: number;
readonly doubleSoundFrequency: number;
readonly poweredAcceleration: number;
readonly poweredMaxSpeed: number;
readonly carVisual: number;
readonly effectVisual: number;
readonly drawOrder: number;
readonly numVerticalFramesOverride: number;
}
/**
* Represents the object definition of a small scenery item such a tree.
*/
interface SmallSceneryObject extends LoadedObject {
/**
* Raw bit flags that describe characteristics of the scenery item.
*/
readonly flags: number;
/**
* The default clearance height of the scenery item.
*/
readonly height: number;
/**
* How much the scenery item costs to build.
*/
readonly price: number;
/**
* How much the scenery item costs to remove.
*/
readonly removalPrice: number;
}
/**
* Represents a ride or stall within the park.
*/
interface Ride {
/**
* The object metadata for this ride.
*/
readonly object: RideObject;
/**
* The unique ID / index of the ride.
*/
readonly id: number;
/**
* The type of the ride represented as the internal built-in ride type ID.
*/
type: number;
/**
* Whether the ride is a ride, shop or facility.
*/
readonly classification: RideClassification;
/**
* The generated or custom name of the ride.
*/
name: string;
/**
* Whether the ride is open, closed or testing.
*/
readonly status: RideStatus;
/**
* Various flags related to the operation of the ride.
*/
lifecycleFlags: number;
/**
* The operation mode.
*/
mode: number;
/**
* Flags related to how trains depart.
*/
departFlags: number;
/**
* The minimum time a train will wait at the station before departing.
*/
minimumWaitingTime: number;
/**
* The maximum time a train will wait at the station before departing.
*/
maximumWaitingTime: number;
/**
* The head vehicle IDs associated with the ride, one for each train.
*/
readonly vehicles: number[];
/**
* The colour for each vehicle when the ride opens. Modifying this directly will not
* change the colour of any currently running trains nor will it reflect them if they
* have been modified.
*/
vehicleColours: VehicleColour[];
/**
* The track colour schemes for the ride.
*/
colourSchemes: TrackColour[];
/**
* The style used for the station, entrance, and exit building.
*/
stationStyle: number;
/**
* The music track to play at each station.
*/
music: number;
/**
* Information about each station.
*/
readonly stations: RideStation[];
/**
* The admission price for the ride and the price of the on-ride photo, or the cost of each item of the stall.
*/
price: number[];
/**
* The excitement metric of the ride represented as a 2 decimal point fixed integer.
* For example, `652` equates to `6.52`.
*/
excitement: number;
/**
* The intensity metric of the ride represented as a 2 decimal point fixed integer.
* For example, `652` equates to `6.52`.
*/
intensity: number;
/**
* The nausea metric of the ride represented as a 2 decimal point fixed integer.
* For example, `652` equates to `6.52`.
*/
nausea: number;
/**
* The total number of customers the ride has served since it was built.
*/
totalCustomers: number;
/**
* The date in months when the ride was built.
* Subtract this from `date.monthsElapsed` to get the age.
*/
buildDate: number;
/**
* How old the ride is in months.
*/
readonly age: number;
/**
* The running cost of the ride billed every fortnight. Multiply this by 16 to get the cost per hour (~ 1 year).
*/
runningCost: number;
/**
* The total profit of the ride over the course of its lifetime.
*/
totalProfit: number;
/**
* How often the ride should be inspected by a mechanic.
*/
inspectionInterval: number;
/**
* The value of the ride.
*/
value: number;
/**
* The percentage of downtime for this ride from 0 to 100.
*/
readonly downtime: number;
}
type RideClassification = "ride" | "stall" | "facility";
type RideStatus = "closed" | "open" | "testing" | "simulating";
interface TrackColour {
main: number;
additional: number;
supports: number;
}
interface VehicleColour {
body: number;
trim: number;
ternary: number;
}
interface RideStation {
start: CoordsXYZ;
length: number;
entrance: CoordsXYZD;
exit: CoordsXYZD;
}
type EntityType =
"balloon" |
"car" |
"crash_splash" |
"crashed_vehicle_particle" |
"duck" |
"explosion_cloud" |
"explosion_flare" |
"jumping_fountain_snow" |
"jumping_fountain_water" |
"litter" |
"money_effect" |
"guest" |
"staff" |
"steam_particle" |
/**
* @deprecated since version 34, use guest or staff instead.
*/
"peep";
/**
* Represents an object "entity" on the map that can typically moves and has a sub-tile coordinate.
*/
interface Entity {
/**
* The entity index within the entity list.
*/
readonly id: number;
/**
* The type of entity, e.g. guest, vehicle, etc.
*/
readonly type: EntityType;
/**
* The x-coordinate of the entity in game units.
*/
x: number;
/**
* The y-coordinate of the entity in game units.
*/
y: number;
/**
* The z-coordinate of the entity in game units.
*/
z: number;
/**
* Removes the entity from the map.
* Note: removing vehicles and peeps that are on rides is currently unsupported.
*/
remove(): void;
}
/**
* Represents a single car on a ride. A train is made up of multiple cars, but
* something like boat hire will be one car per boat.
*/
interface Car extends Entity {
/**
* The ride this car belongs to.
*/
ride: number;
/**
* The ride object for this car, e.g. the ladybird trains object.
*/
rideObject: number;
/**
* The vehicle type for the ride object used. This is a local index
* into the ride object list of vehicle types.
*/
vehicleObject: number;
spriteType: number;
/**
* How many seats the car has, i.e. the capacity.
*/
numSeats: number;
/**
* The next car on the same train. If this is the last or only car on the train,
* this will return null.
*/
nextCarOnTrain: number | null;
/**
* The previous car on the ride. This may be the on the same train or the previous
* train. This will point to the last car if this is the first car on the ride.
*/
previousCarOnRide: number;
/**
* The next car on the ride. This may be the on the same train or the next
* train. This will point to the first car if this is the last car on the ride.
*/
nextCarOnRide: number;
/**
* The current station the train is in or departing.
*/
currentStation: number;
/**
* How heavy the car is. This is the sum of the mass of the empty car and the
* mass of each guest that is riding it.
*/
mass: number;
/**
* How much the car's velocity changes per tick.
*/
acceleration: number;
/**
* How fast the car is moving.
*/
velocity: number;
/**
* The current tilt of the car in the X/Y axis.
*/
bankRotation: number;
/**
* The colour of the car.
*/
colours: VehicleColour;
/**
* The acceleration for vehicles with constant power, e.g.
* transport rides and boats.
*/
poweredAcceleration: number;
/**
* The maximum speed for vehicles with constant power, e.g.
* transport rides and boats.
*/
poweredMaxSpeed: number;
/**
* Current status of the car or train.
*/
status: VehicleStatus;
/**
* The location and direction of where the car is on the track.
*/
trackLocation: CoordsXYZD;
/**
* The current g-forces of this car.
*/
readonly gForces: GForces;
/**
* The progress on the current track piece, in steps.
*/
readonly trackProgress: number;
/**
* The currently projected remaining distance the car will travel.
*/
readonly remainingDistance: number;
/**
* List of guest IDs ordered by seat.
* @deprecated since version 34, use guests instead.
*/
peeps: Array<number | null>;
/**
* List of guest IDs ordered by seat.
*/
guests: Array<number | null>;
/**
* Moves the vehicle forward or backwards along the track, relative to its current
* position. A single visible step is about 8.000 to 14.000 in distance depending
* on the direction its moving in.
*/
travelBy(distance: number): void;
}
type VehicleStatus =
"arriving" |
"crashed" |
"crashing" |
"crooked_house_operating" |
"departing" |
"doing_circus_show" |
"ferris_wheel_rotating" |
"haunted_house_operating" |
"moving_to_end_of_station" |
"operating_1a" |
"rotating" |
"showing_film" |
"simulator_operating" |
"space_rings_operating" |
"starting" |
"stopped_by_block_brake" |
"stopping_1b" |
"stopping" |
"swinging" |
"top_spin_operating" |
"travelling_boat" |
"travelling_cable_lift" |
"travelling_dodgems" |
"travelling" |
"unloading_passengers_1c" |
"unloading_passengers" |
"waiting_for_cable_lift" |
"waiting_for_passengers_17" |
"waiting_for_passengers" |
"waiting_to_depart" |
"waiting_to_start";
/**
* Represents a guest or staff member.
* @deprecated since version 34, use guest or staff instead.
*/
interface Peep extends Entity {
/**
* Whether the peep is a guest or staff member.
*/
peepType: PeepType;
/**
* Name of the peep.
*/
name: string;
/**
* The peep's direct destination.
*/
destination: CoordsXY;
/**
* How tired the guest is between 32 and 128 where lower is more tired.
*/
energy: number;
/**
* The target energy value. Energy will increase / decrease slowly towards this value.
*/
energyTarget: number;
/**
* Gets whether a given flag is set or not.
* @param key The flag to test.
*/
getFlag(key: PeepFlags): boolean;
/**
* Sets the given flag to the given value.
* @param key The flag to set.
* @param value Whether to set or clear the flag.
*/
setFlag(key: PeepFlags, value: boolean): void;
}
type PeepFlags =
"leavingPark" |
"slowWalk" |
"tracking" |
"waving" |
"hasPaidForParkEntry" |
"photo" |
"painting" |
"wow" |
"litter" |
"lost" |
"hunger" |
"toilet" |
"crowded" |
"happiness" |
"nausea" |
"purple" |
"pizza" |
"explode" |
"rideShouldBeMarkedAsFavourite" |
"parkEntranceChosen" |
"contagious" |
"joy" |
"angry" |
"iceCream" |
"hereWeAre";
/**
* @deprecated since version 34, use EntityType instead.
*/
type PeepType = "guest" | "staff";
/**
* Represents a guest.
*/
interface Guest extends Peep {
/**
* Colour of the guest's t-shirt.
*/
tshirtColour: number;
/**
* Colour of the guest's trousers.
*/
trousersColour: number;
/**
* Colour of the guest's balloon.
*/
balloonColour: number;
/**
* Colour of the guest's hat.
*/
hatColour: number;
/**
* Colour of the guest's umbrella.
*/
umbrellaColour: number;
/**
* How happy the guest is between 0 and 255.
*/
happiness: number;
/**
* The target happiness value. Happiness will increase / decrease slowly towards this value.
*/
happinessTarget: number;
/**
* How nauseated the guest is between 0 and 255.
*/
nausea: number;
/**
* The target nausea value. Nausea will increase / decrease slowly towards this value.
*/
nauseaTarget: number;
/**
* How hungry the guest is between 0 and 255. Lower is more hungry.
*/
hunger: number;
/**
* How thirsty the guest is between 0 and 255. Lower is more thirsty.
*/
thirst: number;
/**
* How much the guest requires the need to go to the toilet between 0 and 255.
*/
toilet: number;
/**
* The mass of the guest. Affects vehicle mass.
*/
mass: number;
/**
* The guest's minimum preferred intensity between 0 and 15.
*/
minIntensity: number;
/**
* The guest's maximum preferred intensity between 0 and 15.
*/
maxIntensity: number;
/**
* The guest's tolerance to nauseating rides between 0 and 3.
*/
nauseaTolerance: number;
/**
* Amount of cash in the guest's pocket.
*/
cash: number;
/**
* Whether the guest is within the boundaries of the park.
*/
readonly isInPark: boolean;
/**
* Whether the guest is lost or not. The guest is lost when the countdown is below 90.
*/
readonly isLost: boolean;
/**
* Countdown between 0 and 255 that keeps track of how long the guest has been looking for its current destination.
*/
lostCountdown: number;
}
/**
* Represents a staff member.
*/
interface Staff extends Peep {
/**
* The type of staff member, e.g. handyman, mechanic.
*/
staffType: StaffType;
/**
* Colour of the staff member. Not applicable for entertainers.
*/
colour: number;
/**
* The entertainer's costume, only applicable for entertainers.
*/
costume: number;
/**
* The enabled jobs the staff can do, e.g. sweep litter, water plants, inspect rides etc.
*/
orders: number;
}
type StaffType = "handyman" | "mechanic" | "security" | "entertainer";
/**
* Represents litter entity.
*/
interface Litter extends Entity {
/**
* The type of the litter.
*/
litterType: LitterType;
/**
* The tick number this entity was created.
*/
creationTick: number;
}
type LitterType = "vomit" |
"vomit_alt" |
"empty_can" |
"rubbish" |
"burger_box" |
"empty_cup" |
"empty_box" |
"empty_bottle" |
"empty_bowl_red" |
"empty_drink_carton" |
"empty_juice_cup" |
"empty_bowl_blue";
/**
* Network APIs
* Use `network.status` to determine whether the current game is a client, server or in single player mode.
*/
interface Network {
readonly mode: NetworkMode;
readonly numGroups: number;
readonly numPlayers: number;
readonly groups: PlayerGroup[];
readonly players: Player[];
readonly currentPlayer: Player;
defaultGroup: number;
readonly stats: NetworkStats;
getServerInfo(): ServerInfo;
addGroup(): void;
getGroup(index: number): PlayerGroup;
removeGroup(index: number): void;
getPlayer(index: number): Player;
kickPlayer(index: number): void;
sendMessage(message: string): void;
sendMessage(message: string, players: number[]): void;
createListener(): Listener;
createSocket(): Socket;
}
type NetworkMode = "none" | "server" | "client";
/**
* Represents a player within a network game.
*/
interface Player {
readonly id: number;
readonly name: string;
group: number;
readonly ping: number;
readonly commandsRan: number;
readonly moneySpent: number;
readonly ipAddress: string;
readonly publicKeyHash: string;
}
interface PlayerGroup {
readonly id: number;
name: string;
permissions: PermissionType[];
}
interface ServerInfo {
readonly name: string;
readonly description: string;
readonly greeting: string;
readonly providerName: string;
readonly providerEmail: string;
readonly providerWebsite: string;
}
interface NetworkStats {
bytesReceived: number[];
bytesSent: number[];
}
type PermissionType =
"chat" |
"terraform" |
"set_water_level" |
"toggle_pause" |
"create_ride" |
"remove_ride" |
"build_ride" |
"ride_properties" |
"scenery" |
"path" |
"clear_landscape" |
"guest" |
"staff" |
"park_properties" |
"park_funding" |
"kick_player" |
"modify_groups" |
"set_player_group" |
"cheat" |
"toggle_scenery_cluster" |
"passwordless_login" |
"modify_tile" |
"edit_scenario_options";
/**
* Park APIs
*/
/**
* The type of park message, including icon and behaviour.
*/
type ParkMessageType =
"attraction" | "peep_on_attraction" | "peep" | "money" | "blank" | "research" | "guests" | "award" | "chart";
interface ParkMessage {
/**
* Whether the message has been shown and archived.
*/
readonly isArchived: boolean;
/**
* The date this message was posted in total elapsed months.
*/
month: number;
/**
* The day of the month this message was posted.
*/
day: number;
/**
* How old the message is in number of ticks.
*/
tickCount: number;
/**
* The format of the message such as the icon and whether location is enabled.
*/
type: ParkMessageType;
/**
* The actual message content.
*/
text: string;
/**
* Ride ID for attraction.
* Entity ID for peep_on_attraction or peep.
* Researched item for research.
*/
subject?: number;
/**
* Removes the message.
*/
remove(): void;
}
interface ParkMessageDesc {
type: ParkMessageType;
text: string;
subject?: number;
}
type ParkFlags =
"difficultGuestGeneration" |
"difficultParkRating" |
"forbidHighConstruction" |
"forbidLandscapeChanges" |
"forbidMarketingCampaigns" |
"forbidTreeRemoval" |
"freeParkEntry" |
"noMoney" |
"open" |
"preferLessIntenseRides" |
"preferMoreIntenseRides" |
"scenarioCompleteNameInput" |
"unlockAllPrices";
interface Park {
cash: number;
rating: number;
bankLoan: number;
maxBankLoan: number;
/**
* The current entrance fee for the park.
*/
entranceFee: number;
/**
* The number of guests within the park, not including any outside the park but still
* on the map.
*/
readonly guests: number;
/**
* The maximum number of guests that will spawn naturally (soft guest cap).
* In scenarios with difficult guest generation, guests will not spawn above
* this value without advertisements.
*/
readonly suggestedGuestMaximum: number;
/**
* The probability out of 65535 that guests will spawn per tick.
* The number of guest spawns per second is equal to
* guests per second = 40 * (guestGenerationProbability / 65535)
*/
readonly guestGenerationProbability: number;
/**
* The average amount of cash guests will spawn with.
*/
readonly guestInitialCash: number;
/**
* The average happiness guests will spawn at out of 255.
*/
readonly guestInitialHappiness: number;
/**
* The average hunger guests will spawn at out of 255.
*/
readonly guestInitialHunger: number;
/**
* The average thirst guests will spawn at out of 255.
*/
readonly guestInitialThirst: number;
/**
* The park value, will be updated every 512 ticks.
*/
value: number;
/**
* The company value, will be updated every 512 ticks.
* Calculation is: `park.value + park.cash - park.bankLoan`
*/
companyValue: number;
/**
* The sum of ride values, used to determine the most guests will
* pay to enter the park and for some awards.
* Calculated as the sum of (ride value - ride price) * 2.
*/
readonly totalRideValueForMoney: number;
/**
* The total number of guests that have entered the park.
*/
totalAdmissions: number;
/**
* The total amount of income gained from admissions into the park.
*/
totalIncomeFromAdmissions: number;
/**
* The purchase price of one tile for park ownership.
*/
landPrice: number;
/**
* The purchase price of one tile for construction rights.
*/
constructionRightsPrice: number;
/**
* The amount of penalty points currentlty applied to the park rating for
* drowned guests and crashed coaster cars.
*/
casualtyPenalty: number;
/**
* The number of tiles on the map with park ownership or construction rights.
* Updated every 4096 ticks.
*/
readonly parkSize: number;
name: string;
messages: ParkMessage[];
/**
* Gets whether a given flag is set or not.
* @param key The flag to test.
*/
getFlag(flag: ParkFlags): boolean;
/**
* Sets the given flag to the given value.
* @param key The flag to set.
* @param value Whether to set or clear the flag.
*/
setFlag(flag: ParkFlags, value: boolean): void;
postMessage(message: string): void;
postMessage(message: ParkMessageDesc): void;
}
type ScenarioObjectiveType =
"none" |
"guestsBy" |
"parkValueBy" |
"haveFun" |
"buildTheBest" |
"10Rollercoasters" |
"guestsAndRating" |
"monthlyRideIncome" |
"10RollercoastersLength" |
"finish5Rollercoasters" |
"repayLoanAndParkValue" |
"monthlyFoodIncome";
interface ScenarioObjective {
/**
* The objective type.
*/
type: ScenarioObjective;
/**
* The required number of guests.
*/
guests: number;
/**
* The year the objective must be completed by the end of.
*/
year: number;
/**
* The minimum length required for each rollercoaster.
*/
length: number;
/**
* The minimum excitement rating required for each rollercoaster.
*/
excitement: number;
/**
* The minimum park value required.
*/
parkValue: number;
/**
* The minimum monthly income from rides / food.
*/
monthlyIncome: number;
}
type ScenarioStatus = "inProgress" | "completed" | "failed";
interface Scenario {
/**
* The name of the scenario. This is not necessarily the name of the park.
*/
name: string;
/**
* The description of the scenario, shown above the scenario objective.
*/
details: string;
/**
* The entered player name if the scenario is complete.
*/
completedBy: string;
/**
* The filename of the scenario that is being played. Used to match the
* completion score with the scenario file.
*/
filename: string;
/**
* The criteria required to complete the scenario.
*/
objective: ScenarioObjective;
/**
* The number of consecutive days the park rating has been under the threshold for.
* This is reset when the park rating rises above the threshold again.
* Also used to post warning messages.
*/
parkRatingWarningDays: number;
/**
* The company value when the scenario was completed.
*/
completedCompanyValue?: number;
/**
* The current status of the scenario.
*/
status: ScenarioStatus;
/**
* The current highest recorded company value.
*/
companyValueRecord: number;
}
type ClimateType =
"coolAndWet" |
"warm" |
"hotAndDry" |
"cold";
type WeatherType =
"sunny" |
"partiallyCloudy" |
"cloudy" |
"rain" |
"heavyRain" |
"thunder" |
"snow" |
"heavySnow" |
"blizzard";
interface ClimateState {
readonly weather: WeatherType;
readonly temperature: number;
}
interface Climate {
/**
* The climate of the park.
*/
readonly type: ClimateType;
/**
* The current weather in the park.
*/
readonly current: ClimateState;
/**
* The next weather the park will experience.
*/
readonly future: ClimateState;
}
interface Cheats {
allowArbitraryRideTypeChanges: boolean;
allowTrackPlaceInvalidHeights: boolean;
buildInPauseMode: boolean;
disableAllBreakdowns: boolean;
disableBrakesFailure: boolean;
disableClearanceChecks: boolean;
disableLittering: boolean;
disablePlantAging: boolean;
disableRideValueAging: boolean;
disableSupportLimits: boolean;
disableTrainLengthLimit: boolean;
disableVandalism: boolean;
enableAllDrawableTrackPieces: boolean;
enableChainLiftOnAllTrack: boolean;
fastLiftHill: boolean;
freezeWeather: boolean;
ignoreResearchStatus: boolean;
ignoreRideIntensity: boolean;
neverendingMarketing: boolean;
sandboxMode: boolean;
showAllOperatingModes: boolean;
showVehiclesFromOtherTrackTypes: boolean;
}
/**
* User Interface APIs
* These will only be available to servers and clients that are not running headless mode.
* Plugin writers should check if ui is available using `typeof ui !== 'undefined'`.
*/
interface Ui {
readonly width: number;
readonly height: number;
readonly windows: number;
readonly mainViewport: Viewport;
readonly tileSelection: TileSelection;
readonly tool: Tool | null;
getWindow(id: number): Window;
getWindow(classification: string): Window;
openWindow(desc: WindowDesc): Window;
closeWindows(classification: string, id?: number): void;
closeAllWindows(): void;
/**
* Show a red error box.
* @param title The title / first line of the box.
* @param message The message / second line of the box.
*/
showError(title: string, message: string): void;
/**
* Shows a text input prompt and calls the given callback when entered.
* @param desc The parameters for the text input window.
*/
showTextInput(desc: TextInputDesc): void;
/**
* Shows the window for loading or saving a file and calls the given callback when a file
* is selected.
* @param desc The parameters for the file browse window.
*/
showFileBrowse(desc: FileBrowseDesc): void;
/**
* Shows the scenario select window and calls the given callback when a scenario is
* selected.
*/
showScenarioSelect(desc: ScenarioSelectDesc): void;
/**
* Begins a new tool session. The cursor will change to the style specified by the
* given tool descriptor and cursor events will be provided.
* @param tool The properties and event handlers for the tool.
*/
activateTool(tool: ToolDesc): void;
registerMenuItem(text: string, callback: () => void): void;
registerShortcut(desc: ShortcutDesc): void;
}
/**
* Parameters for the text input window.
*/
interface TextInputDesc {
/**
* The title of the text input window.
*/
title: string;
/**
* The description to show above the text box.
*/
description: string;
/**
* The current value of the text box.
*/
initialValue?: string;
/**
* The maximum length the value can be.
*/
maxLength?: number;
/**
* The function to call when the user has entered a new value and pressed OK.
*/
callback: (value: string) => void;
}
/**
* Parameters for the file browse window.
*/
interface FileBrowseDesc {
/**
* Whether to browse a file for loading or saving. Saving will prompt the user
* before overwriting a file.
*/
type: "load";
/**
* The type of file to browse for.
*/
fileType: "game" | "heightmap";
/**
* The pre-selected file to load by default if the user clicks OK.
*/
defaultPath?: string;
/**
* The function to call when the user has selected a file.
*/
callback: (path: string) => void;
}
/**
* Parameters for the scenario select window.
*/
interface ScenarioSelectDesc {
/**
* The function to call when the user has selected a scenario.
*/
callback: (scenario: ScenarioFile) => void;
}
/**
* Represents an installed scenario's path and metadata.
*/
interface ScenarioFile {
id: number;
category: "beginner" | "challenging" | "expert" | "real" | "other" | "dlc" | "build_your_own";
sourceGame: "rct1" | "rct1_aa" | "rct1_ll" | "rct2" | "rct2_ww" | "rct2_tt" | "real" | "other";
path: string;
internalName: string;
name: string;
details: string;
highscore: {
name: string;
companyValue: number;
};
}
interface TileSelection {
range: MapRange;
tiles: CoordsXY[];
}
interface Tool {
id: string;
cursor: CursorType;
cancel: () => void;
}
interface ToolEventArgs {
readonly isDown: boolean;
readonly screenCoords: ScreenCoordsXY;
readonly mapCoords?: CoordsXYZ;
readonly tileElementIndex?: number;
readonly entityId?: number;
}
/**
* Describes the properties and event handlers for a custom tool.
*/
interface ToolDesc {
id: string;
cursor?: CursorType;
/**
* What types of object in the game can be selected with the tool.
* E.g. only specify terrain if you only want a tile selection.
*/
filter?: ToolFilter[];
onStart?: () => void;
onDown?: (e: ToolEventArgs) => void;
onMove?: (e: ToolEventArgs) => void;
onUp?: (e: ToolEventArgs) => void;
onFinish?: () => void;
}
type CursorType =
"arrow" |
"bench_down" |
"bin_down" |
"blank" |
"cross_hair" |
"diagonal_arrows" |
"dig_down" |
"entrance_down" |
"fence_down" |
"flower_down" |
"fountain_down" |
"hand_closed" |
"hand_open" |
"hand_point" |
"house_down" |
"lamppost_down" |
"paint_down" |
"path_down" |
"picker" |
"statue_down" |
"tree_down" |
"up_arrow" |
"up_down_arrow" |
"volcano_down" |
"walk_down" |
"water_down" |
"zzz";
type ToolFilter =
"terrain" |
"entity" |
"ride" |
"water" |
"scenery" |
"footpath" |
"footpath_item" |
"park_entrance" |
"wall" |
"large_scenery" |
"label" |
"banner";
interface ShortcutDesc {
/**
* The unique identifier for the shortcut.
* If the identifier already exists, the shortcut will not be registered.
* Use full stops to group shortcuts together, e.g. `yourplugin.somewindow.apply`.
*/
id: string;
/**
* The display text for the shortcut.
*/
text: string;
/**
* Default bindings for the shortcut.
* E.g. `["CTRL+SHIFT+L", "MOUSE 3"]`
*/
bindings?: string[];
/**
* Function to call when the shortcut is invoked.
*/
callback: () => void;
}
/**
* Represents the type of a widget, e.g. button or label.
*/
type WidgetType =
"button" | "checkbox" | "colourpicker" | "custom" | "dropdown" | "groupbox" |
"label" | "listview" | "spinner" | "textbox" | "viewport";
type Widget =
ButtonWidget | CheckboxWidget | ColourPickerWidget | CustomWidget | DropdownWidget | GroupBoxWidget |
LabelWidget | ListViewWidget | SpinnerWidget | TextBoxWidget | ViewportWidget;
interface WidgetBase {
readonly window?: Window;
type: WidgetType;
x: number;
y: number;
width: number;
height: number;
name?: string;
tooltip?: string;
isDisabled?: boolean;
isVisible?: boolean;
}
interface ButtonWidget extends WidgetBase {
type: "button";
/**
* Whether the button has a 3D border.
* By default, text buttons have borders and image buttons do not but it can be overridden.
*/
border?: boolean;
image?: number;
isPressed?: boolean;
text?: string;
onClick?: () => void;
}
interface CheckboxWidget extends WidgetBase {
type: "checkbox";
text?: string;
isChecked?: boolean;
onChange?: (isChecked: boolean) => void;
}
interface ColourPickerWidget extends WidgetBase {
type: "colourpicker";
colour?: number;
onChange?: (colour: number) => void;
}
interface CustomWidget extends WidgetBase {
type: "custom";
onDraw?: (this: CustomWidget, g: GraphicsContext) => void;
}
interface DropdownWidget extends WidgetBase {
type: "dropdown";
items?: string[];
selectedIndex?: number;
onChange?: (index: number) => void;
}
interface GroupBoxWidget extends WidgetBase {
type: "groupbox";
}
interface LabelWidget extends WidgetBase {
type: "label";
text?: string;
textAlign?: TextAlignment;
onChange?: (index: number) => void;
}
type TextAlignment = "left" | "centred";
type SortOrder = "none" | "ascending" | "descending";
type ScrollbarType = "none" | "horizontal" | "vertical" | "both";
interface ListViewColumn {
canSort?: boolean;
sortOrder?: SortOrder;
header?: string;
headerTooltip?: string;
width?: number;
ratioWidth?: number;
minWidth?: number;
maxWidth?: number;
}
interface ListViewItemSeperator {
type: "seperator";
text?: string;
}
type ListViewItem = ListViewItemSeperator | string[];
interface RowColumn {
row: number;
column: number;
}
interface ListViewWidget extends WidgetBase {
type: "listview";
scrollbars?: ScrollbarType;
isStriped?: boolean;
showColumnHeaders?: boolean;
columns?: ListViewColumn[];
items?: string[] | ListViewItem[];
selectedCell?: RowColumn;
readonly highlightedCell?: RowColumn;
canSelect?: boolean;
onHighlight?: (item: number, column: number) => void;
onClick?: (item: number, column: number) => void;
}
interface SpinnerWidget extends WidgetBase {
type: "spinner";
text?: string;
onDecrement?: () => void;
onIncrement?: () => void;
onClick?: () => void;
}
interface TextBoxWidget extends WidgetBase {
type: "textbox";
text?: string;
maxLength?: number;
onChange?: (text: string) => void;
}
interface ViewportWidget extends WidgetBase {
type: "viewport";
viewport?: Viewport;
}
interface Window {
classification: number;
number: number;
x: number;
y: number;
width: number;
height: number;
minWidth: number;
maxWidth: number;
minHeight: number;
maxHeight: number;
isSticky: boolean;
colours: number[];
title: string;
widgets: Widget[];
tabIndex: number;
close(): void;
bringToFront(): void;
findWidget<T extends Widget>(name: string): T;
}
interface WindowDesc {
classification: string;
x?: number;
y?: number;
width: number;
height: number;
title: string;
id?: number;
minWidth?: number;
minHeight?: number;
maxWidth?: number;
maxHeight?: number;
widgets?: Widget[];
colours?: number[];
tabs?: WindowTabDesc[];
tabIndex?: number;
onClose?: () => void;
onUpdate?: () => void;
onTabChange?: () => void;
}
interface ImageAnimation {
frameBase: number;
frameCount?: number;
frameDuration?: number;
offset?: ScreenCoordsXY;
}
interface WindowTabDesc {
image: number | ImageAnimation;
widgets?: Widget[];
}
interface Viewport {
left: number;
top: number;
right: number;
bottom: number;
rotation: number;
zoom: number;
visibilityFlags: number;
getCentrePosition(): CoordsXY;
moveTo(position: CoordsXY | CoordsXYZ): void;
scrollTo(position: CoordsXY | CoordsXYZ): void;
}
/**
* API for drawing graphics.
*/
interface GraphicsContext {
colour: number | undefined;
secondaryColour: number | undefined;
ternaryColour: number | undefined;
stroke: number;
fill: number;
paletteId: number | undefined;
readonly width: number;
readonly height: number;
getImage(id: number): ImageInfo | undefined;
measureText(text: string): ScreenSize;
clear(): void;
clip(x: number, y: number, width: number, height: number): void;
box(x: number, y: number, width: number, height: number): void;
image(id: number, x: number, y: number): void;
line(x1: number, y1: number, x2: number, y2: number): void;
rect(x: number, y: number, width: number, height: number): void;
text(text: string, x: number, y: number): void;
well(x: number, y: number, width: number, height: number): void;
}
interface ImageInfo {
readonly id: number;
readonly offset: ScreenCoordsXY;
readonly width: number;
readonly height: number;
readonly isBMP: boolean;
readonly isRLE: boolean;
readonly isPalette: boolean;
readonly noZoom: boolean;
readonly nextZoomId: number | undefined;
}
/**
* Listens for incoming connections.
* Based on node.js net.Server, see https://nodejs.org/api/net.html for more information.
*/
interface Listener {
readonly listening: boolean;
listen(port: number, host?: string): Listener;
close(): Listener;
on(event: "connection", callback: (socket: Socket) => void): Listener;
off(event: "connection", callback: (socket: Socket) => void): Listener;
}
/**
* Represents a socket such as a TCP connection.
* Based on node.js net.Socket, see https://nodejs.org/api/net.html for more information.
*/
interface Socket {
connect(port: number, host: string, callback: Function): Socket;
destroy(error: object): Socket;
setNoDelay(noDelay: boolean): Socket;
end(data?: string): Socket;
write(data: string): boolean;
on(event: "close", callback: (hadError: boolean) => void): Socket;
on(event: "error", callback: (hadError: boolean) => void): Socket;
on(event: "data", callback: (data: string) => void): Socket;
off(event: "close", callback: (hadError: boolean) => void): Socket;
off(event: "error", callback: (hadError: boolean) => void): Socket;
off(event: "data", callback: (data: string) => void): Socket;
}
interface TitleSequence {
/**
* The name of the title sequence.
*/
name: string;
/**
* The full path of the title sequence.
*/
readonly path: string;
/**
* Whether the title sequence is a single file or directory.
*/
readonly isDirectory: boolean;
/**
* Whether or not the title sequence is read-only (e.g. a pre-installed sequence).
*/
readonly isReadOnly: boolean;
/**
* The parks stored within this title sequence.
*/
readonly parks: TitleSequencePark[];
/**
* The commands that describe how to play the title sequence.
*/
commands: TitleSequenceCommand[];
/**
* Whether the title sequence is currently playing.
*/
readonly isPlaying: boolean;
/**
* The current command the title sequence is on if playing.
*/
readonly position: number | null;
addPark(path: string, fileName: string): void;
/**
* Creates a new title sequence identical to this one.
* @param name The name of the new title sequence.
*/
clone(name: string): TitleSequence;
/**
* Deletes this title sequence from disc.
*/
delete(): void;
/**
* Play the title sequence.
*/
play(): void;
/**
* Seek to a specific command in the sequence.
* @param position The index of the command to seek to.
*/
seek(position: number): void;
/**
* Stops playing the title sequence.
*/
stop(): void;
}
interface TitleSequencePark {
/**
* The file name of the park.
*/
fileName: string;
/**
* Deletes this park from the title sequence.
*/
delete(): void;
/**
* Loads this park.
*/
load(): void;
}
type TitleSequenceCommandType =
"load" |
"loadsc" |
"location" |
"rotate" |
"zoom" |
"speed" |
"follow" |
"wait" |
"restart" |
"end";
interface LoadTitleSequenceCommand {
type: "load";
index: number;
}
interface LocationTitleSequenceCommand {
type: "location";
x: number;
y: number;
}
interface RotateTitleSequenceCommand {
type: "rotate";
rotations: number;
}
interface ZoomTitleSequenceCommand {
type: "zoom";
zoom: number;
}
interface FollowTitleSequenceCommand {
type: "follow";
id: number | null;
}
interface SpeedTitleSequenceCommand {
type: "speed";
speed: number;
}
interface WaitTitleSequenceCommand {
type: "wait";
duration: number;
}
interface LoadScenarioTitleSequenceCommand {
type: "loadsc";
scenario: string;
}
interface RestartTitleSequenceCommand {
type: "restart";
}
interface EndTitleSequenceCommand {
type: "end";
}
type TitleSequenceCommand =
LoadTitleSequenceCommand |
LocationTitleSequenceCommand |
RotateTitleSequenceCommand |
ZoomTitleSequenceCommand |
FollowTitleSequenceCommand |
SpeedTitleSequenceCommand |
WaitTitleSequenceCommand |
LoadScenarioTitleSequenceCommand |
RestartTitleSequenceCommand |
EndTitleSequenceCommand;
interface TitleSequenceManager {
/**
* Gets all the available title sequences.
*/
readonly titleSequences: TitleSequence[];
/**
* Creates a new blank title sequence.
* @param name The name of the title sequence.
*/
create(name: string): TitleSequence;
}
}