================================================================================
KILLING TIME: RESURRECTED Scripting Reference
================================================================================

v1.0 2024/09/12

================================================================================
Intro
================================================================================

The Killing Time scripting system, as with several other KEX Engine titles, is 
based on AngelScript. This document does not cover basic usage of the Angel-
Script scripting language; such documentation can be found here:

    https://www.angelcode.com/angelscript/sdk/docs/manual/doc_script.html
    
================================================================================
Typedefs
================================================================================

The following typedefs are natively defined:

typedef uint angle_t;
  An angle in Binary Angle Measurement representation (BAM), which evenly 
  divides 360 degrees across the full range of an unsigned 32-bit integer.

typedef int fixed_t;
  A fixed point number with a divisor of (1 << 16), or FRACUNIT (defined in 
  ktdef.txt)

typedef int HUDFFontHandle;
  Represents the handle to a FreeType font loaded through HUD global functions.

typedef int HUDTextureHandle;
  Represents the handle to a texture loaded through HUD global functions.

================================================================================
Global Properties
================================================================================

The following global variables are natively defined and are always available in
any scope:

Game g_game;
  The gameloop instance. Use to interact with high-level game logic.
  
MetricsDef g_metricsDef;
  Basic gameplay metrics defined in metrics.json
  
PlayerDef g_playerDef;
  Basic player-related metrics defined in player.json
  
Player g_player;
  The player.
  
kexTranslation g_cTranslation;
  Localization engine.
  
================================================================================
Callbacks and Entrypoints
================================================================================

The following AngelScript functions will be called by the game engine; most are
optional and are ignored if they do not exist in a script file.

void main()

  Called once immediately after script compilation. The engine is still
  initializing at this point so the actions that can be taken are limited. Data
  contained entirely in your scripts can be initialized but calls into game
  engine functions should not be made for the most part.

Scripted pickup items

  If a pickup item uses the PickupType::SCRIPTED type, then when the item is 
  collected, the named function will be invoked with the following call 
  signature:
  
  bool fn(Actor @special, Actor @toucher);
  * special is a handle to the item being collected
  * toucher is a handle to the actor doing the collecting (this will always be 
    the player's actor)

State action functions

  Every ActorState contains an "action" member (defined in states.json) which 
  gives the name of an action function to invoke. Depending on whether the state
  is used by an Actor or by a Weapon determines what call signature it should be
  defined with:
  
  Actors:
    void fn(Actor @actor);
    * actor is a handle to the Actor which is performing its state logic
    
  Weapons:
    void fn(Player @player, pspdef_t @psp);
    * player is a handle to the Player object (same as g_player)
    * psp is a handle to the psprite which is processing its action
  
void OnNewLevel()
  Called every time the game engine transitions to a new level. The level is 
  entirely loaded before this function is called, but no logic has been run yet.
  
void OnNewGame()
  Called every time a new game is started. This is the appropriate place to 
  reinitialize any serializable script variables to their game-initial values.
  
void OnSpawnSpecials()
  Called when the internal native function P_SpawnSpecials runs. This gives an
  opportunity to do additional spawning of static level specials.
  
void OnAfterSaveLoaded(bool userload)
  Called after a save game has been completely loaded. The level is prepared to 
  begin running. If userload is true, the game was loaded from the menu. If
  false, then this is a hub level transition within the same game.
  
LineActionReturn OnUseSpecialLine(Actor @actor, line_t @line, int side)
  Allows implementation of custom line specials. If defined, this is called for
  every special line that is used with the 'use' key.
  * actor is the Actor instance that is using the line
  * line is the linedef being used
  * side is the side of the line (0 or 1) on which the Actor is sitting
  The return value of this callback determines what the engine will do next. If
  instructed to return immediately, then nothing else will be done. Otherwise 
  any native action that exists for the special will execute as well.
  
LineActionReturn OnCrossSpecialLine(Actor @actor, line_t @line, int side)
  Allows implementation of custom line specials. If defined, this is called for
  every special line that is crossed by a moving object.
  * actor is the Actor instance that is crossing the line
  * line is the linedef being used
  * side is the side of the line (0 or 1) on which the Actor is sitting
  The return value of this callback determines what the engine will do next. If
  instructed to return immediately, then nothing else will be done. Otherwise 
  any native action that exists for the special will execute as well.
  
LineActionReturn OnShootSpecialLine(Actor @actor, line_t @line, int side)
  Allows implementation of custom line specials. If defined, this is called for
  every special line that is shot by an Actor.
  * actor is the Actor instance that is shooting the line
  * line is the linedef being used
  * side is the side of the line (0 or 1) on which the Actor is sitting
  The return value of this callback determines what the engine will do next. If
  instructed to return immediately, then nothing else will be done. Otherwise 
  any native action that exists for the special will execute as well.

void OnPlayerThink()
  Called from the native function Player::Think() immediately after all player 
  logic for the current gametic is run, once per tick.
  
void OnPlayerDeathThink()
  Called from the native function Player::DeathThink() immediately after all 
  player logic for the current gametic is run, once per tick. This callback only
  runs when the player is currently dead.

void OnPlayerReborn()
  Called when the player is reinitialized.
  
void P_SlotSelected(Player @player, uint slot)
  Called when a weapon selection slot is activated.
  
void P_SwapWeapon(Player @player, uint direction)
  Called when the next/previous weapon actions are activated.
  * direction is 0 if previous and 1 if next.
  
void P_GenocideBomb(fixed_t x, fixed_t y, fixed_t radius)
  Called when the player activates the pw_genocide powerup effect.
  
void P_SpawnSmoke(Actor @actor, fixed_t x, fixed_t y, fixed_t z,
                  fixed_t attackrange, int damage)
  Called when a smoke puff should be spawned due to impact of a tracer.
  
void P_SpawnBlood(Actor @shooter, Actor @actor, fixed_t x, fixed_t y,
                  fixed_t z, fixed_t attackrange, int damage)
  Called when blood should be spawned due to impact of a tracer.
  
void P_SpawnCrusherBlood(Actor @actor)
  Called when blood should be spawned because an Actor is crushed by a moving 
  sector.
  
void ScriptHUD_Render(bool hires)
  Called when the HUD should be rendered.
  
void ScriptHUD_Ticker()
  Called once per 60 Hz gametic for HUD logic.

================================================================================
Global Enumerations
================================================================================

The following global enum types are exposed to the scripting engine from native 
code:

// Describes the effect type of a pickup item defined in ActorInfo
enum PickupType {
  NONE,
  WEAPON,
  AMMO,
  POWERUP,
  HEALTH,
  DAMAGE,
  KEY,
  TESSOBJECT,
  SCRIPTED,
  NUMPICKUPTYPES
}

// Describes the blood type of an Actor as defined in ActorInfo
enum ActorBloodType {
  RED,
  SPARKS,
  GREEN,
  NONE
}

// Flags field to determine actor's "hi-res" or "3DO" behavior types;
// Note that TOGGLED cannot and should not be combined with USEALTSTATES
enum Actor3DOMode {
  NOTHING,
  TOGGLED,        // thing expects to be able to change directly to hi-res by appending "3DO/" to its sprites
  USEALTSTATES,   // thing expects its states to redirect via the "altstate" field when 3DO mode is enabled
  NOSCALEOFFSETS  // thing's offsets should not be scaled because they are already scaled in the JSON data
}

// Bit flags controlling basic Actor behaviors; specified in ActorInfo
enum ActorFlags {
  NOTHING,      // 0, defines no special behaviors
  SPECIAL,      // Actor can be picked up if it specifies a toucheffect
  SOLID,        // Actor is solid for clipping purposes
  SHOOTABLE,    // Actor can be hit by traces and take damaged
  NOSECTOR,     // Actor does not attach itself to its sector's thinglist
  NOBLOCKMAP,   // Actor does not attach to the blockmap
  AMBUSH,       // Actor looks around 360 degrees for targets and is "deaf" if sound propagation is enabled
  JUSTHIT,      // Actor has just taken damage
  JUSTATTACKED, // Actor has just attacked
  SPAWNCEILING, // Actor spawns at ceilingz - height
  NOGRAVITY,    // Actor is not subject to gravity
  DROPOFF,      // Actor can hang and pass over ledges
  PICKUP,       // Actor can collect special items (only works on player)
  NOCLIP,       // Actor has no clipping
  SLIDE,        // Actor slides against walls (only works on player)
  FLOAT,        // Actor is a flying monster
  TELEPORT,     // Actor is not clipped against most 2S lines and cannot activate specials
  MISSILE,      // Actor is a missile
  DROPPED,      // Actor was dropped by a dying enemy
  TRANSLUCENT,  // Actor has normal (fg + bg)/2 transluceny (will use alpha value)
  COUNTKILL,    // Actor is considered a monster
  CORPSE,       // Actor is a sliding corpse
  INFLOAT,      // Actor is currently floating to target z
  FIREDAMAGE,   // Actor does fire damage
  VIEWFACING,   // Activate alternate billboarding mode
  SKULLFLY,     // Actor is flying in the manner of a flaming skull from a certain 90's shooter
  MOVIE,        // Actor is playing a movie
  NOINFIGHTING, // Actor cannot infight with any other target 
  DONTDRAW,     // Actor never generates a vissprite
  BLENDADD,     // Actor uses saturating fg + bg translucency (uses alpha value)
  SQUASHABLE,   // Actor can be killed by touching it
  SPAWNRANDOMZ  // Actor spawns at random z between floorheight and 512 above floorheight
}

// Additional actor state bit flags because we ran out of ActorFlags :)
enum ActorFlags2 {
  NOTHING,         // 0, specifies no special behavior
  REMOVEONACTORS,  // When colliding with other actors as a missile, this actor is removed instead of dying
  HIRESADDBLEND,   // Like BLENDADD but only applies if monster is in hi-res mode
  DEMODISABLED,    // Actor will not spawn if Guerilla Games demo mode is enabled (dev flag, no use)
  HASHIBLOODTYPE,  // If set, then the game will consider the hibloodtype field in an actor when it is in 3DO mode
  DOOR,            // Actor generates a 3D door model
  ALWAYSRESPAWN,   // Actor respawns even outside of skill 5 or -respawn
  NORESPAWN,       // Actor never respawns regardless of skill or settings
  NOROTATIONS,     // Actor will not use rotations other than the first (1), even if provided
  KEEPNOGRAVITY,   // Actor keeps NOGRAVITY flag when dying
  HIRESKEEPNOGRAV, // As above but only if the monster is in 3DO mode when it dies
  WOKEUP,          // Actor has awakened at least once and held a valid target
  BURNED           // Actor converted into cinders due to dying to a fire attack
}

// Skill levels
enum skill_t {
  sk_easy,      // Double ammo, half damage
  sk_medium,    // Normal, more damage
  sk_hard,      // Normal, even more damage
  sk_ohgod,     // Enemies are fast, most damage
  sk_nightmare, // Enemies are fast and respawn, items respawn, most damage, double ammo
  NUMSKILLS
}

// Weapon ordinals; note that higher positive values are defined through weapons.json
enum weapontype_t {
  wp_nochange = -1, // When the value of Player::pendingweapon, no change is pending; not valid as an readyweapon
  wp_none     =  0  // No active weapon; a dummy weapon definition always exists at index 0
}

// Ammo type ordinals; note that higher positive values are defined through weapons.json
enum ammotype_t {
  am_noammo = 0  // A default ammo type which has infinite capacity
}

// Order of powerup definitions
enum powertype_t {
  pw_invisible,    // Invisibility + faster movement
  pw_showsecret,   // Secrets are visible on the automap
  pw_maxhealth,    // Increase player maxhealth to 200%
  pw_strength,     // Player does much greater melee damage
  pw_showmap,      // The entire map is temporarily revealed
  pw_gotammo,      // Player has infinite ammo for weapons which support it
  pw_showmonsters, // Reveal monster locations on the automap
  pw_recharge,     // Add one charge to all player's Winged Vessels (Tess Objects)
  pw_godmode,      // Player is invincible
  pw_genocide,     // Obliterates enemies using the P_GenocideBomb effect
  pw_showgoodies,  // Show item locations on the automap
  pw_divinehealth, // Give player 200% unrecoverable health
  pw_firefaster,   // Player's weapon state tics are divided by two
  pw_halfdamage,   // Player has "Scarab Armor" and takes 50% damage (stacks with skill reductions)
  pw_nofiredamage, // Player takes no damage from sources marked as ActorFlags::FIREDAMAGE
  pw_light,        // Light amplification effect
  NUMPOWERS
}

// The type of a predicate from a LockDef
enum LockPredicateType {
  ALL, // Player must have all keys listed in this predicate to unlock the door 
  ANY  // Player must have only one or more key(s) listed in this predicate to unlock the door
}

// Internal game actions in the Game class state machine
enum GameAction {
  NOTHING,   // No action is pending
  LOADLEVEL, // Load a level
  NEWGAME,   // Start a new game
  LOADGAME,  // Load a save game
  SAVEGAME,  // Save the game
  COMPLETED, // A level has been finished
  WORLDDONE, // The game is ready to move on to the next level
  GAMEWON,   // Player has finished the game entirely
  PLAYDEMO   // Does nothing because we didn't have time to implement it, sorry.
}

// States in the Game loop state machine
enum GameState {
  UNKNOWN, // Startup value, Game class is not initialized yet
  TITLE,   // Showing the title screen
  SETUP,   // In midst of setting up a level
  LEVEL,   // Playing a level
  CREDITS  // Displaying credits
}

// Sector bit flag values which control special internal behaviors
enum SectorFlags {
  NOTHING,    // 0, specifies no special behavior
  SKYCEILING  // Sector is using sky as its ceiling flat
}

// Linedef bit flag values which control special behaviors
enum LineFlags {
  NOTHING,       // 0, specifies no special behavior
  BLOCKING,      // Blocks all objects
  BLOCKMONSTERS, // Blocks monsters but not players
  TWOSIDED,      // Line has two sides; this is enforced for 2S lines
  DONTPEGTOP,    // Unpeg the upper texture
  DONTPEGBOTTOM, // Unpeg the bottom texture
  SECRET,        // Line does not display as special on automap
  SOUNDBLOCK,    // Blocks sound if sound propagation is enabled
  DONTDRAW,      // Never draws on automap except with cheats
  MAPPED         // Line is already revealed on the automap
}

// Describes the slope type of a linedef, determined at runtime from {dx, dy}
enum SlopeType {
  HORIZONTAL, // Line has dy == 0
  VERTICAL,   // Line has dx == 0
  POSITIVE,   // Positive slope (dy/dx > 0)
  NEGATIVE    // Negative slope (dy/dx < 0)
}

// Describes the portion of a sidedef being affected by a button animation
enum bwhere_e {
  top,    // The top texture 
  middle, // The middle texture
  bottom  // The bottom texture
}

// Actor flags as specified in the map via UDMF
enum MapThingFlags {
  NOTHING, // 0, no special behaviors
  SKILL1,  // Spawns on sk_easy
  SKILL2,  // Spawns on sk_medium
  SKILL3,  // Spawns on sk_hard
  SKILL4,  // Spawns on sk_ohgod
  SKILL5,  // Spawns on sk_nightmare
  AMBUSH,  // Sees 360 degrees, "deaf" if sound propagation is enabled
  SINGLE,  // Occurs in single-player mode
  DM,      // Supported for UDMF spec compat only, does nothing
  COOP     // Supported for UDMF spec compat only, does nothing
}

// The blending mode of a filter flash effect on the screen overlay
enum filterflash_e {
  NORM, // (fg + bg) / 2
  MUL,  // clipped fg * bg
  ADD,  // Saturated fg + bg
  SUB,  // clipped fg - bg
  COUNT // Max value
}

// Valid scopes for serializable script values
// Note that the only valid scope for ScriptThinkerHandle objects is 'LEVEL'!
enum ScriptValueScope {
  WORLD, // Script value object has world scope and keeps its value between levels
  LEVEL  // Script value is level-specific and is reinitialized for each map, keeps value between saves
}

// Internal ID value of achievements
enum AchievementId {
  Platinum,
  Vessels,
  Keys,
  Artifacts,
  AnkhKills,
  HedgeMaze,
  AllWeapons,
  DevRoom,
  Clowns,
  Duncan,
  Tess,
  Melee,
  Time,
  Bathhouse,
  Cartographer
  Total
}

// Hardcoded ednum values for ActorInfo
enum EditorNum {
  PLAYER1, // 1
  PLAYER2, // 2 - does nothing 
  PLAYER3, // 3 - does nothing 
  PLAYER4  // 4 - does nothing 
}

// Values for the Actor::movedir property
enum dirtype_t {
  EAST,
  NORTHEAST,
  NORTH,
  NORTHWEST,
  WEST,
  SOUTHWEST,
  SOUTH,
  SOUTHEAST,
  NODIR,
  NUMDIRS
}

// The type of hit a tracer has made as its last intercept
enum TraceHitType {
  NOTHING, // missed entirely (usually cannot happen, fired in the void?)
  THING,   // Actor
  LINE,    // Linedef
  DOOR     // Door actor's 3D hull
}

// Bitflags; controls player autoaiming behavior through the Actor::SpawnPlayerMissile method
enum AutoAimFlags {
  NORMAL,      // Controlled entirely by player autoaim setting
  NOVERTICAL,  // Never apply vertical autoaiming
  NOHORIZONTAL // Never apply horizontal autoaiming
}

// Return values for scripted line actions; controls what the game engine does next
enum LineActionReturn {
  HANDLED_TRUE,  // Return true immediatley to indicate the action was handled
  HANDLED_FALSE, // Return false immediately to indicate the action was not handled
  RUN_NATIVE     // Execute any native effect the line special has normally and return its result
}

// The type of action a ceiling thinker is carrying out 
enum ceiling_e {
  lowerToFloor,
  raiseToHighest,
  lowerAndCrush,
  crushAndRaise,
  fastCrushAndRaise,
  silentCrushAndRaise
}

// The type of action a vertical door thinker is carrying out
enum vldoor_e {
  normal,
  close30ThenOpen,
  close,
  open,
  raiseIn5Mins
}

// The type of action a floor thinker is carrying out 
enum floor_e {
  lowerFloor,
  lowerFloorToLowest,
  turboLower,
  raiseFloor,
  raiseFloorToNearest,
  raiseToTexture,
  lowerAndChange,
  raiseFloor24,
  raiseFloor24AndChange,
  raiseFloorCrush,
  donutRaise,
  lowerFloorCeilingToLowest,
  lowerFloorToExtraParm1,
  raiseFloorToExtraParm1,
  raiseFloorTurbo,
  raiseFloor512,
  buildStair
}

// The type of action a stairs thinker is performing
enum stair_e {
  build8,
  turbo16
}

// Result of a moving plane operation (floor or ceiling)
enum result_e {
  ok,      // everything is nominal
  crushed, // an Actor did not fit as a result of the movement
  pastdest // moved to or beyond destination
}

// Path traversal operation bit flag options
enum PTFlags {
  NOTHING,   // 0, specifies no effect
  EARLYOUT,  // stop iterating as soon as something is blocking
  ADDLINES,  // consider linedefs
  ADDTHINGS, // consider Actors
  ADDDOORS   // consider Door actor 3D hulls
}

// The type of action a plat thinker is carrying out
enum plattype_e {
  perpetualRaise,
  downWaitUpStay,
  raiseAndChange,
  raiseToNearestAndChange
}

// The current state of a plat thinker
enum plat_e {
  up,
  down,
  waiting,
  in_stasis
}

// Player states
enum PlayerState {
  LIVE,
  DEAD,
  REBORN
}

// Player cheats, bit flags
enum PlayerCheats {
  NOTHING,    // 0, no cheats active
  NOCLIP,     // No clipping mode 
  GODMODE,    // Absolute invincibility
  NOMOMENTUM, // "Rubber boots" mode, no sliding
  DEMIGOD,    // Playtester mode, take damage but never dies
  INFPOWERUP, // Powerup time durations never decrement
  RATSMODE,   // Enemies become tiny and can be stomped
  ALLMAP,     // Reveal the full automap
  USEDCHEATS  // Player has used one or more cheats historically
}

// Indexes into the player's psprites array 
enum PspriteNum {
  WEAPON, // The normal core weapon sprites
  FLASH,  // Flash graphic
  SHELL,  // Ejected shell graphic 1
  SHELL2, // Secondary ejected shell graphic
  NUMPSPRITES
}

// Internal order of Winged Vessels inventory
enum TessObjects {
  Invisible,
  ShowSecrets,
  MaxHealth,
  Strength,
  ShowMap,
  GotAmmo,
  ShowMonsters,
  Recharge,
  GodMode,
  Genocide,
  ShowGoodies,
  LAST = ShowGoodies + 1,
  FIRST = 0
}

// The priority assigned when giving the player a message
enum PlayerMsgPriority {
  NORMAL, // White, 3rd row at most
  HIGHER, // Yellow, 2nd row at most
  HIGHEST // Purple, 1st row always
}

// Input actions recorded in the PlayerCmd object
enum inputActions_e {
  IA_INVALID, // not a real value
  IA_FORWARD,
  IA_BACKWARD,
  IA_STRAFE_LEFT,
  IA_STRAFE_RIGHT,
  IA_TURN_LEFT,
  IA_TURN_RIGHT,
  IA_LOOK_UP,
  IA_LOOK_DOWN,
  IA_CENTER_VIEW,
  IA_RUN,
  IA_JUMP,
  IA_CROUCH,
  IA_USE,
  IA_ATTACK,
  IA_NEXT_WEAPON,
  IA_PREV_WEAPON,
  IA_AUTOMAP,
  IA_ZOOM_IN,
  IA_ZOOM_OUT,
  IA_PAUSE,
  IA_FOLLOW,
  IA_INVENTORY_PREV,
  IA_INVENTORY_NEXT,
  IA_INVENTORY_USE,
  IA_SLOT0,
  IA_SLOT1,
  IA_SLOT2,
  IA_SLOT3,
  IA_SLOT4,
  IA_SLOT5,
  IA_SLOT6,
  IA_SLOT7,
  IA_SLOT8,
  IA_SLOT9,
  LASTBUTTONACTION = 21,
  LASTINPUTACTION  = 34,
  NUMBUTTONACTIONS = 22,
  NUMINPUTACTIONS  = 35
}

// Button cmds as recorded in the PlayerCmd object
enum buttonCmd_e {
  BC_NONE,
  BC_FORWARD,
  BC_BACKWARD,
  BC_STRAFE_LEFT,
  BC_STRAFE_RIGHT,
  BC_TURN_LEFT,
  BC_TURN_RIGHT, 
  BC_LOOK_UP,
  BC_LOOK_DOWN,
  BC_CENTER_VIEW,
  BC_STRAFE_MODE,
  BC_RUN,
  BC_JUMP,
  BC_CROUCH,
  BC_USE,
  BC_ATTACK,
  BC_NEXT_WEAPON,
  BC_PREV_WEAPON,
  BC_AUTOMAP,
  BC_ZOOM_IN,
  BC_ZOOM_OUT,
  BC_PAUSE,
  BC_FOLLOW,
  BC_SAVEGAME
}

// Positioning of a tactile event
enum TactilePosition {
  LEFT,
  RIGHT,
  CENTER
}

// Channel of a tactile event 
enum TactileChannel {
  VOICE,
  BODY,
  WEAPON
}

// Argument for starting special music
enum SpecialMusic {
  Menu,
  Credits
}

// Argument to native HUD functions for drawing text
enum textalignment_e {
  left,
  center,
  right
}

================================================================================
Classes
================================================================================

The following class types are exposed to the scripting engine from native code:

//
// Defines a drop type as defined in ActorInfo
//
class ActorDropType {
  kStr item;   // Name of ActorInfo to drop
  uint chance; // Chance out of 255 to select this item
  bool isBad;  // If true, this is a "bad" type of item and can be toggled off
}

//
// Defines a null pickup item with no effect 
//
class NoneEffect { /* Has no properties or methods */ }

//
// Defines a weapon pickup effect
//
class WeaponEffect {
  kStr strWeapon;    // Name of weapon definition from weapons.json
  uint weapon;       // Runtime-resolved index of weapon to give
  bool alwayspickup; // If true, player takes the weapon even if already owned
}

//
// Defines an ammo pickup effect
//
class AmmoEffect {
  kStr strAmmo;       // Name of ammo definition from weapons.json
  uint ammo;          // Runtime-resolved index of ammo to give
  kStr strGiveWeapon; // If not empty, name of weapon to give along with ammo
  uint giveweapon;    // Runtime-resolved index of weapon to give, or 0
  
  // Returns amount of ammo to give for a given skill level
  int GetAmount(uint skill) const;
}

//
// Defines a powerup pickup effect
//
class PowerupEffect {
  powertype_t power; // Enum value of power to give player
}

//
// Defines a health pickup effect
//
class HealthEffect {
  uint amount; // Amount of health to give
  bool maxout; // If true, given health is capped to player maxhealth
}

//
// Defines a damage pickup effect
//
class DamageEffect {
  uint damage; // Amount of damage to inflict
}

//
// Defines a key pickup effect
//
class KeyEffect { / *No properties or methods */}

//
// Defines a Winged Vessel pickup effect 
//
class TessObjectEffect {
  uint tessEffect; // TessObjects enum value
}

//
// Defines a scripted pickup effect
// "fn" must define the name of an AngelScript function to call with the following signature:
//
//   bool fn(Actor @special, Actor @toucher)
//
// If this function exists with the proper signature, it will be invoked when the
// "toucher" Actor has touched an Actor "special" which specifies this pickup effect in its
// ActorInfo definition.
//
class ScriptedEffect {
  kStr fn; // Name of AngelScript callback function to invoke
}

// Runtime instantiation of an ActorInfo toucheffect specification
class ActorTouchEffect {
  PickupType type;       // Enum value specifying the type of touch effect
  kStr       sound;      // Sound effect played when collected if non-empty
  kStr       tacile;     // Tactile effect invoked when collected if non-empty
  kStr       message;    // Message to give (or localization token of message) when collected
  uint       priority;   // PlayerMsgPriority enum value for message
  bool       useflash;   // If true, a filter flash overlay effect will be invoked
  kColor     flashcolor; // RGBA of filter flash effect if any
  uint       flashtime;  // Filter flash overlay duration
  
  // If type == NONE, return pointer to NoneEffect instance; null otherwise
  const NoneEffect       @GetNoneEffect()       const; 
  // If type == WEAPON, return pointer to WeaponEffect instance; null otherwise
  const WeaponEffect     @GetWeaponEffect()     const; 
  // If type == AMMO, return pointer to AmmoEffect instance; null otherwise
  const AmmoEffect       @GetAmmoEffect()       const; 
  // If type == POWERUP, return pointer to AmmoEffect instance; null otherwise
  const PowerupEffect    @GetPowerupEffect()    const; 
  // If type == HEALTH, return pointer to HealthEffect instance; null otherwise
  const HealthEffect     @GetHealthEffect()     const; 
  // If type == DAMAGE, return pointer to DamageEffect instance; null otherwise
  const DamageEffect     @GetDamageEffect()     const; 
  // If type == KEY, return pointer to KeyEffect instance; null otherwise
  const KeyEffect        @GetKeyEffect()        const; 
  // If type == TESSOBJECT, return pointer to TessObjectEffect instance; null otherwise
  const TessObjectEffect @GetTessObjectEffect() const; 
  // If type == SCRIPTED, return pointer to ScriptedEffect instance; null otherwise
  const ScriptedEffect   @GetScriptedEffect() const;
}

//
// Runtime instantiation of an ActorInfo record defined via actors.json
//
class ActorInfo {
  kStr name;                    // Name of this ActorInfo def, must be unique
  uint index;                   // Runtime resolved index of this ActorInfo def
  uint ednum;                   // Editor number for use in UDMF
  int radius;                   // Radius, or half-width, of Actor
  int height;                   // Height of Actor. Because this engine is 3D and no debates to the contrary are valid.
  int spawnhealth;              // Initial hitpoints for Actor
  int painchance;               // Chance out of 255 that damage will cause transition to painstate
  int mass;                     // Mass, affects amount of thrust inflicted when damaged
  int speed;                    // Speed, applies to walking actors and missiles
  int reactiontime;             // Number of tics Actor waits to attack when alerted
  int damage;                   // Damage factor for missiles and SKULLFLY Actors
  int selfdamage;               // Self-damage reduction factor for damage inflictors
  uint8 alpha;                  // Alpha (0-255) if actor has TRANSLUCENT or BLENDADD flags
  int gravity;                  // Gravity factor
  uint spawnstate;              // Runtime-resolved index of state in which Actor should spawn
  uint seestate;                // Runtime-resolved index of state Actor should change to when alerted 
  uint painstate;               // Runtime-resolved index of state Actor should change to if hurt
  uint meleestate;              // Runtime-resolved index of state Actor should change to for melee attack
  uint missilestate;            // Runtime-resolved index of state Actor should change to for missile attack
  uint deathstate;              // Runtime-resolved index of state Actor should change to when killed
  uint lastdeathstate;          // Runtime-resolved index of state Actor should change to 
  uint cinderstate;             // Runtime-resolved index of state actor should change to if burned to death by a fire attack
  uint itemrespawnstate;        // Runtime-resolved index of Actor's last death animation state; affects hires mode toggle
  uint itemremovestate;         // Runtime-resolved index of state Actor should change to if collected as an item; if null, Actor is removed
  kStr seesound;                // Name of alert sound effect if non-empty
  kStr attacksound;             // Name of attack sound effect if non-empty
  kStr painsound;               // Name of pain sound effect if non-empty
  kStr deathsound;              // Name of death sound effect if non-empty
  kStr activesound;             // Name of roaming sound effect if non-empty
  kStr paintactile;             // Name of pain tactile event if non-empty; affects player
  kStr deathtactile;            // Name of death tactile event if non-empty; affects player
  kStr seesoundhi;              // Alternate hi-res mode alert sound effect if non-empty
  kStr attacksoundhi;           // Alternate hi-res attack sound effect if non-empty
  kStr painsoundhi;             // Alternate hi-res pain sound effect if non-empty
  kStr deathsoundhi;            // Alternate hi-res death sound effect if non-empty
  kStr activesoundhi;           // Alternate hi-res roaming sound effect if non-empty
  ActorFlags flags;             // Primary bit flag options
  ActorFlags2 flags2;           // Secondary bit flag options
  ActorBloodType bloodtype;     // Actor blood type
  ActorBloodType hibloodtype;   // Alternate hi-res blood type if (flags2 & HASHIBLOODTYPE)
  float lightr;                 // RGB values of light source if lightradius != 0
  float lightg;                 // RGB values of light source if lightradius != 0
  float lightb;                 // RGB values of light source if lightradius != 0
  int lightradius;              // If non-zero, Actor gives off a light source
  int lightoffsetx;             // Affects relative positioning of Actor's light source
  int lightoffsety;             // Affects relative positioning of Actor's light source
  int lightoffsetz;             // Affects relative positioning of Actor's light source
  uint dropchance;              // Chance out of 255 of each item drop
  uint droprolls;               // Number of times to roll for an item drop
  ActorTouchEffect toucheffect; // Effect this actor has if collected as a special item
  Actor3DOMode modeflags;       // Bit flags controlling this actor's hi-res/"3DO" mode behaviors
  float hiresscale;             // Scale applied when actor is in hi-res mode
  float scale;                  // Scale applied when actor is in normal mode
  uint8 hialpha;                // Alpha applied when actor is in hi-res mode
  int footoffset;               // Value by which to vertically offset actor's sprites in normal mode
  int hifootoffset;             // Value by which to vertically offset actor's sprites in hi-res mode
  kStr missilespecies;          // Arbitrary name; defines a "species" for actor's missiles; actors with same species cannot damage each other with missiles
  
  // Return the number of item drops this actor defines  
  uint GetNumDrops() const;
  
  // Return the item drop record at the specified index; returns null if index is out of bounds
  const ActorDropType @GetDropType(uint i) const;
}

//
// Runtime instantiation of a 3D door definition from doordefs.json
//
class DoorDef {
  uint  doornum;      // Door ID
  kStr  main_texture; // Name of texture used on main surfaces of door
  kStr  jamb_texture; // Name of door jamb textures
  uint  width;        // Width of the main surfaces of the door 
  uint  height;       // Height of the door
  uint  depth;        // Width of the door's jambs 
  float main_offsetx; // X offset of main door texture
  float main_offsety; // Y offset of main door texture
  float main_uscale;  // Horizontal texture scale of main texture
  float main_vscale;  // Vertical texture scale of main texture
  float jamb_offsetx; // X offset of jamb texture
  float jamb_offsety; // Y offset of jamb texture
  float jamb_uscale;  // Horizontal texture scale of jamb texture
  float jamb_vscale;  // Vertical texture scale of jamb texture
  kStr  opensound;    // Sound made when player touches door, if non-empty
  kStr  movesound;    // Sound made as soon as opensound finishes, if non-empty
  bool  flipmaintex;  // If true, reverse main texture
}

//
// A lockdef predicate as defined in lockdefs.json
//
class LockPredicate {
  LockPredicateType type; // Type of predicate: ALL or ANY
  
  // Return the number of key ActorInfo defs referenced by this LockPredicate
  uint GetNumActors() const;
  
  // Return the Nth runtime-resolved ActorInfo index referenced by this LockPredicate
  uint GetActorAt(uint i) const;
}

//
// Runtime instantiation of a LockDef as defined in lockdefs.json
//
class LockDef {
  uint locknum;     // Lock ID number
  kStr needmessage; // Message (or localization token) given when player cannot open lockdef
  bool nocheat;     // Keys for this lock are not given by givekeys or giveall cheats unless forced (ie, `givekeys 1`)
  kStr lockedsound; // If nonempty, sfx to play at line's location if player cannot open lockdef
  
  // Return number of predicates defined in this lockdef.
  uint GetNumPredicates() const;
  
  // Return the Nth predicate of this lockdef; returns null if out of bounds
  const LockPredicate @GetPredicateAt(uint i) const;
}

//
// A simple 4-dimensional vector type
//
class SimpleVec4 {
  float x, y, z, w;
}

//
// Runtime instantiation of a MapInfo def from mapinfo.json
//
class MapInfoDef {
  kStr       levelname;        // Name of map or localization token
  kStr       author;           // Name of map's author or localization token
  kStr       skytexture;       // Name of 2D sky texture or key for skybox def if skyboxes are enabled
  bool       soundpropagation; // Enable full sound propagation behaviors if true
  kStr       worldmap;         // Name of world map graphic to use
  SimpleVec4 fogcolor;         // Normalized RGBA for fog
  float      fogpower;         // Exponent for fog falloff
  int        nextlevel;        // Next level to use for exit linedef types
  int        nextsecret;       // Next secret level to use for secret exit linedef types
}

//
// Runtime reflection of metrics.json object
//
class MetricsDef {
  // Return max Actor step height between sectors
  fixed_t  GetStepHeight() const;
  // Return maximum move factor for Actors
  fixed_t  GetMaxMove() const;
  // Return speed of floating monsters
  fixed_t  GetFloatSpeed() const;
  // Return default gravity factor
  fixed_t  GetGravity() const;
  // Return value at which player is considered to stop moving
  fixed_t  GetStopSpeed() const;
  // Return friction value
  fixed_t  GetFriction() const;
  // Return air friction value
  fixed_t  GetAirFriction() const;
  // Return damage thrust factor
  fixed_t  GetDamageThrust() const;
  // Return normal melee range for monsters
  fixed_t  GetMeleeRange() const;
  // Return normal missile range for monsters
  fixed_t  GetShotRange() const;
  // Return threshold imparted on objects when they change targets
  int  GetBaseThreshold() const;
  // Return number of tics between actor respawns
  int  GetRespawnTics() const;
  // Return probability per tic of actor respawning
  uint GetRespawnProb() const;
  // Return gib sound effect
  const kStr &GetGibSound() const;
  // Return first switch sound effect
  const kStr &GetSwitch1Sound() const;
  // Return secondary switch sound effect
  const kStr &GetSwitch2Sound() const;
  // Return actor used for fire on objects dying of fire damage
  const kStr &GetFireActor() const;
  // Return actor used as respawn fog
  const kStr &GetRespawnFog() const;
  // Return sound effect for respawning
  const kStr &GetRespawnSound() const;
  // Return sound made by moving ceilings
  const kStr &GetCeilingSound() const;
  // Return sound made by opening doors
  const kStr &GetDoorOpenSound() const;
  // Return sound made by closing doors
  const kStr &GetDoorCloseSound() const;
  // Return sound made by starting floors
  const kStr &GetFloorStartSound() const;
  // Return sound made by moving plats
  const kStr &GetPlatMoveSound() const;
  // Return sound made by placing a Winged Vessel on the pedastal
  const kStr &GetPutVesselSound() const;
  // Return sound made when all vessels have been placed
  const kStr &GetAllVesselSound() const;
}

//
// Runtime reflection of player.json object
//
class PlayerDef {
  // Return normal player max health
  int  GetMaxHealth() const;
  // Return max health given by pw_maxhealth powerup
  int  GetMegaHealth() const;
  // Return normal view height
  fixed_t GetViewHeight() const;
  // Return death view height
  fixed_t GetDeathViewHeight() const;
  // Get maximum look pitch value
  angle_t GetMaxPitch() const;
  // Get minimum look pitch value
  angle_t GetMinPitch() const;
  // Get maximum view bobbing factor
  fixed_t  GetMaxBob() const;
  // Get jump height
  fixed_t  GetJumpHeight() const;
  // Get weapon lower speed
  fixed_t  GetLowerSpeed() const;
  // Get weapon raise speed
  fixed_t  GetRaiseSpeed() const;
  // Get weapon bottom screen offset (relative to 640x480)
  fixed_t  GetWeaponBottom() const;
  // Get weapon top screen offset (relative to 640x480)
  fixed_t  GetWeaponTop() const;
  // Get maximum distance for using a special linedef
  fixed_t  GetUseRange() const;
  // Get delay between weapon out-of-ammo click sounds
  int  GetClickDelay() const;
  // Get runtime-resolved index of player actor's ActorInfo definition
  uint GetPlayerClassActorNum() const;
  // Get duration in 60 FPS tics of invisibility powerup
  int  GetInvisibilityTics() const;
  // Get duration in 60 FPS tics of showsecrets powerup
  int  GetShowSecretsTics() const;
  // Get duration in 60 FPS tics of strength powerup
  int  GetStrengthTics() const;
  // Get duration in 60 FPS tics of gotammo powerup
  int  GetGotAmmoTics() const;
  // Get duration in 60 FPS tics of showmonsters powerup
  int  GetShowMonsterTics() const;
  // Get duration in 60 FPS tics of godmode powerup
  int  GetGodModeTics() const;
  // Get radius of genocide bomb effect
  fixed_t  GetGenocideRadius() const;
  // Get damage of genocide bomb efffect
  int  GetGenocideDamage() const;
  // Get duration in 60 FPS tics of showgoodies powerup
  int  GetShowGoodiesTics() const;
  // Get duration in 60 FPS tics of firefaster powerup
  int  GetFireFasterTics() const;
  // Get duration in 60 FPS tics of halfdamage powerup
  int  GetHalfDamageTics() const;
  // Get duration in 60 FPS tics of nofiredamage powerup
  int  GetNoFireDamageTics() const;
  // Get duration in 60 FPS tics of light amp powerup
  int  GetLightTics() const;
  // Get max distance for aiming of missile attacks
  fixed_t  GetMissileAimDist() const;
  // Get default z height for spawning missiles
  fixed_t  GetMissileZ() const;
  // Get reach when collecting items
  fixed_t  GetReach() const;
  // Get cool down for jumps
  int  GetJumpCoolDown() const;
  // Get delay inflicted after impacting from a jump
  int  GetJumpHitDelay() const;
  // Minimum z momentum required before the player screams while falling into a water death sector
  fixed_t  GetScreamMomZ() const;
  // Get name of actor type used for genocide fog
  const kStr &GetGenocideFog() const;
  // Get name of weapon changed to when player receives strength powerup
  const kStr &GetStrengthWeapon() const;
  // Get sound effect plaed when landing from a jump with required z momentum
  const kStr &GetJumpLandSound() const;
  // Get sound effect played when landing in water
  const kStr &GetSplashSound() const;
  // Get sound effect played when walking in water
  const kStr &GetSplashExSound() const;
  // Get sound effect played when falling into a watery death sector
  const kStr &GetFallingSound() const;
  // Get sound effect played when using a Tess object (winged vessel)
  const kStr &GetTessEffectSound() const;
  // Get sound effect played when a powerup expires
  const kStr &GetPowerDownSound() const;
  // Get sound effect played when obtaining Wrath of Gods
  const kStr &GetWrathSound() const;
  // Get sound effect played when pushing a linedef which cannot be activated
  const kStr &GetNoWaySound() const;
}

//
// Runtime reflection of skybox objects from skyboxes.json
//
class Skybox {
  // Get skybox side texture name at index from 0 to 5
  const kStr &GetTextureAt(uint idx) const;
}

//
// Runtime instantiation of an Actor animation state as defined in states.json
//
class ActorState {
  kStr name;        // Name of this state; must be unique
  uint index;       // Runtime-resolved index of this state in the states table
  kStr sprite;      // Sprite name
  uint spriteframe; // Sprite frame
  bool translucent; // If true, draw the object translucent
  bool fullbright;  // If true, draw the object with full brightness
  int  tics;        // Duration of state in 60 FPS tics
  uint nextstate;   // Index of next state in the states table
  kStr action;      // Name of AngelScript action function
  kStr altstate;    // If not empty, alternate state to transition to for hi-res mode
  uint altindex;    // Runtime-resolved index of altstate, if not zero
  
  // Returns the argument of this state at index from 0 to 4.
  int GetArg(uint index) const;
}

//
// Runtime instantiation of a weapon definition as defined in weapons.json
//
class WeaponDef {
  kStr  m_name;              // Name of the weapon definition; must be unique
  uint  m_index;             // Runtime-resolved index of the weapon definition
  uint  m_slot;              // Slot (0-9) to which this weapon binds
  uint  m_slotorder;         // Order of this weapon in its slot relative to others in the same slot
  uint  m_slotindex;         // Runtime enumeration of weapons on a slot in order
  uint  m_priority;          // Priority of the weapon compared to all other weapons
  uint  m_ammotype;          // Runtime-resolved index of ammo type used by this weapon
  uint  m_pickupammo;        // Runtime-resolved index of type of ammo to give when picking up weapon
  int   m_ammopershot;       // Amount of ammo weapon uses per shot
  bool  m_isStartWeapon;     // If true, is a weapon given to the player at the start of all games
  bool  m_isMelee;           // If true, is a melee weapon (does not inflict thrust on targets)
  bool  m_isStealth;         // If true, is a stealth weapon (enemies do not react to use)
  uint  m_upstate;           // Runtime-resolved index of weapon's raise state
  uint  m_downstate;         // Runtime-resolved index of weapon's lower state
  uint  m_readystate;        // Runtime-resolved index of weapon's ready state
  uint  m_attackstate;       // Runtime-resolved index of weapon's attack state
  uint  m_flashstate;        // Runtime-resolved index of weapon's flash state (hi-res only)
  uint  m_shellstate;        // Runtime-resolved index of weapon's shell eject state (hi-res only)
  uint  m_shell2state;       // Runtime-resolved index of secondary shell eject state (hi-res only)
  kStr  m_clicksound;        // If non-empty, click made if weapon is fired without ammo
  kStr  m_clicksoundhi;      // Hi-res alternate for click sound if non-empty
  kStr  m_upgrade;           // Weapon to upgrade to if player collects a second weapon of this type
  float m_hiresscale;        // Scale for hi-res mode
  bool  m_usealtstates;      // If true, use alternate states when in hi-res mode
  bool  m_autotlate;         // If true, auto-append "3DO/" to sprites when in hi-res mode (do not combine with alt states)
  kStr  m_automapicon;       // Path to icon graphic to use for this weapon on the automap
  int   m_automapslot;       // Slot to display icon in on the automap
  bool  m_allowInfiniteAmmo; // If true, weapon allows the infinite ammo cheat (applies to UI elements only)
}

//
// The main game loop object; available as a global singleton object, `g_game`
//
class Game {
  // Returns true if the game is paused for any reason
  bool IsPaused() const;
  // Return the current GameState (see GameState enumeration)
  GameState GetGameState() const;
  // Return the previous GameState
  GameState GetOldGameState() const;
  // Return any currently pending GameAction (see GameAction enumeration)
  GameAction GetGameAction() const;
  // Return the skill level of the pending or current game
  skill_t GetGameSkill() const;
  // Get number of 60 Hz ticks since the game started execution
  int GetGameTic() const;
  // Get the tick on which the current level started play
  int GetLevelStartTic() const;
  // Get number of 60 Hz ticks which the player has spent in levels in the current game (saved in save games)
  int GetLevelTime() const;
  // Get the current game map number
  int GetGameMap() const;
  // Get the pending destination map for hub level transfers
  int GetDestMap() const;
  // Get the current value of the respawn monsters state
  bool GetRespawnMonsters() const;
  // Get the current value of the respawn items state
  bool GetRespawnItems() const;
  // Get the current value of the fast monsters state
  bool GetFastMonsters() const;
  // Shortcut to test if current gametic is divisible by 60
  bool IsTick1() const;
  // Shortcut to test if current gametic is divisible by 30
  bool IsTick2() const;
  // Shortcut to test if current gametic is divisible by 15
  bool IsTick4() const;
  // Set a pending GameAction; the gamestate will transition in response on the next gametic
  void SetGameAction(GameAction act);
  // Play a blocking fullscreen video; the file extension should NOT be provided
  void PlayVideo(const kStr &in path);
  // Get a reference to the current MapInfo definition. This never returns null, a default is provided.
  const MapInfoDef @GetMapInfo() const;
  // Get the current RNG seed.
  uint GetRNGSeed() const;
  // Get the current interpolation fraction
  float GetInterpolationFraction() const;
  // Query if a level exists by its MAPxy number
  bool LevelExists(int mapnum) const;
  // Query if a named level exists (do not include ".wad" extension)
  bool LevelNameExists(const kStr &in mapname) const;
  // Get the current save slot, or -1 if none has been selected
  int GetQuickSaveSlot() const;
}

//
// A vertex placed in the map editor
//
class vertex_t {
  // Obtain fixed-point x coordinate
  fixed_t GetX() const;
  // Obtain fixed-point y coordinate
  fixed_t GetY() const;
}

//
// A sector (group of linedefs) defined in the map editor
//
class sector_t {
  // Get fixed-point floor height
  fixed_t GetFloorHeight() const;
  // Get fixed-point ceiling height
  fixed_t GetCeilingHeight() const;
  // Get x offset of floor texture
  fixed_t GetFloorOffsetX() const;
  // Get y offset of floor texture
  fixed_t GetFloorOffsetY() const;
  // Get x offset of ceiling texture
  fixed_t GetCeilingOffsetX() const;
  // Get y offset of ceiling texture
  fixed_t GetCeilingOffsetY() const;
  // Get ceiling texture name
  const kStr &GetCeilingPic() const;
  // Get floor texture name
  const kStr &GetFloorPic() const;
  // Get handle of floor texture (-1 if none)
  int GetFloorTexHandle() const;
  // Get handle of ceiling texture (-1 if none)
  int GetCeilingTexHandle() const;
  // Get light level
  uint GetLightLevel() const;
  // Get sector special
  int GetSpecial() const;
  // Get sector tag
  int GetTag() const;
  // Get sound traversal index
  uint GetSoundTraversed() const;
  // Get fixed-point sound origin point x coordinate
  fixed_t GetSoundOrgX() const;
  // Get fixed-point sound origin point y coordinate
  fixed_t GetSoundOrgY() const;
  // Get count of linedefs in this sector
  uint GetLineCount() const;
  // Get the root of the list of Actors which are "in" this sector (determined by midpoint)
  Actor @GetThingList() const;
  // Get sector validcount value
  int GetValidCount() const;
  // Get reference to Actor that has made sound in this sector; null if none.
  Actor @GetSoundTarget() const;
  // Get reference to Thinker affecting this sector if any; null if none.
  Thinker @GetSpecialData() const;
  // Get special behavior bit flags (see SectorFlags enumeration)
  SectorFlags GetFlags() const;
  // Get handle to linedef at given index
  line_t @GetLineAt(uint line) const;
  // Get fixed-point sector bounding box value at index from 0 to 3 (TOP, BOTTOM, LEFT, RIGHT)
  fixed_t GetBBoxAt(uint side) const;
  // Get integer blockmap bounding box value at index from 0 to 3 (TOP, BOTTOM, LEFT, RIGHT)
  int GetBlockBoxAt(uint side) const;
  // Set sector floor height instantly
  void SetFloorHeight(fixed_t h);
  // Set sector ceiling height instantly
  void SetCeilingHeight(fixed_t h);
  // Set sector floor x offset
  void SetFloorOffsetX(fixed_t o);
  // Set sector floor y offset
  void SetFloorOffsetY(fixed_t o);
  // Set sector ceiling x offset
  void SetCeilingOffsetX(fixed_t o);
  // Set sector ceiling y offset
  void SetCeilingOffsetY(fixed_t o);
  // Set sector ceiling texture
  void SetCeilingPic(const kStr &in s);
  // Set sector floor texture
  void SetFloorPic(const kStr &in s);
  // Set sector light level
  void SetLightLevel(uint ll);
  // Set sector special
  void SetSpecial(int spec);
  // Set sector tag
  void SetTag(int t);
}

//
// Linedef side as defined in the map editor; lines can have one or two sides.
//
class sidedef_t {
 // Get texture x offset
  fixed_t GetTextureOffset() const;
  // Get texture y offset
  fixed_t GetRowOffset() const;
  // Get top texture name
  const kStr &GetTopTexture() const;
  // Get bottom texture name
  const kStr &GetBottomTexture() const;
  // Get middle texture name
  const kStr &GetMidTexture() const;
  // Get handle to sector (never null)
  sector_t @GetSector() const;
  // Get handle of top texture (-1 if none)
  int GetTopTexHandle() const;
  // Get handle of bottom texture (-1 if none)
  int GetBottomTexHandle() const;
  // Get handle of middle texture (-1 if none)
  int GetMidTexHandle() const;
  // Set texture x offset
  void SetTextureOffset(fixed_t f);
  // Set texture y offset
  void SetRowOffset(fixed_t f);
  // Set top texture name
  void SetTopTexture(const kStr &in tex);
  // Set bottom texture name
  void SetBottomTexture(const kStr &in tex);
  // Set middle texture name
  void SetMidTexture(const kStr &in tex);
}

//
// Button animation data for a linedef
//
class button_t {
  // Get handle to parent linedef
  line_t @GetLine() const; 
  // Get position of animation on sidedef (top, middle, or bottom)
  bwhere_e GetWhere() const;
  // Get index of the step the animation is displaying
  uint GetStep() const;
  // Get duration in ticks of the current animation frame
  int GetTics() const;
  // Set the duration of the current animation frame
  void SetTics(int i);
}

//
// A linedef as specified in the map editor
//
class line_t {
  // Get index of first vertex
  uint GetV1Index() const;
  // Get index of second vertex
  uint GetV2Index() const;
  // Get handle to first vertex; never null
  const vertex_t @GetV1() const;
  // Get handle to second vertex; never null
  const vertex_t @GetV2() const;
  // Get linedef x delta (v2.x - v1.x)
  fixed_t GetDX() const;
  // Get lindedef y delta (v2.y - v1.y)
  fixed_t GetDY() const;
  // Get linedef slope classification
  SlopeType GetSlopeType() const;
  // Get linedef behavior bit flags
  LineFlags GetFlags() const;
  // Get line special
  uint GetSpecial() const;
  // Get line tag
  int GetTag() const;
  // Get index of front side; never invalid
  int GetFrontSideNum() const;
  // Get index of back side; -1 if invalid
  int GetBackSideNum() const;
  // Get linedef fixed point bounding box value at index (TOP, BOTTOM, LEFT, RIGHT)
  fixed_t GetBBoxAt(uint side) const;
  // Get handle of front sector; never null
  sector_t @GetFrontSector() const;
  // Get handle of back sector; null if line has no back side
  sector_t @GetBackSector() const;
  // Get handle of button at position (see bwhere_e enumeration)
  button_t @GetButtonAt(uint pos);
  // Return angle of linedef
  angle_t GetAngle() const;
  // Get first line argument
  int GetArg0() const;
  // Get second line argument
  int GetArg1() const;
  // Get third line argument
  int GetArg2() const;
  // Get fourth line argument
  int GetArg3() const;
  // Get fifth line argument
  int GetArg4() const;
  // Set linedef flags
  void SetFlags(LineFlags f);
  // Unset linedef flags
  void UnsetFlags(LineFlags f);
  // Set line special
  void SetSpecial(uint s);
  // Set line tag
  void SetTag(int s);
}

//
// Line segment as generated by the node builder
//
class seg_t {
  // Get index of first vertex
  uint GetV1Index() const;
  // Get index of second vertex
  uint GetV2Index() const;
  // Get handle of first vertex; never null
  const vertex_t @ GetV1() const;
  // Get handle of second vertex; never null
  const vertex_t @ GetV2() const;
  // Get seg offset along linedef
  double GetOffset() const;
  // Get parent linedef; null if this is a ZNODES dummy seg
  line_t @GetLinedef() const;
  // Get parent sidedef; null if this is a ZNODES dummy seg
  sidedef_t @GetSidedef() const;
  // Get side (0 or 1) of parent line to which this seg belongs
  uint GetSide() const;
  // Get fixed-point normal X component
  int GetNX() const;
  // Get fixed-point normal y component
  int GetNY() const;
  // Get handle of front sector; null if this is a ZNODES dummy seg
  sector_t @GetFrontSector() const;
  // Get handle of back sector; null if this is a ZNODES dummy seg or line has no backsector
  sector_t @GetBackSector() const;
  // Get length of seg
  double GetLength() const;
  // Get ZNODES partner seg if any (null otherwise)
  seg_t @GetPartner() const;
  // True if seg is flagged visible during the current frame
  bool IsVisible() const;
}

//
// Subsector as generated by the node builder
//
class subsector_t {
  // Get handle of sector (never null)
  sector_t @GetSector() const;
  // Get number of segs in this subsector
  uint GetNumLines() const;
  // Get index of first seg in this subsector
  uint GetFirstLine() const;
  // Get index of subsector leaf
  uint GetLeaf() const;
  // Get number of vertexes belonging to this subsector
  uint GetNumVerts() const;
}

//
// BSP tree node as generated by the node builder
//
class node_t
  // Get node line x coordinate
  fixed_t GetX() const;
  // Get node line y coordinate
  fixed_t GetY() const;
  // Get node line delta-x
  fixed_t GetDX() const;
  // Get node line delta-y
  fixed_t GetDY() const;
  // Get index of front child node (child is subsector if NF_SUBSECTOR set)
  uint GetFrontChild() const;
  // Get index of back child node (child is subsector if NF_SUBSECTOR set)
  uint GetBackChild() const;
  // Get entry of node bounding box (TOP, BOTTOM, LEFT, RIGHT)
  fixed_t GetBBoxAt(uint nodeside, uint boxside) const;
}

//
// Mapthing as specified in the map editor
//
class mapthing_t {
  // Get fixed-point x coordinate
  fixed_t GetX() const;
  // Get fixed-point y coordinate
  fixed_t GetY() const;
  // Get BAM angle
  angle_t GetAngle() const;
  // Get first argument
  int GetArg0() const;
  // Get second argument
  int GetArg1() const;
  // Get third argument
  int GetArg2() const;
  // Get fourth argument
  int GetArg3() const;
  // Get fifth argument
  int GetArg4() const;
  // Get Actor ednum
  uint GetType() const;
  // Get MapThingFlags bit flags
  MapThingFlags GetFlags() const;
  // Get Thing ID for scripting
  uint GetID() const;
}

//
// The World class contains all elements of the currently loaded level. It is a global
// singleton exposed through the `GetWorld()` global function.
//
class World {
  // Get map number that is loaded into the World instance
  int GetActiveMapNumber() const;
  // Get number of vertexes
  uint NumVertexes() const;
  // Get number of sectors
  uint NumSectors() const;
  // Get number of sidedefs
  uint NumSidedefs() const;
  // Get number of linedefs
  uint NumLinedefs() const;
  // Get length of line buffer used for sector line lists
  uint LineBufferLen() const;
  // Get number of subsectors
  uint NumSubsectors() const;
  // Get number of segs
  uint NumSegs() const;
  // Get number of leafs
  uint NumLeafs() const;
  // Get number of nodes
  uint NumNodes() const;
  // Get number of fnodes
  uint NumFNodes() const;
  // Get number of mapthings
  uint NumMapthings() const;
  // Get blockmap x origin
  fixed_t GetBMapOrgX() const;
  // Get blockmap y origin
  fixed_t GetBMapOrgY() const;
  // Get blockmap width in number of blocks
  int GetBMapWidth() const;
  // Get blockmap height in number of blocks
  int GetBMapHeight() const;
  // If true, the blockmap contains 0 entries in every block
  bool SkipBMapPad() const;
  // Shortcut to global R_PointOnSide routine
  int PointOnSide(int x, int y, const node_t @ node);
  // Shortcut to global R_PointInSubsector routine
  subsector_t @PointInSubsector(int x, int y);
  // Get handle of vertex at index
  vertex_t @GetVertexAt(uint i);
  // Get handle of sector at index
  sector_t @GetSectorAt(uint i);
  // Get handle of sidedef at index
  sidedef_t @GetSidedefAt(uint i);
  // Get handle of linedef at index
  line_t @GetLinedefAt(uint i);
  // Get handle of subsector at index
  subsector_t @GetSubsectorAt(uint i);
  // Get handle of seg at index
  seg_t @GetSegAt(uint i);
  // Get handle of mapthing at index
  mapthing_t @GetMapthingAt(uint i);
  // Get handle of node at index
  node_t @GetNodeAt(uint i);
}

//
// Parent class of all serializable script value classes which are saved in save 
// games.
//
class ScriptSerializable {
  // Get the name of the serializable script value
  const kStr &GetName() const;
  // Get the scope of the serializable script value (LEVEL or WORLD)
  ScriptValueScope GetScope() const;
  // Set the scope of the serializable script value
  void SetScope(ScriptValueScope s);
}

//
// Basic script serializable value with a mapping to an intrinsic AngelScript type;
// this is a form of variant which will accept any of the listed value types, and 
// can be converted to any other type regardless of the contained value.
//
class ScriptBasicValue : ScriptSerializable {
  // Returns true if the contained value is a boolean
  bool IsBool() const;
  // Returns true if the contained value is an integer
  bool IsInt() const;
  // Returns true if the contained value is an unsigned integer
  bool IsUint() const;
  // Returns true if the contained value is a single-precision floating point number
  bool IsFloat() const;
  // Returns true if the contained value is a double-precision floating point number
  bool IsDouble() const;
  // Returns true if the contained value is a kStr string instance
  bool IsString() const;
  // Return the contained value as a string, only if it is a string; otherwise the result is empty.
  const kStr &GetString() const;
  // Return the contained value converted to a boolean
  bool AsBool() const;
  // Return the contained value converted to an integer
  int AsInt() const;
  // Return the contained value converted to an unsigned integer
  uint AsUint() const;
  // Return the contained value converted to a floating point number
  float AsFloat() const;
  // Return the contained value converted to a double floating point number
  double AsDouble() const;
  // Return the contained value converted to a string
  kStr AsString() const;
  // Set the value to a boolean
  void SetBool(bool b);
  // Set the value to an integer
  void SetInt(int i);
  // Set the value to an unsigned integer
  void SetUint(uint u);
  // Set the value to a float
  void SetFloat(float f);
  // Set the value to a double
  void SetDouble(double d);
  // Set the value to a string
  void SetString(const kStr &in str);
}

//
// Serializable script value which can hold a handle to an instance of any Thinker
// class. This class is the ONLY safe way to store Thinker handles (including Actors).
// This class will only work as expected if given LEVEL scope; otherwise it will become
// null when moving between levels even if given World scope.
//
class ScriptThinkerHandle : ScriptSerializable {
  // Set methods. Set the handle to point to a Thinker-derived object of the 
  // specified class.
  void SetThinker(Thinker @th);
  void SetActor(Actor @actor);
  void SetCeilingMover(CeilingMover @th);
  void SetDoorObject(DoorObject @th);
  void SetFireFlickerThinker(FireFlickerThinker @th);
  void SetFloorMover(FloorMover @th);
  void SetGlowThinker(GlowThinker @th);
  void SetLightFlashThinker(LightFlashThinker @th);
  void SetPlatMover(PlatMover @th);
  void SetScriptThinker(ScriptThinker @th);
  void SetSectorThinker(SectorThinker @th);
  void SetStrobeThinker(StrobeThinker @th);
  void SetVerticalDoorMover(VerticalDoorMover @th);
  
  // Obtain a handle to the contained object as the Thinker superclass. This 
  // method can be used regardless of the value contained. It returns null only if
  // the ScriptThinkerHandle is itself empty (has not been set to a valid object).
  // You can use the AngelScript cast operator to attempt to cast the result to 
  // any class which inherits from Thinker; it will only succeed if the cast is 
  // to a related type.
  Thinker @GetThinker() const;

  // Subclass getter methods - if and only if the contained handle is valid and 
  // is of a type related to the method called, it will be returned. Otherwise
  // the return value will be null.
  Actor              @GetActor()              const;
  CeilingMover       @GetCeilingMover()       const;
  DoorObject         @GetDoorObject()         const;
  FireFlickerThinker @GetFireFlickerThinker() const;
  FloorMover         @GetFloorMover()         const;
  GlowThinker        @GetGlowThinker()        const;
  LightFlashThinker  @GetLightFlashThinker()  const;
  PlatMover          @GetPlatMover()          const;
  ScriptThinker      @GetScriptThinker()      const;
  SectorThinker      @GetSectorThinker()      const;
  StrobeThinker      @GetStrobeThinker()      const;
  VerticalDoorMover  @GetVerticalDoorMover()  const;
  
  // Testing methods - test if the handle is to a Thinker instance of a particular
  // subclass.
  bool IsActor()              const;
  bool IsCeilingMover()       const;
  bool IsDoorObject()         const;
  bool IsFireFlickerThinker() const;
  bool IsFloorMover()         const;
  bool IsGlowThinker()        const;
  bool IsLightFlashThinker()  const;
  bool IsPlatMover()          const;
  bool IsScriptThinker()      const;
  bool IsSectorThinker()      const;
  bool IsStrobeThinker()      const;
  bool IsVerticalDoorMover()  const;
  
  // Reset the handle to null
  void Clear();
  
  // Test if the handle points to a valid object
  bool IsValid() const;
  
  // Obtain a string representation of the object's class name if the handle is not null.
  // Returns empty string if the handle is null.
  kStr GetClassName() const;
}

//
// Represents and allows firing aim and attack traces through the world. Contains
// results of the trace operation after the method returns.
//
class Trace {
   // Call to fire a test trace which collects information about the world but 
   // does not change any objects.
   int AimLineAttack(Actor @t1, angle_t angle, fixed_t distance);
   
   // Call to fire an attack tracer which can do damage to Actors and spawn 
   // puffs on lines.
   void LineAttack(Actor @t1, angle_t angle, fixed_t distance, fixed_t slope, int damage);
   
   // After an aim or attack trace, will contain the handle to an Actor struck by the trace, if any 
   // such actor exists. Otherwise, returns null.
   Actor @GetLineTarget() const;
   
   // After an aim or attack trace, returns the hit type classification of the trace. 
   // See TraceHitType enumeration.
   TraceHitType GetHitType() const;
}

//
// Parent class of all Thinker classes. The properties and methods of Thinker are 
// available in those classes as well, as per AngelScript inheritance mechanics.
// Handles can be cast to and from this type to related types using the AngelScript
// cast operator, which behaves like C++ dynamic_cast with respect to these classes.
//
class Thinker {
  // Get the next thinker on the global thinker list
  Thinker @GetNext() const;
  // Get the previous thinker on the global thinker list
  Thinker @GetPrev() const;
  // Call to add a new thinker to the global thinker list
  void Add();
  // Call to mark the thinker for deferred removal during the next gametic.
  void Remove();
  // Test if a thinker is "live" (true) or is awaiting deferred removal (false).
  // No operations should be performed on Thinkers which are not live.
  bool IsLive() const;
  // Allows upcasting child class instances to Thinker.
  Thinker @CastToThinker();
}

//
// The Actor class represents an object in the game world. Actors are Thinkers 
// which can display sprites, perform AI actions, clip against other elements in 
// the world and each other, experience physics, etc.
//
class Actor : Thinker {
  // Call to unlink the Actor from its current blockmap, sector, and other links.
  // This is necessary to call before altering an Actor's position in the world,
  // unless the Actor has the ActorFlags::NOBLOCKMAP and ActorFlags::NOSECTOR flags.
  void UnsetPosition();
  
  // Link the Actor to the world according to its ActorFlags. Sets blockmap links,
  // sector links, etc.
  void SetPosition();
  
  // Set the Actor to an indicated ActorState by index.
  bool SetState(uint statenum);
  
  // Set the Actor to an indicated ActorState by index, without invoking the action
  // function of the state. Useful to avoid harmful recursions if state transitions
  // happen during operations such as clipping.
  bool SetStateNF(uint statenum);
  
  // Check if a missile just spawned is already inside a wall or an Actor. If so,
  // explode it immediately.
  void CheckMissileSpawn();
  
  // Check if a missile has hit a sky line. Test only, does not remove the object.
  bool CheckMissileHitSkyLine(const line_t @ line) const;
  
  // Explode a missile.
  void ExplodeMissile();
  
  // Test if the Actor is in a state that loops with its spawnstate.
  bool IsInSpawnState() const;
  // Test if the Actor is in a state that loops with its seestate.
  bool IsInWalkingState() const;
  
  // Inflict damage on an Actor using the inflictor (optional) and source (optional).
  // The inflictor is the object doing damage (for example a missile). The source 
  // is the object to blame for the damage.
  void Damage(Actor @inflictor, Actor @source, int damage);
  
  // Kill an Actor.
  void Kill();
  
  // Drop random items defined by the ActorInfo.
  void DropItems();
  
  // Perform a position check - returns true if the object fits at the indicated 
  // location and false otherwise. Can have side effects, such as collection of 
  // special Actors and death to Actors marked as SQUASHABLE.
  bool CheckPosition(fixed_t x, fixed_t y);
  
  // Try to move to position (x,y). Returns true if successful, false otherwise.
  // Can have side effects as above, as well as crossing special lines.
  bool TryMove(fixed_t x, fixed_t y);
  
  // Try to slide against walls. Only players can use this method, other Actors 
  // will simply return from it.
  void SlideMove();
  
  // Takes a valid thing and adjusts the thing->floorz, thing->ceilingz, and possibly thing->z.
  // This is called for all nearby monsters whenever a sector changes height. If the thing 
  // doesn't fit, the z will be set to the lowest value and false will be returned.
  bool ThingHeightClip();
  
  // Force an Actor's interpolated angle and position to its current angle and position.
  // Appropriate when an Actor moves non-continuously (such as teleportation).  
  void UpdateInterpData();
  
  // Activate a crossable line special using this Actor.
  void CrossSpecialLine(line_t @line);
  // Activate a shootable line special using this Actor.
  void ShootSpecialLine(line_t @line);

  // Perform movement AI.  
  bool Move();
  // Try to walk.
  bool TryWalk();
  // Select a new movement direction.
  void NewChaseDir();
  // Look for players to target. If allaround is true, the monster has 360-degree
  // vision.
  bool LookForPlayer(bool allaround);
  
  // Spawn a player missile.
  Actor @SpawnPlayerMissile(uint type, fixed_t momz, AutoAimFlags aaf=AutoAimFlags::NORMAL);
  
  // Obtain handle to the ActorInfo definition for this Actor. Never null.
  const ActorInfo @GetActorInfo() const;
  
  // Get fixed-point position vector components.
  fixed_t GetX() const;
  fixed_t GetY() const;
  fixed_t GetZ() const;
  
  // Get fixed-point radius (half-width)
  fixed_t GetRadius() const;
  // Get fixed-point height
  fixed_t GetHeight() const;
  
  // Get BAM angle
  angle_t GetAngle() const;
  
  // Get arguments by indicated index
  int GetArg0() const;
  int GetArg1() const;
  int GetArg2() const;
  int GetArg3() const;
  int GetArg4() const;
  // Get argument by index parameter (0 to 4)
  int GetArgAt(uint i) const;
  
  // Get ActorFlags.
  ActorFlags GetFlags() const;
  // Get ActorFlags2.
  ActorFlags2 GetFlags2() const;
  
  // Get health / hitpoints.
  int GetHealth() const;
  
  // Get reaction time, used when attacking or teleporting.
  int GetReactionTime() const;
  
  // Get fixed-point momentum vector components.
  fixed_t GetMomX() const;
  fixed_t GetMomY() const;
  fixed_t GetMomZ() const;
  
  // Get counter at index (0 to 7). Counters are generic variables which can 
  // track data per actor. They are not used by the engine, only by scripts.
  int GetCounter(uint idx) const;
  
  // Teleport the actor to (x, y) without any special effects.
  void ChangeLocation(fixed_t x, fixed_t y);
  
  // Set the actor's fixed-point z coordinate. Yes it's a 3D engine, deal with it.
  void SetZ(fixed_t newZ);
  
  // Set actor's angle.
  void SetAngle(angle_t an);
  
  // Set actor arguments
  void SetArg0(int a);
  void SetArg1(int a);
  void SetArg2(int a);
  void SetArg3(int a);
  void SetArg4(int a);
  void SetArgAt(uint idx, int a);
  
  // Set actor flags.
  void SetFlags(ActorFlags af);
  // Unset actor flags
  void UnsetFlags(ActorFlags af);
  
  // Set secondary actor flags
  void SetFlags2(ActorFlags2 af);
  // Unset secondary actor flags.
  void UnsetFlags2(ActorFlags2 af);
  
  // Set reaction time.
  void SetReactionTime(int rt);
  // Decrement reaction time by one.
  int DecrementReactionTime();
  
  // Set fixed-point Actor radius.
  void SetRadius(fixed_t newradius);
  // Set fixed-point Actor height.
  void SetHeight(fixed_t newheight);
  
  // Set actor health.
  void SetHealth(int newhealth);
  
  // Set counter at index to value (index 0 to 7)
  void SetCounter(uint idx, int a);
  
  // Set fixed-point momentum vector components.
  void SetMomX(fixed_t val);
  void SetMomY(fixed_t val);
  void SetMomZ(fixed_t val);
  // Add the fixed-point impulse to the Actor's momentum components
  void AddImpulseX(fixed_t val);
  void AddImpulseY(fixed_t val);
  void AddImpulseZ(fixed_t val);
  // Set entire momentum vector to 0.
  void ClearMomenta();
  
  // Get scripting ID
  uint GetID() const;
  // Set scripting ID
  void SetID(uint id);
  
  // Convenience routine: Test if all indicated ActorFlags are set.
  bool HasAllFlags(ActorFlags af) const;
  // Convenience routine: Test if any indicated ActorFlags are set.
  bool HasAnyFlags(ActorFlags af) const;
  // Convenience routine: Test if none of the indicatated ActorFlags are set.
  bool HasNoneOfFlags(ActorFlags af) const;
  
  // Convenience routine: Test if all indicated ActorFlags2 are set.
  bool HasAllFlags2(ActorFlags2 af) const;
  // Convenience routine: Test if any indicated ActorFlags2 are set.
  bool HasAnyFlags2(ActorFlags2 af) const;
  // Convenience routine: Test if none of the indicatated ActorFlags2 are set.
  bool HasNoneOfFlags2(ActorFlags2 af) const;
  
  // Get highest z contacted over all sectors
  fixed_t GetFloorZ() const;
  // Get lowest ceiling contacted over all sectors
  fixed_t GetCeilingZ() const;
  // Set floor z
  void SetFloorZ(fixed_t z);
  // Set ceiling z
  void SetCeilingZ(fixed_t z);
  
  // Get current movement direction for walking/flying AI
  dirtype_t GetMoveDir() const;
  // Set current movement direction for walking/flying AI
  void SetMoveDir(dirtype_t dt);
  // Get current movecount for walking AI
  int GetMoveCount() const;
  // Set current movecount for walking AI
  void SetMoveCount(int mc);
  // Decrement movecount timer
  int DecrementMoveCount();
  
  // Get handle of sector which the Actor is actually contacting, if any. 
  // Returns null if no such floor exists.
  sector_t @GetFloorSector() const;
  // Set Actor's actually contacted floor sector handle.
  void SetFloorSector(sector_t @sec);
  
  // Get Actor respawn counter
  int GetRespawnCount() const;
  // Set Actor respawn counter
  void SetRespawnCount(int rs);
  
  // Behave as though the item has been touched as a special: If the item has a
  // respawn state or remove state, it will transfer appropriately. If not, the 
  // item will be entirely removed from the gamesim.
  void ItemCollected();
  
  // Get handle to DoorDef object, if this Actor is a 3D swinging door. Null if 
  // not a door.
  const DoorDef @GetDoorDef() const;
  
  // Get current animation state. If the actor is being removed, this may return null.
  const ActorState @GetState() const;
  // Get tics left in the current animation state.
  int GetTics() const;
  // Set tics left in teh current animation state.
  void SetTics(int t);
  
  // Get actor alpha. Only activates if Actor has BLENDADD or TRANSLUCENT flags.
  uint8 GetAlpha() const;
  // Set actor alpha. Only activates if Actor has BLENDADD or TRANSLUCENT flags.
  void SetAlpha(uint8 a);
  
  // Get reference to Actor's spawnpoint.
  const mapthing_t &GetSpawnPoint() const;
  
  // Get actor's current target. Null if none.
  Actor @GetTarget() const;
  // Get actor's current missile tracer. Null if none.
  Actor @GetTracer() const;
  // Set actor's target.
  void SetTarget(Actor @actor);
  // Set actor's missile tracer.
  void SetTracer(Actor @actor);
  
  // If the Actor is the player, return a handle to the Player object. Otherwise
  // returns null.
  Player @GetPlayer() const;
  
  // Get handle to the Actor's subsector. An actor always has a valid subsector.
  subsector_t @GetSubsector() const;
  
  // Get next actor in the same blockmap cell. Only valid if actor is attached to
  // the blockmap.
  Actor @GetBNext() const;
  
  // Get next actor in the same sector (as judged by midpoint). Only valid if the
  // actor is attached to sectors.
  Actor @GetSNext() const;
  
  // Get threshold for changing targets when attacked.
  int GetThreshold() const;
  // Set threshold for changing targets when attacked.
  void SetThreshold(int th);
  // Decrement threshold by one.
  int DecrementThreshold();
  
  // Get sound target in the actor's current subsector's sector.
  Actor @GetSoundTarget() const;
  // Clear sound target in the actor's current subsector's sector.
  void ClearSoundTarget() const;
  
  // Get index of ActorInfo for this actor.
  uint GetType() const;
  
  // Freeze the actor in place.
  void Freeze();
  // Unfreeze the actor.
  void Unfreeze();
  // Query if actor is frozen.
  bool IsFrozen() const;
  
  // Test if actor touches another actor vertically.
  bool TouchesVertically(const Actor @ other) const;
  
  // Query if actor is allowed to infight with the other actor type by ActorInfo index.
  bool InfightsWith(uint index) const;
  // Query if actor is allowed to infight with the other actor type by ActorInfo name.
  bool InfightsWithActorName(const kStr &in name) const;
  // Query if actor is same missile species as other actor type
  bool SameMissileSpeciesAs(const Actor @other) const;
  
  // Test if the Actor can nightmare respawn and if so, respawn it.
  void NightmareRespawn();
}

//
// ScriptThinker allows a thinker which corresponds to a scripted object to be 
// created.
//
class ScriptThinker : Thinker { 

  // Serialization functions - you can call these from the script object's 
  // void Serialize() const method to save data specific to the script object 
  // into a saved game.
  void SaveInt(const kStr &in fieldname, int value) const;
  void SaveUint(const kStr &in fieldname, uint value) const;
  void SaveBool(const kStr &in fieldname, bool value) const;
  void SaveKStr(const kStr &in fieldname, const kStr &in value) const;
  
  // Deserialization functions - you can call these from the script object's 
  // void DeSerialize() method to load data specific to the script object from 
  // a saved game.
  int LoadInt(const kStr &in fieldname);
  uint LoadUint(const kStr &in fieldname);
  bool LoadBool(const kStr &in fieldname);
  kStr LoadKStr(const kStr &in fieldname);
  
  // Two thinker references are provided in the ScriptThinker class which can 
  // be used for any purpose to refer to other Thinker instances. The game 
  // assumes responsibility for serializing these fields. These are reference
  // counted pointers, so the other thinker instances cannot be freed while 
  // these fields still refer to them.
  Thinker @GetOtherRef1() const;
  Thinker @GetOtherRef2() const;
  void SetOtherRef1(Thinker @other);
  void SetOtherRef2(Thinker @other);
}

To use ScriptThinker, you must define an AngelScript class which adheres to the
following interface:

   class AnyClassName {
      // Define a constructor (object factory) which receives the ScriptThinker 
      // handle. You can perform any type of initialization of the AngelScript 
      // object in this constructor. Because the script object has the same 
      // lifetime as the ScriptThinker, it is safe to store a handle to it in 
      // this object for later use.
      AnyClassName(ScriptThinker @th);
      
      // Define the Remove method to perform any custom logic when an instance 
      // of this thinker type is removed from the game.
      void Remove();
      
      // Define the Serialize method to handle saving data in this object when 
      // a saved game is created.
      void Serialize() const;
      
      // Define the DeSerialize method to handle loading data from a saved game 
      // back into this object.
      void DeSerialize();
      
      // Define the Think method to do per-tic logic for this thinker type.
      void Think();
   }

After defining this class, you can create an instance of ScriptThinker which 
will create and keep track of a scripted object of the defined class by using
the following global function:

   ScriptThinker @CreateScriptThinker(const kStr &in asClassName);
   
Pass the scripted object class name ("AnyClassName" in the example above) as the
parameter; you will receive back a handle to the ScriptThinker instance. Note 
that you must call Thinker::Add() on the new ScriptThinker before returning from 
the context in which it was created or the instance will NOT think and furthermore
it will be leaked, which could eventually cause an out-of-memory error.


//
// All thinkers which affect sectors inherit from SectorThinker. It provides
// methods to track the sector which the thinker affects. All SectorThinker 
// child classes have these methods.
//
class SectorThinker : Thinker {
  // Get handle to the sector. May be null.
  sector_t @GetSector() const;
  // Set sector handle to a sector at index "secnum" in the World object.
  void SetSectorByNum(uint secnum);
  // Set sector handle directly.
  void SetSector(sector_t @ sec);
}

//
// Thinker type which drives moving ceilings. Inherits from SectorThinker.
//
class CeilingMover : SectorThinker {
  // Get next ceiling mover instance if any. Null otherwise.
  CeilingMover @GetNextCeiling() const;
  // Get type of ceiling mover.
  ceiling_e GetCeilingType() const;
  // Get bottom height of motion.
  fixed_t GetBottomHeight() const;
  // Get top height of motion.
  fixed_t GetTopHeight() const;
  // Get speed of motion in units per tic.
  fixed_t GetSpeed() const;
  // Get crushing property.
  bool GetCrush() const;
  // Get direction of movement (1 = up, 0 = waiting, -1 = down)
  int GetDirection() const;
  // Get tag
  int GetTag() const;
  // Get previous direction
  int GetOldDirection() const;
  // Set type of ceiling mover
  void SetCeilingType(ceiling_e t);
  // Set bottom height of motion
  void SetBottomHeight(fixed_t h);
  // Set top height of motion
  void SetTopHeight(fixed_t h);
  // Set speed of motion in units per tic.
  void SetSpeed(fixed_t s);
  // Set crushing property
  void SetCrush(bool bCrush);
  // Set direction of movement
  void SetDirection(int dir);
  // Set tag
  void SetTag(int t);
  // Set previous direction
  void SetOldDirection(int dir);
}

//
// Thinker type which drives vertical door actions. Inherits from SectorThinker.
//
class VerticalDoorMover : SectorThinker {
  // Get type of vertical door mover.
  vldoor_e GetType() const;
  // Get top height
  fixed_t GetTopHeight() const;
  // Get speed in units per tic.
  fixed_t GetSpeed() const;
  // Get direction of motion (1 = up, 0 = waiting, -1 = down)
  int GetDirection() const;
  // Get duration in tics to wait at top
  int GetTopWait() const;
  // Get current wait timer
  int GetTopCountdown() const;
  // Set type of vertical door mover
  void SetType(vldoor_e dt);
  // Set top height
  void SetTopHeight(fixed_t th);
  // Set speed of motion
  void SetSpeed(fixed_t sp);
  // Set direction of motion
  void SetDirection(int dir);
  // Set top wait duration
  void SetTopWait(int tw);
  // Set current wait countdown
  void SetTopCountdown(int tcd);
}

//
// Secondary thinker spawned by swinging door Actors during their opening motion.
//
class DoorObject : Thinker {
  // Get parent Actor
  Actor @GetActor() const;
  // Get BAM starting angle
  angle_t GetStartAngle() const;
  // Get BAM target angle
  angle_t GetTargetAngle() const;
  // Get interpolation data
  float GetTweenFrac() const;
  // If true, has made opening sound effect
  bool GetCreaked() const;
}

//
// Thinker type which drives floor movement. Inherits from SectorThinker.
//
class FloorMover : SectorThinker {
  // Get type of floor mover
  floor_e GetFloorType() const;
  // Get crushing property
  bool GetCrush() const;
  // Get direction of motion
  int GetDirection() const;
  // Get special to which sector will change when motion completes
  int GetNewSpecial() const;
  // Get texture to which sector will change when motion completes
  const kStr &GetTexture() const;
  // Get fixed-point destination floor height
  fixed_t GetFloorDestHeight() const;
  // Get fixed-point destination ceiling height
  fixed_t GetCeilingDestHeight() const;
  // Get speed of motion in units per tic
  fixed_t GetSpeed() const;
  // Set floor mover type
  void SetFloorType(floor_e t);
  // Set crushing property
  void SetCrush(bool bCrush);
  // Set direction of motion
  void SetDirection(int dir);
  // Set special to which sector will change when motion completes
  void SetNewSpecial(int spc);
  // Set texture to which sector will change when motion completes
  void SetTexture(const kStr &in tx);
  // Set floor destination height
  void SetFloorDestHeight(fixed_t f);
  // Set ceiling destination height
  void SetCeilingDestHeight(fixed_t c);
  // Set speed of motion
  void SetSpeed(fixed_t spd);
}

//
// Thinker type which drives fire flicker lighting effect. Inherits from 
// SectorThinker.
//
class FireFlickerThinker : SectorThinker {
  // Get counter
  uint GetCount() const;
  // Get maximum light level
  uint GetMaxLight() const;
  // Get minimum light level
  uint GetMinLight() const;
  // Set counter
  void SetCount(uint c);
  // Set maximum light level
  void SetMaxLight(uint ml);
  // Set minimum light level
  void SetMinLight(uint ml);
}

//
// Thinker type which drives random flashing light effect. Inherits from
// SectorThinker.
//
class LightFlashThinker : SectorThinker {
  // Get counter
  uint GetCount() const;
  // Get maximum light level
  uint GetMaxLight() const;
  // Get minimum light level
  uint GetMinLight() const;
  // Get maximum period length
  uint GetMaxTime() const;
  // Get minimum period length
  uint GetMinTime() const;
  // Set counter
  void SetCount(uint c);
  // Set max light level
  void SetMaxLight(uint ml);
  // Set min light level
  void SetMinLight(uint ml);
  // Set maximum period length
  void SetMaxTime(uint mt);
  // Set minimum period length
  void SetMinTime(uint mt);
}

//
// Thinker type which drives strobing light effect. Inherits from SectorThinker.
//
class StrobeThinker : SectorThinker {
  // Get counter
  uint GetCount() const;
  // Get max light level
  uint GetMaxLight() const;
  // Get min light level
  uint GetMinLight() const;
  // Get time spent in bright phase
  uint GetBrightTime() const;
  // Get time spent in dark phase
  uint GetDarkTime() const;
  // Set counter
  void SetCount(uint c);
  // Set max light level
  void SetMaxLight(uint ml);
  // Set min light level
  void SetMinLight(uint ml);
  // Set time spent in bright phase
  void SetBrightTime(uint bt);
  // Set time spent in dark phase
  void SetDarkTime(uint dt);
}

//
// Thinker type which drives glowing light effect. Inherits from SectorThinker.
//
class GlowThinker : SectorThinker {
  // Get max light level
  uint GetMaxLight() const;
  // Get min light level
  uint GetMinLight() const;
  // Get direction of fade
  int GetDirection() const;
  // Set max light level
  void SetMaxLight(uint ml);
  // Set min light level
  void SetMinLight(uint ml);
  // Set direction of fade
  void SetDirection(int dir);
}

//
// Thinker type which drives moving platform actions (floors with more complex
// behavior patterns). Inherits from SectorThinker.
//
class PlatMover : SectorThinker {
  // Get next PlatMover instance, if any. Null otherwise.
  PlatMover @GetNextPlat() const;
  // Get speed of motion in units per tic.
  fixed_t GetSpeed() const;
  // Get low height.
  fixed_t GetLow() const;
  // Get high height.
  fixed_t GetHigh() const;
  // Get wait time.
  int GetWait() const;
  // Get counter.
  int GetCount() const;
  // Get sector tag
  int GetTag() const;
  // Get plat status.
  plat_e GetStatus() const;
  // Get previous plat status
  plat_e GetOldStatus() const;
  // Get plat type
  plattype_e GetPlatType() const;
  // Get crushing property
  bool GetCrush() const;
  // Set speed.
  void SetSpeed(fixed_t sp);
  // Set low height.
  void SetLow(fixed_t lw);
  // Set high height.
  void SetHigh(fixed_t hg);
  // Set wait time.
  void SetWait(int wt);
  // Set counter.
  void SetCount(int ct);
  // Set sector tag.
  void SetTag(int tg);
  // Set plat status.
  void SetStatus(plat_e st);
  // Set old plat status.
  void SetOldStatus(plat_e os);
  // Set plat type
  void SetPlatType(plattype_e pt);
  // Set crushing property
  void SetCrush(bool bc);
}

//
// Point and deltas for a line during clipping operations
//
class divline_t {
  fixed_t x;
  fixed_t y;
  fixed_t dx;
  fixed_t dy;
}

//
// Intercept created during a trace operation
//
class intercept_t {
  // Fractional distance along the trace
  fixed_t frac;
  // If true, is a linedef
  bool isaline; 
  // If true, is a door
  bool isadoor;
  
  // If !isaline && !isadoor, returns handle to Actor intercepted. Null otherwise.
  Actor @GetActor() const;
  
  // If isaline, returns handle to linedef intercepted. Null otherwise
  line_t @GetLine() const;
}

//
// Class holding temporary data for a trace process
//
class PInterceptsContext {
  // Divline representing the full trace
  divline_t trace;
  // Earlyout flag
  bool earlyout;
  // trace bit flags (see PTFlags enumeration)
  int ptflags;

  // Return handle to the intercept at the given index
  const intercept_t @GetInterceptAt(uint idx) const;
  // Get number of valid intercepts
  uint GetNumIntercepts() const;
}

//
// State information for a player's weapon sprites
//
class pspdef_t {
  // Current state. May be null.
  const ActorState @state;
  // Time left in current state in 60 Hz ticks
  int tics;
  // X position on screen relative to anchor spot
  fixed_t sx;
  // Y position on screen relative to anchor spot
  fixed_t sy;
  // Leveltime at which weapon last clicked
  int lastclick;
}

//
// Player's inventory of Tess Objects (Winged Vessels) is represented by an 
// array of these objects.
//
class TessBodyPart {
  bool isOwned; // If true, player has this object
  bool didKey;  // If true, player has placed object on the pedastal
  int  charges; // Number of charges held
}

//
// PlayerMessage object contained in the Player class. Allows giving the player 
// textual messages.
//
class PlayerMessage {
  // Return any current message at the indicated priority level. Empty string if none.
  const kStr &GetMessage(PlayerMsgPriority prio) const;
  // Set player message with the given priority level. Localization tokens are supported.
  void SetMessage(const kStr &in str, PlayerMsgPriority prio);
  // Query if message at priority level is active.
  bool HasMessage(PlayerMsgPriority prio) const;
  // Query if a message at any priority level is active.
  bool HasMessages() const;
  // Cler all messages
  void Clear();
  // Clear a specific priority level of message.
  void ClearMessage(PlayerMsgPriority prio);
  // Get tics left on message countdown at priority level.
  int GetTics(PlayerMsgPriority prio) const;
  // Get alpha of message at priority level.
  int GetAlpha(PlayerMsgPriority prio) const;
}

//
// PlayerCmd class is a global singleton object available through the global 
// GetPlayerCmd() function. Allows tracking and responding to player input.
//
class PlayerCmd {
  // Reset all player input state
  void Reset();
  // Cler button hold timers
  void ClearButtonHoldTimes();
  // Query time button has been held
  uint ButtonHeldTime(const inputActions_e dwButtonIndex) const;
  // Get currently held button cmd flags
  const buttonCmd_e Buttons() const;
  // Query if button is currently down
  bool IsButtonDown(buttonCmd_e btn) const;
  // Set buttons down
  void SetButtons(buttonCmd_e eSetFlags);
  // Clear buttons
  void ClearButtons(const buttonCmd_e eClearFlags);
  // Get current input device index
  int GetCurrentDevice() const;
  // Get current target input device for haptic vibrations
  int GetHapticDevice() const;
  // Get X angle component
  float GetAngleX() const;
  // Get Y angle component
  float GetAngleY() const;
  // Set X angle component
  void SetAngleX(float x);
  // Set Y angle component
  void SetAngleY(float y);
  // Set XY angle components
  void SetAnglesXY(float x, float y);
  // Get X movement component
  float GetMovementX() const;
  // Get Y movement component
  float GetMovementY() const;
  // Set X movement component
  void SetMovementX(float x);
  // Set Y movement component
  void SetMovementY(float y);
  // Set XY movement components
  void SetMovementXY(float x, float y);
  // Get X mouse turn delta component
  float GetMouseTurnDeltaX() const;
  // Get Y mouse turn delta component
  float GetMouseTurnDeltaY() const;
  // Get X gamepad turn delta component
  float GetGamepadTurnDeltaX() const;
  // Get Y gamepad turn delta component
  float GetGamepadTurnDeltaY() const;
  // Get save game slot
  int GetSaveGameSlot() const;
}

//
// The Player class is a global singleton holding most data for the Player. It
// is always available as the `g_player` global variable.
//
class Player {
  // Cause the player to reinitialize as if a new game has started
  void Reborn();
  
  // Force player interpolated data to current values. Appropriate when teleporting.
  void UpdatePlayerInterpData();
  
  // Get current playerstate
  PlayerState GetPlayerState() const;
  // Set current playerstate
  void SetPlayerState(PlayerState ps);
  
  // Get Player cheat flags
  PlayerCheats GetCheats() const;
  // Test if a specific cheat is enabled
  bool IsCheatSet(PlayerCheats cs) const;
  // Set cheats enabled
  void SetCheats(PlayerCheats cs);
  // Set cheats disabled
  void UnsetCheats(PlayerCheats cs);
  // Clear/disable all cheats
  void ClearCheats();
  
  // Get player name entered when save file was created
  const kStr &GetPlayerName() const;
  
  // Get handle to PlayerMessage object
  PlayerMessage @ GetPlayerMessageHandle();
  
  // Get player's Actor.
  Actor @ GetActor() const;
  
  // Get player's last attacker.
  Actor @ GetAttacker() const;
  // Set player's last attacker.
  void SetAttacker(Actor @ actor);
  
  // Get health.
  int GetHealth() const;
  // Get maximum health.
  int GetMaxHealth() const;
  // Set health. Must also update actor's health.
  void SetHealth(int h);
  // Set maximum health.
  void SetMaxHealth(int mh);
  // Heal player for a given amount with specified maxout behavior.
  bool GiveBody(int amount, bool maxout);
  
  // Query current ammo amount by ammo index.
  int AmmoForType(uint type) const;
  // Query current max ammo by ammo index.
  int MaxAmmoForType(uint type) const;
  // Set ammo by ammo index.
  void SetAmmoForType(uint type, int ammo);
  // Set max ammo by ammo index.
  void SetMaxAmmoForType(uint type, int maxammo);
  // Give player ammo
  bool GiveAmmo(uint ammotype, int amt);
  
  // Get extra light caused by player gunflashes
  int GetExtraLight() const;
  
  // Get index of player's ready weapon.
  int GetReadyWeapon() const;
  
  // Get index of player's pending weapon. -1 if no change is pending.
  int GetPendingWeapon() const;
  
  // Query if weapon is owned by weapon index.
  bool GetWeaponOwned(uint type) const;
  
  // If true, player is holding down fire for consecutive attacks.
  bool IsRefiring() const;
  
  // Set extra light caused by player gunflash.
  void SetExtraLight(int light);
  
  // Set player's ready weapon by index
  void SetReadyWeapon(int rw);
  // Set player's pending weapon by index. -1 means no change.
  void SetPendingWeapon(int pw);
  
  // Returns number of times player has refired
  int GetRefire() const;
  // Set number of times player has refired
  void SetRefire(int refire);
  // Clear refire count.
  void ClearRefire();
  // Increment refire count by one.
  int IncrementRefire();
  
  // Calculate slope for attacks based on player's vertical aim
  fixed_t CalcSlope() const;
  
  // Give the player a weapon by weapon index
  bool GiveWeapon(uint type);
  
  // Bring up the player's ready weapon
  void BringUpWeapon();
  
  // Check if player has sufficient ammo to fire weapon
  bool CheckAmmo(const WeaponDef @ wp) const;
  // Check if weapon has infinite ammo.
  bool HasInfiniteAmmo(const WeaponDef @ wp) const;
  // Check if player readyweapon has sufficent ammo to fire
  bool CheckAmmo() const;
  // Check if player readyweapon has sufficient ammo to fire and if not, change weapons
  bool CheckAmmoWithChange();
  // Check for weapon change when new ammo has been collected
  bool ChangeWeaponForNewAmmo(uint type);
  // Change to highest priority weapon which supports the strength powerup
  void ChangeToStrengthMode();
  
  // Fire the player's ready weapon
  void FireWeapon();
  
  // Lower the player's weapon
  void DropWeapon();
  
  // Decrease the given ammo type by the given amount, not to decrease below zero.
  void DecreaseAmmo(uint ammotype, int amount);
  // Decrease the ready weapon's ammo by its ammo-per-shot
  void DecreaseAmmoForReadyWeapon();
  
  // Spawn a missile. Shortcut to Actor::SpawnPlayerMissile.
  Actor @SpawnMissile(uint type, int momz, AutoAimFlags aaf=AutoAimFlags::NORMAL);
  
  // Get WeaponDef of the player's readyweapon.
  const WeaponDef @GetReadyWeaponDef() const;
  // Get WeaponDef of the player's pending weapon. Null if no pending change.
  const WeaponDef @GetPendingWeaponDef() const;
  
  // Find next weapon in priority order
  const WeaponDef @FindNextWeapon() const;
  // Find previous weapon in priority order
  const WeaponDef @FindPrevWeapon() const;
  
  // True if ready weapon is declared as a melee weapon in its definition
  bool HasMeleeWeaponEquipped() const;
  // Query if weapon is owned by index.
  bool IsWeaponOwned(uint idx) const;
  // Set weapon owned by index.
  void SetWeaponOwned(uint idx, bool b);
  
  // Get handle to psprite at given index.
  pspdef_t @GetPspriteRef(PspriteNum num);
  
  // Get powerup status. > 0 means active.
  int GetPower(powertype_t power) const;
  // Give a powerup. If useTessObj is true, a corresponding Tess Object will be used up, if any.
  bool GivePower(powertype_t power, bool useTessObj);
  // Take away a powerup.
  void TakePower(powertype_t power);
  
  // Activate the genocide bomb effect.
  void GenocideBomb(fixed_t x, fixed_t y, int radius);
  
  // Give a specified TessObject
  bool GiveTessBodyPart(TessObjects to);
  // Use a TessObject effect by index.
  void UseTessEffect(TessObjects to);
  // Get TessBodyPart object handle by index.
  TessBodyPart @GetTessBodyPart(TessObjects to);
  // Get number of owned TessBodyPart objects.
  uint GetTessBodyPartInventoryCount() const;
  // Test if Tess Object inventory window is open
  bool GetTessWindowVisiblity() const;
  // Set Tess Object inventory window visibility
  void SetTessWindowVisiblity(bool b);
  // Set player's selected TessBodyPart.
  void SetTessBodyPartSelected(uint index);
  // Reset Tess Body Part selection to no selected object.
  void ResetTessBodyPartSelected();
  // Add the delta to the currently selected TessObject and select that object.
  void SetTessBodyPartSelectedRelative(int delta);
  // Get currently selected Tess Body Part.
  uint GetTessBodyPartSelected() const;
  // Returns constant value for "no object selected".
  uint GetTessBodyPartNoSelection() const;
  
  // Test if player has indicated key.
  bool HasCard(const kStr &in name) const;
  // Give the player a key (use the ActorInfo definition name).
  bool GiveCard(const kStr &in name);
  // Take away a player's key.
  bool RemoveCard(const kStr &in name);
  // Query if player has tried to unlock a given door
  uint GetFlashKeyState(uint idx) const;
  // Set player state for having tried to unlock a given door. `locknum` is the lockdef ID.
  void SetFlashKeyState(uint idx, uint locknum);
  
  // Get absolute view z.
  fixed_t GetViewZ() const;
  // Get prior view z for interpolation.
  fixed_t GetOldViewZ() const;
  // Get relative view height
  fixed_t GetViewHeight() const;
  // Set relative view height
  void SetViewHeight(fixed_t f);
  // Get per-frame delta to view height (eg., due to impacts on the ground)
  fixed_t GetDeltaViewHeight() const;
  // Get view bobbing factor
  fixed_t GetBob() const;
  // Get vertical view angle
  fixed_t GetLookUpAngle() const;
  // Get prior vertical view angle, for interpolation
  fixed_t GetOldLookUpAngle() const;
  // Query if player is on solid ground
  bool IsOnGround() const;
  // Get jump countdown timer
  int GetJumpTimer() const;
  // Set jump countdown timer
  void SetJumpTimer(int jt);
  
  // Test if player can uncrouch
  bool FitsAtLocation() const;
  
  // Recalculate player's view z, view height.
  void CalcHeight();
  // Get timer for water splash sound effects
  int GetSplashTimer() const;
  // Set timer for water splash sound effects
  void SetSplashTimer(int t);
  
  // Is player holding down attack?
  bool IsAttackDown() const;
  // Is player holding down "use"?
  bool IsUseDown() const;
  // Set attack as up or down.
  void SetAttackDown(bool b);
  // Set use as up or down.
  void SetUseDown(bool b);
  
  // If Game is in GameState::LEVEL, player has a valid living actor, and player is
  // in PlayerState::LIVE, returns true. False otherwise.
  bool CanSave() const;
}

================================================================================
Global Functions
================================================================================

The following global functions are available:

------
Actors
------

Actor @P_SpawnActor(fixed_t x, fixed_t y, fixed_t z, angle_t angle, uint type);
  Spawn actor with ActorInfo index at (x, y, z) and given angle.

Actor @P_SpawnMissile(Actor @source, Actor @dest, uint type);
  Spawn a missile. Dest == null is allowed; the missile will be fired at the
  source actor's current angle.

Actor @P_SpawnMissileEx(Actor @source, fixed_t x, fixed_t y, fixed_t z, angle_t angle, fixed_t momz, uint type);
  Missile spawning with additional parameters supported.

Actor @P_FindActorFromID(uint id, const Actor @rover);
  If rover is null,
     Returns the first actor with the given scripting ID, else null if none.
  If rover is not null,
     Returns the next actor with the same scripting ID, else null if no more.
  Call repeatedly with the prior result as rover in order to iterate on all 
  actors with the same ID, until null is returned.

void P_NoiseAlert(Actor @target, Actor @emitter);
  Begin sound propagation from emitter and record target as the source of the
  sound. MapInfo must enable sound propagation for this to have full effect.

void P_DeathSlide(Actor @ actor, fixed_t x, fixed_t y);
  Test if the Actor can slide to the location (x,y), testing for intersections
  with one-sided lines along the way. The motion will be cut short if any such
  lines are intersected.

bool P_TouchSpecialThing(Actor @special, Actor @toucher);
  Have actor "toucher" attempt to collect actor "special" as an item. This is 
  only supported for touchers who are players, other objects will simply return
  from the routine immediately.

void P_RadiusAttack(Actor @spot, Actor@ source, int damage, int radius);
  Create a blast radius attack at spot, blaming source for any damage done,
  with independent damage and radius.

bool P_CheckSight(const Actor @t1, const Actor @t2);
  Check if actor t1 can see actor t2.

bool P_SpawnActorOnSectorTag(int ednum, int sectorTag);
  Spawn actor(s) with editor number `ednum` at TeleportMan objects in the tagged
  sector(s).

bool TeleportToTag(int tag, Actor @pActor, bool getFacing);
  Teleport pActor to a TeleportMan object in the first tagged sector.

bool PerformATeleport(line_t @pLine, Actor @pActor);
  If pLine.special is >= 9700, game will hub transition to the map (special - 9700).
  Otherwise, TeleportToTag is called with the line's tag.

bool P_TeleportMove(Actor @thing, fixed_t x, fixed_t y);
  Generic teleport routine.

---------
ActorInfo
---------

bool IsValidActorClass(uint classnum);
  Returns true if the index is >= 0 and < number of ActorInfo definitions

const ActorInfo @ActorInfoForString(const kStr &in str);
  Look up an ActorInfo definition by name. Null if no such definition exists.
  
const ActorInfo @ActorInfoForNum(uint index);
  Look up an ActorInfo definition by index. Null if invalid.

----------
ActorState
----------

const ActorState @StateForString(const kStr &in str);
  Look up a state by its state name. Null if no such state exists.

const ActorState @StateForNum(uint index);
  Look up a state by its index. Null if invalid.

-------
DoorDef
-------

uint GetNumDoorDefs();
  Returns number of DoorDef objects defined
  
const DoorDef @GetDoorDefAt(uint idx);
  Get DoorDef object by index. Null if invalid.
  
const DoorDef @DoorDefForDoorNum(uint doornum);
  Look up DoorDef object by doornum ID. Null if no such definition exists.

--------------------
Filter Color Overlay
--------------------

void R_ScriptFilterFlash(filterflash_e type, const kColor color, uint millis, float decayScalar, float radiusScalar);
  Start a filter flash color overlay effect, such as is used for item collection,
  damage, and firing the Ankh weapon.

---
HUD
---

int HUD_ScreenWidth();
  Get physical screen width.

int HUD_ScreenHeight();
  Get physical screen height.

int HUD_FindTextureRaw(const kStr &in strTextureName, bool linear);
  Look up a texture by name. Returns texture handle.

int HUD_FindTexture(const kStr &in strTextureName, bool hires);
  Look up a texture supporing low/hi-res toggle. Returns texture handle.

int HUD_CreateFont(const kStr &in strFontName, float size);
  Load a FreeType font. Returns font handle.

float HUD_FontStringHeight(int handle, const kStr &in str, float scale);
  Calculate height of a line of text in the given font.

int HUD_TextureWidth(int handle);
  Get texture width.

int HUD_TextureHeight(int handle);
  Get texure height.

int HUD_TextureOffsetX(int handle);
  Get texture x offset (defined via JSON); 0 if none.

int HUD_TextureOffsetY(int handle);
  Get texture y offset (defined via JSON); 0 if none.

void HUD_DrawTexture(int handle, int x, int y, int w, int h);
  Draw indicated texture at (x,y) with given dimensions (w,h)

void HUD_DrawRectangle(int x1, int y1, int x2, int y2, const kColor &in color);
  Draw a solid color rectangle.

void HUD_DrawText(int handle, const kStr &in str, int x, int y, float scale, int align);
  Draw text using the indicated font by handle. Localization tokens are supported.

void HUD_DrawTextColor(int handle, const kStr &in str, int x, int y, float scale, int align, const kColor &in color);
  Draw colored text.

void HUD_FreeResources();
  Free HUD textures and fonts.

float GetRotatingHue();
  Returns a rotating hue value suitable for conversion to kColor using its 
  HSVtoRGB method. This is used by HUD and automap components to draw items 
  with a rainbow color shifting effect.

---------------
Linedef Actions
---------------

bool EV_DoCeiling(line_t @line, ceiling_e type);
  Spawn a ceiling action.

bool EV_CeilingCrushStop(line_t @line);
  Stop crushing ceilings.

bool EV_DoDoor(const line_t @pLine, vldoor_e type);
  Start a remotely triggered door action.

void EV_VerticalDoor(const line_t @pLine, Actor @pActor);
  Start a manual door action.

void P_SpawnDoorCloseIn30(sector_t @ pSector);
  Spawn a door which closes in 30 seconds.

void P_SpawnDoorRaiseIn5Mins(sector_t @ pSector);
  Spawn a door which raises after 5 minutes.

void P_SpawnMovingDoorObject(Actor @pTargetDoorActor);
  Spawn a swinging door.

result_e T_MovePlane(sector_t @sector, fixed_t speed, fixed_t dest, bool crush, int floorOrCeiling, int direction);
  Move the floor or ceiling plane up or down with full control over parameters.

bool EV_BuildStairs(const line_t @line, stair_e type);
  Start a stair building action.

bool EV_DoDonut(const line_t @line);
  Start a donut action.
  
bool EV_DoFloor(const line_t @line, floor_e floortype, int extraParm=0);
  Start a floor moving action.

void P_SpawnFireFlicker(sector_t @pSector);
  Spawn a FireFlickerThinker affecting this sector.

void P_SpawnLightFlash(sector_t @pSector);
  Spawn a LightFlashThinker affecting this sector.

void P_SpawnStrobeFlash(sector_t @pSector, uint fastOrSlow, bool inSync);
  Spawn a StrobeThinker affecting this sector.

void P_SpawnGlowingLight(sector_t @pSector);
  Spaawn a GlowThinker affecting this sector.

void EV_StartLightStrobing(const line_t @pLine);
  Spawn a StrobeThinker affecting this sector.

void EV_TurnTagLightsOff(const line_t @pLine);
  Turn tagged sectors' lights to 0.

void EV_LightTurnOn(const line_t @pLine, uint bright);
  Turn tagged sectors' lights to 255.

bool P_ChangeSector(sector_t @sector, bool crunch);
  Call to update Actors in a moving sector.

bool EV_DoPlat(line_t @pLine, plattype_e type, int amount);
  Start a plat action.

void EV_StopPlat(line_t @pLine);
  Stop a perpetual plat.

bool P_UseSpecialLine(Actor @thing, line_t @line, int side);
  Have the actor attempt to activate a special line by using it.
  
void P_ChangeSwitchTexture(line_t @line, bool useAgain);
  If the linedef has a switch texture, then its button state will advance. If
  `useAgain` is false, the line's special will be cleared to 0.

-------
LockDef
-------

uint GetNumLockDefs();
  Returns the number of LockDefs defined.
  
const LockDef @GetLockDefAt(uint idx);
  Look up LockDef record by index. Null if invalid.
  
const LockDef @LockDefForLockNum(uint locknum);
  Look up LockDef by lock ID number. Null if no such LockDef defined.
  
bool P_CheckKey(Player @pPlayer, int keyNum, bool giveNeedMsg);
  Check if the player can unlock the specified lock ID. If giveNeedMsg is true,
  messages and sound effects will occur, otherwise this is a silent check only.
  
-------------
Map Utilities
-------------

int P_AproxDistance(fixed_t dx, fixed_t dy);
  Return fixed-point approximate distance.

int P_PointOnLineSide(fixed_t x, fixed_t y, const line_t @line);
  Classify point versus linedef. 

sector_t @getNextSector(const line_t @line, const sector_t @sec);
  Gets the sector on the opposite side of the line which is not `sec`.

fixed_t P_FindLowestFloorSurrounding(const sector_t @sec);
  Returns height of the lowest surrounding floor.

fixed_t P_FindHighestFloorSurrounding(const sector_t @sec);
  Returns height of the highest surrounding floor.

fixed_t P_FindNextHighestFloor(const sector_t@ sec, fixed_t currentheight);
  Returns the height of the next highest surrounding floor.

fixed_t P_FindLowestCeilingSurrounding(const sector_t @sec);
  Returns the height of the lowest surrounding ceiling.

fixed_t P_FindHighestCeilingSurrounding(const sector_t @sec);
  Returns the height of the highest surrounding ceiling.

uint P_FindMinSurroundingLight(const sector_t @sector, uint max);
  Returns the lowest surrounding light level.

int P_FindSectorFromLineTag(const line_t @line, int start);
  Find the next sector with the same tag as the given linedef, starting at 
  sector index `start`.

int P_FindSectorFromTag(int tag);
  Find the first sector with a matching tag. Returns -1 if none.

int P_FindSectorFromTag2(int tag, int start);
  Find the next sector with the matching tag starting from sector index `start`.

int P_FindLinedefFromTag(int tag);
  Find the first linedef with a matching tag. Returns -1 if none.

sector_t @P_FindSectorFromSpecial(uint special, sector_t @sector);
    Find the next sector with the indicated special, starting from `sector` (if
    null, starts from the beginning).

line_t @P_FindLineFromSpecial(uint special, line_t @line);
    Find the next linedef with the indicated special, starting from `line` (if
    null, starts from the beginning).

----------
MapInfoDef
----------

const MapInfoDef @MapInfoForStr(const kStr &in name);
  Look up a MapInfoDef object by the map name. ".wad" should not be included.
  
----
Math
----

fixed_t FixedMul(fixed_t a, fixed_t b);
  Multiply two fixed-point numbers.

fixed_t FixedDiv(fixed_t a, fixed_t b);
  Divide two fixed-point numbers.

fixed_t FineCosine(angle_t an);
  Look up the cosine of a BAM. The value must be shifted down first using the 
  ANGLETOFINESHIFT constant (defined in ktdef.txt)

fixed_t FineSine(angle_t an);
  Look up the cosine of a BAM. The value must be shifted down first using the 
  ANGLETOFINESHIFT constant (defined in ktdef.txt)

fixed_t FineTangent(angle_t an);
  Look up the cosine of a BAM. The value must be shifted down first using the 
  ANGLETOFINESHIFT constant (defined in ktdef.txt)

--------------
Movies
--------------

void P_MovieStart(Actor @actor, int movienum);
  Have actor play the indicated movie by movie def ID.

void P_MovieStop(bool noMusicRestart);
  Stop any currently playing actor movie.

void P_MoviePause();
  Pause any currently playing actor movie.

void P_MovieResume();
  Resume any currently paused actor movie.

bool P_MovieIsPlaying();
  Query if an actor movie is currently playing.

---------
PlayerCmd
---------
PlayerCmd &GetPlayerCmd();
  Obtain reference to the global singleton PlayerCmd object.

------
Player
------

void P_SetPsprite(Player @player, PspriteNum position, uint statenum);
  Set the player's psprite at the given index to the indicated state by index.

-----------------------
Random Number Generator
-----------------------

uint M_Random();
  Return a random between 0 and 255 which does not interact with gamesim.
  
uint P_Random();
  Return a random between 0 and 255 intended for use with the gamesim.

uint P_BurgerRandom(int max);
  Return a random number chosen in a manner similar to the game's original RNG.

int P_BurgerRandomSigned(int max);
  Return a signed random number chosen in a manner similar to the game's 
  original RNG.

int P_SubRandom();
  Return the signed difference between two RNG calls without invoking a 
  dependency on order of evaluation.
  
------------------
Renderer Utilities
------------------

bool R_PointInSubsectorStrict(const subsector_t @ssec, fixed_t x, fixed_t y);
  Test if the indicated point lies entirely within the provided subsector, as 
  judged by it being on the first side of every seg in the subsector.

angle_t R_PointToAngle(fixed_t x, fixed_t y);
  Classify octant of point and return its global angle.

angle_t R_PointToAngle2(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2);
  Determine angle between two points.

angle_t R_PointToAngleAccurate(fixed_t x, fixed_t y);
  Classify octant of point and return its global angle using floating-point 
  arctangent function.

angle_t R_PointToPitch(fixed_t z1, fixed_t z2, fixed_t dist);
  Undocumented.

angle_t R_PointToAngleFloat(fixed_t x, fixed_t y);
  Undocumented.
  
--------------------------
Serializable Script Values
--------------------------

ScriptBasicValue @FindScriptBasicValue(const kStr &in name);
  Find a ScriptBasicValue by name. Returns null if no such variable is defined.

ScriptBasicValue @FindOrCreateScriptBasicValue(const kStr &in name, ScriptValueScope scope=ScriptValueScope::WORLD);
  Find a ScriptBasicValue by name if it exists. If it does not, the variable is
  created and returned with the given scope.

ScriptThinkerHandle @FindScriptThinkerHandle(const kStr &in name);
  Find a ScriptThinkerHandle by name. Returns null if no such variable is defined.

ScriptThinkerHandle @FindOrCreateScriptThinkerHandle(const kStr &in name, ScriptValueScope scope=ScriptValueScope::WORLD);
  Find a ScriptThinkerHandle by name if it exists. If it does not, the variable is
  created and returned with the given scope. Only LEVEL scope makes sense for this
  type of value in general but WORLD scope is still allowed.

------
Skybox
------

const Skybox @SkyboxForString(const kStr &in texturename);
  Look up a Skybox definition by its key (which is a corresponding 2D sky 
  texture name).
  
-----
Sound
-----

void S_StartSoundAtXYZStr(const kStr &in name, fixed_t x, fixed_t y, fixed_t z);
  Start a locational sound.

void S_StartSoundStr(Actor @origin, const kStr &in name);
  Start sound from an actor.

void S_StartSoundExclusiveStr(Actor @origin, const kStr &in name);
  Start sound from an actor. Any other sounds playing from the actor are stopped.

void S_StartMusicByID(uint id);
  Start a song by its music definition ID.

void S_StartMusicByIDWithFade(uint id);
  Start a song by its music definition ID, fading out any existing track first.

void S_StartMusicSpecial(SpecialMusic type);
  Start special music (title or credits).

void S_StopMusic();
  Stop any currently playing song.

const kStr &S_GetCurrentMusicTrack();
  Get file path of currently playing song.

void S_StartMusicStr(const kStr &in name);
  Start music by name.

bool S_IsSoundPlaying(const kStr &in name);
  Test if a sound is playing by name.

bool S_IsSoundPlayingByActor(const Actor @origin, const kStr &in name);
  Test if a specific actor is playing a sound by name.
  
-------
Tactile
-------

int Tactile_PlayStr(const kStr &in key, TactileChannel channel, TactilePosition position, float volume=1.0f);
  Start the named tactile effect with channel, position, and volume parameters.
  Returns handle to the running effect.

void Tactile_Stop(int handle);
  Stop the running tactile effect.

void Tactile_StopAll();
  Stop all running tactile effects.

void Tactile_Pause(bool paused);
  Pause or unpause ongoing tactile effects.
  
--------
Thinkers
--------

Thinker @GetThinkerCap();
  Get the head of the global list of active Thinker instances.
  
Thinker @CreateThinkerByClassName(const kStr &in classname);
  Creates a new instance of the given Thinker class. The object is only initialized
  at a basic level (default values); any customization is the responsibility of 
  the caller. You must call the Thinker::Add() method before returning from the 
  creation context or the object will NOT think, and will be leaked, which may 
  eventually cause an out-of-memory error.
  
ScriptThinker @CreateScriptThinker(const kStr &in asClassName);
  Create a ScriptThinker instance which is paired with a new instance of the 
  indicated AngelScript class. See the ScriptThinker class explanation for
  instructions on how to use this function.

---------
WeaponDef
---------

const WeaponDef @WeaponDefForString(const kStr &in str);
  Look up a WeaponDef object by its name. Null if no such definition exists.

const WeaponDef @WeaponDefForIndex(uint idx);
  Look up a WeaponDef object by its index. Null if invalid.

uint NumWeaponDefs();
  Returns the total number of WeaponDef objects.
  
-----
World
-----

World @GetWorld();
  Get the currently loaded World object. Null if GameState is not LEVEL.

================================================================================
Interfaces
================================================================================

The following interfaces are defined, allowing script-defined objects to be 
passed to certain functions and have their methods invoked:

----------------------
IBlockmapActorIterator
----------------------

Allows implementing a custom blockmap iteration for actors. Pass an instance of 
an object that implements this interface to the following function:

  bool P_ScriptBlockmapActorIterator(int bx, int by, IBlockmapActorIterator @iter);
  
(bx, by) are the coordinates of the block in the blockmap (use the blockmap
origin, blockmap width and height, and MAPBLOCKUNIT constant (defined in 
ktdef.txt) to translate and reduce world coordinates into blockmap indices.

interface IBlockmapActorIterator {
  bool Iterate(Actor @actor);
}

If the Iterate method returns false, the iteration will stop.

----------------------
IBlockmapLineIterator
----------------------

Allows implementing a custom blockmap iteration for linedefs. Pass an instance 
of an object that implements this interface to the following function:

  bool P_ScriptBlockmapLineIterator(int bx, int by, IBlockmapLineIterator @iter);
  
(bx, by) are the coordinates of the block in the blockmap (use the blockmap
origin, blockmap width and height, and MAPBLOCKUNIT constant (defined in 
ktdef.txt) to translate and reduce world coordinates into blockmap indices.

interface IBlockmapLineIterator {
  bool Iterate(line_t @line);
  bool IsLineVisited(uint index);
}

If the Iterate method returns false, the iteration will stop.

Use IsLineVisited to check if the line has already been processed, and to 
record what lines have been processed (use an array sized at World::NumLinedefs()).
If IsLineVisited returns false, the Iterate function will not be called for that
line.

--------------
IPathTraverser
--------------

Allows implementing a custom path traversal. Pass an instance of an object that 
implements this interface to the following function:

  bool P_ScriptPathTraverse(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2,
    PTFlags flags, IPathTraverser @trav);
    
interface IPathTraverser {
  bool Traverse(const PInterceptsContext @ctx, const intercept_t @intercept);
}

If the Traverse method returns false, the traversal will end.

================================================================================
KEX Engine Utilities
================================================================================

The following classes and other definitions are provided by the KEX Engine and 
are not specific to Killing Time.

// Defines flags for cvars
enum cvarFlags_t {
  CVF_BOOL,      // Boolean type
  CVF_INT,       // Integer type
  CVF_FLOAT,     // Floating point type
  CVF_STRING,    // String type
  CVF_CONFIG,    // Is saved to config file
  CVF_ALLOCATED, // Created at runtime (internal use only)
  CVF_HIDDEN,    // Hidden from console
  CVF_CHEAT,     // Activates social cheat flag
  CVF_VIRTUAL,   // Internal use only
  CVF_NETLOCK,   // Internal use only
  CVF_SERVER,    // Internal use only
  CVF_USER,      // Internal use only
  CVF_NOSET,     // Cvar is constant at runtime
  CVF_DEVELOPER  // Hidden from console unless developer variable is enabled
}

-------
kexCvar
-------
Allows defining a console variable. If the engine already defines the variable,
then this definition will have no effect other than to expose the cvar object to
scripting.

class kexCvar {
  // Constructor
  kexCvar(const kStr &in name, uint flags, const kStr &in defaultValue, const kStr &in desc);
  
  bool  GetBool()  const; // Get value converted to boolean
  int   GetInt()   const; // Get value converted to integer
  uint  GetUint()  const; // Get value converted to unsigned integer
  float GetFloat() const; // Get value converted to float
}

---------
kBitDelta
---------

class kBitDelta {
  bool WriteByte(uint8 i);
  uint8 ReadByte();
}

------
kColor
------
Represents an RGBA color.

class kColor {
  uint8 r, g, b, a;
  
  // Constructors
  kColor();                                   // Default constructor; alpha black
  kColor(const kColor &in other);             // Copy constructor
  kColor(uint8 r, uint8 g, uint8 b, uint8 a); // RGBA constructor
  kColor(const kColor &in other, uint8 a);    // Copy color but use different alpha
  kColor(uint8 rgb, uint8 a);                 // Construct grayscale color
  kColor(uint abgr);                          // Construct from 32-bit ABGR value
  kColor(float h, float s, float v);          // Construct from HSV
  
  // Obtain 32-bit ABGR
  uint DwColor() const;
  // Convert to kVec3
  kVec3 ToVec3() const;
  // Convert from kVec3
  void FromVec3(const kVec3 &in vec);
  // Convert to kVec3 containing linear values (0.0 - 1.0)
  kVec3 ToVec3Linear() const;
  // Convert from kVec3 containing linear values
  void FromVec3Linear(const kVec3 &in vec);
  // Convert to HSV, set saturation to 0, and convert back to RGB.
  void SetGrayScale();
  // Convert to HSV, set saturation, and convert back to RGB
  void SetSaturation(float s);
  // Convert to HSV, set value, and convert back to RGB
  void SetLuminance(float l);
  // Obtain HSV saturation
  float GetSaturation() const;
  // Obtain HSV value.
  float GetLuminance() const;
  
  // Implements operator =
  kColor &opAssign(const kColor &in other);
  
  // Linear interpolate this color toward the other color
  void LerpRGB(const kColor &in other, float t):

  // Create pre-multiplied RGBA version
  kColor ToPreMultiplied() const;
  
  // Pre-multiply RGBA in-place
  void PreMultiply();

  // Convert to HSV
  void RGBToHSV(float &out h, float &out s, float &out v) const;
  // Convert HSV to RGB in-place
  void HSVToRGB(float h, float s, float v);
  // Convert to HSL
  void RGBToHSL(float &out h, float &out s, float &out l) const;
  // Convert HSL to RGB in place
  void HSLToRGB(float h, float s, float l);

  // Implements operator ==
  bool   opEquals(const kColor &in) const;
  // Implements operator +
  kColor opAdd(const kColor &in) const;
  // Implements operator -
  kColor opSub(const kColor &in) const;
  // Implements operator *
  kColor opMul(const kColor &in) const;
  // Implements operator * 
  kColor opMul(float) const;
  // Implements operator +=
  kColor &opAddAssign(const kColor &in);
  // Implements operator -=
  kColor &opSubAssign(const kColor &in);
  // Implements operator *=
  kColor &opMulAssign(const kColor &in);
  // Implements operator *=
  kColor &opMulAssign(float);
}

kColor kexColor_FromHSL(float h, float s, float l);
  Obtain a kColor instance from HSL.

kColor kexColor_Random();
  Generate a random color.
  
kColor kexColor_Tab20(uint i);
  Obtain tab20 colors by color index.

kColor kexColor_Tab20Dark(uint i);
  Obtain dark tab20 colors by color index.
  
kColor kexColor_Tab20Light(uint i);
  Obtain light tab20 colors by color index.  
  
kColor kexColor_ViridisScale(float v);
  Obtain kColor using viridis scale value. v in [0.0, 1.0).
  
kColor kexColor_LerpRGB(const kColor &in first, const kColor &in second, float t);
  Linear interpolate between two colors.

// The kexColors namespace contains global color constants
namespace kexColors {
  const kColor white;
  const kColor gray;
  const kColor black;
  const kColor red;
  const kColor green;
  const kColor blue;
  const kColor yellow;
  const kColor orange;
  const kColor cyan;
  const kColor magenta;
  const kColor transparent;
  const kColor tab20blue;
  const kColor tab20blue2;
  const kColor tab20orange;
  const kColor tab20orange2;
  const kColor tab20green;
  const kColor tab20green2;
  const kColor tab20red;
  const kColor tab20red2;
  const kColor tab20purple;
  const kColor tab20purple2;
  const kColor tab20brown;
  const kColor tab20brown2;
  const kColor tab20pink;
  const kColor tab20pink2;
  const kColor tab20grey;
  const kColor tab20grey2;
  const kColor tab20olive;
  const kColor tab20olive2;
  const kColor tab20cyan;
  const kColor tab20cyan2;
}

-----
kDict
-----
kDict is a simple string-to-string map. kDictMem may also appear and is the same
type but in a form that can be passed to and from the engine with a handle.

class kDict {
  // Insert a { key, value } pair into the map
  void Add(const kStr &in key, const kStr &in value);
  // Clear the map
  void Empty();
  // If the key exists in the map, set its value. 
  void SetValue(const kStr &in key, const kStr &in value);
  // Query if a key exists in the map
  bool HasKey(const kStr &in key);
  
  // Translate string value of a key into various types, returing the default
  // value if the key does not exist.
  bool GetFloat(const kStr &in key, float &out f, const float defaultValue = 0);
  bool GetInt(const kStr &in key, int &out i, const int defaultValue = 0)",     
  bool GetBool(const kStr &in key, bool &out b, const bool defaultValue = false)
  bool GetString(const kStr &in key, kStr &out str);
  bool GetVector(const kStr &in key, kVec3 &out vec);
}

-----
kVec3
-----
Three-dimensional floating-point vector type.

class kVec3 {
  // Constructors
  kVec3();                          // Default constructor: { 0,0,0 }
  kVec3(float x, float y, float z);
  kVec3(const kVec3 &in other);     // Copy constructor
  
  // Normalize vector in-place.
  kVec3 &Normalize();
  
  // Return cross product of this x v2
  kVec3 Cross(const kVec3 &in v2) const;
  // Return dot product of this . v2
  float Dot(const kVec3 &in v2) const;
  // Return length of vector
  float Length() const;
  // Return square length of vector
  float LengthSq() const;
  // Return distance between points
  float Distance(const kVec3 &in vec) const;
  // Return square distance between points
  float DistanceSq(const kVec3 &in vec) const;
  // atan2(y, x)
  float ToYaw();
  // atan2(z, sqrt(x * x + y * y));
  float ToPitch();
  // Set to { 0, 0, 0 }
  void Clear();
  // Set to { x, y, z }
  void Set(float x, float y, float z);
  // Linear interpolate toward vec
  kVec3 Lerp(const kVec3 &in vec, float t) const;
  // Linear interpolate in-place toward vec
  kVec3 &Lerp(const kVec3 &in vec, float t);
  // Project onto vec in-place using dot product
  kVec3 &Project(const kVec3 &in normal, float amount);
  // Reflect
  kVec3 &Reflect(const kVec3 &in normal, float energyFactor);
  // Generate a random vector and lerp toward it in-place
  kVec3 &Randomize(float lerp);
  //
  kVec3 &CubicCurve(const kVec3 &in end, float time, const kVec3 &in point);
  //
  kVec3 &QuadraticCurve(const kVec3 &in end, float time, const kVec3 &in pt1, const kVec3 &in pt2);
  // Implements operator +
  kVec3 opAdd(const kVec3 &in);
  // Implements operator +=
  kVec3 &opAddAssign(const kVec3 &in);
  // Implements unary - operator
  kVec3 opNeg();
  // Implements operator -
  kVec3 opSub(const kVec3 &in);
  // Implements operator -=
  kVec3 &opSubAssign(const kVec3 &in);
  // Implements operator *
  kVec3 opMul(const kVec3 &in);
  // Implements operator *
  kVec3 opMul(float val);
  // Implements operator *=
  kVec3 &opMulAssign(const kVec3 &in);
  // Implements operator *=
  kVec3 &opMulAssign(float val);
  // Implements operator /
  kVec3 opDiv(const kVec3 &in);
  // Implements operator /
  kVec3 opDiv(float val);
  // Implements operator /=
  kVec3 &opDivAssign(const kVec3 &in)
  // Implements operator =
  kVec3 &opAssign(const kVec3 &in);
  // Implements const operator []; indices allowed are 0 to 2.
  float opIndex(uint) const;
  // Implements operator []; indices allowed are 0 to 2.
  float opIndex(uint);
  
  // Return a string representation of the vector
  kStr ToString();

  // Implements operator * for quaternion
  kVec3 opMul(const kQuat &in quat);
  // Implements operator *= for quaternion
  kVec3 &opMulAssign(const kQuat &in quat);
  // Convert to quaternion
  kQuat ToQuaternion() const;

  // Properties
  float x;
  float y;
  float z;
}

--------------
Math Namespace
--------------
Contains kexlib math functions.

namespace Math {                                            // C++ equiv or comment
  float Sin(float x);                                       // sinf(x)
  float Cos(float x);                                       // cosf(x)
  float Tan(float x);                                       // tanf(x)
  float ATan2(float y, float x);                            // atan2f(y, x)
  float Fabs(float x);                                      // fabsf(x)
  float ACos(float x);                                      // acosf(x)
  float Sqrt(float x);                                      // sqrtf(x)
  int Abs(int x);                                           // abs(x)
  float Ceil(float x);                                      // ceil(x)
  float Floor(float x);                                     // floor(x)
  float Log(float x);                                       // logf(x)
  float Pow(float x, float y);                              // powf(x, y)
  float Deg2Rad(float);                                     // Degress to radians
  float Rad2Deg(float);                                     // Radians to degrees
  float InvSqrt(float);                                     // Inverse square root
  float IncMax(float v, float inc, float dest);             // Increment v up or down toward dest
  int SysRand();                                            // Return int from std::mt19937
  int Rand();                                               // Custom linear congruential generator
  uint8 RandByte();                                         // Ditto
  int RandMax(int max);                                     // Ditto with modulus by limit
  float NLerp(float f, float t, float dest);                // Linear interpolate but fancy? IDK sorry.
  float Accelerate(float fVal, float fAccel, float fMax);   // Accelerate fVal
  float RandFloat();                                        // Random between 0.0 and 1.0
  float RandCFloat();                                       // Random near 0.0
  float RandRange(float r1, float r2);                      // Random between r1 and r2
  void ClampRef(float &out v, float min, float max);        // Clamp v to between min and max inclusive
  float Lerp(float start, float dest, float t);             // Linear interpolate
  float CosTween(float f);                                  // 0.5 - (cos(t * pi) * 0.5)
  float CosArc(float t);                                    // -((cos(deg2rad(360*t)) - 1.0) * 0.5)
  float SmoothStep(float a, float b, float x);
  float HermiteBlend(float r1, float r2, float r3);
  float Min(float a, float b);                              // Return minimum of a or b
  float Max(float a, float b);                              // Return maximum of a or b
  
  const float pi;      // Constant value of pi
  const kVec3 vecZero; // Constant { 0, 0, 0 } vector
}

-----
kQuat
-----
Quaternion class.

class kQuat {
  kQuat();                                   // Default constructor
  kQuat(float a, float x, float y, float z); // Angle-coordinates
  kQuat(float a, kVec3 &in vec);             // Angle-vec3
  kQuat(float a, float b, float c);
  kQuat(const kQuat &in other);              // Copy constructor
  
  // Normalize quaternion
  kQuat &Normalize();
  // Implements operator +
  kQuat opAdd(const kQuat &in other);
  // Implements operator -
  kQuat opSub(const kQuat &in other);
  // Implements operator *
  kQuat opMul(const kQuat &in other);
  // Implements operator =
  kQuat &opAssign(const kQuat &in other);
  
  // Properties
  float x, y, z, w;
}

------
kAngle
------
Angle class.

class kAngle {
  kAngle();                       // Default constructor
  kAngle(float ang);
  kAngle(const kAngle &in other); // Copy constructor
  
  // Return difference with f
  float Diff(float f) const;
  // Return difference with other
  float Diff(const kAngle &in other) const;
  // Interpolation
  float Interpolate(float dest, float t) const;
  // operator +
  kAngle opAdd(float f) const;
  // operator +=
  kAngle &opAddAssign(float f);
  // operator -
  kAngle opSub(float f) const;
  // operator -=
  kAngle &opSubAssign(float f);
  // operator +
  kAngle opAdd(const kAngle &in other) const;
  // operator +=
  kAngle &opAddAssign(const kAngle &in other);
  // operator -
  kAngle opSub(const kAngle &in other) const;
  // operator -=
  kAngle &opSubAssign(const kAngle &in other);
  // operator =
  kAngle &opAssign(float);
  // operator =
  kAngle &opAssign(const kAngle &in);
  // unary minus operator
  kAngle opNeg() const;
  // cast to float
  float opImplConv();
}

------
kPlane
------
Three-dimensional plane class

// Point-on-plane-side classification enumeration
enum EnumPlaneSide {
  PSIDE_FRONT,
  PSIDE_BACK,
  PSIDE_ON
}

class kPlane {
  // Constructors
  kPlane();
  kPlane(float a, float b, float c, float d);                            // From general plane equation
  kPlane(const kVec3 &in pt1, const kVec3 &in pt2, const kVec3 &in pt3); // From three points
  kPlane(const kVec3 &in normal, const kVec3 &in point);                 // From point and normal
  kPlane(const kPlane &in other);                                        // Copy constructor
  
  // Get normal vector, const
  const kVec3 &Normal() const;
  // Get normal vector
  kVec3 &Normal();
  // Point dot product
  float Dot(const kVec3 &in vec) const;
  // Plane dot product
  float Dot(const kPlane &in other) const;
  // Point-to-plane distance
  float Distance(const kVec3 &in pt) const;
  // 
  float ToYaw() const;
  //
  bool IsFacing(float yaw) const;
  // Classify point with respect to plane
  const int PointOnSide(const kVec3 &in vec) const;
}

---
ref
---
`ref` is a generic handle which can refer to any type of value.

class ref {
  ref();
  ref(const ref &in other);
  ref(const ?&in value);
  ~ref();
  
  // cast to real type
  void opCast(?&out);
  
  // operator @r =
  ref &opHndlAssign(const ref &in other);
  // operator @r =
  ref &opHndlAssign(const ?&in value);
  // operator ==
  bool opEquals(const ref &in other) const;
  // operator ==
  bool opEquals(const ?&in value) const;
}

----
kStr
----
KEX Engine string type.

class kStr {
  kStr();
  kStr(const kStr &in other);
  ~kStr();
  
  // Convert to uppercase in-place
  kStr &ToUpper();
  // Conver to lowercase in-place
  kStr &ToLower();
  // Convert to integer
  int Atoi() const;
  // Convert to float
  float Atof() const;
  // Test if contains substring
  bool Contains(const kStr &in substr) const;
  // Test if contains substring, case-insensitive
  bool ContainsNoCase(const kStr &in substr) const;
  // Test if is empty
  bool IsEmpty() const;
  // First index of substring, or uint64(-1) if not found
  uint64 IndexOf(const kStr &in substr) const;
  // Return length of string
  uint64 Length() const;

  // operator =
  kStr &opAssign(const kStr &in other);
  // operator ==
  bool opEquals(const kStr& in other) const;
  // operator +
  kStr opAdd(const kStr &in other) const;
  // Append bool
  kStr opAdd(bool) const;
  // Append int
  kStr opAdd(int) const;
  // Append uint
  kStr opAdd(uint) const;
  // Append int64
  kStr opAdd(int64) const;
  // Append uint64
  kStr opAdd(uint64) const;
  // Append float
  kStr opAdd(float) const;
  // operator +=
  kStr &opAddAssign(const kStr &in other);
  // operator +=
  kStr &opAddAssign(bool b);
}

----
kSys
----
System interface object. Available as a global singleton:

  kSys Sys;
  
class kSys {
  // Print message to the console
  void Print(const kStr &in str);
  // Print warning message to the console
  void Warning(const kStr &in str);
  // Get screen width
  int VideoWidth();
  // Get screen height
  int VideoHeight();
  // Get mouse X coordinate
  int Mouse_X();
  // Get mouse Y coordinate
  int Mouse_Y();
  // Get value of a cvar as string
  bool GetCvarValue(const kStr &in name, kStr &out value);
}

--------------
kexTranslation
--------------
Provides access to KEX Engine localization facilities. Strings that start with 
a "$" will be looked up in the map of localized strings, and if found, the
substitution will be returned. If not found, the string originally passed in is
returned unchanged.

// Possible localization platform values
enum kexLocPlatform_e {
  LocPlatform_UserPlatformCount = 8,
  LocPlatform_Windows,
  LocPlatform_Linux,
  LocPlatform_Mac,
  LocPlatform_Switch,
  LocPlatform_XboxOne,
  LocPlatform_PlayStation4,
  LocPlatform_XboxSeries,
  LocPlatform_WindowsStore,
  LocPlatform_PlayStation5,
  LocPlatform_FirstUserPlatform,
  LocPlatform_Current
}

class kexTranslation {
  // Get group index of a string
  uint GetGroupIndex(const kStr &in str);
  // Get a string, taking a specific platform into account
  kStr GetString(const kStr &in str, kexLocPlatform_e platform) const;
  // Get a string by index, taking a specific platform into account
  kStr GetString(int index, kexLocPlatform_e platform) const;
  // Get a string in a group with platform
  kStr GetGroupString(const kStr &in str, uint groupIndex, uint platform) const;
  // Get a string by index, with group and platform
  kStr GetGroupString(int index, uint groupIndex, uint platform) const;
  // Translate string with specific platform
  kStr TranslateString(const kStr &in, kexLocPlatform_e) const;
  // Translate string.
  kStr TranslateString(const kStr &in) const;
  // Translate string in group with platform
  kStr TranslateGroupString(const kStr &in str, uint groupIndex, uint platform) const;
  // Translate string making mapped substitutions.
  kStr TranslateStringWithArgs(const kStr &in str, const kDict &in pairs, uint platform) const;
  // Translate group string making mapped substitutions.
  kStr TranslateGroupStringWithArgs(const kStr &in str, const kDict &in pairs, uint groupIndex, uint platform) const;
}

================================================================================
EOF
================================================================================
